From 5543eb9de806f02ba54bb33cd15d23221b5eda4d Mon Sep 17 00:00:00 2001 From: PJ Fanning Date: Fri, 16 Feb 2018 22:41:27 +0000 Subject: [PATCH] add xmlbeans code (latest from xmlbeans svn) git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1824563 13f79535-47bb-0310-9956-ffa450edef68 --- xmlbeans/CHANGES.txt | 180 + xmlbeans/KEYS | 194 + xmlbeans/LICENSE.txt | 202 + xmlbeans/NOTICE.txt | 29 + xmlbeans/README.txt | 57 + xmlbeans/STATUS | 16 + xmlbeans/bin/_setlib | 32 + xmlbeans/bin/_setlib.cmd | 28 + xmlbeans/bin/dumpxsb | 33 + xmlbeans/bin/dumpxsb.cmd | 30 + xmlbeans/bin/inst2xsd | 31 + xmlbeans/bin/inst2xsd.cmd | 33 + xmlbeans/bin/scomp | 31 + xmlbeans/bin/scomp.cmd | 35 + xmlbeans/bin/scopy.cmd | 31 + xmlbeans/bin/sdownload | 31 + xmlbeans/bin/sdownload.cmd | 34 + xmlbeans/bin/sfactor | 34 + xmlbeans/bin/sfactor.cmd | 31 + xmlbeans/bin/svalidate | 32 + xmlbeans/bin/svalidate.cmd | 34 + xmlbeans/bin/validate | 32 + xmlbeans/bin/validate.cmd | 33 + xmlbeans/bin/xpretty | 30 + xmlbeans/bin/xpretty.cmd | 27 + xmlbeans/bin/xsd2inst | 30 + xmlbeans/bin/xsd2inst.cmd | 32 + xmlbeans/bin/xsdtree | 30 + xmlbeans/bin/xsdtree.cmd | 27 + xmlbeans/bin/xstc | 30 + xmlbeans/bin/xstc.cmd | 30 + xmlbeans/build.xml | 1182 +++ xmlbeans/docs/guide/antXmlbean.html | 346 + .../guide/conGettingStartedwithXMLBeans.html | 531 ++ xmlbeans/docs/guide/conHandlingAny.html | 1 + .../guide/conIntroToTheSchemaTypeSystem.html | 229 + .../conJavaTypesGeneratedFromUserDerived.html | 471 ++ .../conMethodsForGeneratedJavaTypes.html | 275 + .../guide/conNavigatingXMLwithCursors.html | 222 + .../conSelectingXMLwithXQueryPathXPath.html | 340 + .../docs/guide/conUnderstandingXMLTokens.html | 189 + .../guide/conUsingBookmarksToAnnotateXML.html | 97 + .../docs/guide/conValidationWithXmlBeans.html | 1 + .../conXMLBeansSupportBuiltInSchemaTypes.html | 343 + xmlbeans/docs/guide/tools.html | 542 ++ .../docs/images/conCursorTokenLocations.gif | Bin 0 -> 17745 bytes xmlbeans/docs/images/conXMLTypeHierarchy.gif | Bin 0 -> 21405 bytes xmlbeans/docs/stylesheet.css | 53 + xmlbeans/docs/xmlbeans.css | 496 ++ xmlbeans/external/lib/jam-0.1.0-src.jar | Bin 0 -> 173899 bytes xmlbeans/external/lib/jam.LICENSE.txt | 202 + xmlbeans/external/lib/junit.LICENSE.txt | 221 + xmlbeans/external/lib/junit.jar | Bin 0 -> 117558 bytes xmlbeans/external/lib/oldxbean.jar | Bin 0 -> 2669036 bytes xmlbeans/external/lib/piccolo.LICENSE.txt | 202 + .../lib/piccolo_apache_dist_20040629.jar | Bin 0 -> 141219 bytes .../lib/piccolo_apache_dist_20040629_v2.jar | Bin 0 -> 143156 bytes .../lib/piccolo_apache_dist_20040711.jar | Bin 0 -> 144059 bytes .../lib/piccolo_apache_dist_20040711_v2.jar | Bin 0 -> 150718 bytes xmlbeans/maven-plugin/INSTRUCTIONS.txt | 68 + xmlbeans/maven-plugin/LICENSE.txt | 203 + xmlbeans/maven-plugin/NOTICE.txt | 3 + xmlbeans/maven-plugin/plugin.jelly | 104 + xmlbeans/maven-plugin/plugin.properties | 50 + xmlbeans/maven-plugin/project.properties | 28 + xmlbeans/maven-plugin/project.xml | 88 + .../xmlbeans/maven/SchemaCompilerWrapper.java | 270 + xmlbeans/samples/AbstractTypes/README.txt | 35 + xmlbeans/samples/AbstractTypes/build.xml | 108 + .../AbstractTypes/schemas/abstractBase.xsd | 30 + .../AbstractTypes/schemas/myfigures.xsd | 39 + .../samples/abstracttypes/AbstractTypes.java | 69 + .../abstracttypes/AbstractTypesTest.java | 30 + xmlbeans/samples/Any/README.txt | 41 + xmlbeans/samples/Any/build.xml | 120 + xmlbeans/samples/Any/schemas/any.xsd | 42 + .../xmlbeans/samples/any/ListOfStrings.java | 195 + .../xmlbeans/samples/any/RootDocument.java | 198 + .../samples/any/StringelementDocument.java | 116 + .../samples/any/impl/ListOfStringsImpl.java | 328 + .../samples/any/impl/RootDocumentImpl.java | 228 + .../any/impl/StringelementDocumentImpl.java | 94 + .../apache/xmlbeans/samples/anytype/Any.java | 457 ++ .../xmlbeans/samples/anytype/AnyTest.java | 45 + xmlbeans/samples/Any/xml/any.xml | 28 + xmlbeans/samples/DateTime/README.txt | 47 + xmlbeans/samples/DateTime/build.xml | 121 + .../samples/DateTime/schemas/datetime.xsd | 42 + .../xmlbeans/samples/datetime/DateTime.java | 308 + .../samples/datetime/DateTimeTest.java | 49 + .../samples/DateTime/xml/datetimesample.xml | 37 + .../DateTime/xml/newdatetimesample.xml | 53 + xmlbeans/samples/MixedContent/README.txt | 34 + xmlbeans/samples/MixedContent/build.xml | 120 + .../MixedContent/schemas/inventory.xsd | 49 + .../xmlbeans/samples/cursor/MixedContent.java | 263 + .../samples/cursor/MixedContentTest.java | 50 + .../MixedContent/xml/inventoryitems.xml | 36 + xmlbeans/samples/OrderMatters/README.txt | 29 + xmlbeans/samples/OrderMatters/build.xml | 120 + .../samples/OrderMatters/schemas/stmt.xsd | 38 + .../xmlbeans/samples/cursor/OrderMatters.java | 102 + .../samples/cursor/OrderMattersTest.java | 46 + xmlbeans/samples/OrderMatters/xml/stmt.xml | 33 + xmlbeans/samples/SampleTemplate/README.txt | 44 + xmlbeans/samples/SampleTemplate/build.xml | 122 + .../samples/SampleTemplate/schemas/hello.xsd | 29 + .../samples/template/SampleTemplate.java | 81 + .../samples/template/SampleTemplateTest.java | 34 + xmlbeans/samples/SampleTemplate/xml/bad.xml | 19 + xmlbeans/samples/SampleTemplate/xml/hello.xml | 21 + xmlbeans/samples/SchemaEnum/README.txt | 28 + xmlbeans/samples/SchemaEnum/build.xml | 120 + .../samples/SchemaEnum/schemas/EasyPO.xsd | 50 + .../SchemaEnum/schemas/PriceSummary.xsd | 63 + .../samples/enumeration/SchemaEnum.java | 279 + .../samples/enumeration/SchemaEnumTest.java | 52 + .../samples/SchemaEnum/xml/PriceSummary.xml | 36 + .../samples/SchemaEnum/xml/PurchaseOrder.xml | 44 + xmlbeans/samples/SubstitutionGroup/README.txt | 52 + xmlbeans/samples/SubstitutionGroup/build.xml | 120 + .../SubstitutionGroup/schemas/EasyPo.xsd | 91 + .../substitutiongroup/SubstitutionGroup.java | 235 + .../SubstitutionGroupTest.java | 49 + .../SubstitutionGroup/xml/Purchase-Order.xml | 55 + .../xml/newPurchase-Order.xml | 72 + xmlbeans/samples/Validation/README.txt | 38 + xmlbeans/samples/Validation/build.xml | 120 + .../samples/Validation/schemas/todolist.xsd | 54 + .../samples/validation/Validation.java | 188 + .../samples/validation/ValidationTest.java | 43 + .../validation/todolist/ActionType.java | 170 + .../samples/validation/todolist/IdType.java | 98 + .../samples/validation/todolist/ItemType.java | 225 + .../samples/validation/todolist/NameType.java | 98 + .../validation/todolist/TodolistDocument.java | 177 + .../todolist/impl/ActionTypeImpl.java | 26 + .../validation/todolist/impl/IdTypeImpl.java | 26 + .../todolist/impl/ItemTypeImpl.java | 445 ++ .../todolist/impl/NameTypeImpl.java | 26 + .../todolist/impl/TodolistDocumentImpl.java | 209 + xmlbeans/samples/Validation/xml/todolist.xml | 36 + xmlbeans/samples/XQueryXPath/README.txt | 48 + xmlbeans/samples/XQueryXPath/build.xml | 120 + .../XQueryXPath/schemas/employeeschema.xsd | 52 + .../xmlbeans/samples/xquery/ExecQuery.java | 154 + .../xmlbeans/samples/xquery/SelectPath.java | 172 + .../xmlbeans/samples/xquery/XQueryXPath.java | 117 + .../samples/xquery/XQueryXPathTest.java | 32 + .../samples/XQueryXPath/xml/employees.xml | 71 + xmlbeans/samples/XmlSort/README.txt | 51 + xmlbeans/samples/XmlSort/build.xml | 96 + .../xmlbeans/samples/cursor/XmlSort.java | 219 + xmlbeans/samples/XmlSort/xml/unsorted.xml | 22 + xmlbeans/samples/XmlTree/README.txt | 38 + xmlbeans/samples/XmlTree/build.xml | 120 + .../xmlbeans/samples/xmltree/XmlEntry.java | 130 + .../xmlbeans/samples/xmltree/XmlModel.java | 154 + .../xmlbeans/samples/xmltree/XmlTree.java | 154 + .../samples/xmltree/XmlTreeFrame.java | 252 + .../xmlbeans/samples/xmltree/XmlTreeTest.java | 42 + .../samples/XmlTree/xml/PurchaseOrder.xml | 44 + xmlbeans/samples/XsdConfig/README.txt | 41 + xmlbeans/samples/XsdConfig/build.xml | 175 + .../samples/XsdConfig/schemas/catalog.xsd | 57 + .../XsdConfig/schemas/myconfig.xsdconfig | 49 + .../samples/xsdconfig/CatalogXsd.java | 155 + .../samples/xsdconfig/CatalogXsdConfig.java | 155 + .../samples/xsdconfig/XsdConfigTest.java | 41 + .../xmlbeans/samples/xsdconfig/XsdTest.java | 40 + xmlbeans/samples/XsdConfig/xml/catalog.xml | 38 + xmlbeans/samples/build.xml | 335 + xmlbeans/samples/vxsdb/README.txt | 51 + xmlbeans/samples/vxsdb/build.xml | 85 + xmlbeans/samples/vxsdb/datamodel.vm | 47 + xmlbeans/samples/vxsdb/doc/NOTES.txt | 27 + xmlbeans/samples/vxsdb/doc/vxsdb.html | 407 + .../vxsdb/external/DdlUtils-1.0-RC1.jar | Bin 0 -> 347708 bytes xmlbeans/samples/vxsdb/global.vm | 33 + xmlbeans/samples/vxsdb/property.vm | 46 + xmlbeans/samples/vxsdb/run.xml | 102 + xmlbeans/samples/vxsdb/schemas/easypo.xsd | 57 + xmlbeans/samples/vxsdb/sql/create.sample.sql | 84 + xmlbeans/samples/vxsdb/src/java/log4j.xml | 33 + .../samples/vxsdb/VelocityXmlBeansDB.java | 192 + xmlbeans/samples/vxsdb/type.vm | 22 + .../samples/vxsdb/xml/datamodel.sample.xml | 118 + .../impl/common/ConcurrentReaderHashMap.java | 1287 ++++ .../xmlbeans/impl/common/EncodingMap.java | 430 ++ .../impl/common/GenericXmlInputStream.java | 243 + .../xmlbeans/impl/common/GlobalLock.java | 30 + .../apache/xmlbeans/impl/common/IOUtil.java | 121 + .../impl/common/IdentityConstraint.java | 668 ++ .../common/InvalidLexicalValueException.java | 76 + .../xmlbeans/impl/common/JarHelper.java | 194 + .../xmlbeans/impl/common/Levenshtein.java | 88 + .../xmlbeans/impl/common/LoadSaveUtils.java | 140 + .../apache/xmlbeans/impl/common/Mutex.java | 83 + .../apache/xmlbeans/impl/common/NameUtil.java | 815 ++ .../xmlbeans/impl/common/PrefixResolver.java | 31 + .../impl/common/PushedInputStream.java | 209 + .../xmlbeans/impl/common/QNameHelper.java | 405 + .../impl/common/ReaderInputStream.java | 59 + .../xmlbeans/impl/common/ResolverUtil.java | 77 + .../apache/xmlbeans/impl/common/Sax2Dom.java | 246 + .../impl/common/SniffedXmlInputStream.java | 296 + .../impl/common/SniffedXmlReader.java | 80 + .../xmlbeans/impl/common/SoftCache.java | 63 + .../xmlbeans/impl/common/SystemCache.java | 111 + .../impl/common/ValidationContext.java | 24 + .../impl/common/ValidatorListener.java | 60 + .../xmlbeans/impl/common/XBeanDebug.java | 119 + .../apache/xmlbeans/impl/common/XMLChar.java | 650 ++ .../xmlbeans/impl/common/XMLNameHelper.java | 116 + .../apache/xmlbeans/impl/common/XPath.java | 1119 +++ .../impl/common/XmlEncodingSniffer.java | 164 + .../xmlbeans/impl/common/XmlErrorPrinter.java | 60 + .../xmlbeans/impl/common/XmlErrorWatcher.java | 69 + .../xmlbeans/impl/common/XmlEventBase.java | 112 + .../xmlbeans/impl/common/XmlLocale.java | 27 + .../xmlbeans/impl/common/XmlNameImpl.java | 107 + .../xmlbeans/impl/common/XmlObjectList.java | 133 + .../impl/common/XmlReaderToWriter.java | 116 + .../xmlbeans/impl/common/XmlStreamUtils.java | 215 + .../xmlbeans/impl/common/XmlWhitespace.java | 157 + .../apache/xmlbeans/impl/common/readme.txt | 5 + .../src/configschema/schema/xmlconfig.xsd | 316 + .../configschema/schema/xmlconfig.xsdconfig | 17 + .../javadoc/JavadocTigerDelegateImpl_150.java | 65 + .../reflect/ReflectTigerDelegateImpl_150.java | 87 + .../impl/richParser/XMLStreamReaderExt.java | 224 + .../richParser/XMLStreamReaderExtImpl.java | 1341 ++++ .../repackage/repackage/EditBuildScript.java | 99 + .../src/repackage/repackage/Repackage.java | 462 ++ .../src/repackage/repackage/Repackager.java | 184 + .../xmlbeans/impl/soap/AttachmentPart.java | 410 + .../org/apache/xmlbeans/impl/soap/Detail.java | 65 + .../xmlbeans/impl/soap/DetailEntry.java | 25 + .../xmlbeans/impl/soap/FactoryFinder.java | 154 + .../xmlbeans/impl/soap/MessageFactory.java | 169 + .../apache/xmlbeans/impl/soap/MimeHeader.java | 60 + .../xmlbeans/impl/soap/MimeHeaders.java | 310 + .../org/apache/xmlbeans/impl/soap/Name.java | 91 + .../org/apache/xmlbeans/impl/soap/Node.java | 92 + .../apache/xmlbeans/impl/soap/SOAPBody.java | 125 + .../xmlbeans/impl/soap/SOAPBodyElement.java | 32 + .../xmlbeans/impl/soap/SOAPConnection.java | 60 + .../impl/soap/SOAPConnectionFactory.java | 65 + .../xmlbeans/impl/soap/SOAPConstants.java | 38 + .../xmlbeans/impl/soap/SOAPElement.java | 288 + .../impl/soap/SOAPElementFactory.java | 117 + .../xmlbeans/impl/soap/SOAPEnvelope.java | 191 + .../xmlbeans/impl/soap/SOAPException.java | 177 + .../xmlbeans/impl/soap/SOAPFactory.java | 147 + .../apache/xmlbeans/impl/soap/SOAPFault.java | 203 + .../xmlbeans/impl/soap/SOAPFaultElement.java | 26 + .../apache/xmlbeans/impl/soap/SOAPHeader.java | 149 + .../xmlbeans/impl/soap/SOAPHeaderElement.java | 77 + .../xmlbeans/impl/soap/SOAPMessage.java | 372 + .../apache/xmlbeans/impl/soap/SOAPPart.java | 261 + .../org/apache/xmlbeans/impl/soap/Text.java | 32 + .../apache/xmlbeans/impl/store/CharUtil.java | 930 +++ .../org/apache/xmlbeans/impl/store/Cur.java | 3611 +++++++++ .../apache/xmlbeans/impl/store/Cursor.java | 4377 +++++++++++ .../apache/xmlbeans/impl/store/DomImpl.java | 4907 ++++++++++++ .../apache/xmlbeans/impl/store/Jsr173.java | 1252 +++ .../apache/xmlbeans/impl/store/Locale.java | 3816 +++++++++ .../org/apache/xmlbeans/impl/store/Path.java | 715 ++ .../xmlbeans/impl/store/PathDelegate.java | 94 + .../apache/xmlbeans/impl/store/Public2.java | 380 + .../xmlbeans/impl/store/QNameFactory.java | 34 + .../org/apache/xmlbeans/impl/store/Query.java | 525 ++ .../xmlbeans/impl/store/QueryDelegate.java | 89 + .../org/apache/xmlbeans/impl/store/Saaj.java | 150 + .../org/apache/xmlbeans/impl/store/Saver.java | 4432 +++++++++++ .../apache/xmlbeans/impl/store/Validate.java | 284 + .../org/apache/xmlbeans/impl/store/Xobj.java | 3251 ++++++++ .../store/org/w3c/dom/DOMConfiguration.java | 27 + .../src/store/org/w3c/dom/DOMStringList.java | 25 + xmlbeans/src/store/org/w3c/dom/TypeInfo.java | 31 + .../store/org/w3c/dom/UserDataHandler.java | 27 + .../xmlbeans/impl/inst2xsd/Inst2Xsd.java | 377 + .../impl/inst2xsd/Inst2XsdOptions.java | 116 + .../impl/inst2xsd/RussianDollStrategy.java | 831 ++ .../impl/inst2xsd/SalamiSliceStrategy.java | 47 + .../impl/inst2xsd/VenetianBlindStrategy.java | 116 + .../impl/inst2xsd/XsdGenStrategy.java | 28 + .../impl/inst2xsd/util/Attribute.java | 99 + .../xmlbeans/impl/inst2xsd/util/Element.java | 138 + .../xmlbeans/impl/inst2xsd/util/Type.java | 326 + .../impl/inst2xsd/util/TypeSystemHolder.java | 396 + .../xpathgen/XPathGenerationException.java | 14 + .../impl/xpathgen/XPathGenerator.java | 208 + .../xmlbeans/impl/xsd2inst/SampleXmlUtil.java | 1189 +++ .../xsd2inst/SchemaInstanceGenerator.java | 353 + xmlbeans/src/toolschema/ltgfmt.xsd | 68 + xmlbeans/src/toolschema/ltgfmt.xsdconfig | 17 + xmlbeans/src/toolschema/substwsdl.xsd | 57 + xmlbeans/src/toolschema/substwsdl.xsdconfig | 17 + xmlbeans/src/toolschema/xsdownload.xsd | 40 + xmlbeans/src/toolschema/xsdownload.xsdconfig | 17 + .../impl/schema/TypeSystemHolder.java | 79 + .../apache/xmlbeans/impl/regex/BMPattern.java | 230 + .../org/apache/xmlbeans/impl/regex/Match.java | 180 + .../org/apache/xmlbeans/impl/regex/Op.java | 247 + .../xmlbeans/impl/regex/ParseException.java | 45 + .../impl/regex/ParserForXMLSchema.java | 476 ++ .../org/apache/xmlbeans/impl/regex/README.txt | 24 + .../apache/xmlbeans/impl/regex/REUtil.java | 326 + .../xmlbeans/impl/regex/RangeToken.java | 614 ++ .../xmlbeans/impl/regex/RegexParser.java | 1080 +++ .../impl/regex/RegularExpression.java | 3147 ++++++++ .../impl/regex/SchemaRegularExpression.java | 51 + .../org/apache/xmlbeans/impl/regex/Token.java | 1518 ++++ .../xmlbeans/impl/regex/message.properties | 39 + .../xmlbeans/impl/regex/message_fr.properties | 32 + .../xmlbeans/impl/regex/message_ja.properties | 32 + .../impl/schema/BuiltinSchemaTypeSystem.java | 1072 +++ .../schema/ClassLoaderResourceLoader.java | 37 + .../impl/schema/FileResourceLoader.java | 80 + .../impl/schema/PathResourceLoader.java | 79 + .../impl/schema/SchemaAnnotationImpl.java | 231 + .../impl/schema/SchemaAttributeGroupImpl.java | 113 + .../impl/schema/SchemaAttributeModelImpl.java | 106 + .../xmlbeans/impl/schema/SchemaContainer.java | 210 + .../impl/schema/SchemaDependencies.java | 162 + .../schema/SchemaGlobalAttributeImpl.java | 85 + .../impl/schema/SchemaGlobalElementImpl.java | 130 + .../schema/SchemaIdentityConstraintImpl.java | 213 + .../impl/schema/SchemaLocalAttributeImpl.java | 147 + .../impl/schema/SchemaLocalElementImpl.java | 113 + .../impl/schema/SchemaModelGroupImpl.java | 119 + .../impl/schema/SchemaParticleImpl.java | 258 + .../impl/schema/SchemaPropertyImpl.java | 204 + .../schema/SchemaStringEnumEntryImpl.java | 47 + .../impl/schema/SchemaTypeCodePrinter.java | 2859 +++++++ .../xmlbeans/impl/schema/SchemaTypeImpl.java | 2471 ++++++ .../impl/schema/SchemaTypeLoaderBase.java | 609 ++ .../impl/schema/SchemaTypeLoaderImpl.java | 615 ++ .../impl/schema/SchemaTypeSystemCompiler.java | 491 ++ .../impl/schema/SchemaTypeSystemImpl.java | 3807 +++++++++ .../impl/schema/SchemaTypeVisitorImpl.java | 514 ++ .../impl/schema/SoapEncSchemaTypeSystem.java | 348 + .../xmlbeans/impl/schema/StscChecker.java | 1732 +++++ .../impl/schema/StscComplexTypeResolver.java | 2128 +++++ .../xmlbeans/impl/schema/StscImporter.java | 1008 +++ .../xmlbeans/impl/schema/StscJavaizer.java | 943 +++ .../xmlbeans/impl/schema/StscResolver.java | 303 + .../impl/schema/StscSimpleTypeResolver.java | 1247 +++ .../xmlbeans/impl/schema/StscState.java | 1595 ++++ .../xmlbeans/impl/schema/StscTranslator.java | 1781 +++++ .../impl/schema/XQuerySchemaTypeSystem.java | 1139 +++ .../xmlbeans/impl/schema/XmlValueRef.java | 67 + .../org/apache/xmlbeans/impl/util/Base64.java | 361 + .../org/apache/xmlbeans/impl/util/Diff.java | 55 + .../apache/xmlbeans/impl/util/FilerImpl.java | 231 + .../org/apache/xmlbeans/impl/util/HexBin.java | 155 + .../xmlbeans/impl/util/XsTypeConverter.java | 790 ++ .../ValidatingInfoXMLStreamReader.java | 179 + .../validator/ValidatingXMLInputStream.java | 389 + .../validator/ValidatingXMLStreamReader.java | 939 +++ .../xmlbeans/impl/validator/Validator.java | 1946 +++++ .../impl/validator/ValidatorUtil.java | 142 + .../impl/values/JavaBase64Holder.java | 153 + .../impl/values/JavaBase64HolderEx.java | 125 + .../impl/values/JavaBooleanHolder.java | 81 + .../impl/values/JavaBooleanHolderEx.java | 61 + .../impl/values/JavaDecimalHolder.java | 177 + .../impl/values/JavaDecimalHolderEx.java | 215 + .../impl/values/JavaDoubleHolder.java | 111 + .../impl/values/JavaDoubleHolderEx.java | 111 + .../xmlbeans/impl/values/JavaFloatHolder.java | 112 + .../impl/values/JavaFloatHolderEx.java | 112 + .../impl/values/JavaGDateHolderEx.java | 319 + .../impl/values/JavaGDurationHolderEx.java | 160 + .../impl/values/JavaHexBinaryHolder.java | 155 + .../impl/values/JavaHexBinaryHolderEx.java | 128 + .../xmlbeans/impl/values/JavaIntHolder.java | 103 + .../xmlbeans/impl/values/JavaIntHolderEx.java | 183 + .../impl/values/JavaIntegerHolder.java | 98 + .../impl/values/JavaIntegerHolderEx.java | 181 + .../xmlbeans/impl/values/JavaLongHolder.java | 95 + .../impl/values/JavaLongHolderEx.java | 181 + .../impl/values/JavaNotationHolder.java | 30 + .../impl/values/JavaNotationHolderEx.java | 142 + .../xmlbeans/impl/values/JavaQNameHolder.java | 199 + .../impl/values/JavaQNameHolderEx.java | 143 + .../values/JavaStringEnumerationHolderEx.java | 73 + .../impl/values/JavaStringHolder.java | 56 + .../impl/values/JavaStringHolderEx.java | 129 + .../xmlbeans/impl/values/JavaUriHolder.java | 66 + .../xmlbeans/impl/values/JavaUriHolderEx.java | 153 + .../impl/values/NamespaceContext.java | 167 + .../xmlbeans/impl/values/StringEnumValue.java | 24 + .../impl/values/XmlAnySimpleTypeImpl.java | 73 + .../values/XmlAnySimpleTypeRestriction.java | 29 + .../xmlbeans/impl/values/XmlAnyTypeImpl.java | 32 + .../xmlbeans/impl/values/XmlAnyUriImpl.java | 20 + .../impl/values/XmlAnyUriRestriction.java | 24 + .../impl/values/XmlBase64BinaryImpl.java | 24 + .../values/XmlBase64BinaryRestriction.java | 25 + .../xmlbeans/impl/values/XmlBooleanImpl.java | 22 + .../impl/values/XmlBooleanRestriction.java | 25 + .../xmlbeans/impl/values/XmlByteImpl.java | 28 + .../impl/values/XmlComplexContentImpl.java | 1335 ++++ .../xmlbeans/impl/values/XmlDateImpl.java | 28 + .../xmlbeans/impl/values/XmlDateTimeImpl.java | 28 + .../xmlbeans/impl/values/XmlDecimalImpl.java | 22 + .../impl/values/XmlDecimalRestriction.java | 25 + .../xmlbeans/impl/values/XmlDoubleImpl.java | 22 + .../impl/values/XmlDoubleRestriction.java | 25 + .../xmlbeans/impl/values/XmlDurationImpl.java | 28 + .../xmlbeans/impl/values/XmlEntitiesImpl.java | 28 + .../xmlbeans/impl/values/XmlEntityImpl.java | 28 + .../xmlbeans/impl/values/XmlFloatImpl.java | 23 + .../impl/values/XmlFloatRestriction.java | 25 + .../xmlbeans/impl/values/XmlGDayImpl.java | 28 + .../impl/values/XmlGMonthDayImpl.java | 27 + .../xmlbeans/impl/values/XmlGMonthImpl.java | 27 + .../xmlbeans/impl/values/XmlGYearImpl.java | 27 + .../impl/values/XmlGYearMonthImpl.java | 27 + .../impl/values/XmlHexBinaryImpl.java | 23 + .../impl/values/XmlHexBinaryRestriction.java | 25 + .../xmlbeans/impl/values/XmlIdImpl.java | 28 + .../xmlbeans/impl/values/XmlIdRefImpl.java | 28 + .../xmlbeans/impl/values/XmlIdRefsImpl.java | 27 + .../xmlbeans/impl/values/XmlIntImpl.java | 23 + .../impl/values/XmlIntRestriction.java | 25 + .../xmlbeans/impl/values/XmlIntegerImpl.java | 23 + .../impl/values/XmlIntegerRestriction.java | 25 + .../xmlbeans/impl/values/XmlLanguageImpl.java | 27 + .../xmlbeans/impl/values/XmlListImpl.java | 360 + .../xmlbeans/impl/values/XmlLongImpl.java | 23 + .../impl/values/XmlLongRestriction.java | 25 + .../xmlbeans/impl/values/XmlNCNameImpl.java | 39 + .../xmlbeans/impl/values/XmlNameImpl.java | 28 + .../impl/values/XmlNegativeIntegerImpl.java | 28 + .../xmlbeans/impl/values/XmlNmTokenImpl.java | 40 + .../xmlbeans/impl/values/XmlNmTokensImpl.java | 28 + .../values/XmlNonNegativeIntegerImpl.java | 28 + .../values/XmlNonPositiveIntegerImpl.java | 28 + .../impl/values/XmlNormalizedStringImpl.java | 27 + .../xmlbeans/impl/values/XmlNotationImpl.java | 22 + .../impl/values/XmlNotationRestriction.java | 25 + .../xmlbeans/impl/values/XmlObjectBase.java | 3217 ++++++++ .../impl/values/XmlPositiveIntegerImpl.java | 27 + .../xmlbeans/impl/values/XmlQNameImpl.java | 23 + .../impl/values/XmlQNameRestriction.java | 25 + .../xmlbeans/impl/values/XmlShortImpl.java | 28 + .../impl/values/XmlStringEnumeration.java | 25 + .../xmlbeans/impl/values/XmlStringImpl.java | 23 + .../impl/values/XmlStringRestriction.java | 25 + .../xmlbeans/impl/values/XmlTimeImpl.java | 28 + .../xmlbeans/impl/values/XmlTokenImpl.java | 28 + .../xmlbeans/impl/values/XmlUnionImpl.java | 665 ++ .../impl/values/XmlUnsignedByteImpl.java | 28 + .../impl/values/XmlUnsignedIntImpl.java | 28 + .../impl/values/XmlUnsignedLongImpl.java | 28 + .../impl/values/XmlUnsignedShortImpl.java | 27 + .../values/XmlValueDisconnectedException.java | 33 + .../values/XmlValueNotNillableException.java | 20 + .../values/XmlValueNotSupportedException.java | 25 + .../values/XmlValueOutOfRangeException.java | 25 + .../apache/xmlbeans/soap/SOAPArrayType.java | 457 ++ .../xmlbeans/soap/SchemaWSDLArrayType.java | 26 + .../impl/values/NamespaceManager.java | 30 + .../xmlbeans/impl/values/TypeStore.java | 353 + .../xmlbeans/impl/values/TypeStoreUser.java | 185 + .../impl/values/TypeStoreUserFactory.java | 28 + .../impl/values/TypeStoreVisitor.java | 51 + .../impl/tool/BaseSchemaResourceManager.java | 719 ++ .../xmlbeans/impl/tool/CodeGenUtil.java | 424 + .../xmlbeans/impl/tool/CommandLine.java | 230 + .../org/apache/xmlbeans/impl/tool/Diff.java | 384 + .../apache/xmlbeans/impl/tool/Extension.java | 70 + .../xmlbeans/impl/tool/FactorImports.java | 475 ++ .../xmlbeans/impl/tool/InstanceValidator.java | 225 + .../xmlbeans/impl/tool/PrettyPrinter.java | 132 + .../apache/xmlbeans/impl/tool/RunXQuery.java | 244 + .../impl/tool/SchemaCodeGenerator.java | 253 + .../xmlbeans/impl/tool/SchemaCompiler.java | 1269 +++ .../impl/tool/SchemaCompilerExtension.java | 39 + .../apache/xmlbeans/impl/tool/SchemaCopy.java | 258 + .../impl/tool/SchemaImportResolver.java | 147 + .../impl/tool/SchemaResourceManager.java | 308 + .../impl/tool/StreamInstanceValidator.java | 235 + .../impl/tool/TypeHierarchyPrinter.java | 287 + .../apache/xmlbeans/impl/tool/XMLBean.java | 870 +++ .../impl/tool/XMLBeanXSTCHarness.java | 109 + .../apache/xmlbeans/impl/tool/XSTCTester.java | 510 ++ .../apache/xmlbeans/impl/tool/XsbDumper.java | 1340 ++++ .../impl/config/BindingConfigImpl.java | 480 ++ .../impl/config/InterfaceExtensionImpl.java | 411 + .../apache/xmlbeans/impl/config/NameSet.java | 224 + .../xmlbeans/impl/config/NameSetBuilder.java | 75 + .../impl/config/PrePostExtensionImpl.java | 169 + .../xmlbeans/impl/config/UserTypeImpl.java | 46 + .../apache/xmlbeans/xml/stream/Attribute.java | 47 + .../xml/stream/AttributeIterator.java | 48 + .../xml/stream/BufferedXMLInputStream.java | 49 + .../xml/stream/ChangePrefixMapping.java | 43 + .../xmlbeans/xml/stream/CharacterData.java | 37 + .../apache/xmlbeans/xml/stream/Comment.java | 30 + .../xmlbeans/xml/stream/ElementFilter.java | 28 + .../xmlbeans/xml/stream/EndDocument.java | 29 + .../xmlbeans/xml/stream/EndElement.java | 31 + .../xmlbeans/xml/stream/EndPrefixMapping.java | 33 + .../xmlbeans/xml/stream/EntityReference.java | 30 + .../apache/xmlbeans/xml/stream/Location.java | 54 + .../xml/stream/ProcessingInstruction.java | 38 + .../xml/stream/ReferenceResolver.java | 39 + .../org/apache/xmlbeans/xml/stream/Space.java | 30 + .../xmlbeans/xml/stream/StartDocument.java | 46 + .../xmlbeans/xml/stream/StartElement.java | 56 + .../xml/stream/StartPrefixMapping.java | 39 + .../apache/xmlbeans/xml/stream/XMLEvent.java | 149 + .../xmlbeans/xml/stream/XMLInputStream.java | 142 + .../apache/xmlbeans/xml/stream/XMLName.java | 57 + .../xml/stream/XMLStreamException.java | 141 + .../xml/stream/events/ElementTypeNames.java | 71 + .../xml/stream/utils/NestedThrowable.java | 105 + .../javax/xml/namespace/NamespaceContext.java | 25 + .../xmlpublic/javax/xml/namespace/QName.java | 231 + .../org/apache/xmlbeans/BindingConfig.java | 99 + .../org/apache/xmlbeans/CDataBookmark.java | 58 + .../apache/xmlbeans/DelegateXmlObject.java | 28 + .../xmlpublic/org/apache/xmlbeans/Filer.java | 46 + .../org/apache/xmlbeans/FilterXmlObject.java | 812 ++ .../xmlpublic/org/apache/xmlbeans/GDate.java | 1105 +++ .../org/apache/xmlbeans/GDateBuilder.java | 1503 ++++ .../apache/xmlbeans/GDateSpecification.java | 239 + .../org/apache/xmlbeans/GDuration.java | 421 + .../org/apache/xmlbeans/GDurationBuilder.java | 668 ++ .../xmlbeans/GDurationSpecification.java | 95 + .../apache/xmlbeans/InterfaceExtension.java | 50 + .../org/apache/xmlbeans/ObjectFactory.java | 31 + .../org/apache/xmlbeans/PrePostExtension.java | 50 + .../org/apache/xmlbeans/QNameCache.java | 150 + .../org/apache/xmlbeans/QNameSet.java | 447 ++ .../org/apache/xmlbeans/QNameSetBuilder.java | 721 ++ .../xmlbeans/QNameSetSpecification.java | 129 + .../org/apache/xmlbeans/ResourceLoader.java | 24 + .../org/apache/xmlbeans/SchemaAnnotated.java | 27 + .../org/apache/xmlbeans/SchemaAnnotation.java | 63 + .../apache/xmlbeans/SchemaAttributeGroup.java | 70 + .../apache/xmlbeans/SchemaAttributeModel.java | 56 + .../org/apache/xmlbeans/SchemaBookmark.java | 42 + .../apache/xmlbeans/SchemaCodePrinter.java | 40 + .../org/apache/xmlbeans/SchemaComponent.java | 127 + .../org/apache/xmlbeans/SchemaField.java | 89 + .../xmlbeans/SchemaGlobalAttribute.java | 50 + .../apache/xmlbeans/SchemaGlobalElement.java | 85 + .../xmlbeans/SchemaIdentityConstraint.java | 97 + .../apache/xmlbeans/SchemaLocalAttribute.java | 38 + .../apache/xmlbeans/SchemaLocalElement.java | 53 + .../org/apache/xmlbeans/SchemaModelGroup.java | 68 + .../org/apache/xmlbeans/SchemaParticle.java | 197 + .../org/apache/xmlbeans/SchemaProperty.java | 232 + .../xmlbeans/SchemaStringEnumEntry.java | 39 + .../org/apache/xmlbeans/SchemaType.java | 908 +++ .../xmlbeans/SchemaTypeElementSequencer.java | 43 + .../org/apache/xmlbeans/SchemaTypeLoader.java | 165 + .../xmlbeans/SchemaTypeLoaderException.java | 78 + .../org/apache/xmlbeans/SchemaTypeSystem.java | 208 + .../org/apache/xmlbeans/SimpleValue.java | 333 + .../xmlbeans/StringEnumAbstractBase.java | 99 + .../org/apache/xmlbeans/SystemProperties.java | 50 + .../org/apache/xmlbeans/UserType.java | 27 + .../XMLStreamValidationException.java | 41 + .../org/apache/xmlbeans/XmlAnySimpleType.java | 154 + .../org/apache/xmlbeans/XmlAnyURI.java | 133 + .../org/apache/xmlbeans/XmlBase64Binary.java | 151 + .../org/apache/xmlbeans/XmlBeans.java | 884 +++ .../org/apache/xmlbeans/XmlBoolean.java | 149 + .../org/apache/xmlbeans/XmlByte.java | 149 + .../org/apache/xmlbeans/XmlCalendar.java | 317 + .../org/apache/xmlbeans/XmlCursor.java | 1813 +++++ .../org/apache/xmlbeans/XmlDate.java | 185 + .../org/apache/xmlbeans/XmlDateTime.java | 188 + .../org/apache/xmlbeans/XmlDecimal.java | 151 + .../xmlbeans/XmlDocumentProperties.java | 200 + .../org/apache/xmlbeans/XmlDouble.java | 149 + .../org/apache/xmlbeans/XmlDuration.java | 151 + .../org/apache/xmlbeans/XmlENTITIES.java | 160 + .../org/apache/xmlbeans/XmlENTITY.java | 133 + .../org/apache/xmlbeans/XmlError.java | 641 ++ .../org/apache/xmlbeans/XmlErrorCodes.java | 1899 +++++ .../org/apache/xmlbeans/XmlException.java | 111 + .../org/apache/xmlbeans/XmlFactoryHook.java | 117 + .../org/apache/xmlbeans/XmlFloat.java | 149 + .../org/apache/xmlbeans/XmlGDay.java | 184 + .../org/apache/xmlbeans/XmlGMonth.java | 184 + .../org/apache/xmlbeans/XmlGMonthDay.java | 170 + .../org/apache/xmlbeans/XmlGYear.java | 184 + .../org/apache/xmlbeans/XmlGYearMonth.java | 171 + .../org/apache/xmlbeans/XmlHexBinary.java | 152 + .../xmlpublic/org/apache/xmlbeans/XmlID.java | 136 + .../org/apache/xmlbeans/XmlIDREF.java | 137 + .../org/apache/xmlbeans/XmlIDREFS.java | 164 + .../xmlpublic/org/apache/xmlbeans/XmlInt.java | 150 + .../org/apache/xmlbeans/XmlInteger.java | 156 + .../org/apache/xmlbeans/XmlLanguage.java | 135 + .../org/apache/xmlbeans/XmlLineNumber.java | 74 + .../org/apache/xmlbeans/XmlLong.java | 150 + .../org/apache/xmlbeans/XmlNCName.java | 139 + .../org/apache/xmlbeans/XmlNMTOKEN.java | 138 + .../org/apache/xmlbeans/XmlNMTOKENS.java | 161 + .../org/apache/xmlbeans/XmlNOTATION.java | 137 + .../org/apache/xmlbeans/XmlName.java | 139 + .../apache/xmlbeans/XmlNegativeInteger.java | 136 + .../xmlbeans/XmlNonNegativeInteger.java | 136 + .../xmlbeans/XmlNonPositiveInteger.java | 136 + .../apache/xmlbeans/XmlNormalizedString.java | 143 + .../org/apache/xmlbeans/XmlObject.java | 852 ++ .../xmlbeans/XmlOptionCharEscapeMap.java | 142 + .../org/apache/xmlbeans/XmlOptions.java | 1036 +++ .../org/apache/xmlbeans/XmlOptionsBean.java | 445 ++ .../apache/xmlbeans/XmlPositiveInteger.java | 136 + .../org/apache/xmlbeans/XmlQName.java | 159 + .../apache/xmlbeans/XmlRuntimeException.java | 109 + .../org/apache/xmlbeans/XmlSaxHandler.java | 57 + .../org/apache/xmlbeans/XmlShort.java | 150 + .../org/apache/xmlbeans/XmlSimpleList.java | 188 + .../org/apache/xmlbeans/XmlString.java | 143 + .../org/apache/xmlbeans/XmlTime.java | 171 + .../org/apache/xmlbeans/XmlToken.java | 147 + .../org/apache/xmlbeans/XmlTokenSource.java | 378 + .../org/apache/xmlbeans/XmlUnsignedByte.java | 152 + .../org/apache/xmlbeans/XmlUnsignedInt.java | 152 + .../org/apache/xmlbeans/XmlUnsignedLong.java | 139 + .../org/apache/xmlbeans/XmlUnsignedShort.java | 152 + .../apache/xmlbeans/XmlValidationError.java | 312 + .../org/apache/xmlbeans/message.properties | 974 +++ .../org/apache/xmlbeans/package.html | 62 + xmlbeans/src/xmlschema/schema/XML.xsd | 81 + xmlbeans/src/xmlschema/schema/XML.xsdconfig | 17 + xmlbeans/src/xpath_xquery/QueryInterface.g | 1 + .../src/xpath_xquery/SelectPathInterface.g | 1 + .../impl/xpath/saxon/XBeansXPath.java | 173 + .../impl/xquery/saxon/XBeansXQuery.java | 125 + xmlbeans/src/xsdschema/schema/XMLSchema.xsd | 2548 ++++++ .../src/xsdschema/schema/XMLSchema.xsdconfig | 17 + .../src/zipcompare/zipcompare/ZipCompare.java | 143 + .../cases/schema/appview/Add_AcctSiebel7.xml | 42 + .../CarLocationMessage-inv.xml | 38 + .../ValidatingStream/CarLocationMessage.xml | 38 + .../xbean/ValidatingStream/Employees.xml | 56 + .../cases/xbean/ValidatingStream/foo-inv.xml | 1 + .../test/cases/xbean/ValidatingStream/foo.xsd | 15 + .../xbean/ValidatingStream/global-attr.xml | 3 + .../xbean/ValidatingStream/location-inv.xml | 11 + .../cases/xbean/ValidatingStream/location.xml | 10 + .../cases/xbean/ValidatingStream/location.xsd | 27 + .../ValidatingStream/mixed-content-inv.xml | 9 + .../xbean/ValidatingStream/mixed-content.xml | 9 + .../xbean/ValidatingStream/mixed-content.xsd | 25 + .../ValidatingStream/nomixed-content-inv.xml | 9 + .../cases/xbean/ValidatingStream/numerals.xsd | 34 + .../xbean/ValidatingStream/person-frag.xml | 6 + .../xbean/ValidatingStream/person-frag2.xml | 5 + .../xbean/ValidatingStream/person-inv.xml | 21 + .../ValidatingStream/person-justname-inv.xml | 6 + .../ValidatingStream/person-justname.xml | 7 + .../ValidatingStream/person-sibling-inv.xml | 17 + .../xbean/ValidatingStream/person-sibling.xml | 17 + .../xbean/ValidatingStream/person-xsi-inv.xml | 7 + .../cases/xbean/ValidatingStream/person.xml | 21 + .../cases/xbean/ValidatingStream/person.xsd | 47 + .../test/cases/xbean/ValidatingStream/po.xml | 33 + .../xbean/ValidatingStream/simpleTypes.xsd | 23 + .../xbean/compile/scomp/detailed/laxDoc.xsd | 42 + .../cases/xbean/compile/scomp/incr/incr1.xsd | 9 + .../xbean/compile/scomp/incr/incr2-1.xsd | 10 + .../cases/xbean/compile/scomp/incr/incr2.xsd | 9 + .../cases/xbean/compile/scomp/incr/incr3.xsd | 3 + .../cases/xbean/compile/scomp/incr/incr4.xsd | 11 + .../cases/xbean/compile/scomp/j2ee/XML.xsd | 81 + .../scomp/j2ee/application-client_1_4.xsd | 276 + .../compile/scomp/j2ee/application_1_4.xsd | 329 + .../compile/scomp/j2ee/connector_1_5.xsd | 1011 +++ .../xbean/compile/scomp/j2ee/ejb-jar_2_1.xsd | 2383 ++++++ .../xbean/compile/scomp/j2ee/j2ee_1_4.xsd | 1406 ++++ .../xbean/compile/scomp/j2ee/jsp_2_0.xsd | 304 + .../xbean/compile/scomp/j2ee/web-app_2_4.xsd | 1278 +++ .../compile/scomp/pricequote/PriceQuote.xsd | 15 + .../compile/scomp/schemacompiler/enum1.xsd_ | 35 + .../scomp/schemacompiler/enum1_redefine.xsd_ | 37 + .../compile/scomp/schemacompiler/enum2.xsd_ | 53 + .../scomp/schemacompiler/enum2_redefine.xsd_ | 36 + .../compile/scomp/schemacompiler/enum3.xsd_ | 33 + .../scomp/schemacompiler/enum3_redefine.xsd_ | 35 + .../compile/scomp/schemacompiler/ext/H1.java | 8 + .../compile/scomp/schemacompiler/ext/H2.java | 9 + .../compile/scomp/schemacompiler/ext/I1.java | 6 + .../compile/scomp/schemacompiler/ext/I2.java | 6 + .../methodsColide_jira205_278.xsd_ | 37 + .../methodsColide_jira205_278.xsdconfig_ | 17 + .../scomp/schemacompiler/union_initial.xsd | 43 + .../scomp/schemacompiler/union_redefine.xsd | 35 + .../simple/javasrc/SimplePersonTest.java | 108 + .../xbean/compile/scomp/simple/person.xml | 16 + .../xbean/compile/scomp/simple/person.xsd | 65 + .../xbean/compile/scomp/simple/simplec.xsd | 27 + .../cases/xbean/compile/som/constraints.xsd_ | 101 + .../xbean/compile/som/constraints_added.xsd_ | 94 + .../cases/xbean/compile/som/datatypes.xsd_ | 206 + .../xbean/compile/som/datatypes_added.xsd_ | 197 + .../xbean/compile/som/datatypes_modified.xsd_ | 205 + .../xbean/compile/som/derived_types.xsd_ | 208 + .../compile/som/derived_types_added.xsd_ | 201 + .../compile/som/derived_types_modifed.xsd_ | 236 + .../cases/xbean/compile/som/elemattr.xsd_ | 63 + .../xbean/compile/som/elemattr_added.xsd_ | 59 + .../xbean/compile/som/elemattr_modified.xsd_ | 67 + .../test/cases/xbean/compile/som/groups.xsd_ | 101 + .../cases/xbean/compile/som/groups_added.xsd_ | 114 + .../xbean/compile/som/groups_modified.xsd_ | 70 + .../som/instance_constraints_invalid.xml | 45 + .../som/instance_constraints_valid.xml | 46 + .../compile/som/instance_datatypes_valid.xml | 87 + .../som/instance_derived_types_modify.xml | 70 + .../som/instance_derived_types_valid.xml | 84 + .../xbean/compile/som/instance_elemattr.xml | 55 + .../compile/som/instance_elemattr_added.xml | 61 + .../compile/som/instance_elemattr_valid.xml | 64 + .../som/instance_simple_types_invalid.xml | 73 + .../compile/som/instance_subst_grps_valid.xml | 52 + .../cases/xbean/compile/som/namespaces1.xsd_ | 51 + .../cases/xbean/compile/som/namespaces2.xsd_ | 52 + .../som/namespaces_import_fileonly.xsd_ | 54 + .../som/namespaces_import_filepath.xsd | 40 + .../xbean/compile/som/namespaces_include.xsd_ | 39 + .../compile/som/namespaces_noimports.xsd_ | 37 + .../xbean/compile/som/reusable_grps.xsd_ | 103 + .../compile/som/reusable_grps_added.xsd_ | 99 + .../compile/som/reusable_grps_modified.xsd_ | 124 + .../test/cases/xbean/dom/ComplexTypeTest.xsd | 60 + .../xbean/dom/W3C/level2/core/files/README | 1 + .../dom/W3C/level2/core/files/hc_staff.xml | 48 + .../dom/W3C/level2/core/files/nodtdstaff.xml | 11 + .../xbean/dom/W3C/level2/core/files/staff.dtd | 17 + .../xbean/dom/W3C/level2/core/files/staff.xml | 48 + .../dom/W3C/level2/core/files/staff2.dtd | 8 + .../dom/W3C/level2/core/files/staff2.xml | 13 + .../dom/W3C/level2/core/files/staffNS.dtd | 45 + .../dom/W3C/level2/core/files/staffNS.xml | 48 + .../W3C/level2/core/files/xhtml1-frameset.dtd | 1235 +++ .../W3C/level2/core/files/xhtml1-strict.dtd | 978 +++ .../level2/core/files/xhtml1-transitional.dtd | 1201 +++ xmlbeans/test/cases/xbean/dom/dumb.xsd | 35 + xmlbeans/test/cases/xbean/dom/id.xml | 87 + xmlbeans/test/cases/xbean/dom/id.xsd | 47 + .../interfaceFeature/averageCase/po.xsd | 62 + .../interfaceFeature/averageCase/po.xsdconfig | 23 + .../methodNameCollision/company.xsd | 38 + .../methodNameCollision/company.xsdconfig | 23 + .../interfaceFeature/multInterfaces/po.xsd | 62 + .../multInterfaces/po.xsdconfig | 23 + .../interfaceFeature/readOnlyBean/po.xsd | 62 + .../readOnlyBean/po.xsdconfig | 23 + .../ValueRestriction/company.xsd | 38 + .../ValueRestriction/company.xsdconfig | 26 + .../prePostFeature/readOnlyBean/po.xsd | 62 + .../prePostFeature/readOnlyBean/po.xsdconfig | 26 + .../xbean/marshal/com/mytest/YourClass.java | 461 ++ xmlbeans/test/cases/xbean/misc/dyntest.xml | 8 + xmlbeans/test/cases/xbean/misc/dyntest.xsd | 18 + xmlbeans/test/cases/xbean/misc/dyntest2.xml | 5 + xmlbeans/test/cases/xbean/misc/dyntest2.xsd | 17 + .../test/cases/xbean/misc/jira/easypo.xml | 24 + .../cases/xbean/misc/jira/xmlbeans_04.xsd_ | 29 + .../cases/xbean/misc/jira/xmlbeans_08.xsd_ | 27 + .../cases/xbean/misc/jira/xmlbeans_08a.xsd_ | 19 + .../cases/xbean/misc/jira/xmlbeans_09.xml | 26 + .../cases/xbean/misc/jira/xmlbeans_09.xsd_ | 75 + .../cases/xbean/misc/jira/xmlbeans_102.xsd | 173 + .../misc/jira/xmlbeans_102_netui-config.xsd_ | 173 + .../cases/xbean/misc/jira/xmlbeans_105.xml | 5 + .../cases/xbean/misc/jira/xmlbeans_105.xsd | 21 + .../cases/xbean/misc/jira/xmlbeans_105a.xsd | 20 + .../cases/xbean/misc/jira/xmlbeans_175.xsd | 31 + .../cases/xbean/misc/jira/xmlbeans_177.xml | 9 + .../cases/xbean/misc/jira/xmlbeans_177.xsd | 13 + .../cases/xbean/misc/jira/xmlbeans_177a.xml | 7 + .../cases/xbean/misc/jira/xmlbeans_177a.xsd | 17 + .../jira/xmlbeans_184_datentypen_V1.30.xsd_ | 615 ++ .../jira/xmlbeans_184_ehd_header_V1.30.xsd_ | 61 + .../jira/xmlbeans_184_ehd_root_V1.30.xsd_ | 87 + .../misc/jira/xmlbeans_184_keytabs_V1.30.xsd_ | 78 + .../jira/xmlbeans_184_vdx_data_V1.04.xsd_ | 1261 +++ .../jira/xmlbeans_184_vdx_header_V1.04.xsd_ | 163 + .../jira/xmlbeans_184_vdx_root_V1.04.xsd_ | 73 + .../cases/xbean/misc/jira/xmlbeans_208.xsd | 32 + .../cases/xbean/misc/jira/xmlbeans_228.xsd | 33 + .../cases/xbean/misc/jira/xmlbeans_236.xsd_ | 28 + .../cases/xbean/misc/jira/xmlbeans_239a.xsd_ | 44 + .../cases/xbean/misc/jira/xmlbeans_239b.xsd_ | 44 + .../cases/xbean/misc/jira/xmlbeans_239c.xsd_ | 46 + .../cases/xbean/misc/jira/xmlbeans_251.xsd_ | 26 + .../misc/jira/xmlbeans_307_maxallowedenum.xsd | 3683 +++++++++ .../jira/xmlbeans_307_morethanallowedenum.xsd | 3696 +++++++++ .../cases/xbean/misc/jira/xmlbeans_33a.xsd | 54 + .../cases/xbean/misc/jira/xmlbeans_33b.xsd | 41 + .../cases/xbean/misc/jira/xmlbeans_34a.xsd_ | 40 + .../cases/xbean/misc/jira/xmlbeans_34b.xsd_ | 46 + .../cases/xbean/misc/jira/xmlbeans_35.xsd_ | 95 + .../cases/xbean/misc/jira/xmlbeans_45a.xsd | 11 + .../cases/xbean/misc/jira/xmlbeans_45b.xsd | 17 + .../cases/xbean/misc/jira/xmlbeans_46.xsd | 16 + .../cases/xbean/misc/jira/xmlbeans_48.xsd | 15 + .../cases/xbean/misc/jira/xmlbeans_49.xsd_ | 767 ++ .../cases/xbean/misc/jira/xmlbeans_54.xsd_ | 34 + .../cases/xbean/misc/jira/xmlbeans_57.xml | 4 + .../cases/xbean/misc/jira/xmlbeans_62.xml | 36 + .../cases/xbean/misc/jira/xmlbeans_64.xml | 915 +++ .../cases/xbean/misc/jira/xmlbeans_64.xsd | 131 + .../cases/xbean/misc/jira/xmlbeans_68.xsd | 19 + .../cases/xbean/misc/jira/xmlbeans_71.xml | 7 + .../cases/xbean/misc/jira/xmlbeans_71.xsd | 13 + .../cases/xbean/misc/jira/xmlbeans_78.xml | 40 + .../cases/xbean/misc/jira/xmlbeans_97.xsd | 21 + .../xbean/misc/jira/xmlbeans_97.xsdconfig | 21 + .../cases/xbean/misc/jira/xmlbeans_98.xml | 4 + .../cases/xbean/misc/jira/xmlbeans_98.xsd | 16 + .../cases/xbean/misc/jira/xmlbeans_98_exp.xml | 0 .../cases/xbean/misc/jira/xmlbeans_99.xml | 11 + .../cases/xbean/misc/jira/xmlbeans_99.xsd | 20 + .../test/cases/xbean/misc/primitiveTypes.xml | 109 + .../xbean/misc/signature-example-dsa.xml | 70 + .../xbean/misc/signature-example-rsa.xml | 58 + .../cases/xbean/misc/signature-example.xml | 55 + .../test/cases/xbean/misc/syscachetest.xsd | 35 + xmlbeans/test/cases/xbean/misc/xkms-1.0.wsdl | 1364 ++++ .../cases/xbean/misc/xmldsig-core-schema.xsd | 309 + .../xbean/schema/typesonly/typesonly.xsd | 60 + .../xbean/scomp/attribute/AttributeGroup.xsd | 27 + .../scomp/attribute/GlobalAttrDefault.xsd | 16 + .../xbean/scomp/attribute/GlobalAttrFixed.xsd | 16 + .../xbean/scomp/attribute/GlobalAttrId.xsd | 28 + .../xbean/scomp/attribute/GlobalAttrType.xsd | 27 + .../scomp/attribute/LocalAttrFixedDefault.xsd | 16 + .../xbean/scomp/attribute/LocalAttrUse.xsd | 27 + .../xbean/scomp/contentType/Anonymous.xsd | 27 + .../scomp/contentType/ComplexTypeTest.xsd | 47 + .../cases/xbean/scomp/contentType/Group.xsd | 64 + .../xbean/scomp/contentType/ListType.xsd | 48 + .../cases/xbean/scomp/contentType/Named.xsd | 28 + .../xbean/scomp/contentType/SimpleType.xsd | 15 + .../xbean/scomp/contentType/UnionType.xsd | 59 + .../contentType/builtInTypes/DateTime.xsd | 19 + .../contentType/builtInTypes/NumberBased.xsd | 25 + .../contentType/builtInTypes/StringBased.xsd | 16 + .../cases/xbean/scomp/derivation/Abstract.xsd | 35 + .../scomp/derivation/AttributeExtension.xsd | 26 + .../scomp/derivation/AttributeRestriction.xsd | 33 + .../derivation/AttributeUseProhibited.xsd | 17 + .../scomp/derivation/AttributeWCExtension.xsd | 148 + .../derivation/AttributeWCRestriction.xsd | 56 + .../cases/xbean/scomp/derivation/Block.xsd | 177 + .../derivation/ComplexContentExtension.xsd | 40 + .../scomp/derivation/ElementRestriction.xsd | 37 + .../scomp/derivation/ElementWCRestriction.xsd | 45 + .../xbean/scomp/derivation/EmptyContent.xsd | 44 + .../scomp/derivation/FinalBlockDefault.xsd | 75 + .../scomp/derivation/GroupRestrictionTest.xsd | 95 + .../derivation/MixedContentExtension.xsd | 23 + .../derivation/MixedContentRestriction.xsd | 60 + .../derivation/SimpleContentExtension.xsd | 27 + .../derivation/SimpleTypeRestriction.xsd | 21 + .../derivation/facets/DateTimePattern.xsd | 57 + .../derivation/facets/FacetRestriction.xsd | 98 + .../xbean/scomp/derivation/facets/Facets.xsd | 93 + .../derivation/facets/ListRestriction.xsd | 65 + .../derivation/facets/UnionRestriction.xsd | 27 + .../test/cases/xbean/scomp/element/Any.xsd | 9 + .../xbean/scomp/element/GlobalEltDefault.xsd | 16 + .../xbean/scomp/element/GlobalEltFixed.xsd | 9 + .../xbean/scomp/element/GlobalEltNillable.xsd | 22 + .../scomp/element/LocalEltMinMaxOccurs.xsd | 26 + .../xbean/scomp/element/NamedModelGroup.xsd | 31 + .../cases/xbean/scomp/element/NillTest.xsd | 38 + .../xbean/scomp/idConstraints/Constraint.xsd | 95 + .../scomp/namespace/AttributeFormDefault.xsd | 22 + .../xbean/scomp/namespace/AttributeWC.xsd | 89 + .../scomp/namespace/ElementFormDefault.xsd | 15 + .../cases/xbean/scomp/namespace/ElementWC.xsd | 120 + .../xbean/scomp/namespace/NoNamespace.xsd | 9 + .../xbean/scomp/redefine/AttrRedefineSub.xs | 12 + .../scomp/redefine/AttrRedefineSuper.xsd | 20 + .../xbean/scomp/redefine/BaseAttrGroup.xs | 10 + .../xbean/scomp/redefine/BaseModelGroup.xs | 16 + .../cases/xbean/scomp/redefine/BaseSimple.xs | 17 + .../xbean/scomp/redefine/ModelGroupSub.xs | 20 + .../xbean/scomp/redefine/ModelGroupSuper.xsd | 23 + .../xbean/scomp/redefine/SimpleRedefined.xsd | 17 + .../cases/xbean/scomp/redefine/TypeBase.xs | 5 + .../xbean/scomp/redefine/TypeRedefine.xsd | 5 + .../cases/xbean/scomp/substGroup/Abstract.xsd | 23 + .../cases/xbean/scomp/substGroup/Block.xsd | 29 + .../cases/xbean/scomp/substGroup/Deep.xsd | 81 + .../cases/xbean/scomp/substGroup/OneLevel.xsd | 52 + .../xbean/scomp/substGroup/UserAbstract.xsd | 22 + .../xbean/scomp/substGroup/UserReported.xsd | 22 + .../cases/xbean/scomp/substGroup/Wide.xsd | 68 + .../test/cases/xbean/simple/dumb/dumb.xml | 2 + .../test/cases/xbean/simple/dumb/dumb.xsd | 23 + .../test/cases/xbean/simple/dumb/sub/bar.xsd | 11 + .../DupElementsInSameSchema.xsd | 8 + .../simple/dupSchemaElements/custOrdUdf.xsd | 21 + .../simple/dupSchemaElements/viewtarget.xsd | 32 + .../xbean/tools/inst2xsd/options/base.xml | 5 + .../xbean/tools/inst2xsd/options/base0.xsd | 11 + .../xbean/tools/inst2xsd/options/base_rd0.xsd | 12 + .../tools/inst2xsd/options/base_rd_eN0.xsd | 12 + .../tools/inst2xsd/options/base_rd_scs0.xsd | 12 + .../inst2xsd/options/base_rd_scs_eN0.xsd | 12 + .../xbean/tools/inst2xsd/options/base_ss0.xsd | 15 + .../tools/inst2xsd/options/base_ss_eN0.xsd | 15 + .../tools/inst2xsd/options/base_ss_scs0.xsd | 15 + .../inst2xsd/options/base_ss_scs_eN0.xsd | 15 + .../xbean/tools/inst2xsd/options/base_vb0.xsd | 11 + .../tools/inst2xsd/options/base_vb_eN0.xsd | 11 + .../tools/inst2xsd/options/base_vb_scs0.xsd | 11 + .../inst2xsd/options/base_vb_scs_eN0.xsd | 11 + .../xbean/tools/inst2xsd/schema/choice.xml | 6 + .../tools/inst2xsd/schema/choice_ss0.xsd | 41 + .../schema/complex/choice/attrchoice.xml | 7 + .../schema/complex/choice/attrchoice_ss0.xsd | 22 + .../schema/complex/choice/attrchoice_ss1.xsd | 35 + .../schema/complex/choice/nschoice.xml | 12 + .../schema/complex/choice/nschoice_ss0.xsd | 13 + .../schema/complex/choice/nschoice_ss1.xsd | 13 + .../schema/complex/choice/nschoice_ss2.xsd | 13 + .../schema/complex/choice/nschoice_ss3.xsd | 17 + .../schema/complex/choice/schema0.xsd | 4 + .../schema/complex/choice/schema1.xsd | 29 + .../schema/complex/choice/simplechoice.xml | 7 + .../complex/choice/simplechoice_rd0.xsd | 11 + .../complex/choice/simplechoice_ss0.xsd | 13 + .../complex/choice/simplechoice_vb0.xsd | 10 + .../schema/complex/enum/attr/attrenum.xml | 11 + .../schema/complex/enum/attr/attrenum_rd0.xsd | 5 + .../schema/complex/enum/attr/attrenum_rd1.xsd | 5 + .../schema/complex/enum/attr/attrenum_rd2.xsd | 44 + .../complex/enum/attr/attrenum_rd_enum0.xsd | 5 + .../complex/enum/attr/attrenum_rd_enum1.xsd | 5 + .../complex/enum/attr/attrenum_rd_enum2.xsd | 44 + .../schema/complex/enum/attr/attrenum_ss0.xsd | 5 + .../schema/complex/enum/attr/attrenum_ss1.xsd | 5 + .../schema/complex/enum/attr/attrenum_ss2.xsd | 38 + .../complex/enum/attr/attrenum_ss_enum0.xsd | 5 + .../complex/enum/attr/attrenum_ss_enum1.xsd | 4 + .../complex/enum/attr/attrenum_ss_enum2.xsd | 37 + .../schema/complex/enum/attr/attrenum_vb0.xsd | 5 + .../schema/complex/enum/attr/attrenum_vb1.xsd | 5 + .../schema/complex/enum/attr/attrenum_vb2.xsd | 31 + .../complex/enum/attr/attrenum_vb_enum0.xsd | 5 + .../complex/enum/attr/attrenum_vb_enum1.xsd | 5 + .../complex/enum/attr/attrenum_vb_enum2.xsd | 31 + .../inst2xsd/schema/complex/enum/enum.xml | 12 + .../schema/complex/enum/enum2_rd0.xsd | 23 + .../schema/complex/enum/enum2_ss0.xsd | 33 + .../schema/complex/enum/enum2_vb0.xsd | 20 + .../schema/complex/enum/enumQName.xml | 12 + .../schema/complex/enum/enumQName_vb_eN0.xsd | 20 + .../complex/enum/enumQName_vb_enum0.xsd | 27 + .../schema/complex/enum/enum_vb_eN0.xsd | 20 + .../schema/complex/enum/enum_vb_scs_enum0.xsd | 20 + .../schema/complex/global/globalattr_rd0.xsd | 4 + .../schema/complex/global/globalattr_rd1.xsd | 29 + .../schema/complex/global/globalattr_ss0.xsd | 4 + .../schema/complex/global/globalattr_ss1.xsd | 32 + .../schema/complex/global/globalattr_vb0.xsd | 4 + .../schema/complex/global/globalattr_vb1.xsd | 26 + .../schema/complex/global/globalattribute.xml | 5 + .../complex/nestedNSArray/nestedArray_rd0.xsd | 11 + .../complex/nestedNSArray/nestedArray_rd1.xsd | 12 + .../complex/nestedNSArray/nestedArray_rd2.xsd | 11 + .../complex/nestedNSArray/nestedArray_rd3.xsd | 11 + .../complex/nestedNSArray/nestedArray_ss0.xsd | 11 + .../complex/nestedNSArray/nestedArray_ss1.xsd | 12 + .../complex/nestedNSArray/nestedArray_ss2.xsd | 12 + .../complex/nestedNSArray/nestedArray_ss3.xsd | 11 + .../complex/nestedNSArray/nestedArray_vb0.xsd | 10 + .../complex/nestedNSArray/nestedArray_vb1.xsd | 11 + .../complex/nestedNSArray/nestedArray_vb2.xsd | 10 + .../complex/nestedNSArray/nestedArray_vb3.xsd | 10 + .../complex/nestedNSArray/nestedNSArray.xml | 12 + .../inst2xsd/schema/complex/sample/choice.xml | 7 + .../schema/complex/sample/choice_rd0.xsd | 5 + .../schema/complex/sample/choice_rd1.xsd | 60 + .../schema/complex/sample/choice_rd_eN0.xsd | 5 + .../schema/complex/sample/choice_rd_eN1.xsd | 60 + .../complex/sample/choice_rd_scs_eN0.xsd | 5 + .../complex/sample/choice_rd_scs_eN1.xsd | 60 + .../inst2xsd/schema/complex/sample/oops0.xsd | 5 + .../inst2xsd/schema/complex/sample/oops1.xsd | 60 + .../inst2xsd/schema/examples/cd_catalog.xml | 212 + .../schema/examples/cd_catalog_rd0.xsd | 33 + .../schema/examples/cd_catalog_ss0.xsd | 40 + .../schema/examples/cd_catalog_vb0.xsd | 32 + .../inst2xsd/schema/examples/cdcatalog.xml | 27 + .../schema/examples/cdcatalog_rd0.xsd | 21 + .../schema/examples/cdcatalog_ss0.xsd | 28 + .../schema/examples/cdcatalog_vb0.xsd | 19 + .../inst2xsd/schema/examples/component.xml | 17 + .../schema/examples/component_rd0.xsd | 29 + .../schema/examples/component_ss0.xsd | 31 + .../schema/examples/component_vb0.xsd | 26 + .../inst2xsd/schema/examples/html_example.xml | 18 + .../schema/examples/html_example_rd0.xsd | 54 + .../schema/examples/html_example_ss0.xsd | 60 + .../schema/examples/html_example_vb0.xsd | 47 + .../tools/inst2xsd/schema/examples/po/po.xml | 33 + .../inst2xsd/schema/examples/po/po_rd_eN0.xsd | 53 + .../inst2xsd/schema/examples/po/po_ss0.xsd | 123 + .../inst2xsd/schema/examples/po/po_ss_eN0.xsd | 67 + .../inst2xsd/schema/examples/po/po_vb0.xsd | 62 + .../inst2xsd/schema/examples/po/po_vb_eN0.xsd | 48 + .../schema/examples/po/po_vb_scs0.xsd | 48 + .../schema/examples/po/po_vb_scs_enum0.xsd | 62 + .../inst2xsd/schema/examples/rss2sample.xml | 41 + .../rss2sample_contentsmart_4enum_vb0.xsd | 77 + .../rss2sample_contentsmart_neverenum_vb0.xsd | 34 + .../rss2sample_contentstring_4enum_vb0.xsd | 77 + ...rss2sample_contentstring_neverenum_vb0.xsd | 34 + .../examples/rss2sample_contentstring_vb0.xsd | 77 + .../examples/rss2sample_neverenum_vb0.xsd | 34 + .../schema/examples/rss2sample_rd0.xsd | 80 + .../schema/examples/rss2sample_ss0.xsd | 97 + .../schema/examples/rss2sample_vb0.xsd | 77 + .../inst2xsd/schema/examples/sampleRss091.xml | 50 + .../schema/examples/sampleRss091_rd0.xsd | 77 + .../schema/examples/sampleRss091_ss0.xsd | 93 + .../schema/examples/sampleRss091_vb0.xsd | 73 + .../inst2xsd/schema/examples/sampleRss092.xml | 103 + .../schema/examples/sampleRss092_rd0.xsd | 66 + .../schema/examples/sampleRss092_ss0.xsd | 78 + .../schema/examples/sampleRss092_vb0.xsd | 61 + .../inst2xsd/schema/examples/schema0.xsd | 61 + .../inst2xsd/schema/examples/slashdot.rdf.xml | 76 + .../inst2xsd/schema/examples/slashdot.xml | 124 + .../schema/examples/slashdotrdf_rd0.xsd | 13 + .../schema/examples/slashdotrdf_rd1.xsd | 69 + .../schema/examples/slashdotrdf_ss0.xsd | 13 + .../schema/examples/slashdotrdf_ss1.xsd | 51 + .../schema/examples/slashdotrdf_vb0.xsd | 12 + .../schema/examples/slashdotrdf_vb1.xsd | 65 + .../examples/slashdotxml_neverenum_ss0.xsd | 34 + .../schema/examples/slashdotxml_rd0.xsd | 113 + .../schema/examples/slashdotxml_ss0.xsd | 123 + .../schema/examples/slashdotxml_vb0.xsd | 111 + .../inst2xsd/schema/examples/xmlnews.xml | 26 + .../inst2xsd/schema/examples/xmlnews_rd0.xsd | 50 + .../inst2xsd/schema/examples/xmlnews_ss0.xsd | 61 + .../inst2xsd/schema/examples/xmlnews_vb0.xsd | 43 + .../inst2xsd/schema/examples/xsl_example.xml | 25 + .../inst2xsd/schema/examples/xsl_rd0.xsd | 34 + .../inst2xsd/schema/examples/xsl_rd1.xsd | 51 + .../inst2xsd/schema/examples/xsl_ss0.xsd | 35 + .../inst2xsd/schema/examples/xsl_ss1.xsd | 50 + .../inst2xsd/schema/examples/xsl_vb0.xsd | 30 + .../inst2xsd/schema/examples/xsl_vb1.xsd | 41 + .../schema/namespaces/duplicatedNS.xml | 17 + .../schema/namespaces/duplicatedNS_rd0.xsd | 23 + .../schema/namespaces/duplicatedNS_ss0.xsd | 18 + .../schema/namespaces/duplicatedNS_vb0.xsd | 13 + .../inst2xsd/schema/namespaces/multipleNS.xml | 10 + .../schema/namespaces/multipleNS_rd0.xsd | 4 + .../schema/namespaces/multipleNS_rd1.xsd | 4 + .../schema/namespaces/multipleNS_rd2.xsd | 4 + .../schema/namespaces/multipleNS_rd3.xsd | 13 + .../schema/namespaces/multipleNS_ss0.xsd | 4 + .../schema/namespaces/multipleNS_ss1.xsd | 4 + .../schema/namespaces/multipleNS_ss2.xsd | 4 + .../schema/namespaces/multipleNS_ss3.xsd | 14 + .../schema/namespaces/multipleNS_vb0.xsd | 4 + .../schema/namespaces/multipleNS_vb1.xsd | 4 + .../schema/namespaces/multipleNS_vb2.xsd | 4 + .../schema/namespaces/multipleNS_vb3.xsd | 12 + .../schema/namespaces/multipleNestedNS.xml | 12 + .../namespaces/multipleNestedNS_rd0.xsd | 5 + .../namespaces/multipleNestedNS_rd1.xsd | 5 + .../namespaces/multipleNestedNS_rd2.xsd | 4 + .../namespaces/multipleNestedNS_rd3.xsd | 16 + .../namespaces/multipleNestedNS_ss0.xsd | 5 + .../namespaces/multipleNestedNS_ss1.xsd | 5 + .../namespaces/multipleNestedNS_ss2.xsd | 17 + .../namespaces/multipleNestedNS_ss3.xsd | 4 + .../namespaces/multipleNestedNS_vb0.xsd | 5 + .../namespaces/multipleNestedNS_vb1.xsd | 5 + .../namespaces/multipleNestedNS_vb2.xsd | 4 + .../namespaces/multipleNestedNS_vb3.xsd | 15 + .../tools/inst2xsd/schema/namespaces/must.xml | 6 + .../inst2xsd/schema/namespaces/must_rd0.xsd | 10 + .../inst2xsd/schema/namespaces/must_rd1.xsd | 10 + .../inst2xsd/schema/namespaces/must_ss0.xsd | 10 + .../inst2xsd/schema/namespaces/must_ss1.xsd | 10 + .../inst2xsd/schema/namespaces/must_vb0.xsd | 15 + .../inst2xsd/schema/namespaces/must_vb1.xsd | 9 + .../inst2xsd/schema/namespaces/simple.xml | 6 + .../inst2xsd/schema/namespaces/simple_rd0.xsd | 13 + .../inst2xsd/schema/namespaces/simple_ss0.xsd | 17 + .../inst2xsd/schema/namespaces/simple_vb0.xsd | 12 + .../tools/inst2xsd/schema/simpleName.xml | 5 + .../tools/inst2xsd/schema/simpleName_rd0.xsd | 11 + .../tools/inst2xsd/schema/simpleName_ss0.xsd | 13 + .../tools/inst2xsd/schema/simpleName_vb0.xsd | 10 + .../tools/inst2xsd/schema/types/CData.xml | 15 + .../tools/inst2xsd/schema/types/cdata_rd0.xsd | 4 + .../tools/inst2xsd/schema/types/cdata_ss0.xsd | 4 + .../tools/inst2xsd/schema/types/cdata_vb0.xsd | 4 + .../tools/inst2xsd/schema/types/comments.xml | 10 + .../inst2xsd/schema/types/comments_rd0.xsd | 37 + .../inst2xsd/schema/types/comments_ss0.xsd | 42 + .../inst2xsd/schema/types/comments_vb0.xsd | 37 + .../inst2xsd/schema/types/commentschoice.xml | 10 + .../schema/types/commentschoice_eNrd0.xsd | 27 + .../schema/types/commentschoice_eNss0.xsd | 30 + .../schema/types/commentschoice_eNvb0.xsd | 27 + .../schema/types/commentschoice_vb0.xsd | 33 + .../inst2xsd/schema/types/innercomment.xml | 4 + .../schema/types/innercomment_vb0.xsd | 13 + .../tools/inst2xsd/schema/types/person.xml | 20 + .../inst2xsd/schema/types/person_vb0.xsd | 42 + .../xbean/tools/inst2xsd/schema/types/po.xml | 23 + .../tools/inst2xsd/schema/types/po_vb0.xsd | 4 + .../tools/inst2xsd/schema/types/po_vb1.xsd | 43 + .../inst2xsd/schema/types/schemaLocation.xml | 21 + .../schema/types/schemaLocation_vb0.xsd | 4 + .../schema/types/schemaLocation_vb1.xsd | 13 + .../schema/types/schemaLocation_vb2.xsd | 11 + .../schema/types/schemaLocation_vb3.xsd | 9 + .../tools/inst2xsd/schema/types/unicode.xml | 6 + .../inst2xsd/schema/types/unicode_rd0.xsd | 12 + .../inst2xsd/schema/types/unicode_ss0.xsd | 15 + .../inst2xsd/schema/types/unicode_vb0.xsd | 11 + .../tools/inst2xsd/schema/types/xsinil.xml | 5 + .../inst2xsd/schema/types/xsinil_rd0.xsd | 11 + .../inst2xsd/schema/types/xsinil_rd1.xsd | 5 + .../inst2xsd/schema/types/xsinil_ss0.xsd | 11 + .../inst2xsd/schema/types/xsinil_ss1.xsd | 5 + .../inst2xsd/schema/types/xsinil_vb0.xsd | 10 + .../inst2xsd/schema/types/xsinil_vb1.xsd | 5 + .../tools/inst2xsd/schema/types/xsitype.xml | 8 + .../inst2xsd/schema/types/xsitype_vb0.xsd | 11 + .../inst2xsd/schema/types/xsitype_vb1.xsd | 6 + xmlbeans/test/cases/xbean/tranxml.tar.bz2 | Bin 0 -> 282149 bytes .../cases/xbean/usertype/averageCase/po.xsd | 62 + .../xbean/usertype/averageCase/po.xsdconfig | 21 + .../xbean/usertype/multipleItems/company.xsd | 40 + .../usertype/multipleItems/company.xsdconfig | 21 + .../test/cases/xbean/xmlcursor/CR196679.xsd | 18 + .../xbean/xmlcursor/CarLocationMessage.xml | 38 + .../test/cases/xbean/xmlcursor/Employees.xml | 56 + .../cases/xbean/xmlcursor/TranXML_License.txt | 118 + .../xbean/xmlcursor/W3C_Software_Licence.txt | 23 + .../cases/xbean/xmlcursor/XQueryInput.xml | 15 + .../cases/xbean/xmlcursor/XQueryInput.xsd | 19 + xmlbeans/test/cases/xbean/xmlcursor/doc.xml | 9 + .../test/cases/xbean/xmlcursor/location.xsd | 36 + .../test/cases/xbean/xmlcursor/person.xsd | 34 + xmlbeans/test/cases/xbean/xmlcursor/po.xml | 32 + xmlbeans/test/cases/xbean/xmlcursor/po.xsd | 62 + .../cases/xbean/xmlcursor/xpath/LICENSE.txt | 7 + .../cases/xbean/xmlcursor/xpath/cdcatalog.xml | 212 + .../xbean/xmlcursor/xpath/jaxen/axis.xml | 25 + .../xbean/xmlcursor/xpath/jaxen/basic.xml | 11 + .../xmlcursor/xpath/jaxen/basicupdate.xml | 47 + .../xbean/xmlcursor/xpath/jaxen/contents.xml | 70 + .../xpath/jaxen/defaultNamespace.xml | 6 + .../xbean/xmlcursor/xpath/jaxen/evaluate.xml | 28 + .../xbean/xmlcursor/xpath/jaxen/fibo.xml | 29 + .../cases/xbean/xmlcursor/xpath/jaxen/id.xml | 21 + .../xbean/xmlcursor/xpath/jaxen/lang.xml | 11 + .../xbean/xmlcursor/xpath/jaxen/message.xml | 27 + .../xbean/xmlcursor/xpath/jaxen/moreover.xml | 244 + .../xbean/xmlcursor/xpath/jaxen/much_ado.xml | 6850 +++++++++++++++++ .../xmlcursor/xpath/jaxen/namespaces.xml | 18 + .../xbean/xmlcursor/xpath/jaxen/nitf.xml | 67 + .../xbean/xmlcursor/xpath/jaxen/numbers.xml | 18 + .../cases/xbean/xmlcursor/xpath/jaxen/pi.xml | 13 + .../cases/xbean/xmlcursor/xpath/jaxen/pi2.xml | 6 + .../xbean/xmlcursor/xpath/jaxen/simple.xml | 8 + .../xmlcursor/xpath/jaxen/testNamespaces.xml | 21 + .../xbean/xmlcursor/xpath/jaxen/text.xml | 10 + .../xmlcursor/xpath/jaxen/underscore.xml | 6 + .../cases/xbean/xmlcursor/xpath/jaxen/web.xml | 42 + .../cases/xbean/xmlcursor/xpath/zvon1.xml | 11 + .../cases/xbean/xmlcursor/xpath/zvon10.xml | 9 + .../cases/xbean/xmlcursor/xpath/zvon11.xml | 5 + .../cases/xbean/xmlcursor/xpath/zvon12.xml | 20 + .../cases/xbean/xmlcursor/xpath/zvon13.xml | 20 + .../cases/xbean/xmlcursor/xpath/zvon14.xml | 20 + .../cases/xbean/xmlcursor/xpath/zvon15.xml | 21 + .../cases/xbean/xmlcursor/xpath/zvon16.xml | 21 + .../cases/xbean/xmlcursor/xpath/zvon17.xml | 29 + .../cases/xbean/xmlcursor/xpath/zvon18.xml | 23 + .../cases/xbean/xmlcursor/xpath/zvon19.xml | 23 + .../cases/xbean/xmlcursor/xpath/zvon2.xml | 15 + .../cases/xbean/xmlcursor/xpath/zvon20.xml | 23 + .../cases/xbean/xmlcursor/xpath/zvon21.xml | 25 + .../cases/xbean/xmlcursor/xpath/zvon22.xml | 14 + .../cases/xbean/xmlcursor/xpath/zvon3.xml | 26 + .../cases/xbean/xmlcursor/xpath/zvon4.xml | 7 + .../cases/xbean/xmlcursor/xpath/zvon5.xml | 7 + .../cases/xbean/xmlcursor/xpath/zvon6.xml | 6 + .../cases/xbean/xmlcursor/xpath/zvon7.xml | 16 + .../cases/xbean/xmlcursor/xpath/zvon8.xml | 16 + .../cases/xbean/xmlcursor/xpath/zvon9.xml | 9 + .../cases/xbean/xmlcursor/xquery/2DocJoin.xq | 0 .../xbean/xmlcursor/xquery/Constructor.xq | 6 + .../test/cases/xbean/xmlcursor/xquery/Join.xq | 10 + .../xbean/xmlcursor/xquery/NIST/XQcatalog.xsd | 260 + .../xbean/xmlcursor/xquery/bookstore.xml | 35 + .../xbean/xmlcursor/xquery/employees.xml | 56 + .../cases/xbean/xmlcursor/xquery/xmlQuery.zip | Bin 0 -> 970814 bytes .../xmlcursor/xquery/xmlUseCases/catalog.xml | 145 + .../xmlcursor/xquery/xmlUseCases/catalog.xsd | 33 + .../cases/xbean/xmlcursor/xstypes/default.xsd | 46 + .../cases/xbean/xmlcursor/xstypes/person.xsd | 104 + .../cases/xbean/xmlcursor/xstypes/setters.xsd | 6 + .../cases/xbean/xmlcursor/xstypes/simplec.xsd | 27 + .../cases/xbean/xmlcursor/xstypes/xstypes.xml | 24 + .../test/cases/xbean/xmlobject/CR192525.xsd | 23 + .../xbean/xmlobject/SelectAttribute-Doc.xml | 22 + .../cases/xbean/xmlobject/SelectAttribute.xsd | 33 + .../xmlobject/SelectChildren-AnyTypeDoc.xml | 14 + .../xmlobject/SelectChildren-NormalDoc.xml | 7 + .../cases/xbean/xmlobject/SelectChildren.xsd | 27 + .../xbean/xmlobject/SimpleXmlObject.java.txt | 68 + xmlbeans/test/cases/xbean/xmlobject/Test.xsd | 19 + .../test/cases/xbean/xmlobject/Test36510.xsd | 52 + .../test/cases/xbean/xmlobject/Test40907.xsd | 28 + .../test/cases/xbean/xmlobject/defaults.xsd | 17 + .../test/cases/xbean/xmlobject/easypo.xsd | 44 + .../cases/xbean/xmlobject/easypo.xsdconfig | 29 + .../test/cases/xbean/xmlobject/easypo1.xml | 29 + .../test/cases/xbean/xmlobject/enumtest.xml | 6 + .../test/cases/xbean/xmlobject/enumtest.xsd | 67 + .../cases/xbean/xmlobject/enumtest.xsdconfig | 7 + .../test/cases/xbean/xmlobject/inttest.xsd | 47 + .../xbean/xmlobject/japanese/LICENSE.txt | 24 + .../xbean/xmlobject/japanese/japanese.xml | 88 + .../xmlobject/japanese/pr-xml-euc-jp.xml | 3549 +++++++++ .../xmlobject/japanese/pr-xml-euc-jp1.xml | 3392 ++++++++ .../xmlobject/japanese/pr-xml-iso-2022-jp.xml | 3549 +++++++++ .../japanese/pr-xml-little-endian.xml | Bin 0 -> 16400 bytes .../xmlobject/japanese/pr-xml-shift_jis.xml | 3549 +++++++++ .../xmlobject/japanese/pr-xml-utf-16.xml | Bin 0 -> 16401 bytes .../xbean/xmlobject/japanese/pr-xml-utf-8.xml | 3548 +++++++++ .../xbean/xmlobject/japanese/prefix_test.xml | 9 + .../xbean/xmlobject/japanese/readme.html | 201 + .../cases/xbean/xmlobject/japanese/spec.dtd | 975 +++ .../xmlobject/japanese/weekly-euc-jp.dtd | 72 + .../xmlobject/japanese/weekly-euc-jp.xml | 78 + .../xmlobject/japanese/weekly-iso-2022-jp.dtd | 72 + .../xmlobject/japanese/weekly-iso-2022-jp.xml | 78 + .../japanese/weekly-little-endian.xml | Bin 0 -> 3186 bytes .../xmlobject/japanese/weekly-shift_jis.dtd | 72 + .../xmlobject/japanese/weekly-shift_jis.xml | 78 + .../xmlobject/japanese/weekly-utf-16.dtd | Bin 0 -> 5222 bytes .../xmlobject/japanese/weekly-utf-16.xml | Bin 0 -> 3186 bytes .../xbean/xmlobject/japanese/weekly-utf-8.dtd | 71 + .../xbean/xmlobject/japanese/weekly-utf-8.xml | 78 + .../cases/xbean/xmlobject/listandunion.xsd | 68 + .../test/cases/xbean/xmlobject/nameworld.xml | 34 + .../test/cases/xbean/xmlobject/nameworld.xsd | 33 + .../test/cases/xbean/xmlobject/numerals.xsd | 34 + .../test/cases/xbean/xmlobject/person.xml | 24 + .../test/cases/xbean/xmlobject/person.xsd | 104 + .../test/cases/xbean/xmlobject/redefine1.xsd | 8 + .../test/cases/xbean/xmlobject/redefine2.xsd | 16 + .../xbean/xmlobject/selectChldAttTest.xsd | 67 + .../cases/xbean/xmlobject/soap-envelope.xsd | 124 + .../cases/xbean/xmlobject/soap12-encoding.xsd | 545 ++ .../test/cases/xbean/xmlobject/soapfaults.xsd | 28 + .../xbean/xmlobject/store/ConsolidateTest.xml | 38 + .../test/cases/xbean/xmlobject/store/XML.xsd | 81 + .../cases/xbean/xmlobject/store/XMLSchema.xsd | 2548 ++++++ .../cases/xbean/xmlobject/store/easypo1.xml | 29 + .../cases/xbean/xmlobject/store/erictest.xml | 1 + .../cases/xbean/xmlobject/store/people.xml | 171 + .../cases/xbean/xmlobject/store/small.xml | 12 + .../test/cases/xbean/xmlobject/store/test.xml | 1 + .../test/cases/xbean/xmlobject/substgroup.xsd | 87 + .../cases/xbean/xmlobject/substgroup2.xsd | 72 + .../xbean/xmlobject/version1.xsddonotcompile | 20 + .../xbean/xmlobject/version2.xsddonotcompile | 17 + .../test/cases/xbean/xmlobject/version3.xsd | 19 + xmlbeans/test/cases/xbean/xmlobject/wsdl.xml | 1149 +++ .../PrettyPrintNamespaceTest.xsd | 22 + .../test/docs/BuildingAndRunningTests.txt | 86 + xmlbeans/test/docs/TestOrganization.txt | 166 + xmlbeans/test/lib/LICENSE.txt | 28 + xmlbeans/test/lib/w3c_domts.jar | Bin 0 -> 974688 bytes xmlbeans/test/perf/bin/castor.bat | 60 + xmlbeans/test/perf/bin/castor.properties | 1 + xmlbeans/test/perf/bin/castor.sh | 25 + xmlbeans/test/perf/bin/jaxb.bat | 60 + xmlbeans/test/perf/bin/jaxb.sh | 26 + xmlbeans/test/perf/bin/jaxb2.bat | 77 + xmlbeans/test/perf/bin/jibx.bat | 60 + xmlbeans/test/perf/bin/jibx.sh | 26 + xmlbeans/test/perf/bin/parsers.bat | 21 + xmlbeans/test/perf/bin/run_all.bat | 8 + xmlbeans/test/perf/bin/run_all.sh | 7 + xmlbeans/test/perf/bin/run_all_nonmemory.bat | 8 + xmlbeans/test/perf/bin/run_castor.bat | 32 + xmlbeans/test/perf/bin/run_castor.sh | 32 + xmlbeans/test/perf/bin/run_jaxb.bat | 32 + xmlbeans/test/perf/bin/run_jaxb.sh | 32 + xmlbeans/test/perf/bin/run_jaxb2.bat | 48 + xmlbeans/test/perf/bin/run_jibx.bat | 14 + xmlbeans/test/perf/bin/run_jibx.sh | 14 + xmlbeans/test/perf/bin/run_svn.bat | 93 + xmlbeans/test/perf/bin/run_svn.sh | 93 + xmlbeans/test/perf/bin/run_svn_nonmemory.bat | 73 + xmlbeans/test/perf/bin/run_v1.bat | 86 + xmlbeans/test/perf/bin/run_v1.sh | 86 + xmlbeans/test/perf/bin/run_v1_nonmemory.bat | 66 + xmlbeans/test/perf/bin/run_v2.bat | 93 + xmlbeans/test/perf/bin/run_v2.sh | 93 + xmlbeans/test/perf/bin/run_v2_nonmemory.bat | 73 + xmlbeans/test/perf/bin/run_xerces.bat | 93 + xmlbeans/test/perf/bin/run_xerces.sh | 93 + .../test/perf/bin/run_xerces_nonmemory.bat | 53 + xmlbeans/test/perf/bin/run_xmlbeans_all.bat | 3 + .../test/perf/bin/run_xmlbeans_nonmemory.bat | 3 + xmlbeans/test/perf/bin/svn.bat | 60 + xmlbeans/test/perf/bin/svn.sh | 25 + xmlbeans/test/perf/bin/v1.bat | 61 + xmlbeans/test/perf/bin/v1.sh | 27 + xmlbeans/test/perf/bin/v2.bat | 76 + xmlbeans/test/perf/bin/v2.sh | 25 + xmlbeans/test/perf/bin/xerces.bat | 60 + xmlbeans/test/perf/bin/xerces.sh | 26 + xmlbeans/test/perf/build.xml | 940 +++ xmlbeans/test/perf/cases/parser_instances.zip | Bin 0 -> 76195 bytes xmlbeans/test/perf/cases/xsd/doc.xsd | 29 + .../test/perf/cases/xsd/non-primitives.xsd | 39 + xmlbeans/test/perf/cases/xsd/perf-results.xsd | 59 + xmlbeans/test/perf/cases/xsd/primitives.xsd | 44 + .../test/perf/cases/xsd/purchase-order-1.xml | 38 + .../test/perf/cases/xsd/purchase-order-2.xml | 398 + .../test/perf/cases/xsd/purchase-order-3.xml | 830 ++ .../test/perf/cases/xsd/purchase-order-4.xml | 1550 ++++ .../test/perf/cases/xsd/purchase-order-5.xml | 2090 +++++ .../test/perf/cases/xsd/purchase-order-6.xml | 2690 +++++++ .../test/perf/cases/xsd/purchase-order-7.xml | 3326 ++++++++ .../cases/xsd/purchase-order-jibxbinding.xml | 37 + .../test/perf/cases/xsd/purchase-order.xsd | 51 + xmlbeans/test/perf/download.properties | 35 + xmlbeans/test/perf/env.bat | 3 + xmlbeans/test/perf/env.sh | 4 + xmlbeans/test/perf/results.xml | 88 + .../castor/NPrimTopDownCastor.java | 88 + .../castor/POGetCustNameCastor.java | 97 + .../castor/POGetSetGetCustNameCastor.java | 116 + .../performance/castor/POReadAllCastor.java | 120 + .../performance/castor/POReadOneCastor.java | 99 + .../performance/castor/POTopDownCastor.java | 96 + .../castor/POTopDownSaveCastor.java | 103 + .../performance/castor/PrimTopDownCastor.java | 87 + .../performance/jaxb/NPrimTopDownJaxb.java | 88 + .../performance/jaxb/POGetCustNameJaxb.java | 107 + .../jaxb/POGetSetGetCustNameJaxb.java | 129 + .../test/performance/jaxb/POReadAllJaxb.java | 130 + .../test/performance/jaxb/POReadOneJaxb.java | 114 + .../test/performance/jaxb/POTopDownJaxb.java | 102 + .../performance/jaxb/POTopDownSaveJaxb.java | 109 + .../performance/jaxb/PrimTopDownJaxb.java | 92 + .../performance/jaxb2/NPrimTopDownJaxb2.java | 88 + .../performance/jaxb2/POGetCustNameJaxb2.java | 104 + .../jaxb2/POGetSetGetCustNameJaxb2.java | 122 + .../performance/jaxb2/POReadAllJaxb2.java | 134 + .../performance/jaxb2/POReadOneJaxb2.java | 106 + .../performance/jaxb2/POTopDownJaxb2.java | 98 + .../performance/jaxb2/POTopDownSaveJaxb2.java | 109 + .../performance/jaxb2/PrimTopDownJaxb2.java | 87 + .../test/performance/jibx/POReadAllJibx.java | 129 + .../test/performance/jibx/POReadOneJibx.java | 111 + .../performance/jibx/binding/Customer.java | 23 + .../jibx/binding/JibxPurchaseOrder.java | 31 + .../performance/jibx/binding/Lineitem.java | 29 + .../performance/jibx/binding/Shipper.java | 25 + .../performance/parsers/BaseSaxPerfTest.java | 302 + .../parsers/DefaultSaxParserPerfTests.java | 84 + .../test/performance/parsers/Jaxb2Tests.java | 231 + .../performance/parsers/PiccoloPerfTests.java | 67 + .../test/performance/parsers/Utils.java | 133 + .../test/performance/parsers/XMLParsers.java | 140 + .../parsers/XercesSaxParserPerfTests.java | 84 + .../performance/parsers/XmlBeansTests.java | 167 + .../test/performance/svn/BisLoadSVN.java | 83 + .../svn/CursorGetAttributeSVN.java | 82 + .../performance/svn/CursorGetElementSVN.java | 81 + .../svn/CursorGetSetGetAttributeSVN.java | 97 + .../svn/CursorGetSetGetElementSVN.java | 96 + .../test/performance/svn/CursorWalkSVN.java | 108 + .../test/performance/svn/DomWalkNLSVN.java | 96 + .../test/performance/svn/DomWalkSVN.java | 95 + .../svn/MaxMemUntypedBisLoadSVN.java | 78 + .../test/performance/svn/NPrimTopDownSVN.java | 79 + .../performance/svn/POGetCustNameSVN.java | 100 + .../svn/POGetSetGetCustNameSVN.java | 116 + .../performance/svn/POQueryLineItemsSVN.java | 101 + .../test/performance/svn/POReadAllSVN.java | 117 + .../test/performance/svn/POReadOneSVN.java | 100 + .../performance/svn/POSelectLineItemsSVN.java | 101 + .../test/performance/svn/POTopDownSVN.java | 91 + .../performance/svn/POTopDownSaveSVN.java | 98 + .../performance/svn/POValidateXmlObjSVN.java | 93 + .../test/performance/svn/PrimTopDownSVN.java | 81 + .../test/performance/utils/Constants.java | 114 + .../test/performance/utils/PerfUtil.java | 150 + .../test/performance/utils/RunComparator.java | 250 + .../test/performance/v1/BisLoadV1.java | 83 + .../performance/v1/CursorGetAttributeV1.java | 84 + .../performance/v1/CursorGetElementV1.java | 82 + .../v1/CursorGetSetGetAttributeV1.java | 98 + .../v1/CursorGetSetGetElementV1.java | 97 + .../test/performance/v1/CursorWalkV1.java | 107 + .../test/performance/v1/DomWalkNLV1.java | 98 + .../test/performance/v1/DomWalkV1.java | 97 + .../v1/MaxMemUntypedBisLoadV1.java | 73 + .../test/performance/v1/NPrimTopDownV1.java | 80 + .../test/performance/v1/POGetCustNameV1.java | 100 + .../performance/v1/POGetSetGetCustNameV1.java | 116 + .../test/performance/v1/POReadAllV1.java | 125 + .../test/performance/v1/POReadOneV1.java | 103 + .../performance/v1/POSelectLineItemsV1.java | 101 + .../test/performance/v1/POTopDownSaveV1.java | 99 + .../test/performance/v1/POTopDownV1.java | 93 + .../performance/v1/POValidateXmlObjV1.java | 95 + .../test/performance/v1/PrimTopDownV1.java | 82 + .../test/performance/v2/BisLoadV2.java | 83 + .../performance/v2/CursorGetAttributeV2.java | 82 + .../performance/v2/CursorGetElementV2.java | 81 + .../v2/CursorGetSetGetAttributeV2.java | 97 + .../v2/CursorGetSetGetElementV2.java | 96 + .../test/performance/v2/CursorWalkV2.java | 108 + .../test/performance/v2/DomWalkNLV2.java | 96 + .../test/performance/v2/DomWalkV2.java | 95 + .../v2/MaxMemUntypedBisLoadV2.java | 78 + .../test/performance/v2/NPrimTopDownV2.java | 79 + .../test/performance/v2/POGetCustNameV2.java | 100 + .../performance/v2/POGetSetGetCustNameV2.java | 116 + .../performance/v2/POQueryLineItemsV2.java | 101 + .../test/performance/v2/POReadAllV2.java | 117 + .../test/performance/v2/POReadOneV2.java | 100 + .../performance/v2/POSelectLineItemsV2.java | 101 + .../test/performance/v2/POTopDownSaveV2.java | 98 + .../test/performance/v2/POTopDownV2.java | 91 + .../performance/v2/POValidateXmlObjV2.java | 93 + .../test/performance/v2/PrimTopDownV2.java | 81 + .../performance/xerces/BisLoadXercesDom.java | 84 + .../performance/xerces/BisLoadXercesSax.java | 112 + .../performance/xerces/DomWalkNLXerces.java | 104 + .../performance/xerces/DomWalkXerces.java | 101 + .../xerces/MaxMemUntypedBisLoadXercesDom.java | 84 + .../xerces/MaxMemUntypedBisLoadXercesSax.java | 110 + .../xerces/POReadAllXercesDom.java | 134 + .../xerces/POReadAllXercesSax.java | 174 + .../xerces/POReadOneXercesDom.java | 109 + .../xerces/POReadOneXercesSax.java | 167 + .../xerces/POTopDownXercesDom.java | 143 + .../xerces/POTopDownXercesSax.java | 234 + .../performance/xerces/POValidateXerces.java | 153 + .../xmlbeans/test/tools/PerfResultTask.java | 83 + .../xmlbeans/test/tools/PerfResultUtil.java | 136 + xmlbeans/test/readme.txt | 14 + .../checkin/TestUriValidation.java | 110 + .../ValidatingXMLStreamReaderTests.java | 562 ++ .../common/TestPrefixResolver.java | 34 + .../ValidatingXmlStreamReaderTests.java | 524 ++ .../detailed/ValidatorUtilTests.java | 78 + xmlbeans/test/src/common/Common.java | 336 + .../scomp/checkin/CompilationTests.java | 490 ++ .../checkin/XmlBeansCompCheckinTests.java | 313 + .../compile/scomp/common/CompileCommon.java | 56 + .../compile/scomp/common/CompileTestBase.java | 434 ++ .../common/mockobj/TestBindingConfig.java | 165 + .../scomp/common/mockobj/TestFiler.java | 88 + .../scomp/detailed/DetailedCompTests.java | 289 + .../scomp/detailed/SchemaCompilerTests.java | 172 + .../detailed/XmlBeanCompilationTests.java | 327 + .../detailed/IncrCompilationTests.java | 433 ++ .../detailed/ModelGroupTests.java | 355 + .../schemaCompile/detailed/PerfTests.java | 124 + .../som/checkin/PartialSOMCheckinTest.java | 1424 ++++ .../compile/scomp/som/common/SomTestBase.java | 601 ++ .../som/detailed/PartialSOMDetailedTest.java | 632 ++ .../src/dom/checkin/AttributeSyncTest.java | 43 + .../test/src/dom/checkin/AttributeTest.java | 417 + .../src/dom/checkin/CDataSectionSyncTest.java | 42 + .../src/dom/checkin/CDataSectionTest.java | 105 + .../test/src/dom/checkin/CommentSyncTest.java | 43 + .../test/src/dom/checkin/CommentTest.java | 93 + .../test/src/dom/checkin/DirtyCacheTests.java | 83 + .../dom/checkin/DocumentFragmentSyncTest.java | 43 + .../src/dom/checkin/DocumentFragmentTest.java | 114 + .../src/dom/checkin/DocumentSyncTest.java | 42 + .../test/src/dom/checkin/DocumentTest.java | 689 ++ .../checkin/DomImplementationSyncTest.java | 43 + .../dom/checkin/DomImplementationTest.java | 145 + xmlbeans/test/src/dom/checkin/DomTests.java | 122 + .../test/src/dom/checkin/ElementSyncTest.java | 42 + .../test/src/dom/checkin/ElementTest.java | 703 ++ .../src/dom/checkin/NamedNodeMapSyncTest.java | 43 + .../src/dom/checkin/NamedNodeMapTest.java | 378 + .../src/dom/checkin/NodeListSyncTest.java | 43 + .../test/src/dom/checkin/NodeListTest.java | 94 + xmlbeans/test/src/dom/checkin/PISyncTest.java | 43 + xmlbeans/test/src/dom/checkin/PITest.java | 170 + .../test/src/dom/checkin/TextSyncTest.java | 43 + xmlbeans/test/src/dom/checkin/TextTest.java | 140 + .../src/dom/common/CharacterDataTest.java | 384 + xmlbeans/test/src/dom/common/DomUtils.java | 176 + xmlbeans/test/src/dom/common/Loader.java | 28 + xmlbeans/test/src/dom/common/NewLoader.java | 46 + xmlbeans/test/src/dom/common/NodeTest.java | 406 + .../src/dom/common/NodeWithChildrenTest.java | 415 + xmlbeans/test/src/dom/common/TestSetup.java | 21 + .../src/dom/detailed/AttrNamespaceTest.java | 133 + xmlbeans/test/src/dom/detailed/IDTest.java | 121 + .../detailed/ImportUnsupportedNodesTest.java | 139 + .../dom/detailed/InsertDeleteNodesTest.java | 179 + .../src/dom/detailed/MoveImportNodeTest.java | 150 + .../src/dom/detailed/MultipleDocsTest.java | 204 + .../dom/detailed/TextInsertDeleteTest.java | 147 + xmlbeans/test/src/dom/detailed/TextTest.java | 72 + .../test/src/dom/detailed/w3c/alltests.java | 339 + .../test/src/dom/detailed/w3c/ibmtests.java | 173 + .../test/src/drt/drtcases/BindingTests.java | 292 + .../test/src/drt/drtcases/MarshalTests.java | 1913 +++++ xmlbeans/test/src/drt/drtcases/TestEnv.java | 72 + .../test/src/misc/checkin/CharUtilTests.java | 248 + .../test/src/misc/checkin/ErrorCodeTest.java | 133 + .../src/misc/checkin/RichParserTests.java | 255 + .../misc/checkin/RuntimeSchemaLoaderTest.java | 101 + .../test/src/misc/checkin/ThreadingTest.java | 102 + .../test/src/misc/checkin/VersionTest.java | 67 + .../src/misc/checkin/XMLBEANS412Test.java | 99 + .../test/src/misc/common/JiraTestBase.java | 66 + .../test/src/misc/common/ParsersBase.java | 132 + .../src/misc/detailed/CharEncodingTest.java | 120 + .../src/misc/detailed/CharEscapeTest.java | 284 + .../src/misc/detailed/ClassLoadingTest.java | 311 + .../detailed/JiraRegression151_200Test.java | 129 + .../misc/detailed/JiraRegression1_50Test.java | 555 ++ .../detailed/JiraRegression201_250Test.java | 123 + .../detailed/JiraRegression251_300Test.java | 41 + .../detailed/JiraRegression50_100Test.java | 854 ++ .../JiraRegressionSchemaCompilerTest.java | 121 + .../detailed/JiraRegressionTest101_150.java | 99 + .../test/src/misc/detailed/LargeEnumTest.java | 131 + .../test/src/misc/detailed/SampleRunner.java | 130 + .../detailed/SystemCacheClassloadersTest.java | 198 + .../misc/detailed/SystemCacheTestImpl.java | 45 + .../src/misc/detailed/SystemCacheTests.java | 72 + .../misc/detailed/XMLStreamReaderTest.java | 99 + .../test/src/random/checkin/RandomTest.java | 46 + xmlbeans/test/src/random/common/Random.java | 852 ++ xmlbeans/test/src/schemas/defaults.xsd | 32 + .../attributes/detailed/AttrGroupTest.java | 76 + .../detailed/GlobalAttrDefault.java | 90 + .../attributes/detailed/GlobalAttrFixed.java | 170 + .../attributes/detailed/GlobalAttrIdTest.java | 50 + .../attributes/detailed/GlobalAttrType.java | 146 + .../detailed/LocalAttrFixedDefault.java | 61 + .../attributes/detailed/LocalAttrForm.java | 67 + .../attributes/detailed/LocalAttrUse.java | 201 + xmlbeans/test/src/scomp/common/BaseCase.java | 101 + .../complex/detailed/AnonymousTest.java | 111 + .../complex/detailed/ComplexContentTest.java | 83 + .../detailed/ElementOnlyContentTest.java | 99 + .../complex/detailed/EmptyContentTest.java | 71 + .../complex/detailed/MixedContentTest.java | 194 + .../complex/detailed/NamedTest.java | 102 + .../complex/modelGroup/detailed/AllTest.java | 99 + .../modelGroup/detailed/ChoiceTest.java | 87 + .../detailed/NestSequenceChoiceTest.java | 161 + .../modelGroup/detailed/SequenceTest.java | 73 + .../simple/detailed/BuiltInType.java | 369 + .../contentType/simple/detailed/ListType.java | 169 + .../simple/detailed/SimpleType.java | 57 + .../simple/detailed/UnionType.java | 286 + .../derivation/detailed/AbstractTest.java | 66 + .../scomp/derivation/detailed/BlockTest.java | 257 + .../scomp/derivation/detailed/FinalTest.java | 50 + .../detailed/AttributeExtensionTest.java | 62 + .../detailed/AttributeWCExtension.java | 201 + .../detailed/ComplexContentExtensionTest.java | 347 + .../detailed/EmptyContentExtension.java | 45 + .../detailed/MixedContentExtension.java | 109 + .../detailed/SimpleTypeExtensionTest.java | 76 + .../detailed/AttrWCRestriction.java | 140 + .../detailed/AttributeRestriction.java | 111 + .../detailed/ElementRestriction.java | 90 + .../detailed/ElementWCRestriction.java | 171 + .../detailed/EmptyContentRestriction.java | 67 + .../restriction/detailed/EnumTest.java | 84 + .../detailed/GroupRestrictionTest.java | 141 + .../detailed/MixedContentRestriction.java | 119 + .../SimpleContentRestrictionTest.java | 54 + .../detailed/SimpleTypeRestriction.java | 69 + .../detailed/SubstitutionTest.java | 66 + .../facets/detailed/FacetRestrictionTest.java | 279 + .../facets/detailed/FacetsTest.java | 278 + .../facets/detailed/ListRestriction.java | 186 + .../facets/detailed/UnionRestriction.java | 103 + .../src/scomp/elements/detailed/AnyTest.java | 90 + .../elements/detailed/GlobalEltDefault.java | 61 + .../elements/detailed/GlobalEltFixed.java | 88 + .../scomp/elements/detailed/GlobalEltId.java | 38 + .../elements/detailed/GlobalEltNillable.java | 228 + .../detailed/LocalEltMinMaxOccurs.java | 92 + .../detailed/NamedModelGroupsTest.java | 50 + .../src/scomp/elements/detailed/NillTest.java | 218 + .../idConstraint/detailed/KeyKeyref.java | 252 + .../namespace/checkin/PreserveNamespaces.java | 138 + .../namespace/detailed/AttrFormDefault.java | 70 + .../scomp/namespace/detailed/AttributeWC.java | 370 + .../detailed/ElementFormDefault.java | 62 + .../scomp/namespace/detailed/ElementWC.java | 402 + .../redefine/detailed/AttrGroupRedefine.java | 49 + .../redefine/detailed/GroupRedefine.java | 39 + .../redefine/detailed/MultipleRedefines.java | 227 + .../redefine/detailed/SimpleRedefine.java | 63 + .../src/scomp/substGroup/detailed/Deep.java | 161 + .../scomp/substGroup/detailed/OneLevel.java | 138 + .../substGroup/detailed/UserReportedTest.java | 78 + .../src/scomp/substGroup/detailed/Wide.java | 138 + .../restriction/detailed/Abstract.java | 144 + .../restriction/detailed/Block.java | 194 + .../restriction/detailed/Final.java | 118 + .../inst2xsd/checkin/Inst2XsdAttrTest.java | 125 + .../inst2xsd/checkin/Inst2XsdCheckinTest.java | 336 + .../inst2xsd/checkin/Inst2XsdOptionsTest.java | 51 + .../inst2xsd/checkin/Inst2XsdTypeTest.java | 141 + .../tools/inst2xsd/common/Inst2XsdCommon.java | 102 + .../inst2xsd/common/Inst2XsdTestBase.java | 548 ++ .../detailed/ComplexDetailedTest.java | 197 + .../inst2xsd/detailed/DetailedLCDTest.java | 264 + .../detailed/Inst2XsdDetailedAttrTest.java | 117 + .../detailed/Inst2XsdDetailedOptionsTest.java | 425 + .../detailed/Inst2XsdDetailedTest.java | 183 + .../detailed/Inst2XsdDetailedTypeTest.java | 116 + .../inst2xsd/detailed/Inst2XsdMiscTest.java | 139 + .../xmlcursor/checkin/AddToSelectionTest.java | 143 + .../xmlcursor/checkin/AnnotationsTests.java | 77 + .../xmlcursor/checkin/BeginElementTest.java | 125 + .../xmlcursor/checkin/ClearBookmarkTest.java | 121 + .../xmlcursor/checkin/ClearSelectionTest.java | 64 + .../checkin/ComparePositionTest.java | 111 + .../test/src/xmlcursor/checkin/CopyTest.java | 236 + .../checkin/CopyXmlContentsTest.java | 175 + .../checkin/CurrentTokenTypeTest.java | 135 + .../src/xmlcursor/checkin/DisposeTest.java | 58 + .../checkin/GetAllBookmarkRefsTest.java | 108 + .../checkin/GetAllNamespacesTest.java | 135 + .../checkin/GetAttributeTextTest.java | 80 + .../xmlcursor/checkin/GetBookmarkTest.java | 120 + .../src/xmlcursor/checkin/GetCharsTest.java | 74 + .../xmlcursor/checkin/GetCharsType2Test.java | 137 + .../checkin/GetDocChangeStampTest.java | 69 + .../src/xmlcursor/checkin/GetNameTest.java | 146 + .../src/xmlcursor/checkin/GetObjectTest.java | 126 + .../checkin/InsertAttributeTest.java | 302 + .../xmlcursor/checkin/InsertCharsTest.java | 131 + .../xmlcursor/checkin/InsertCommentTest.java | 146 + .../xmlcursor/checkin/InsertElementTest.java | 147 + .../xmlcursor/checkin/InsertProcInstTest.java | 165 + .../checkin/IsAtSamePositionAsTest.java | 108 + .../checkin/IsInSameDocumentTest.java | 99 + .../src/xmlcursor/checkin/MoveCharsTest.java | 252 + .../test/src/xmlcursor/checkin/MoveTest.java | 208 + .../xmlcursor/checkin/PrevTokenTypeTest.java | 128 + .../checkin/RemoveAttributeTest.java | 104 + .../xmlcursor/checkin/RemoveCharsTest.java | 98 + .../src/xmlcursor/checkin/RemoveTest.java | 144 + .../src/xmlcursor/checkin/SelectPathTest.java | 129 + .../checkin/SetAttributeTextTest.java | 90 + .../xmlcursor/checkin/SetBookmarkTest.java | 158 + .../src/xmlcursor/checkin/SetNameTest.java | 114 + .../src/xmlcursor/checkin/SetTextTest.java | 178 + .../src/xmlcursor/checkin/StoreTests.java | 2302 ++++++ .../src/xmlcursor/checkin/ToCursorTest.java | 104 + .../checkin/ToFirstAttributeTest.java | 95 + .../checkin/ToFirstChildElementTest.java | 94 + .../checkin/ToFirstContentTokenTest.java | 116 + .../checkin/ToLastAttributeTest.java | 93 + .../checkin/ToLastChildElementTest.java | 103 + .../checkin/ToNextAttributeTest.java | 96 + .../xmlcursor/checkin/ToNextBookmarkTest.java | 148 + .../src/xmlcursor/checkin/ToNextCharTest.java | 97 + .../xmlcursor/checkin/ToNextElementTest.java | 83 + .../checkin/ToNextSelectionTest.java | 151 + .../xmlcursor/checkin/ToNextSiblingTest.java | 152 + .../checkin/ToParentElementTest.java | 108 + .../checkin/ToPrevAttributeTest.java | 96 + .../xmlcursor/checkin/ToPrevBookmarkTest.java | 137 + .../src/xmlcursor/checkin/ToPrevCharTest.java | 101 + .../xmlcursor/checkin/ToPrevElementTest.java | 98 + .../src/xmlcursor/checkin/TokensTest.java | 148 + .../xmlcursor/common/BasicCursorTestCase.java | 142 + .../test/src/xmlcursor/common/Common.java | 85 + .../src/xmlcursor/detailed/CopyCharsTest.java | 178 + .../test/src/xmlcursor/detailed/CopyTest.java | 45 + .../CursorGeneratedTypedObjectTest.java | 235 + .../xmlcursor/detailed/CursorLocations.java | 352 + .../detailed/CursorVsObjectAttributeTest.java | 105 + .../CursorVsObjectInsertRemoveTest.java | 88 + .../CursorVsObjectSetGetTextTest.java | 100 + .../src/xmlcursor/detailed/GetTextTest.java | 194 + .../xmlcursor/detailed/GetTextValueTest.java | 201 + .../detailed/InsertAttributeTest2.java | 202 + .../detailed/InsertNamespaceTest.java | 178 + .../src/xmlcursor/detailed/MoveXmlTest2.java | 214 + .../detailed/MultipleCopyFromCursorTest.java | 150 + .../xmlcursor/detailed/MultipleCopyTest.java | 98 + .../detailed/MultipleCursorSetTest.java | 89 + .../detailed/NamespaceForPrefixTest.java | 167 + .../detailed/ObjectCursorInteractionTest.java | 196 + .../detailed/PrefixForNamespaceTest.java | 137 + .../src/xmlcursor/detailed/PushPopTest.java | 61 + .../xmlcursor/detailed/SelectionsTest.java | 152 + .../xmlcursor/detailed/SetTextValueTest.java | 231 + .../xmlcursor/detailed/ToBookmarkTest.java | 403 + .../src/xmlcursor/detailed/ToChildTest.java | 321 + .../xmlcursor/detailed/XmlLineNumberTest.java | 169 + .../jsr173/common/AttributeTest.java | 352 + .../jsr173/common/CharactersTest.java | 250 + .../xmlcursor/jsr173/common/ElementTest.java | 154 + .../jsr173/common/GeneralMethodsTest.java | 143 + .../xmlcursor/jsr173/common/IsXXXTest.java | 169 + .../jsr173/common/NamespaceTest.java | 287 + .../src/xmlcursor/jsr173/common/PITest.java | 80 + .../src/xmlcursor/jsr173/common/README.txt | 5 + .../jsr173/detailed/CursorAttributeTest.java | 40 + .../jsr173/detailed/CursorCharactersTest.java | 37 + .../jsr173/detailed/CursorElementTest.java | 37 + .../detailed/CursorGeneralMethodsTest.java | 38 + .../jsr173/detailed/CursorIsXXXTest.java | 36 + .../jsr173/detailed/CursorNamespaceTest.java | 35 + .../jsr173/detailed/CursorPITest.java | 36 + .../src/xmlcursor/xpath/CustomerTest.java | 198 + .../xmlcursor/xpath/common/BaseXPathTest.java | 108 + .../xmlcursor/xpath/common/XPathCommon.java | 148 + .../xpath/common/XPathExpressionTest.java | 256 + .../xpath/common/XPathFunctionAuxTest.java | 294 + .../xpath/common/XPathFunctionTest.java | 522 ++ .../xpath/common/XPathLocationTest.java | 164 + .../xpath/common/XPathNodetestTest.java | 134 + .../complex/checkin/ContainerCommentTest.java | 83 + .../complex/checkin/JaxenXPathTests.java | 356 + .../detailed/DeclareNamespaceTest.java | 165 + .../xpath/complex/detailed/NodeCopyTest.java | 104 + .../xpath/complex/detailed/TypesTest.java | 139 + .../detailed/XPathExpressionTestImpl.java | 181 + .../detailed/XPathFunctionAuxTest.java | 297 + .../detailed/XPathFunctionTestImpl.java | 177 + .../xpath/complex/detailed/XPathNodeTest.java | 103 + .../xpath/complex/detailed/XPathTest.java | 1325 ++++ .../xpath/xbean_xpath/detailed/AxesTest.java | 378 + .../xpath/xbean_xpath/detailed/NodeTest.java | 188 + .../xpath/xbean_xpath/detailed/README.txt | 1 + .../xquery/checkin/QueryEngineTests.java | 34 + .../xquery/common/AbstractRunner.java | 40 + .../xmlcursor/xquery/common/XQTestCase.java | 32 + .../xquery/detailed/NISTSuiteRunner.java | 104 + .../xmlcursor/xquery/detailed/NISTTest.java | 93 + .../xquery/detailed/StoreTestsXqrl.java | 206 + .../xquery/detailed/UseCaseTest.java | 104 + .../xquery/detailed/XQUseCaseRunner.java | 119 + .../xmlcursor/xquery/detailed/XQueryTest.java | 311 + .../detailed/XQueryVariableBindingTest.java | 205 + .../xmlcursor/xquery/detailed/ZipUtil.java | 64 + .../src/xmlobject/checkin/AssortedTests.java | 233 + .../test/src/xmlobject/checkin/CDataTest.java | 111 + .../src/xmlobject/checkin/CreationTests.java | 88 + .../test/src/xmlobject/checkin/DumbTest.java | 66 + .../src/xmlobject/checkin/EasyPoTests.java | 134 + .../checkin/InstanceValidationTests.java | 2033 +++++ .../src/xmlobject/checkin/NameworldTest.java | 118 + .../src/xmlobject/checkin/RedefineTest.java | 117 + .../xmlobject/checkin/SelectChldAttTests.java | 265 + .../xmlobject/checkin/SerializationTests.java | 172 + .../test/src/xmlobject/checkin/SetTest.java | 132 + .../xmlobject/checkin/SubstGroupTests.java | 248 + .../src/xmlobject/checkin/ValidateTest.java | 92 + .../test/src/xmlobject/checkin/XPathTest.java | 124 + .../common/SelectChildrenAttribCommon.java | 138 + .../src/xmlobject/common/StringXmlReader.java | 101 + .../test/src/xmlobject/common/XmlReader.java | 111 + .../src/xmlobject/detailed/CompareToTest.java | 162 + .../test/src/xmlobject/detailed/CopyTest.java | 64 + .../xmlobject/detailed/IsImmutableTest.java | 93 + .../test/src/xmlobject/detailed/NilTest.java | 114 + .../detailed/SelectAttributeTests.java | 138 + .../detailed/SelectChildrenTests.java | 216 + .../detailed/SerializationDetailedTests.java | 57 + .../xmlobject/detailed/SetIdentityTest.java | 88 + .../src/xmlobject/detailed/SoapFaultTest.java | 141 + .../xmlobject/detailed/SubstGroupTests.java | 592 ++ .../src/xmlobject/detailed/TestXmlReader.java | 82 + .../src/xmlobject/detailed/TestsFromBugs.java | 180 + .../xmlobject/detailed/TypedObjectCursor.java | 55 + .../xmlobject/detailed/TypedSettersTests.java | 164 + .../src/xmlobject/detailed/TypesTest.java | 129 + .../xmlobject/detailed/ValueEqualsTest.java | 79 + .../detailed/XmlObjectAbstractClassTest.java | 144 + .../averageCase/checkin/AverageTest.java | 69 + .../averageCase/existing/FooHandler.java | 47 + .../averageCase/existing/IFoo.java | 25 + .../checkin/NameCollisionTest.java | 77 + .../existing/FooHandler.java | 48 + .../methodNameCollision/existing/IFoo.java | 28 + .../checkin/MultInterfacesTest.java | 100 + .../multInterfaces/existing/IReport.java | 26 + .../multInterfaces/existing/ISum.java | 20 + .../existing/ReportHandler.java | 85 + .../readOnlyBean/checkin/ReadOnlyTest.java | 80 + .../readOnlyBean/existing/FooHandler.java | 49 + .../readOnlyBean/existing/IFoo.java | 22 + .../checkin/ValueRestrictionTest.java | 72 + .../ValueRestriction/existing/ISetter.java | 21 + .../existing/SetterHandler.java | 50 + .../readOnlyBean/checkin/ReadOnlyTest.java | 65 + .../readOnlyBean/existing/FooHandler.java | 65 + .../readOnlyBean/existing/IFoo.java | 23 + .../schematypes/checkin/EnumTests.java | 180 + .../schematypes/checkin/GDateTests.java | 755 ++ .../schematypes/checkin/IntTests.java | 43 + .../schematypes/checkin/NumeralsTests.java | 274 + .../schematypes/checkin/QNameTests.java | 120 + .../schematypes/checkin/SchemaTypesTests.java | 213 + .../detailed/ListAndUnionTests.java | 184 + .../schematypes/detailed/QNameSetTest.java | 314 + .../averageCase/checkin/AverageTest.java | 100 + .../usertype/averageCase/existing/SKU.java | 42 + .../averageCase/existing/SKUHandler.java | 40 + .../multipleItems/checkin/AverageTest.java | 222 + .../usertype/multipleItems/existing/Room.java | 42 + .../multipleItems/existing/RoomHandler.java | 41 + .../xmlloader/detailed/JapaneseTextTest.java | 75 + .../xmlloader/detailed/ParseTest.java | 82 + .../xmlloader/detailed/PiccoloParseTests.java | 46 + .../xmlloader/detailed/XmlLoaderBvtTest.java | 53 + .../xmlloader/detailed/XmlLoaderMiscTest.java | 129 + .../detailed/XmlStreamBeanReader.java | 101 + .../detailed/NewDomNodeTest.java | 123 + .../detailed/PrettyPrintNamespaceTest.java | 70 + .../detailed/RoundTripLoaderTest.java | 172 + .../xmltokensource/detailed/XmlTextTest.java | 132 + xmlbeans/test/tools/lib/JWhich.jar | Bin 0 -> 4624 bytes .../tools/lib/ant-ext/ant-contrib-0.6.jar | Bin 0 -> 136172 bytes xmlbeans/test/tools/lib/ant-ext/antexts.jar | Bin 0 -> 10509 bytes xmlbeans/test/tools/lib/junit.jar | Bin 0 -> 121070 bytes xmlbeans/test/tools/lib/xerces-2.5.0.jar | Bin 0 -> 927669 bytes xmlbeans/test/tools/lib/xerces1.4.4.jar | Bin 0 -> 1812019 bytes xmlbeans/test/tools/lib/xsl/TestReport.xsd | 129 + xmlbeans/test/tools/lib/xsl/TestReport.xsl | 1974 +++++ xmlbeans/test/tools/lib/xsl/junit.css | 68 + .../tools/JUnit/JUnitXResultFormatter.java | 39 + .../tools/src/tools/JUnit/JUnitXRunner.java | 234 + .../tools/src/tools/JUnit/JUnitXTask.java | 264 + .../tools/JUnit/SimpleResultFormatter.java | 379 + .../tools/JUnit/TestReportMergeUtility.java | 297 + .../src/tools/JUnit/XmlResultFormatter.java | 477 ++ .../tools/JUnit/XmlResultFormatterImpl.java | 551 ++ .../tools/src/tools/ant/BuildFileTest.java | 486 ++ .../tools/src/tools/io/TeeOutputStream.java | 53 + .../tools/src/tools/util/ClassCompare.java | 57 + .../tools/src/tools/util/ComparisonError.java | 26 + xmlbeans/test/tools/src/tools/util/Diff.java | 853 ++ .../test/tools/src/tools/util/JarUtil.java | 143 + xmlbeans/test/tools/src/tools/util/Log.java | 255 + .../tools/src/tools/util/ResourceClass.java | 133 + .../tools/src/tools/util/ResourceUtil.java | 248 + .../src/tools/util/SchemaFilenameFilter.java | 30 + .../tools/src/tools/util/SchemaValidator.java | 125 + .../tools/src/tools/util/TestRunUtil.java | 87 + xmlbeans/test/tools/src/tools/util/Util.java | 1230 +++ .../src/tools/util/XMLFilenameFilter.java | 30 + xmlbeans/test/tools/src/tools/xml/Utils.java | 51 + .../tools/src/tools/xml/XmlComparator.java | 208 + xmlbeans/testbuild.xml | 1127 +++ xmlbeans/xbeanenv.cmd | 1 + xmlbeans/xbeanenv.sh | 1 + xmlbeans/xkit/README.txt | 253 + xmlbeans/xkit/doap_XMLBeans.rdf | 90 + 1893 files changed, 343800 insertions(+) create mode 100644 xmlbeans/CHANGES.txt create mode 100644 xmlbeans/KEYS create mode 100755 xmlbeans/LICENSE.txt create mode 100644 xmlbeans/NOTICE.txt create mode 100644 xmlbeans/README.txt create mode 100644 xmlbeans/STATUS create mode 100755 xmlbeans/bin/_setlib create mode 100644 xmlbeans/bin/_setlib.cmd create mode 100755 xmlbeans/bin/dumpxsb create mode 100644 xmlbeans/bin/dumpxsb.cmd create mode 100755 xmlbeans/bin/inst2xsd create mode 100644 xmlbeans/bin/inst2xsd.cmd create mode 100755 xmlbeans/bin/scomp create mode 100644 xmlbeans/bin/scomp.cmd create mode 100644 xmlbeans/bin/scopy.cmd create mode 100755 xmlbeans/bin/sdownload create mode 100644 xmlbeans/bin/sdownload.cmd create mode 100755 xmlbeans/bin/sfactor create mode 100644 xmlbeans/bin/sfactor.cmd create mode 100755 xmlbeans/bin/svalidate create mode 100644 xmlbeans/bin/svalidate.cmd create mode 100755 xmlbeans/bin/validate create mode 100644 xmlbeans/bin/validate.cmd create mode 100755 xmlbeans/bin/xpretty create mode 100644 xmlbeans/bin/xpretty.cmd create mode 100755 xmlbeans/bin/xsd2inst create mode 100644 xmlbeans/bin/xsd2inst.cmd create mode 100755 xmlbeans/bin/xsdtree create mode 100644 xmlbeans/bin/xsdtree.cmd create mode 100755 xmlbeans/bin/xstc create mode 100644 xmlbeans/bin/xstc.cmd create mode 100644 xmlbeans/build.xml create mode 100644 xmlbeans/docs/guide/antXmlbean.html create mode 100644 xmlbeans/docs/guide/conGettingStartedwithXMLBeans.html create mode 100644 xmlbeans/docs/guide/conHandlingAny.html create mode 100644 xmlbeans/docs/guide/conIntroToTheSchemaTypeSystem.html create mode 100644 xmlbeans/docs/guide/conJavaTypesGeneratedFromUserDerived.html create mode 100644 xmlbeans/docs/guide/conMethodsForGeneratedJavaTypes.html create mode 100644 xmlbeans/docs/guide/conNavigatingXMLwithCursors.html create mode 100644 xmlbeans/docs/guide/conSelectingXMLwithXQueryPathXPath.html create mode 100644 xmlbeans/docs/guide/conUnderstandingXMLTokens.html create mode 100644 xmlbeans/docs/guide/conUsingBookmarksToAnnotateXML.html create mode 100644 xmlbeans/docs/guide/conValidationWithXmlBeans.html create mode 100644 xmlbeans/docs/guide/conXMLBeansSupportBuiltInSchemaTypes.html create mode 100644 xmlbeans/docs/guide/tools.html create mode 100644 xmlbeans/docs/images/conCursorTokenLocations.gif create mode 100644 xmlbeans/docs/images/conXMLTypeHierarchy.gif create mode 100644 xmlbeans/docs/stylesheet.css create mode 100644 xmlbeans/docs/xmlbeans.css create mode 100644 xmlbeans/external/lib/jam-0.1.0-src.jar create mode 100644 xmlbeans/external/lib/jam.LICENSE.txt create mode 100644 xmlbeans/external/lib/junit.LICENSE.txt create mode 100644 xmlbeans/external/lib/junit.jar create mode 100644 xmlbeans/external/lib/oldxbean.jar create mode 100644 xmlbeans/external/lib/piccolo.LICENSE.txt create mode 100644 xmlbeans/external/lib/piccolo_apache_dist_20040629.jar create mode 100644 xmlbeans/external/lib/piccolo_apache_dist_20040629_v2.jar create mode 100644 xmlbeans/external/lib/piccolo_apache_dist_20040711.jar create mode 100644 xmlbeans/external/lib/piccolo_apache_dist_20040711_v2.jar create mode 100644 xmlbeans/maven-plugin/INSTRUCTIONS.txt create mode 100644 xmlbeans/maven-plugin/LICENSE.txt create mode 100644 xmlbeans/maven-plugin/NOTICE.txt create mode 100644 xmlbeans/maven-plugin/plugin.jelly create mode 100644 xmlbeans/maven-plugin/plugin.properties create mode 100644 xmlbeans/maven-plugin/project.properties create mode 100644 xmlbeans/maven-plugin/project.xml create mode 100644 xmlbeans/maven-plugin/src/java/org/apache/xmlbeans/maven/SchemaCompilerWrapper.java create mode 100644 xmlbeans/samples/AbstractTypes/README.txt create mode 100644 xmlbeans/samples/AbstractTypes/build.xml create mode 100644 xmlbeans/samples/AbstractTypes/schemas/abstractBase.xsd create mode 100644 xmlbeans/samples/AbstractTypes/schemas/myfigures.xsd create mode 100644 xmlbeans/samples/AbstractTypes/src/org/apache/xmlbeans/samples/abstracttypes/AbstractTypes.java create mode 100644 xmlbeans/samples/AbstractTypes/src/org/apache/xmlbeans/samples/abstracttypes/AbstractTypesTest.java create mode 100644 xmlbeans/samples/Any/README.txt create mode 100644 xmlbeans/samples/Any/build.xml create mode 100644 xmlbeans/samples/Any/schemas/any.xsd create mode 100644 xmlbeans/samples/Any/src/org/apache/xmlbeans/samples/any/ListOfStrings.java create mode 100644 xmlbeans/samples/Any/src/org/apache/xmlbeans/samples/any/RootDocument.java create mode 100644 xmlbeans/samples/Any/src/org/apache/xmlbeans/samples/any/StringelementDocument.java create mode 100644 xmlbeans/samples/Any/src/org/apache/xmlbeans/samples/any/impl/ListOfStringsImpl.java create mode 100644 xmlbeans/samples/Any/src/org/apache/xmlbeans/samples/any/impl/RootDocumentImpl.java create mode 100644 xmlbeans/samples/Any/src/org/apache/xmlbeans/samples/any/impl/StringelementDocumentImpl.java create mode 100644 xmlbeans/samples/Any/src/org/apache/xmlbeans/samples/anytype/Any.java create mode 100644 xmlbeans/samples/Any/src/org/apache/xmlbeans/samples/anytype/AnyTest.java create mode 100644 xmlbeans/samples/Any/xml/any.xml create mode 100644 xmlbeans/samples/DateTime/README.txt create mode 100644 xmlbeans/samples/DateTime/build.xml create mode 100644 xmlbeans/samples/DateTime/schemas/datetime.xsd create mode 100644 xmlbeans/samples/DateTime/src/org/apache/xmlbeans/samples/datetime/DateTime.java create mode 100644 xmlbeans/samples/DateTime/src/org/apache/xmlbeans/samples/datetime/DateTimeTest.java create mode 100644 xmlbeans/samples/DateTime/xml/datetimesample.xml create mode 100644 xmlbeans/samples/DateTime/xml/newdatetimesample.xml create mode 100644 xmlbeans/samples/MixedContent/README.txt create mode 100644 xmlbeans/samples/MixedContent/build.xml create mode 100755 xmlbeans/samples/MixedContent/schemas/inventory.xsd create mode 100644 xmlbeans/samples/MixedContent/src/org/apache/xmlbeans/samples/cursor/MixedContent.java create mode 100644 xmlbeans/samples/MixedContent/src/org/apache/xmlbeans/samples/cursor/MixedContentTest.java create mode 100644 xmlbeans/samples/MixedContent/xml/inventoryitems.xml create mode 100644 xmlbeans/samples/OrderMatters/README.txt create mode 100644 xmlbeans/samples/OrderMatters/build.xml create mode 100644 xmlbeans/samples/OrderMatters/schemas/stmt.xsd create mode 100644 xmlbeans/samples/OrderMatters/src/org/apache/xmlbeans/samples/cursor/OrderMatters.java create mode 100644 xmlbeans/samples/OrderMatters/src/org/apache/xmlbeans/samples/cursor/OrderMattersTest.java create mode 100644 xmlbeans/samples/OrderMatters/xml/stmt.xml create mode 100644 xmlbeans/samples/SampleTemplate/README.txt create mode 100644 xmlbeans/samples/SampleTemplate/build.xml create mode 100755 xmlbeans/samples/SampleTemplate/schemas/hello.xsd create mode 100644 xmlbeans/samples/SampleTemplate/src/org/apache/xmlbeans/samples/template/SampleTemplate.java create mode 100644 xmlbeans/samples/SampleTemplate/src/org/apache/xmlbeans/samples/template/SampleTemplateTest.java create mode 100644 xmlbeans/samples/SampleTemplate/xml/bad.xml create mode 100644 xmlbeans/samples/SampleTemplate/xml/hello.xml create mode 100644 xmlbeans/samples/SchemaEnum/README.txt create mode 100644 xmlbeans/samples/SchemaEnum/build.xml create mode 100755 xmlbeans/samples/SchemaEnum/schemas/EasyPO.xsd create mode 100755 xmlbeans/samples/SchemaEnum/schemas/PriceSummary.xsd create mode 100644 xmlbeans/samples/SchemaEnum/src/org/apache/xmlbeans/samples/enumeration/SchemaEnum.java create mode 100644 xmlbeans/samples/SchemaEnum/src/org/apache/xmlbeans/samples/enumeration/SchemaEnumTest.java create mode 100644 xmlbeans/samples/SchemaEnum/xml/PriceSummary.xml create mode 100644 xmlbeans/samples/SchemaEnum/xml/PurchaseOrder.xml create mode 100644 xmlbeans/samples/SubstitutionGroup/README.txt create mode 100644 xmlbeans/samples/SubstitutionGroup/build.xml create mode 100644 xmlbeans/samples/SubstitutionGroup/schemas/EasyPo.xsd create mode 100644 xmlbeans/samples/SubstitutionGroup/src/org/apache/xmlbeans/samples/substitutiongroup/SubstitutionGroup.java create mode 100644 xmlbeans/samples/SubstitutionGroup/src/org/apache/xmlbeans/samples/substitutiongroup/SubstitutionGroupTest.java create mode 100644 xmlbeans/samples/SubstitutionGroup/xml/Purchase-Order.xml create mode 100644 xmlbeans/samples/SubstitutionGroup/xml/newPurchase-Order.xml create mode 100644 xmlbeans/samples/Validation/README.txt create mode 100644 xmlbeans/samples/Validation/build.xml create mode 100644 xmlbeans/samples/Validation/schemas/todolist.xsd create mode 100644 xmlbeans/samples/Validation/src/org/apache/xmlbeans/samples/validation/Validation.java create mode 100644 xmlbeans/samples/Validation/src/org/apache/xmlbeans/samples/validation/ValidationTest.java create mode 100644 xmlbeans/samples/Validation/src/org/apache/xmlbeans/samples/validation/todolist/ActionType.java create mode 100644 xmlbeans/samples/Validation/src/org/apache/xmlbeans/samples/validation/todolist/IdType.java create mode 100644 xmlbeans/samples/Validation/src/org/apache/xmlbeans/samples/validation/todolist/ItemType.java create mode 100644 xmlbeans/samples/Validation/src/org/apache/xmlbeans/samples/validation/todolist/NameType.java create mode 100644 xmlbeans/samples/Validation/src/org/apache/xmlbeans/samples/validation/todolist/TodolistDocument.java create mode 100644 xmlbeans/samples/Validation/src/org/apache/xmlbeans/samples/validation/todolist/impl/ActionTypeImpl.java create mode 100644 xmlbeans/samples/Validation/src/org/apache/xmlbeans/samples/validation/todolist/impl/IdTypeImpl.java create mode 100644 xmlbeans/samples/Validation/src/org/apache/xmlbeans/samples/validation/todolist/impl/ItemTypeImpl.java create mode 100644 xmlbeans/samples/Validation/src/org/apache/xmlbeans/samples/validation/todolist/impl/NameTypeImpl.java create mode 100644 xmlbeans/samples/Validation/src/org/apache/xmlbeans/samples/validation/todolist/impl/TodolistDocumentImpl.java create mode 100644 xmlbeans/samples/Validation/xml/todolist.xml create mode 100644 xmlbeans/samples/XQueryXPath/README.txt create mode 100644 xmlbeans/samples/XQueryXPath/build.xml create mode 100644 xmlbeans/samples/XQueryXPath/schemas/employeeschema.xsd create mode 100644 xmlbeans/samples/XQueryXPath/src/org/apache/xmlbeans/samples/xquery/ExecQuery.java create mode 100644 xmlbeans/samples/XQueryXPath/src/org/apache/xmlbeans/samples/xquery/SelectPath.java create mode 100644 xmlbeans/samples/XQueryXPath/src/org/apache/xmlbeans/samples/xquery/XQueryXPath.java create mode 100644 xmlbeans/samples/XQueryXPath/src/org/apache/xmlbeans/samples/xquery/XQueryXPathTest.java create mode 100644 xmlbeans/samples/XQueryXPath/xml/employees.xml create mode 100644 xmlbeans/samples/XmlSort/README.txt create mode 100644 xmlbeans/samples/XmlSort/build.xml create mode 100644 xmlbeans/samples/XmlSort/src/org/apache/xmlbeans/samples/cursor/XmlSort.java create mode 100644 xmlbeans/samples/XmlSort/xml/unsorted.xml create mode 100644 xmlbeans/samples/XmlTree/README.txt create mode 100644 xmlbeans/samples/XmlTree/build.xml create mode 100644 xmlbeans/samples/XmlTree/src/org/apache/xmlbeans/samples/xmltree/XmlEntry.java create mode 100644 xmlbeans/samples/XmlTree/src/org/apache/xmlbeans/samples/xmltree/XmlModel.java create mode 100644 xmlbeans/samples/XmlTree/src/org/apache/xmlbeans/samples/xmltree/XmlTree.java create mode 100644 xmlbeans/samples/XmlTree/src/org/apache/xmlbeans/samples/xmltree/XmlTreeFrame.java create mode 100644 xmlbeans/samples/XmlTree/src/org/apache/xmlbeans/samples/xmltree/XmlTreeTest.java create mode 100644 xmlbeans/samples/XmlTree/xml/PurchaseOrder.xml create mode 100644 xmlbeans/samples/XsdConfig/README.txt create mode 100644 xmlbeans/samples/XsdConfig/build.xml create mode 100644 xmlbeans/samples/XsdConfig/schemas/catalog.xsd create mode 100644 xmlbeans/samples/XsdConfig/schemas/myconfig.xsdconfig create mode 100644 xmlbeans/samples/XsdConfig/src/org/apache/xmlbeans/samples/xsdconfig/CatalogXsd.java create mode 100644 xmlbeans/samples/XsdConfig/src/org/apache/xmlbeans/samples/xsdconfig/CatalogXsdConfig.java create mode 100644 xmlbeans/samples/XsdConfig/src/org/apache/xmlbeans/samples/xsdconfig/XsdConfigTest.java create mode 100644 xmlbeans/samples/XsdConfig/src/org/apache/xmlbeans/samples/xsdconfig/XsdTest.java create mode 100644 xmlbeans/samples/XsdConfig/xml/catalog.xml create mode 100644 xmlbeans/samples/build.xml create mode 100644 xmlbeans/samples/vxsdb/README.txt create mode 100644 xmlbeans/samples/vxsdb/build.xml create mode 100644 xmlbeans/samples/vxsdb/datamodel.vm create mode 100644 xmlbeans/samples/vxsdb/doc/NOTES.txt create mode 100644 xmlbeans/samples/vxsdb/doc/vxsdb.html create mode 100644 xmlbeans/samples/vxsdb/external/DdlUtils-1.0-RC1.jar create mode 100644 xmlbeans/samples/vxsdb/global.vm create mode 100644 xmlbeans/samples/vxsdb/property.vm create mode 100644 xmlbeans/samples/vxsdb/run.xml create mode 100644 xmlbeans/samples/vxsdb/schemas/easypo.xsd create mode 100644 xmlbeans/samples/vxsdb/sql/create.sample.sql create mode 100644 xmlbeans/samples/vxsdb/src/java/log4j.xml create mode 100644 xmlbeans/samples/vxsdb/src/java/org/apache/xmlbeans/samples/vxsdb/VelocityXmlBeansDB.java create mode 100644 xmlbeans/samples/vxsdb/type.vm create mode 100644 xmlbeans/samples/vxsdb/xml/datamodel.sample.xml create mode 100644 xmlbeans/src/common/org/apache/xmlbeans/impl/common/ConcurrentReaderHashMap.java create mode 100644 xmlbeans/src/common/org/apache/xmlbeans/impl/common/EncodingMap.java create mode 100644 xmlbeans/src/common/org/apache/xmlbeans/impl/common/GenericXmlInputStream.java create mode 100644 xmlbeans/src/common/org/apache/xmlbeans/impl/common/GlobalLock.java create mode 100644 xmlbeans/src/common/org/apache/xmlbeans/impl/common/IOUtil.java create mode 100644 xmlbeans/src/common/org/apache/xmlbeans/impl/common/IdentityConstraint.java create mode 100644 xmlbeans/src/common/org/apache/xmlbeans/impl/common/InvalidLexicalValueException.java create mode 100644 xmlbeans/src/common/org/apache/xmlbeans/impl/common/JarHelper.java create mode 100644 xmlbeans/src/common/org/apache/xmlbeans/impl/common/Levenshtein.java create mode 100644 xmlbeans/src/common/org/apache/xmlbeans/impl/common/LoadSaveUtils.java create mode 100644 xmlbeans/src/common/org/apache/xmlbeans/impl/common/Mutex.java create mode 100644 xmlbeans/src/common/org/apache/xmlbeans/impl/common/NameUtil.java create mode 100644 xmlbeans/src/common/org/apache/xmlbeans/impl/common/PrefixResolver.java create mode 100644 xmlbeans/src/common/org/apache/xmlbeans/impl/common/PushedInputStream.java create mode 100644 xmlbeans/src/common/org/apache/xmlbeans/impl/common/QNameHelper.java create mode 100644 xmlbeans/src/common/org/apache/xmlbeans/impl/common/ReaderInputStream.java create mode 100644 xmlbeans/src/common/org/apache/xmlbeans/impl/common/ResolverUtil.java create mode 100644 xmlbeans/src/common/org/apache/xmlbeans/impl/common/Sax2Dom.java create mode 100644 xmlbeans/src/common/org/apache/xmlbeans/impl/common/SniffedXmlInputStream.java create mode 100644 xmlbeans/src/common/org/apache/xmlbeans/impl/common/SniffedXmlReader.java create mode 100644 xmlbeans/src/common/org/apache/xmlbeans/impl/common/SoftCache.java create mode 100644 xmlbeans/src/common/org/apache/xmlbeans/impl/common/SystemCache.java create mode 100644 xmlbeans/src/common/org/apache/xmlbeans/impl/common/ValidationContext.java create mode 100644 xmlbeans/src/common/org/apache/xmlbeans/impl/common/ValidatorListener.java create mode 100644 xmlbeans/src/common/org/apache/xmlbeans/impl/common/XBeanDebug.java create mode 100644 xmlbeans/src/common/org/apache/xmlbeans/impl/common/XMLChar.java create mode 100644 xmlbeans/src/common/org/apache/xmlbeans/impl/common/XMLNameHelper.java create mode 100644 xmlbeans/src/common/org/apache/xmlbeans/impl/common/XPath.java create mode 100644 xmlbeans/src/common/org/apache/xmlbeans/impl/common/XmlEncodingSniffer.java create mode 100644 xmlbeans/src/common/org/apache/xmlbeans/impl/common/XmlErrorPrinter.java create mode 100644 xmlbeans/src/common/org/apache/xmlbeans/impl/common/XmlErrorWatcher.java create mode 100644 xmlbeans/src/common/org/apache/xmlbeans/impl/common/XmlEventBase.java create mode 100755 xmlbeans/src/common/org/apache/xmlbeans/impl/common/XmlLocale.java create mode 100644 xmlbeans/src/common/org/apache/xmlbeans/impl/common/XmlNameImpl.java create mode 100644 xmlbeans/src/common/org/apache/xmlbeans/impl/common/XmlObjectList.java create mode 100644 xmlbeans/src/common/org/apache/xmlbeans/impl/common/XmlReaderToWriter.java create mode 100644 xmlbeans/src/common/org/apache/xmlbeans/impl/common/XmlStreamUtils.java create mode 100644 xmlbeans/src/common/org/apache/xmlbeans/impl/common/XmlWhitespace.java create mode 100644 xmlbeans/src/common/org/apache/xmlbeans/impl/common/readme.txt create mode 100644 xmlbeans/src/configschema/schema/xmlconfig.xsd create mode 100644 xmlbeans/src/configschema/schema/xmlconfig.xsdconfig create mode 100644 xmlbeans/src/jamsupport/org/apache/xmlbeans/impl/jam/internal/javadoc/JavadocTigerDelegateImpl_150.java create mode 100644 xmlbeans/src/jamsupport/org/apache/xmlbeans/impl/jam/internal/reflect/ReflectTigerDelegateImpl_150.java create mode 100644 xmlbeans/src/marshal/org/apache/xmlbeans/impl/richParser/XMLStreamReaderExt.java create mode 100644 xmlbeans/src/marshal/org/apache/xmlbeans/impl/richParser/XMLStreamReaderExtImpl.java create mode 100644 xmlbeans/src/repackage/repackage/EditBuildScript.java create mode 100644 xmlbeans/src/repackage/repackage/Repackage.java create mode 100644 xmlbeans/src/repackage/repackage/Repackager.java create mode 100644 xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/AttachmentPart.java create mode 100644 xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/Detail.java create mode 100644 xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/DetailEntry.java create mode 100644 xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/FactoryFinder.java create mode 100644 xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/MessageFactory.java create mode 100644 xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/MimeHeader.java create mode 100644 xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/MimeHeaders.java create mode 100644 xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/Name.java create mode 100644 xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/Node.java create mode 100644 xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/SOAPBody.java create mode 100644 xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/SOAPBodyElement.java create mode 100644 xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/SOAPConnection.java create mode 100644 xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/SOAPConnectionFactory.java create mode 100644 xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/SOAPConstants.java create mode 100644 xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/SOAPElement.java create mode 100644 xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/SOAPElementFactory.java create mode 100644 xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/SOAPEnvelope.java create mode 100644 xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/SOAPException.java create mode 100644 xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/SOAPFactory.java create mode 100644 xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/SOAPFault.java create mode 100644 xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/SOAPFaultElement.java create mode 100644 xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/SOAPHeader.java create mode 100644 xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/SOAPHeaderElement.java create mode 100644 xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/SOAPMessage.java create mode 100644 xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/SOAPPart.java create mode 100644 xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/Text.java create mode 100755 xmlbeans/src/store/org/apache/xmlbeans/impl/store/CharUtil.java create mode 100755 xmlbeans/src/store/org/apache/xmlbeans/impl/store/Cur.java create mode 100755 xmlbeans/src/store/org/apache/xmlbeans/impl/store/Cursor.java create mode 100755 xmlbeans/src/store/org/apache/xmlbeans/impl/store/DomImpl.java create mode 100755 xmlbeans/src/store/org/apache/xmlbeans/impl/store/Jsr173.java create mode 100755 xmlbeans/src/store/org/apache/xmlbeans/impl/store/Locale.java create mode 100755 xmlbeans/src/store/org/apache/xmlbeans/impl/store/Path.java create mode 100644 xmlbeans/src/store/org/apache/xmlbeans/impl/store/PathDelegate.java create mode 100755 xmlbeans/src/store/org/apache/xmlbeans/impl/store/Public2.java create mode 100755 xmlbeans/src/store/org/apache/xmlbeans/impl/store/QNameFactory.java create mode 100644 xmlbeans/src/store/org/apache/xmlbeans/impl/store/Query.java create mode 100644 xmlbeans/src/store/org/apache/xmlbeans/impl/store/QueryDelegate.java create mode 100755 xmlbeans/src/store/org/apache/xmlbeans/impl/store/Saaj.java create mode 100755 xmlbeans/src/store/org/apache/xmlbeans/impl/store/Saver.java create mode 100644 xmlbeans/src/store/org/apache/xmlbeans/impl/store/Validate.java create mode 100644 xmlbeans/src/store/org/apache/xmlbeans/impl/store/Xobj.java create mode 100755 xmlbeans/src/store/org/w3c/dom/DOMConfiguration.java create mode 100755 xmlbeans/src/store/org/w3c/dom/DOMStringList.java create mode 100755 xmlbeans/src/store/org/w3c/dom/TypeInfo.java create mode 100755 xmlbeans/src/store/org/w3c/dom/UserDataHandler.java create mode 100644 xmlbeans/src/tools/org/apache/xmlbeans/impl/inst2xsd/Inst2Xsd.java create mode 100644 xmlbeans/src/tools/org/apache/xmlbeans/impl/inst2xsd/Inst2XsdOptions.java create mode 100644 xmlbeans/src/tools/org/apache/xmlbeans/impl/inst2xsd/RussianDollStrategy.java create mode 100644 xmlbeans/src/tools/org/apache/xmlbeans/impl/inst2xsd/SalamiSliceStrategy.java create mode 100644 xmlbeans/src/tools/org/apache/xmlbeans/impl/inst2xsd/VenetianBlindStrategy.java create mode 100644 xmlbeans/src/tools/org/apache/xmlbeans/impl/inst2xsd/XsdGenStrategy.java create mode 100644 xmlbeans/src/tools/org/apache/xmlbeans/impl/inst2xsd/util/Attribute.java create mode 100644 xmlbeans/src/tools/org/apache/xmlbeans/impl/inst2xsd/util/Element.java create mode 100644 xmlbeans/src/tools/org/apache/xmlbeans/impl/inst2xsd/util/Type.java create mode 100644 xmlbeans/src/tools/org/apache/xmlbeans/impl/inst2xsd/util/TypeSystemHolder.java create mode 100644 xmlbeans/src/tools/org/apache/xmlbeans/impl/xpathgen/XPathGenerationException.java create mode 100644 xmlbeans/src/tools/org/apache/xmlbeans/impl/xpathgen/XPathGenerator.java create mode 100644 xmlbeans/src/tools/org/apache/xmlbeans/impl/xsd2inst/SampleXmlUtil.java create mode 100644 xmlbeans/src/tools/org/apache/xmlbeans/impl/xsd2inst/SchemaInstanceGenerator.java create mode 100644 xmlbeans/src/toolschema/ltgfmt.xsd create mode 100644 xmlbeans/src/toolschema/ltgfmt.xsdconfig create mode 100644 xmlbeans/src/toolschema/substwsdl.xsd create mode 100644 xmlbeans/src/toolschema/substwsdl.xsdconfig create mode 100644 xmlbeans/src/toolschema/xsdownload.xsd create mode 100644 xmlbeans/src/toolschema/xsdownload.xsdconfig create mode 100644 xmlbeans/src/typeholder/org/apache/xmlbeans/impl/schema/TypeSystemHolder.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/regex/BMPattern.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/regex/Match.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/regex/Op.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/regex/ParseException.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/regex/ParserForXMLSchema.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/regex/README.txt create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/regex/REUtil.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/regex/RangeToken.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/regex/RegexParser.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/regex/RegularExpression.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/regex/SchemaRegularExpression.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/regex/Token.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/regex/message.properties create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/regex/message_fr.properties create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/regex/message_ja.properties create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/BuiltinSchemaTypeSystem.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/ClassLoaderResourceLoader.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/FileResourceLoader.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/PathResourceLoader.java create mode 100755 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaAnnotationImpl.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaAttributeGroupImpl.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaAttributeModelImpl.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaContainer.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaDependencies.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaGlobalAttributeImpl.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaGlobalElementImpl.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaIdentityConstraintImpl.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaLocalAttributeImpl.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaLocalElementImpl.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaModelGroupImpl.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaParticleImpl.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaPropertyImpl.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaStringEnumEntryImpl.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaTypeCodePrinter.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaTypeImpl.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaTypeLoaderBase.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaTypeLoaderImpl.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaTypeSystemCompiler.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaTypeSystemImpl.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaTypeVisitorImpl.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SoapEncSchemaTypeSystem.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/StscChecker.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/StscComplexTypeResolver.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/StscImporter.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/StscJavaizer.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/StscResolver.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/StscSimpleTypeResolver.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/StscState.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/StscTranslator.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/XQuerySchemaTypeSystem.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/XmlValueRef.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/util/Base64.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/util/Diff.java create mode 100755 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/util/FilerImpl.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/util/HexBin.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/util/XsTypeConverter.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/validator/ValidatingInfoXMLStreamReader.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/validator/ValidatingXMLInputStream.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/validator/ValidatingXMLStreamReader.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/validator/Validator.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/validator/ValidatorUtil.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaBase64Holder.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaBase64HolderEx.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaBooleanHolder.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaBooleanHolderEx.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaDecimalHolder.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaDecimalHolderEx.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaDoubleHolder.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaDoubleHolderEx.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaFloatHolder.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaFloatHolderEx.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaGDateHolderEx.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaGDurationHolderEx.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaHexBinaryHolder.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaHexBinaryHolderEx.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaIntHolder.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaIntHolderEx.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaIntegerHolder.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaIntegerHolderEx.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaLongHolder.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaLongHolderEx.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaNotationHolder.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaNotationHolderEx.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaQNameHolder.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaQNameHolderEx.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaStringEnumerationHolderEx.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaStringHolder.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaStringHolderEx.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaUriHolder.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaUriHolderEx.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/NamespaceContext.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/StringEnumValue.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlAnySimpleTypeImpl.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlAnySimpleTypeRestriction.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlAnyTypeImpl.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlAnyUriImpl.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlAnyUriRestriction.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlBase64BinaryImpl.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlBase64BinaryRestriction.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlBooleanImpl.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlBooleanRestriction.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlByteImpl.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlComplexContentImpl.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlDateImpl.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlDateTimeImpl.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlDecimalImpl.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlDecimalRestriction.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlDoubleImpl.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlDoubleRestriction.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlDurationImpl.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlEntitiesImpl.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlEntityImpl.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlFloatImpl.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlFloatRestriction.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlGDayImpl.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlGMonthDayImpl.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlGMonthImpl.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlGYearImpl.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlGYearMonthImpl.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlHexBinaryImpl.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlHexBinaryRestriction.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlIdImpl.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlIdRefImpl.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlIdRefsImpl.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlIntImpl.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlIntRestriction.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlIntegerImpl.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlIntegerRestriction.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlLanguageImpl.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlListImpl.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlLongImpl.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlLongRestriction.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlNCNameImpl.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlNameImpl.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlNegativeIntegerImpl.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlNmTokenImpl.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlNmTokensImpl.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlNonNegativeIntegerImpl.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlNonPositiveIntegerImpl.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlNormalizedStringImpl.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlNotationImpl.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlNotationRestriction.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlObjectBase.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlPositiveIntegerImpl.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlQNameImpl.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlQNameRestriction.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlShortImpl.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlStringEnumeration.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlStringImpl.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlStringRestriction.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlTimeImpl.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlTokenImpl.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlUnionImpl.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlUnsignedByteImpl.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlUnsignedIntImpl.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlUnsignedLongImpl.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlUnsignedShortImpl.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlValueDisconnectedException.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlValueNotNillableException.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlValueNotSupportedException.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlValueOutOfRangeException.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/soap/SOAPArrayType.java create mode 100644 xmlbeans/src/typeimpl/org/apache/xmlbeans/soap/SchemaWSDLArrayType.java create mode 100644 xmlbeans/src/typestore/org/apache/xmlbeans/impl/values/NamespaceManager.java create mode 100644 xmlbeans/src/typestore/org/apache/xmlbeans/impl/values/TypeStore.java create mode 100644 xmlbeans/src/typestore/org/apache/xmlbeans/impl/values/TypeStoreUser.java create mode 100644 xmlbeans/src/typestore/org/apache/xmlbeans/impl/values/TypeStoreUserFactory.java create mode 100644 xmlbeans/src/typestore/org/apache/xmlbeans/impl/values/TypeStoreVisitor.java create mode 100644 xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/BaseSchemaResourceManager.java create mode 100644 xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/CodeGenUtil.java create mode 100644 xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/CommandLine.java create mode 100644 xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/Diff.java create mode 100644 xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/Extension.java create mode 100644 xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/FactorImports.java create mode 100644 xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/InstanceValidator.java create mode 100644 xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/PrettyPrinter.java create mode 100644 xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/RunXQuery.java create mode 100644 xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/SchemaCodeGenerator.java create mode 100644 xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/SchemaCompiler.java create mode 100644 xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/SchemaCompilerExtension.java create mode 100644 xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/SchemaCopy.java create mode 100644 xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/SchemaImportResolver.java create mode 100644 xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/SchemaResourceManager.java create mode 100644 xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/StreamInstanceValidator.java create mode 100644 xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/TypeHierarchyPrinter.java create mode 100644 xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/XMLBean.java create mode 100644 xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/XMLBeanXSTCHarness.java create mode 100644 xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/XSTCTester.java create mode 100644 xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/XsbDumper.java create mode 100755 xmlbeans/src/xmlconfig/org/apache/xmlbeans/impl/config/BindingConfigImpl.java create mode 100755 xmlbeans/src/xmlconfig/org/apache/xmlbeans/impl/config/InterfaceExtensionImpl.java create mode 100644 xmlbeans/src/xmlconfig/org/apache/xmlbeans/impl/config/NameSet.java create mode 100644 xmlbeans/src/xmlconfig/org/apache/xmlbeans/impl/config/NameSetBuilder.java create mode 100755 xmlbeans/src/xmlconfig/org/apache/xmlbeans/impl/config/PrePostExtensionImpl.java create mode 100644 xmlbeans/src/xmlconfig/org/apache/xmlbeans/impl/config/UserTypeImpl.java create mode 100755 xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/Attribute.java create mode 100755 xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/AttributeIterator.java create mode 100755 xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/BufferedXMLInputStream.java create mode 100755 xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/ChangePrefixMapping.java create mode 100755 xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/CharacterData.java create mode 100755 xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/Comment.java create mode 100755 xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/ElementFilter.java create mode 100755 xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/EndDocument.java create mode 100755 xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/EndElement.java create mode 100755 xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/EndPrefixMapping.java create mode 100755 xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/EntityReference.java create mode 100755 xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/Location.java create mode 100755 xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/ProcessingInstruction.java create mode 100755 xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/ReferenceResolver.java create mode 100755 xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/Space.java create mode 100755 xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/StartDocument.java create mode 100755 xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/StartElement.java create mode 100755 xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/StartPrefixMapping.java create mode 100755 xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/XMLEvent.java create mode 100755 xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/XMLInputStream.java create mode 100755 xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/XMLName.java create mode 100755 xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/XMLStreamException.java create mode 100755 xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/events/ElementTypeNames.java create mode 100755 xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/utils/NestedThrowable.java create mode 100644 xmlbeans/src/xmlpublic/javax/xml/namespace/NamespaceContext.java create mode 100644 xmlbeans/src/xmlpublic/javax/xml/namespace/QName.java create mode 100755 xmlbeans/src/xmlpublic/org/apache/xmlbeans/BindingConfig.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/CDataBookmark.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/DelegateXmlObject.java create mode 100755 xmlbeans/src/xmlpublic/org/apache/xmlbeans/Filer.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/FilterXmlObject.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/GDate.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/GDateBuilder.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/GDateSpecification.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/GDuration.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/GDurationBuilder.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/GDurationSpecification.java create mode 100755 xmlbeans/src/xmlpublic/org/apache/xmlbeans/InterfaceExtension.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/ObjectFactory.java create mode 100755 xmlbeans/src/xmlpublic/org/apache/xmlbeans/PrePostExtension.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/QNameCache.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/QNameSet.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/QNameSetBuilder.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/QNameSetSpecification.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/ResourceLoader.java create mode 100755 xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaAnnotated.java create mode 100755 xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaAnnotation.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaAttributeGroup.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaAttributeModel.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaBookmark.java create mode 100755 xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaCodePrinter.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaComponent.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaField.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaGlobalAttribute.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaGlobalElement.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaIdentityConstraint.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaLocalAttribute.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaLocalElement.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaModelGroup.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaParticle.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaProperty.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaStringEnumEntry.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaType.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaTypeElementSequencer.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaTypeLoader.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaTypeLoaderException.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaTypeSystem.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/SimpleValue.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/StringEnumAbstractBase.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/SystemProperties.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/UserType.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/XMLStreamValidationException.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlAnySimpleType.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlAnyURI.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlBase64Binary.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlBeans.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlBoolean.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlByte.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlCalendar.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlCursor.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlDate.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlDateTime.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlDecimal.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlDocumentProperties.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlDouble.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlDuration.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlENTITIES.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlENTITY.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlError.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlErrorCodes.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlException.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlFactoryHook.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlFloat.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlGDay.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlGMonth.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlGMonthDay.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlGYear.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlGYearMonth.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlHexBinary.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlID.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlIDREF.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlIDREFS.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlInt.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlInteger.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlLanguage.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlLineNumber.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlLong.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlNCName.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlNMTOKEN.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlNMTOKENS.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlNOTATION.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlName.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlNegativeInteger.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlNonNegativeInteger.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlNonPositiveInteger.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlNormalizedString.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlObject.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlOptionCharEscapeMap.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlOptions.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlOptionsBean.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlPositiveInteger.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlQName.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlRuntimeException.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlSaxHandler.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlShort.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlSimpleList.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlString.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlTime.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlToken.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlTokenSource.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlUnsignedByte.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlUnsignedInt.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlUnsignedLong.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlUnsignedShort.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlValidationError.java create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/message.properties create mode 100644 xmlbeans/src/xmlpublic/org/apache/xmlbeans/package.html create mode 100644 xmlbeans/src/xmlschema/schema/XML.xsd create mode 100644 xmlbeans/src/xmlschema/schema/XML.xsdconfig create mode 100644 xmlbeans/src/xpath_xquery/QueryInterface.g create mode 100644 xmlbeans/src/xpath_xquery/SelectPathInterface.g create mode 100644 xmlbeans/src/xpath_xquery/org/apache/xmlbeans/impl/xpath/saxon/XBeansXPath.java create mode 100644 xmlbeans/src/xpath_xquery/org/apache/xmlbeans/impl/xquery/saxon/XBeansXQuery.java create mode 100644 xmlbeans/src/xsdschema/schema/XMLSchema.xsd create mode 100644 xmlbeans/src/xsdschema/schema/XMLSchema.xsdconfig create mode 100644 xmlbeans/src/zipcompare/zipcompare/ZipCompare.java create mode 100644 xmlbeans/test/cases/schema/appview/Add_AcctSiebel7.xml create mode 100755 xmlbeans/test/cases/xbean/ValidatingStream/CarLocationMessage-inv.xml create mode 100755 xmlbeans/test/cases/xbean/ValidatingStream/CarLocationMessage.xml create mode 100755 xmlbeans/test/cases/xbean/ValidatingStream/Employees.xml create mode 100644 xmlbeans/test/cases/xbean/ValidatingStream/foo-inv.xml create mode 100644 xmlbeans/test/cases/xbean/ValidatingStream/foo.xsd create mode 100755 xmlbeans/test/cases/xbean/ValidatingStream/global-attr.xml create mode 100755 xmlbeans/test/cases/xbean/ValidatingStream/location-inv.xml create mode 100755 xmlbeans/test/cases/xbean/ValidatingStream/location.xml create mode 100755 xmlbeans/test/cases/xbean/ValidatingStream/location.xsd create mode 100755 xmlbeans/test/cases/xbean/ValidatingStream/mixed-content-inv.xml create mode 100755 xmlbeans/test/cases/xbean/ValidatingStream/mixed-content.xml create mode 100755 xmlbeans/test/cases/xbean/ValidatingStream/mixed-content.xsd create mode 100755 xmlbeans/test/cases/xbean/ValidatingStream/nomixed-content-inv.xml create mode 100755 xmlbeans/test/cases/xbean/ValidatingStream/numerals.xsd create mode 100755 xmlbeans/test/cases/xbean/ValidatingStream/person-frag.xml create mode 100755 xmlbeans/test/cases/xbean/ValidatingStream/person-frag2.xml create mode 100755 xmlbeans/test/cases/xbean/ValidatingStream/person-inv.xml create mode 100755 xmlbeans/test/cases/xbean/ValidatingStream/person-justname-inv.xml create mode 100755 xmlbeans/test/cases/xbean/ValidatingStream/person-justname.xml create mode 100755 xmlbeans/test/cases/xbean/ValidatingStream/person-sibling-inv.xml create mode 100755 xmlbeans/test/cases/xbean/ValidatingStream/person-sibling.xml create mode 100755 xmlbeans/test/cases/xbean/ValidatingStream/person-xsi-inv.xml create mode 100755 xmlbeans/test/cases/xbean/ValidatingStream/person.xml create mode 100755 xmlbeans/test/cases/xbean/ValidatingStream/person.xsd create mode 100755 xmlbeans/test/cases/xbean/ValidatingStream/po.xml create mode 100755 xmlbeans/test/cases/xbean/ValidatingStream/simpleTypes.xsd create mode 100644 xmlbeans/test/cases/xbean/compile/scomp/detailed/laxDoc.xsd create mode 100644 xmlbeans/test/cases/xbean/compile/scomp/incr/incr1.xsd create mode 100644 xmlbeans/test/cases/xbean/compile/scomp/incr/incr2-1.xsd create mode 100644 xmlbeans/test/cases/xbean/compile/scomp/incr/incr2.xsd create mode 100644 xmlbeans/test/cases/xbean/compile/scomp/incr/incr3.xsd create mode 100644 xmlbeans/test/cases/xbean/compile/scomp/incr/incr4.xsd create mode 100755 xmlbeans/test/cases/xbean/compile/scomp/j2ee/XML.xsd create mode 100755 xmlbeans/test/cases/xbean/compile/scomp/j2ee/application-client_1_4.xsd create mode 100755 xmlbeans/test/cases/xbean/compile/scomp/j2ee/application_1_4.xsd create mode 100755 xmlbeans/test/cases/xbean/compile/scomp/j2ee/connector_1_5.xsd create mode 100755 xmlbeans/test/cases/xbean/compile/scomp/j2ee/ejb-jar_2_1.xsd create mode 100755 xmlbeans/test/cases/xbean/compile/scomp/j2ee/j2ee_1_4.xsd create mode 100755 xmlbeans/test/cases/xbean/compile/scomp/j2ee/jsp_2_0.xsd create mode 100755 xmlbeans/test/cases/xbean/compile/scomp/j2ee/web-app_2_4.xsd create mode 100755 xmlbeans/test/cases/xbean/compile/scomp/pricequote/PriceQuote.xsd create mode 100644 xmlbeans/test/cases/xbean/compile/scomp/schemacompiler/enum1.xsd_ create mode 100644 xmlbeans/test/cases/xbean/compile/scomp/schemacompiler/enum1_redefine.xsd_ create mode 100644 xmlbeans/test/cases/xbean/compile/scomp/schemacompiler/enum2.xsd_ create mode 100644 xmlbeans/test/cases/xbean/compile/scomp/schemacompiler/enum2_redefine.xsd_ create mode 100644 xmlbeans/test/cases/xbean/compile/scomp/schemacompiler/enum3.xsd_ create mode 100644 xmlbeans/test/cases/xbean/compile/scomp/schemacompiler/enum3_redefine.xsd_ create mode 100644 xmlbeans/test/cases/xbean/compile/scomp/schemacompiler/ext/H1.java create mode 100644 xmlbeans/test/cases/xbean/compile/scomp/schemacompiler/ext/H2.java create mode 100644 xmlbeans/test/cases/xbean/compile/scomp/schemacompiler/ext/I1.java create mode 100644 xmlbeans/test/cases/xbean/compile/scomp/schemacompiler/ext/I2.java create mode 100644 xmlbeans/test/cases/xbean/compile/scomp/schemacompiler/methodsColide_jira205_278.xsd_ create mode 100644 xmlbeans/test/cases/xbean/compile/scomp/schemacompiler/methodsColide_jira205_278.xsdconfig_ create mode 100644 xmlbeans/test/cases/xbean/compile/scomp/schemacompiler/union_initial.xsd create mode 100644 xmlbeans/test/cases/xbean/compile/scomp/schemacompiler/union_redefine.xsd create mode 100755 xmlbeans/test/cases/xbean/compile/scomp/simple/javasrc/SimplePersonTest.java create mode 100755 xmlbeans/test/cases/xbean/compile/scomp/simple/person.xml create mode 100755 xmlbeans/test/cases/xbean/compile/scomp/simple/person.xsd create mode 100755 xmlbeans/test/cases/xbean/compile/scomp/simple/simplec.xsd create mode 100644 xmlbeans/test/cases/xbean/compile/som/constraints.xsd_ create mode 100644 xmlbeans/test/cases/xbean/compile/som/constraints_added.xsd_ create mode 100644 xmlbeans/test/cases/xbean/compile/som/datatypes.xsd_ create mode 100644 xmlbeans/test/cases/xbean/compile/som/datatypes_added.xsd_ create mode 100644 xmlbeans/test/cases/xbean/compile/som/datatypes_modified.xsd_ create mode 100644 xmlbeans/test/cases/xbean/compile/som/derived_types.xsd_ create mode 100644 xmlbeans/test/cases/xbean/compile/som/derived_types_added.xsd_ create mode 100644 xmlbeans/test/cases/xbean/compile/som/derived_types_modifed.xsd_ create mode 100644 xmlbeans/test/cases/xbean/compile/som/elemattr.xsd_ create mode 100644 xmlbeans/test/cases/xbean/compile/som/elemattr_added.xsd_ create mode 100644 xmlbeans/test/cases/xbean/compile/som/elemattr_modified.xsd_ create mode 100644 xmlbeans/test/cases/xbean/compile/som/groups.xsd_ create mode 100644 xmlbeans/test/cases/xbean/compile/som/groups_added.xsd_ create mode 100644 xmlbeans/test/cases/xbean/compile/som/groups_modified.xsd_ create mode 100644 xmlbeans/test/cases/xbean/compile/som/instance_constraints_invalid.xml create mode 100644 xmlbeans/test/cases/xbean/compile/som/instance_constraints_valid.xml create mode 100644 xmlbeans/test/cases/xbean/compile/som/instance_datatypes_valid.xml create mode 100644 xmlbeans/test/cases/xbean/compile/som/instance_derived_types_modify.xml create mode 100644 xmlbeans/test/cases/xbean/compile/som/instance_derived_types_valid.xml create mode 100644 xmlbeans/test/cases/xbean/compile/som/instance_elemattr.xml create mode 100644 xmlbeans/test/cases/xbean/compile/som/instance_elemattr_added.xml create mode 100644 xmlbeans/test/cases/xbean/compile/som/instance_elemattr_valid.xml create mode 100644 xmlbeans/test/cases/xbean/compile/som/instance_simple_types_invalid.xml create mode 100644 xmlbeans/test/cases/xbean/compile/som/instance_subst_grps_valid.xml create mode 100644 xmlbeans/test/cases/xbean/compile/som/namespaces1.xsd_ create mode 100644 xmlbeans/test/cases/xbean/compile/som/namespaces2.xsd_ create mode 100644 xmlbeans/test/cases/xbean/compile/som/namespaces_import_fileonly.xsd_ create mode 100644 xmlbeans/test/cases/xbean/compile/som/namespaces_import_filepath.xsd create mode 100644 xmlbeans/test/cases/xbean/compile/som/namespaces_include.xsd_ create mode 100644 xmlbeans/test/cases/xbean/compile/som/namespaces_noimports.xsd_ create mode 100644 xmlbeans/test/cases/xbean/compile/som/reusable_grps.xsd_ create mode 100644 xmlbeans/test/cases/xbean/compile/som/reusable_grps_added.xsd_ create mode 100644 xmlbeans/test/cases/xbean/compile/som/reusable_grps_modified.xsd_ create mode 100644 xmlbeans/test/cases/xbean/dom/ComplexTypeTest.xsd create mode 100755 xmlbeans/test/cases/xbean/dom/W3C/level2/core/files/README create mode 100755 xmlbeans/test/cases/xbean/dom/W3C/level2/core/files/hc_staff.xml create mode 100755 xmlbeans/test/cases/xbean/dom/W3C/level2/core/files/nodtdstaff.xml create mode 100755 xmlbeans/test/cases/xbean/dom/W3C/level2/core/files/staff.dtd create mode 100755 xmlbeans/test/cases/xbean/dom/W3C/level2/core/files/staff.xml create mode 100755 xmlbeans/test/cases/xbean/dom/W3C/level2/core/files/staff2.dtd create mode 100755 xmlbeans/test/cases/xbean/dom/W3C/level2/core/files/staff2.xml create mode 100755 xmlbeans/test/cases/xbean/dom/W3C/level2/core/files/staffNS.dtd create mode 100755 xmlbeans/test/cases/xbean/dom/W3C/level2/core/files/staffNS.xml create mode 100755 xmlbeans/test/cases/xbean/dom/W3C/level2/core/files/xhtml1-frameset.dtd create mode 100755 xmlbeans/test/cases/xbean/dom/W3C/level2/core/files/xhtml1-strict.dtd create mode 100755 xmlbeans/test/cases/xbean/dom/W3C/level2/core/files/xhtml1-transitional.dtd create mode 100644 xmlbeans/test/cases/xbean/dom/dumb.xsd create mode 100644 xmlbeans/test/cases/xbean/dom/id.xml create mode 100644 xmlbeans/test/cases/xbean/dom/id.xsd create mode 100755 xmlbeans/test/cases/xbean/extensions/interfaceFeature/averageCase/po.xsd create mode 100755 xmlbeans/test/cases/xbean/extensions/interfaceFeature/averageCase/po.xsdconfig create mode 100755 xmlbeans/test/cases/xbean/extensions/interfaceFeature/methodNameCollision/company.xsd create mode 100755 xmlbeans/test/cases/xbean/extensions/interfaceFeature/methodNameCollision/company.xsdconfig create mode 100755 xmlbeans/test/cases/xbean/extensions/interfaceFeature/multInterfaces/po.xsd create mode 100755 xmlbeans/test/cases/xbean/extensions/interfaceFeature/multInterfaces/po.xsdconfig create mode 100755 xmlbeans/test/cases/xbean/extensions/interfaceFeature/readOnlyBean/po.xsd create mode 100755 xmlbeans/test/cases/xbean/extensions/interfaceFeature/readOnlyBean/po.xsdconfig create mode 100755 xmlbeans/test/cases/xbean/extensions/prePostFeature/ValueRestriction/company.xsd create mode 100755 xmlbeans/test/cases/xbean/extensions/prePostFeature/ValueRestriction/company.xsdconfig create mode 100755 xmlbeans/test/cases/xbean/extensions/prePostFeature/readOnlyBean/po.xsd create mode 100755 xmlbeans/test/cases/xbean/extensions/prePostFeature/readOnlyBean/po.xsdconfig create mode 100755 xmlbeans/test/cases/xbean/marshal/com/mytest/YourClass.java create mode 100755 xmlbeans/test/cases/xbean/misc/dyntest.xml create mode 100755 xmlbeans/test/cases/xbean/misc/dyntest.xsd create mode 100755 xmlbeans/test/cases/xbean/misc/dyntest2.xml create mode 100755 xmlbeans/test/cases/xbean/misc/dyntest2.xsd create mode 100644 xmlbeans/test/cases/xbean/misc/jira/easypo.xml create mode 100644 xmlbeans/test/cases/xbean/misc/jira/xmlbeans_04.xsd_ create mode 100644 xmlbeans/test/cases/xbean/misc/jira/xmlbeans_08.xsd_ create mode 100644 xmlbeans/test/cases/xbean/misc/jira/xmlbeans_08a.xsd_ create mode 100644 xmlbeans/test/cases/xbean/misc/jira/xmlbeans_09.xml create mode 100644 xmlbeans/test/cases/xbean/misc/jira/xmlbeans_09.xsd_ create mode 100644 xmlbeans/test/cases/xbean/misc/jira/xmlbeans_102.xsd create mode 100644 xmlbeans/test/cases/xbean/misc/jira/xmlbeans_102_netui-config.xsd_ create mode 100644 xmlbeans/test/cases/xbean/misc/jira/xmlbeans_105.xml create mode 100644 xmlbeans/test/cases/xbean/misc/jira/xmlbeans_105.xsd create mode 100644 xmlbeans/test/cases/xbean/misc/jira/xmlbeans_105a.xsd create mode 100644 xmlbeans/test/cases/xbean/misc/jira/xmlbeans_175.xsd create mode 100644 xmlbeans/test/cases/xbean/misc/jira/xmlbeans_177.xml create mode 100644 xmlbeans/test/cases/xbean/misc/jira/xmlbeans_177.xsd create mode 100644 xmlbeans/test/cases/xbean/misc/jira/xmlbeans_177a.xml create mode 100644 xmlbeans/test/cases/xbean/misc/jira/xmlbeans_177a.xsd create mode 100644 xmlbeans/test/cases/xbean/misc/jira/xmlbeans_184_datentypen_V1.30.xsd_ create mode 100644 xmlbeans/test/cases/xbean/misc/jira/xmlbeans_184_ehd_header_V1.30.xsd_ create mode 100644 xmlbeans/test/cases/xbean/misc/jira/xmlbeans_184_ehd_root_V1.30.xsd_ create mode 100644 xmlbeans/test/cases/xbean/misc/jira/xmlbeans_184_keytabs_V1.30.xsd_ create mode 100644 xmlbeans/test/cases/xbean/misc/jira/xmlbeans_184_vdx_data_V1.04.xsd_ create mode 100644 xmlbeans/test/cases/xbean/misc/jira/xmlbeans_184_vdx_header_V1.04.xsd_ create mode 100644 xmlbeans/test/cases/xbean/misc/jira/xmlbeans_184_vdx_root_V1.04.xsd_ create mode 100644 xmlbeans/test/cases/xbean/misc/jira/xmlbeans_208.xsd create mode 100644 xmlbeans/test/cases/xbean/misc/jira/xmlbeans_228.xsd create mode 100644 xmlbeans/test/cases/xbean/misc/jira/xmlbeans_236.xsd_ create mode 100644 xmlbeans/test/cases/xbean/misc/jira/xmlbeans_239a.xsd_ create mode 100644 xmlbeans/test/cases/xbean/misc/jira/xmlbeans_239b.xsd_ create mode 100644 xmlbeans/test/cases/xbean/misc/jira/xmlbeans_239c.xsd_ create mode 100644 xmlbeans/test/cases/xbean/misc/jira/xmlbeans_251.xsd_ create mode 100644 xmlbeans/test/cases/xbean/misc/jira/xmlbeans_307_maxallowedenum.xsd create mode 100644 xmlbeans/test/cases/xbean/misc/jira/xmlbeans_307_morethanallowedenum.xsd create mode 100644 xmlbeans/test/cases/xbean/misc/jira/xmlbeans_33a.xsd create mode 100644 xmlbeans/test/cases/xbean/misc/jira/xmlbeans_33b.xsd create mode 100644 xmlbeans/test/cases/xbean/misc/jira/xmlbeans_34a.xsd_ create mode 100644 xmlbeans/test/cases/xbean/misc/jira/xmlbeans_34b.xsd_ create mode 100644 xmlbeans/test/cases/xbean/misc/jira/xmlbeans_35.xsd_ create mode 100644 xmlbeans/test/cases/xbean/misc/jira/xmlbeans_45a.xsd create mode 100644 xmlbeans/test/cases/xbean/misc/jira/xmlbeans_45b.xsd create mode 100644 xmlbeans/test/cases/xbean/misc/jira/xmlbeans_46.xsd create mode 100644 xmlbeans/test/cases/xbean/misc/jira/xmlbeans_48.xsd create mode 100644 xmlbeans/test/cases/xbean/misc/jira/xmlbeans_49.xsd_ create mode 100644 xmlbeans/test/cases/xbean/misc/jira/xmlbeans_54.xsd_ create mode 100644 xmlbeans/test/cases/xbean/misc/jira/xmlbeans_57.xml create mode 100644 xmlbeans/test/cases/xbean/misc/jira/xmlbeans_62.xml create mode 100644 xmlbeans/test/cases/xbean/misc/jira/xmlbeans_64.xml create mode 100644 xmlbeans/test/cases/xbean/misc/jira/xmlbeans_64.xsd create mode 100644 xmlbeans/test/cases/xbean/misc/jira/xmlbeans_68.xsd create mode 100644 xmlbeans/test/cases/xbean/misc/jira/xmlbeans_71.xml create mode 100644 xmlbeans/test/cases/xbean/misc/jira/xmlbeans_71.xsd create mode 100644 xmlbeans/test/cases/xbean/misc/jira/xmlbeans_78.xml create mode 100644 xmlbeans/test/cases/xbean/misc/jira/xmlbeans_97.xsd create mode 100644 xmlbeans/test/cases/xbean/misc/jira/xmlbeans_97.xsdconfig create mode 100644 xmlbeans/test/cases/xbean/misc/jira/xmlbeans_98.xml create mode 100644 xmlbeans/test/cases/xbean/misc/jira/xmlbeans_98.xsd create mode 100644 xmlbeans/test/cases/xbean/misc/jira/xmlbeans_98_exp.xml create mode 100644 xmlbeans/test/cases/xbean/misc/jira/xmlbeans_99.xml create mode 100644 xmlbeans/test/cases/xbean/misc/jira/xmlbeans_99.xsd create mode 100755 xmlbeans/test/cases/xbean/misc/primitiveTypes.xml create mode 100755 xmlbeans/test/cases/xbean/misc/signature-example-dsa.xml create mode 100755 xmlbeans/test/cases/xbean/misc/signature-example-rsa.xml create mode 100755 xmlbeans/test/cases/xbean/misc/signature-example.xml create mode 100644 xmlbeans/test/cases/xbean/misc/syscachetest.xsd create mode 100755 xmlbeans/test/cases/xbean/misc/xkms-1.0.wsdl create mode 100755 xmlbeans/test/cases/xbean/misc/xmldsig-core-schema.xsd create mode 100755 xmlbeans/test/cases/xbean/schema/typesonly/typesonly.xsd create mode 100644 xmlbeans/test/cases/xbean/scomp/attribute/AttributeGroup.xsd create mode 100644 xmlbeans/test/cases/xbean/scomp/attribute/GlobalAttrDefault.xsd create mode 100644 xmlbeans/test/cases/xbean/scomp/attribute/GlobalAttrFixed.xsd create mode 100644 xmlbeans/test/cases/xbean/scomp/attribute/GlobalAttrId.xsd create mode 100644 xmlbeans/test/cases/xbean/scomp/attribute/GlobalAttrType.xsd create mode 100644 xmlbeans/test/cases/xbean/scomp/attribute/LocalAttrFixedDefault.xsd create mode 100644 xmlbeans/test/cases/xbean/scomp/attribute/LocalAttrUse.xsd create mode 100644 xmlbeans/test/cases/xbean/scomp/contentType/Anonymous.xsd create mode 100644 xmlbeans/test/cases/xbean/scomp/contentType/ComplexTypeTest.xsd create mode 100644 xmlbeans/test/cases/xbean/scomp/contentType/Group.xsd create mode 100644 xmlbeans/test/cases/xbean/scomp/contentType/ListType.xsd create mode 100644 xmlbeans/test/cases/xbean/scomp/contentType/Named.xsd create mode 100644 xmlbeans/test/cases/xbean/scomp/contentType/SimpleType.xsd create mode 100644 xmlbeans/test/cases/xbean/scomp/contentType/UnionType.xsd create mode 100644 xmlbeans/test/cases/xbean/scomp/contentType/builtInTypes/DateTime.xsd create mode 100644 xmlbeans/test/cases/xbean/scomp/contentType/builtInTypes/NumberBased.xsd create mode 100644 xmlbeans/test/cases/xbean/scomp/contentType/builtInTypes/StringBased.xsd create mode 100644 xmlbeans/test/cases/xbean/scomp/derivation/Abstract.xsd create mode 100644 xmlbeans/test/cases/xbean/scomp/derivation/AttributeExtension.xsd create mode 100644 xmlbeans/test/cases/xbean/scomp/derivation/AttributeRestriction.xsd create mode 100644 xmlbeans/test/cases/xbean/scomp/derivation/AttributeUseProhibited.xsd create mode 100644 xmlbeans/test/cases/xbean/scomp/derivation/AttributeWCExtension.xsd create mode 100644 xmlbeans/test/cases/xbean/scomp/derivation/AttributeWCRestriction.xsd create mode 100644 xmlbeans/test/cases/xbean/scomp/derivation/Block.xsd create mode 100644 xmlbeans/test/cases/xbean/scomp/derivation/ComplexContentExtension.xsd create mode 100644 xmlbeans/test/cases/xbean/scomp/derivation/ElementRestriction.xsd create mode 100644 xmlbeans/test/cases/xbean/scomp/derivation/ElementWCRestriction.xsd create mode 100644 xmlbeans/test/cases/xbean/scomp/derivation/EmptyContent.xsd create mode 100644 xmlbeans/test/cases/xbean/scomp/derivation/FinalBlockDefault.xsd create mode 100644 xmlbeans/test/cases/xbean/scomp/derivation/GroupRestrictionTest.xsd create mode 100644 xmlbeans/test/cases/xbean/scomp/derivation/MixedContentExtension.xsd create mode 100644 xmlbeans/test/cases/xbean/scomp/derivation/MixedContentRestriction.xsd create mode 100644 xmlbeans/test/cases/xbean/scomp/derivation/SimpleContentExtension.xsd create mode 100644 xmlbeans/test/cases/xbean/scomp/derivation/SimpleTypeRestriction.xsd create mode 100644 xmlbeans/test/cases/xbean/scomp/derivation/facets/DateTimePattern.xsd create mode 100644 xmlbeans/test/cases/xbean/scomp/derivation/facets/FacetRestriction.xsd create mode 100644 xmlbeans/test/cases/xbean/scomp/derivation/facets/Facets.xsd create mode 100644 xmlbeans/test/cases/xbean/scomp/derivation/facets/ListRestriction.xsd create mode 100644 xmlbeans/test/cases/xbean/scomp/derivation/facets/UnionRestriction.xsd create mode 100644 xmlbeans/test/cases/xbean/scomp/element/Any.xsd create mode 100644 xmlbeans/test/cases/xbean/scomp/element/GlobalEltDefault.xsd create mode 100644 xmlbeans/test/cases/xbean/scomp/element/GlobalEltFixed.xsd create mode 100644 xmlbeans/test/cases/xbean/scomp/element/GlobalEltNillable.xsd create mode 100644 xmlbeans/test/cases/xbean/scomp/element/LocalEltMinMaxOccurs.xsd create mode 100644 xmlbeans/test/cases/xbean/scomp/element/NamedModelGroup.xsd create mode 100644 xmlbeans/test/cases/xbean/scomp/element/NillTest.xsd create mode 100644 xmlbeans/test/cases/xbean/scomp/idConstraints/Constraint.xsd create mode 100644 xmlbeans/test/cases/xbean/scomp/namespace/AttributeFormDefault.xsd create mode 100644 xmlbeans/test/cases/xbean/scomp/namespace/AttributeWC.xsd create mode 100644 xmlbeans/test/cases/xbean/scomp/namespace/ElementFormDefault.xsd create mode 100644 xmlbeans/test/cases/xbean/scomp/namespace/ElementWC.xsd create mode 100644 xmlbeans/test/cases/xbean/scomp/namespace/NoNamespace.xsd create mode 100644 xmlbeans/test/cases/xbean/scomp/redefine/AttrRedefineSub.xs create mode 100644 xmlbeans/test/cases/xbean/scomp/redefine/AttrRedefineSuper.xsd create mode 100644 xmlbeans/test/cases/xbean/scomp/redefine/BaseAttrGroup.xs create mode 100644 xmlbeans/test/cases/xbean/scomp/redefine/BaseModelGroup.xs create mode 100644 xmlbeans/test/cases/xbean/scomp/redefine/BaseSimple.xs create mode 100644 xmlbeans/test/cases/xbean/scomp/redefine/ModelGroupSub.xs create mode 100644 xmlbeans/test/cases/xbean/scomp/redefine/ModelGroupSuper.xsd create mode 100644 xmlbeans/test/cases/xbean/scomp/redefine/SimpleRedefined.xsd create mode 100644 xmlbeans/test/cases/xbean/scomp/redefine/TypeBase.xs create mode 100644 xmlbeans/test/cases/xbean/scomp/redefine/TypeRedefine.xsd create mode 100644 xmlbeans/test/cases/xbean/scomp/substGroup/Abstract.xsd create mode 100644 xmlbeans/test/cases/xbean/scomp/substGroup/Block.xsd create mode 100644 xmlbeans/test/cases/xbean/scomp/substGroup/Deep.xsd create mode 100644 xmlbeans/test/cases/xbean/scomp/substGroup/OneLevel.xsd create mode 100644 xmlbeans/test/cases/xbean/scomp/substGroup/UserAbstract.xsd create mode 100644 xmlbeans/test/cases/xbean/scomp/substGroup/UserReported.xsd create mode 100644 xmlbeans/test/cases/xbean/scomp/substGroup/Wide.xsd create mode 100755 xmlbeans/test/cases/xbean/simple/dumb/dumb.xml create mode 100755 xmlbeans/test/cases/xbean/simple/dumb/dumb.xsd create mode 100755 xmlbeans/test/cases/xbean/simple/dumb/sub/bar.xsd create mode 100755 xmlbeans/test/cases/xbean/simple/dupSchemaElements/DupElementsInSameSchema.xsd create mode 100755 xmlbeans/test/cases/xbean/simple/dupSchemaElements/custOrdUdf.xsd create mode 100755 xmlbeans/test/cases/xbean/simple/dupSchemaElements/viewtarget.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/options/base.xml create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/options/base0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/options/base_rd0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/options/base_rd_eN0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/options/base_rd_scs0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/options/base_rd_scs_eN0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/options/base_ss0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/options/base_ss_eN0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/options/base_ss_scs0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/options/base_ss_scs_eN0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/options/base_vb0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/options/base_vb_eN0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/options/base_vb_scs0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/options/base_vb_scs_eN0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/choice.xml create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/choice_ss0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/complex/choice/attrchoice.xml create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/complex/choice/attrchoice_ss0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/complex/choice/attrchoice_ss1.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/complex/choice/nschoice.xml create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/complex/choice/nschoice_ss0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/complex/choice/nschoice_ss1.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/complex/choice/nschoice_ss2.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/complex/choice/nschoice_ss3.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/complex/choice/schema0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/complex/choice/schema1.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/complex/choice/simplechoice.xml create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/complex/choice/simplechoice_rd0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/complex/choice/simplechoice_ss0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/complex/choice/simplechoice_vb0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/complex/enum/attr/attrenum.xml create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/complex/enum/attr/attrenum_rd0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/complex/enum/attr/attrenum_rd1.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/complex/enum/attr/attrenum_rd2.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/complex/enum/attr/attrenum_rd_enum0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/complex/enum/attr/attrenum_rd_enum1.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/complex/enum/attr/attrenum_rd_enum2.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/complex/enum/attr/attrenum_ss0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/complex/enum/attr/attrenum_ss1.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/complex/enum/attr/attrenum_ss2.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/complex/enum/attr/attrenum_ss_enum0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/complex/enum/attr/attrenum_ss_enum1.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/complex/enum/attr/attrenum_ss_enum2.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/complex/enum/attr/attrenum_vb0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/complex/enum/attr/attrenum_vb1.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/complex/enum/attr/attrenum_vb2.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/complex/enum/attr/attrenum_vb_enum0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/complex/enum/attr/attrenum_vb_enum1.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/complex/enum/attr/attrenum_vb_enum2.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/complex/enum/enum.xml create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/complex/enum/enum2_rd0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/complex/enum/enum2_ss0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/complex/enum/enum2_vb0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/complex/enum/enumQName.xml create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/complex/enum/enumQName_vb_eN0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/complex/enum/enumQName_vb_enum0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/complex/enum/enum_vb_eN0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/complex/enum/enum_vb_scs_enum0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/complex/global/globalattr_rd0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/complex/global/globalattr_rd1.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/complex/global/globalattr_ss0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/complex/global/globalattr_ss1.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/complex/global/globalattr_vb0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/complex/global/globalattr_vb1.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/complex/global/globalattribute.xml create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/complex/nestedNSArray/nestedArray_rd0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/complex/nestedNSArray/nestedArray_rd1.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/complex/nestedNSArray/nestedArray_rd2.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/complex/nestedNSArray/nestedArray_rd3.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/complex/nestedNSArray/nestedArray_ss0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/complex/nestedNSArray/nestedArray_ss1.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/complex/nestedNSArray/nestedArray_ss2.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/complex/nestedNSArray/nestedArray_ss3.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/complex/nestedNSArray/nestedArray_vb0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/complex/nestedNSArray/nestedArray_vb1.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/complex/nestedNSArray/nestedArray_vb2.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/complex/nestedNSArray/nestedArray_vb3.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/complex/nestedNSArray/nestedNSArray.xml create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/complex/sample/choice.xml create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/complex/sample/choice_rd0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/complex/sample/choice_rd1.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/complex/sample/choice_rd_eN0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/complex/sample/choice_rd_eN1.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/complex/sample/choice_rd_scs_eN0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/complex/sample/choice_rd_scs_eN1.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/complex/sample/oops0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/complex/sample/oops1.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/examples/cd_catalog.xml create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/examples/cd_catalog_rd0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/examples/cd_catalog_ss0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/examples/cd_catalog_vb0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/examples/cdcatalog.xml create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/examples/cdcatalog_rd0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/examples/cdcatalog_ss0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/examples/cdcatalog_vb0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/examples/component.xml create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/examples/component_rd0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/examples/component_ss0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/examples/component_vb0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/examples/html_example.xml create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/examples/html_example_rd0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/examples/html_example_ss0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/examples/html_example_vb0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/examples/po/po.xml create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/examples/po/po_rd_eN0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/examples/po/po_ss0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/examples/po/po_ss_eN0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/examples/po/po_vb0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/examples/po/po_vb_eN0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/examples/po/po_vb_scs0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/examples/po/po_vb_scs_enum0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/examples/rss2sample.xml create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/examples/rss2sample_contentsmart_4enum_vb0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/examples/rss2sample_contentsmart_neverenum_vb0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/examples/rss2sample_contentstring_4enum_vb0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/examples/rss2sample_contentstring_neverenum_vb0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/examples/rss2sample_contentstring_vb0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/examples/rss2sample_neverenum_vb0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/examples/rss2sample_rd0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/examples/rss2sample_ss0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/examples/rss2sample_vb0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/examples/sampleRss091.xml create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/examples/sampleRss091_rd0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/examples/sampleRss091_ss0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/examples/sampleRss091_vb0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/examples/sampleRss092.xml create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/examples/sampleRss092_rd0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/examples/sampleRss092_ss0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/examples/sampleRss092_vb0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/examples/schema0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/examples/slashdot.rdf.xml create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/examples/slashdot.xml create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/examples/slashdotrdf_rd0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/examples/slashdotrdf_rd1.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/examples/slashdotrdf_ss0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/examples/slashdotrdf_ss1.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/examples/slashdotrdf_vb0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/examples/slashdotrdf_vb1.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/examples/slashdotxml_neverenum_ss0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/examples/slashdotxml_rd0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/examples/slashdotxml_ss0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/examples/slashdotxml_vb0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/examples/xmlnews.xml create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/examples/xmlnews_rd0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/examples/xmlnews_ss0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/examples/xmlnews_vb0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/examples/xsl_example.xml create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/examples/xsl_rd0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/examples/xsl_rd1.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/examples/xsl_ss0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/examples/xsl_ss1.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/examples/xsl_vb0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/examples/xsl_vb1.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/namespaces/duplicatedNS.xml create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/namespaces/duplicatedNS_rd0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/namespaces/duplicatedNS_ss0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/namespaces/duplicatedNS_vb0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/namespaces/multipleNS.xml create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/namespaces/multipleNS_rd0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/namespaces/multipleNS_rd1.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/namespaces/multipleNS_rd2.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/namespaces/multipleNS_rd3.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/namespaces/multipleNS_ss0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/namespaces/multipleNS_ss1.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/namespaces/multipleNS_ss2.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/namespaces/multipleNS_ss3.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/namespaces/multipleNS_vb0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/namespaces/multipleNS_vb1.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/namespaces/multipleNS_vb2.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/namespaces/multipleNS_vb3.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/namespaces/multipleNestedNS.xml create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/namespaces/multipleNestedNS_rd0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/namespaces/multipleNestedNS_rd1.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/namespaces/multipleNestedNS_rd2.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/namespaces/multipleNestedNS_rd3.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/namespaces/multipleNestedNS_ss0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/namespaces/multipleNestedNS_ss1.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/namespaces/multipleNestedNS_ss2.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/namespaces/multipleNestedNS_ss3.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/namespaces/multipleNestedNS_vb0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/namespaces/multipleNestedNS_vb1.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/namespaces/multipleNestedNS_vb2.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/namespaces/multipleNestedNS_vb3.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/namespaces/must.xml create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/namespaces/must_rd0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/namespaces/must_rd1.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/namespaces/must_ss0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/namespaces/must_ss1.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/namespaces/must_vb0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/namespaces/must_vb1.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/namespaces/simple.xml create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/namespaces/simple_rd0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/namespaces/simple_ss0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/namespaces/simple_vb0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/simpleName.xml create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/simpleName_rd0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/simpleName_ss0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/simpleName_vb0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/types/CData.xml create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/types/cdata_rd0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/types/cdata_ss0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/types/cdata_vb0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/types/comments.xml create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/types/comments_rd0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/types/comments_ss0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/types/comments_vb0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/types/commentschoice.xml create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/types/commentschoice_eNrd0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/types/commentschoice_eNss0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/types/commentschoice_eNvb0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/types/commentschoice_vb0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/types/innercomment.xml create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/types/innercomment_vb0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/types/person.xml create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/types/person_vb0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/types/po.xml create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/types/po_vb0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/types/po_vb1.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/types/schemaLocation.xml create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/types/schemaLocation_vb0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/types/schemaLocation_vb1.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/types/schemaLocation_vb2.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/types/schemaLocation_vb3.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/types/unicode.xml create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/types/unicode_rd0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/types/unicode_ss0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/types/unicode_vb0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/types/xsinil.xml create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/types/xsinil_rd0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/types/xsinil_rd1.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/types/xsinil_ss0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/types/xsinil_ss1.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/types/xsinil_vb0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/types/xsinil_vb1.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/types/xsitype.xml create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/types/xsitype_vb0.xsd create mode 100644 xmlbeans/test/cases/xbean/tools/inst2xsd/schema/types/xsitype_vb1.xsd create mode 100755 xmlbeans/test/cases/xbean/tranxml.tar.bz2 create mode 100644 xmlbeans/test/cases/xbean/usertype/averageCase/po.xsd create mode 100644 xmlbeans/test/cases/xbean/usertype/averageCase/po.xsdconfig create mode 100644 xmlbeans/test/cases/xbean/usertype/multipleItems/company.xsd create mode 100644 xmlbeans/test/cases/xbean/usertype/multipleItems/company.xsdconfig create mode 100644 xmlbeans/test/cases/xbean/xmlcursor/CR196679.xsd create mode 100755 xmlbeans/test/cases/xbean/xmlcursor/CarLocationMessage.xml create mode 100755 xmlbeans/test/cases/xbean/xmlcursor/Employees.xml create mode 100755 xmlbeans/test/cases/xbean/xmlcursor/TranXML_License.txt create mode 100755 xmlbeans/test/cases/xbean/xmlcursor/W3C_Software_Licence.txt create mode 100644 xmlbeans/test/cases/xbean/xmlcursor/XQueryInput.xml create mode 100644 xmlbeans/test/cases/xbean/xmlcursor/XQueryInput.xsd create mode 100755 xmlbeans/test/cases/xbean/xmlcursor/doc.xml create mode 100755 xmlbeans/test/cases/xbean/xmlcursor/location.xsd create mode 100755 xmlbeans/test/cases/xbean/xmlcursor/person.xsd create mode 100755 xmlbeans/test/cases/xbean/xmlcursor/po.xml create mode 100755 xmlbeans/test/cases/xbean/xmlcursor/po.xsd create mode 100755 xmlbeans/test/cases/xbean/xmlcursor/xpath/LICENSE.txt create mode 100755 xmlbeans/test/cases/xbean/xmlcursor/xpath/cdcatalog.xml create mode 100755 xmlbeans/test/cases/xbean/xmlcursor/xpath/jaxen/axis.xml create mode 100755 xmlbeans/test/cases/xbean/xmlcursor/xpath/jaxen/basic.xml create mode 100755 xmlbeans/test/cases/xbean/xmlcursor/xpath/jaxen/basicupdate.xml create mode 100755 xmlbeans/test/cases/xbean/xmlcursor/xpath/jaxen/contents.xml create mode 100755 xmlbeans/test/cases/xbean/xmlcursor/xpath/jaxen/defaultNamespace.xml create mode 100755 xmlbeans/test/cases/xbean/xmlcursor/xpath/jaxen/evaluate.xml create mode 100755 xmlbeans/test/cases/xbean/xmlcursor/xpath/jaxen/fibo.xml create mode 100755 xmlbeans/test/cases/xbean/xmlcursor/xpath/jaxen/id.xml create mode 100755 xmlbeans/test/cases/xbean/xmlcursor/xpath/jaxen/lang.xml create mode 100755 xmlbeans/test/cases/xbean/xmlcursor/xpath/jaxen/message.xml create mode 100755 xmlbeans/test/cases/xbean/xmlcursor/xpath/jaxen/moreover.xml create mode 100755 xmlbeans/test/cases/xbean/xmlcursor/xpath/jaxen/much_ado.xml create mode 100755 xmlbeans/test/cases/xbean/xmlcursor/xpath/jaxen/namespaces.xml create mode 100755 xmlbeans/test/cases/xbean/xmlcursor/xpath/jaxen/nitf.xml create mode 100755 xmlbeans/test/cases/xbean/xmlcursor/xpath/jaxen/numbers.xml create mode 100755 xmlbeans/test/cases/xbean/xmlcursor/xpath/jaxen/pi.xml create mode 100755 xmlbeans/test/cases/xbean/xmlcursor/xpath/jaxen/pi2.xml create mode 100755 xmlbeans/test/cases/xbean/xmlcursor/xpath/jaxen/simple.xml create mode 100755 xmlbeans/test/cases/xbean/xmlcursor/xpath/jaxen/testNamespaces.xml create mode 100755 xmlbeans/test/cases/xbean/xmlcursor/xpath/jaxen/text.xml create mode 100755 xmlbeans/test/cases/xbean/xmlcursor/xpath/jaxen/underscore.xml create mode 100755 xmlbeans/test/cases/xbean/xmlcursor/xpath/jaxen/web.xml create mode 100755 xmlbeans/test/cases/xbean/xmlcursor/xpath/zvon1.xml create mode 100755 xmlbeans/test/cases/xbean/xmlcursor/xpath/zvon10.xml create mode 100755 xmlbeans/test/cases/xbean/xmlcursor/xpath/zvon11.xml create mode 100755 xmlbeans/test/cases/xbean/xmlcursor/xpath/zvon12.xml create mode 100755 xmlbeans/test/cases/xbean/xmlcursor/xpath/zvon13.xml create mode 100755 xmlbeans/test/cases/xbean/xmlcursor/xpath/zvon14.xml create mode 100755 xmlbeans/test/cases/xbean/xmlcursor/xpath/zvon15.xml create mode 100755 xmlbeans/test/cases/xbean/xmlcursor/xpath/zvon16.xml create mode 100755 xmlbeans/test/cases/xbean/xmlcursor/xpath/zvon17.xml create mode 100755 xmlbeans/test/cases/xbean/xmlcursor/xpath/zvon18.xml create mode 100755 xmlbeans/test/cases/xbean/xmlcursor/xpath/zvon19.xml create mode 100755 xmlbeans/test/cases/xbean/xmlcursor/xpath/zvon2.xml create mode 100755 xmlbeans/test/cases/xbean/xmlcursor/xpath/zvon20.xml create mode 100755 xmlbeans/test/cases/xbean/xmlcursor/xpath/zvon21.xml create mode 100755 xmlbeans/test/cases/xbean/xmlcursor/xpath/zvon22.xml create mode 100755 xmlbeans/test/cases/xbean/xmlcursor/xpath/zvon3.xml create mode 100755 xmlbeans/test/cases/xbean/xmlcursor/xpath/zvon4.xml create mode 100755 xmlbeans/test/cases/xbean/xmlcursor/xpath/zvon5.xml create mode 100755 xmlbeans/test/cases/xbean/xmlcursor/xpath/zvon6.xml create mode 100755 xmlbeans/test/cases/xbean/xmlcursor/xpath/zvon7.xml create mode 100755 xmlbeans/test/cases/xbean/xmlcursor/xpath/zvon8.xml create mode 100755 xmlbeans/test/cases/xbean/xmlcursor/xpath/zvon9.xml create mode 100644 xmlbeans/test/cases/xbean/xmlcursor/xquery/2DocJoin.xq create mode 100644 xmlbeans/test/cases/xbean/xmlcursor/xquery/Constructor.xq create mode 100644 xmlbeans/test/cases/xbean/xmlcursor/xquery/Join.xq create mode 100644 xmlbeans/test/cases/xbean/xmlcursor/xquery/NIST/XQcatalog.xsd create mode 100644 xmlbeans/test/cases/xbean/xmlcursor/xquery/bookstore.xml create mode 100644 xmlbeans/test/cases/xbean/xmlcursor/xquery/employees.xml create mode 100644 xmlbeans/test/cases/xbean/xmlcursor/xquery/xmlQuery.zip create mode 100644 xmlbeans/test/cases/xbean/xmlcursor/xquery/xmlUseCases/catalog.xml create mode 100644 xmlbeans/test/cases/xbean/xmlcursor/xquery/xmlUseCases/catalog.xsd create mode 100755 xmlbeans/test/cases/xbean/xmlcursor/xstypes/default.xsd create mode 100755 xmlbeans/test/cases/xbean/xmlcursor/xstypes/person.xsd create mode 100755 xmlbeans/test/cases/xbean/xmlcursor/xstypes/setters.xsd create mode 100755 xmlbeans/test/cases/xbean/xmlcursor/xstypes/simplec.xsd create mode 100755 xmlbeans/test/cases/xbean/xmlcursor/xstypes/xstypes.xml create mode 100644 xmlbeans/test/cases/xbean/xmlobject/CR192525.xsd create mode 100755 xmlbeans/test/cases/xbean/xmlobject/SelectAttribute-Doc.xml create mode 100755 xmlbeans/test/cases/xbean/xmlobject/SelectAttribute.xsd create mode 100755 xmlbeans/test/cases/xbean/xmlobject/SelectChildren-AnyTypeDoc.xml create mode 100755 xmlbeans/test/cases/xbean/xmlobject/SelectChildren-NormalDoc.xml create mode 100755 xmlbeans/test/cases/xbean/xmlobject/SelectChildren.xsd create mode 100755 xmlbeans/test/cases/xbean/xmlobject/SimpleXmlObject.java.txt create mode 100755 xmlbeans/test/cases/xbean/xmlobject/Test.xsd create mode 100755 xmlbeans/test/cases/xbean/xmlobject/Test36510.xsd create mode 100755 xmlbeans/test/cases/xbean/xmlobject/Test40907.xsd create mode 100755 xmlbeans/test/cases/xbean/xmlobject/defaults.xsd create mode 100755 xmlbeans/test/cases/xbean/xmlobject/easypo.xsd create mode 100755 xmlbeans/test/cases/xbean/xmlobject/easypo.xsdconfig create mode 100755 xmlbeans/test/cases/xbean/xmlobject/easypo1.xml create mode 100755 xmlbeans/test/cases/xbean/xmlobject/enumtest.xml create mode 100755 xmlbeans/test/cases/xbean/xmlobject/enumtest.xsd create mode 100755 xmlbeans/test/cases/xbean/xmlobject/enumtest.xsdconfig create mode 100755 xmlbeans/test/cases/xbean/xmlobject/inttest.xsd create mode 100644 xmlbeans/test/cases/xbean/xmlobject/japanese/LICENSE.txt create mode 100644 xmlbeans/test/cases/xbean/xmlobject/japanese/japanese.xml create mode 100644 xmlbeans/test/cases/xbean/xmlobject/japanese/pr-xml-euc-jp.xml create mode 100644 xmlbeans/test/cases/xbean/xmlobject/japanese/pr-xml-euc-jp1.xml create mode 100644 xmlbeans/test/cases/xbean/xmlobject/japanese/pr-xml-iso-2022-jp.xml create mode 100644 xmlbeans/test/cases/xbean/xmlobject/japanese/pr-xml-little-endian.xml create mode 100644 xmlbeans/test/cases/xbean/xmlobject/japanese/pr-xml-shift_jis.xml create mode 100644 xmlbeans/test/cases/xbean/xmlobject/japanese/pr-xml-utf-16.xml create mode 100644 xmlbeans/test/cases/xbean/xmlobject/japanese/pr-xml-utf-8.xml create mode 100644 xmlbeans/test/cases/xbean/xmlobject/japanese/prefix_test.xml create mode 100644 xmlbeans/test/cases/xbean/xmlobject/japanese/readme.html create mode 100644 xmlbeans/test/cases/xbean/xmlobject/japanese/spec.dtd create mode 100644 xmlbeans/test/cases/xbean/xmlobject/japanese/weekly-euc-jp.dtd create mode 100644 xmlbeans/test/cases/xbean/xmlobject/japanese/weekly-euc-jp.xml create mode 100644 xmlbeans/test/cases/xbean/xmlobject/japanese/weekly-iso-2022-jp.dtd create mode 100644 xmlbeans/test/cases/xbean/xmlobject/japanese/weekly-iso-2022-jp.xml create mode 100644 xmlbeans/test/cases/xbean/xmlobject/japanese/weekly-little-endian.xml create mode 100644 xmlbeans/test/cases/xbean/xmlobject/japanese/weekly-shift_jis.dtd create mode 100644 xmlbeans/test/cases/xbean/xmlobject/japanese/weekly-shift_jis.xml create mode 100644 xmlbeans/test/cases/xbean/xmlobject/japanese/weekly-utf-16.dtd create mode 100644 xmlbeans/test/cases/xbean/xmlobject/japanese/weekly-utf-16.xml create mode 100644 xmlbeans/test/cases/xbean/xmlobject/japanese/weekly-utf-8.dtd create mode 100644 xmlbeans/test/cases/xbean/xmlobject/japanese/weekly-utf-8.xml create mode 100755 xmlbeans/test/cases/xbean/xmlobject/listandunion.xsd create mode 100755 xmlbeans/test/cases/xbean/xmlobject/nameworld.xml create mode 100755 xmlbeans/test/cases/xbean/xmlobject/nameworld.xsd create mode 100755 xmlbeans/test/cases/xbean/xmlobject/numerals.xsd create mode 100755 xmlbeans/test/cases/xbean/xmlobject/person.xml create mode 100755 xmlbeans/test/cases/xbean/xmlobject/person.xsd create mode 100755 xmlbeans/test/cases/xbean/xmlobject/redefine1.xsd create mode 100755 xmlbeans/test/cases/xbean/xmlobject/redefine2.xsd create mode 100755 xmlbeans/test/cases/xbean/xmlobject/selectChldAttTest.xsd create mode 100755 xmlbeans/test/cases/xbean/xmlobject/soap-envelope.xsd create mode 100755 xmlbeans/test/cases/xbean/xmlobject/soap12-encoding.xsd create mode 100755 xmlbeans/test/cases/xbean/xmlobject/soapfaults.xsd create mode 100755 xmlbeans/test/cases/xbean/xmlobject/store/ConsolidateTest.xml create mode 100755 xmlbeans/test/cases/xbean/xmlobject/store/XML.xsd create mode 100755 xmlbeans/test/cases/xbean/xmlobject/store/XMLSchema.xsd create mode 100755 xmlbeans/test/cases/xbean/xmlobject/store/easypo1.xml create mode 100755 xmlbeans/test/cases/xbean/xmlobject/store/erictest.xml create mode 100755 xmlbeans/test/cases/xbean/xmlobject/store/people.xml create mode 100755 xmlbeans/test/cases/xbean/xmlobject/store/small.xml create mode 100755 xmlbeans/test/cases/xbean/xmlobject/store/test.xml create mode 100755 xmlbeans/test/cases/xbean/xmlobject/substgroup.xsd create mode 100644 xmlbeans/test/cases/xbean/xmlobject/substgroup2.xsd create mode 100644 xmlbeans/test/cases/xbean/xmlobject/version1.xsddonotcompile create mode 100644 xmlbeans/test/cases/xbean/xmlobject/version2.xsddonotcompile create mode 100644 xmlbeans/test/cases/xbean/xmlobject/version3.xsd create mode 100644 xmlbeans/test/cases/xbean/xmlobject/wsdl.xml create mode 100755 xmlbeans/test/cases/xbean/xmltokensource/PrettyPrintNamespaceTest.xsd create mode 100755 xmlbeans/test/docs/BuildingAndRunningTests.txt create mode 100755 xmlbeans/test/docs/TestOrganization.txt create mode 100755 xmlbeans/test/lib/LICENSE.txt create mode 100755 xmlbeans/test/lib/w3c_domts.jar create mode 100755 xmlbeans/test/perf/bin/castor.bat create mode 100644 xmlbeans/test/perf/bin/castor.properties create mode 100644 xmlbeans/test/perf/bin/castor.sh create mode 100644 xmlbeans/test/perf/bin/jaxb.bat create mode 100644 xmlbeans/test/perf/bin/jaxb.sh create mode 100644 xmlbeans/test/perf/bin/jaxb2.bat create mode 100755 xmlbeans/test/perf/bin/jibx.bat create mode 100644 xmlbeans/test/perf/bin/jibx.sh create mode 100644 xmlbeans/test/perf/bin/parsers.bat create mode 100644 xmlbeans/test/perf/bin/run_all.bat create mode 100644 xmlbeans/test/perf/bin/run_all.sh create mode 100644 xmlbeans/test/perf/bin/run_all_nonmemory.bat create mode 100644 xmlbeans/test/perf/bin/run_castor.bat create mode 100644 xmlbeans/test/perf/bin/run_castor.sh create mode 100644 xmlbeans/test/perf/bin/run_jaxb.bat create mode 100644 xmlbeans/test/perf/bin/run_jaxb.sh create mode 100644 xmlbeans/test/perf/bin/run_jaxb2.bat create mode 100644 xmlbeans/test/perf/bin/run_jibx.bat create mode 100644 xmlbeans/test/perf/bin/run_jibx.sh create mode 100644 xmlbeans/test/perf/bin/run_svn.bat create mode 100644 xmlbeans/test/perf/bin/run_svn.sh create mode 100644 xmlbeans/test/perf/bin/run_svn_nonmemory.bat create mode 100644 xmlbeans/test/perf/bin/run_v1.bat create mode 100644 xmlbeans/test/perf/bin/run_v1.sh create mode 100644 xmlbeans/test/perf/bin/run_v1_nonmemory.bat create mode 100644 xmlbeans/test/perf/bin/run_v2.bat create mode 100644 xmlbeans/test/perf/bin/run_v2.sh create mode 100644 xmlbeans/test/perf/bin/run_v2_nonmemory.bat create mode 100644 xmlbeans/test/perf/bin/run_xerces.bat create mode 100644 xmlbeans/test/perf/bin/run_xerces.sh create mode 100644 xmlbeans/test/perf/bin/run_xerces_nonmemory.bat create mode 100644 xmlbeans/test/perf/bin/run_xmlbeans_all.bat create mode 100644 xmlbeans/test/perf/bin/run_xmlbeans_nonmemory.bat create mode 100644 xmlbeans/test/perf/bin/svn.bat create mode 100644 xmlbeans/test/perf/bin/svn.sh create mode 100755 xmlbeans/test/perf/bin/v1.bat create mode 100644 xmlbeans/test/perf/bin/v1.sh create mode 100755 xmlbeans/test/perf/bin/v2.bat create mode 100644 xmlbeans/test/perf/bin/v2.sh create mode 100644 xmlbeans/test/perf/bin/xerces.bat create mode 100644 xmlbeans/test/perf/bin/xerces.sh create mode 100644 xmlbeans/test/perf/build.xml create mode 100644 xmlbeans/test/perf/cases/parser_instances.zip create mode 100644 xmlbeans/test/perf/cases/xsd/doc.xsd create mode 100644 xmlbeans/test/perf/cases/xsd/non-primitives.xsd create mode 100644 xmlbeans/test/perf/cases/xsd/perf-results.xsd create mode 100644 xmlbeans/test/perf/cases/xsd/primitives.xsd create mode 100644 xmlbeans/test/perf/cases/xsd/purchase-order-1.xml create mode 100644 xmlbeans/test/perf/cases/xsd/purchase-order-2.xml create mode 100644 xmlbeans/test/perf/cases/xsd/purchase-order-3.xml create mode 100644 xmlbeans/test/perf/cases/xsd/purchase-order-4.xml create mode 100644 xmlbeans/test/perf/cases/xsd/purchase-order-5.xml create mode 100644 xmlbeans/test/perf/cases/xsd/purchase-order-6.xml create mode 100644 xmlbeans/test/perf/cases/xsd/purchase-order-7.xml create mode 100644 xmlbeans/test/perf/cases/xsd/purchase-order-jibxbinding.xml create mode 100644 xmlbeans/test/perf/cases/xsd/purchase-order.xsd create mode 100644 xmlbeans/test/perf/download.properties create mode 100755 xmlbeans/test/perf/env.bat create mode 100755 xmlbeans/test/perf/env.sh create mode 100644 xmlbeans/test/perf/results.xml create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/castor/NPrimTopDownCastor.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/castor/POGetCustNameCastor.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/castor/POGetSetGetCustNameCastor.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/castor/POReadAllCastor.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/castor/POReadOneCastor.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/castor/POTopDownCastor.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/castor/POTopDownSaveCastor.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/castor/PrimTopDownCastor.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/jaxb/NPrimTopDownJaxb.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/jaxb/POGetCustNameJaxb.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/jaxb/POGetSetGetCustNameJaxb.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/jaxb/POReadAllJaxb.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/jaxb/POReadOneJaxb.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/jaxb/POTopDownJaxb.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/jaxb/POTopDownSaveJaxb.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/jaxb/PrimTopDownJaxb.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/jaxb2/NPrimTopDownJaxb2.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/jaxb2/POGetCustNameJaxb2.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/jaxb2/POGetSetGetCustNameJaxb2.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/jaxb2/POReadAllJaxb2.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/jaxb2/POReadOneJaxb2.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/jaxb2/POTopDownJaxb2.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/jaxb2/POTopDownSaveJaxb2.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/jaxb2/PrimTopDownJaxb2.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/jibx/POReadAllJibx.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/jibx/POReadOneJibx.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/jibx/binding/Customer.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/jibx/binding/JibxPurchaseOrder.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/jibx/binding/Lineitem.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/jibx/binding/Shipper.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/parsers/BaseSaxPerfTest.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/parsers/DefaultSaxParserPerfTests.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/parsers/Jaxb2Tests.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/parsers/PiccoloPerfTests.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/parsers/Utils.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/parsers/XMLParsers.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/parsers/XercesSaxParserPerfTests.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/parsers/XmlBeansTests.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/svn/BisLoadSVN.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/svn/CursorGetAttributeSVN.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/svn/CursorGetElementSVN.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/svn/CursorGetSetGetAttributeSVN.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/svn/CursorGetSetGetElementSVN.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/svn/CursorWalkSVN.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/svn/DomWalkNLSVN.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/svn/DomWalkSVN.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/svn/MaxMemUntypedBisLoadSVN.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/svn/NPrimTopDownSVN.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/svn/POGetCustNameSVN.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/svn/POGetSetGetCustNameSVN.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/svn/POQueryLineItemsSVN.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/svn/POReadAllSVN.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/svn/POReadOneSVN.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/svn/POSelectLineItemsSVN.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/svn/POTopDownSVN.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/svn/POTopDownSaveSVN.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/svn/POValidateXmlObjSVN.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/svn/PrimTopDownSVN.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/utils/Constants.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/utils/PerfUtil.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/utils/RunComparator.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/v1/BisLoadV1.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/v1/CursorGetAttributeV1.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/v1/CursorGetElementV1.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/v1/CursorGetSetGetAttributeV1.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/v1/CursorGetSetGetElementV1.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/v1/CursorWalkV1.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/v1/DomWalkNLV1.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/v1/DomWalkV1.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/v1/MaxMemUntypedBisLoadV1.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/v1/NPrimTopDownV1.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/v1/POGetCustNameV1.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/v1/POGetSetGetCustNameV1.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/v1/POReadAllV1.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/v1/POReadOneV1.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/v1/POSelectLineItemsV1.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/v1/POTopDownSaveV1.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/v1/POTopDownV1.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/v1/POValidateXmlObjV1.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/v1/PrimTopDownV1.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/v2/BisLoadV2.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/v2/CursorGetAttributeV2.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/v2/CursorGetElementV2.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/v2/CursorGetSetGetAttributeV2.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/v2/CursorGetSetGetElementV2.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/v2/CursorWalkV2.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/v2/DomWalkNLV2.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/v2/DomWalkV2.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/v2/MaxMemUntypedBisLoadV2.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/v2/NPrimTopDownV2.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/v2/POGetCustNameV2.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/v2/POGetSetGetCustNameV2.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/v2/POQueryLineItemsV2.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/v2/POReadAllV2.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/v2/POReadOneV2.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/v2/POSelectLineItemsV2.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/v2/POTopDownSaveV2.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/v2/POTopDownV2.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/v2/POValidateXmlObjV2.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/v2/PrimTopDownV2.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/xerces/BisLoadXercesDom.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/xerces/BisLoadXercesSax.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/xerces/DomWalkNLXerces.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/xerces/DomWalkXerces.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/xerces/MaxMemUntypedBisLoadXercesDom.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/xerces/MaxMemUntypedBisLoadXercesSax.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/xerces/POReadAllXercesDom.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/xerces/POReadAllXercesSax.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/xerces/POReadOneXercesDom.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/xerces/POReadOneXercesSax.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/xerces/POTopDownXercesDom.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/xerces/POTopDownXercesSax.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/performance/xerces/POValidateXerces.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/tools/PerfResultTask.java create mode 100644 xmlbeans/test/perf/src/org/apache/xmlbeans/test/tools/PerfResultUtil.java create mode 100755 xmlbeans/test/readme.txt create mode 100644 xmlbeans/test/src/ValidatingXSRTests/checkin/TestUriValidation.java create mode 100755 xmlbeans/test/src/ValidatingXSRTests/checkin/ValidatingXMLStreamReaderTests.java create mode 100755 xmlbeans/test/src/ValidatingXSRTests/common/TestPrefixResolver.java create mode 100755 xmlbeans/test/src/ValidatingXSRTests/detailed/ValidatingXmlStreamReaderTests.java create mode 100755 xmlbeans/test/src/ValidatingXSRTests/detailed/ValidatorUtilTests.java create mode 100644 xmlbeans/test/src/common/Common.java create mode 100644 xmlbeans/test/src/compile/scomp/checkin/CompilationTests.java create mode 100644 xmlbeans/test/src/compile/scomp/checkin/XmlBeansCompCheckinTests.java create mode 100644 xmlbeans/test/src/compile/scomp/common/CompileCommon.java create mode 100644 xmlbeans/test/src/compile/scomp/common/CompileTestBase.java create mode 100644 xmlbeans/test/src/compile/scomp/common/mockobj/TestBindingConfig.java create mode 100644 xmlbeans/test/src/compile/scomp/common/mockobj/TestFiler.java create mode 100644 xmlbeans/test/src/compile/scomp/detailed/DetailedCompTests.java create mode 100644 xmlbeans/test/src/compile/scomp/detailed/SchemaCompilerTests.java create mode 100644 xmlbeans/test/src/compile/scomp/detailed/XmlBeanCompilationTests.java create mode 100644 xmlbeans/test/src/compile/scomp/incr/schemaCompile/detailed/IncrCompilationTests.java create mode 100644 xmlbeans/test/src/compile/scomp/incr/schemaCompile/detailed/ModelGroupTests.java create mode 100644 xmlbeans/test/src/compile/scomp/incr/schemaCompile/detailed/PerfTests.java create mode 100644 xmlbeans/test/src/compile/scomp/som/checkin/PartialSOMCheckinTest.java create mode 100644 xmlbeans/test/src/compile/scomp/som/common/SomTestBase.java create mode 100644 xmlbeans/test/src/compile/scomp/som/detailed/PartialSOMDetailedTest.java create mode 100755 xmlbeans/test/src/dom/checkin/AttributeSyncTest.java create mode 100755 xmlbeans/test/src/dom/checkin/AttributeTest.java create mode 100755 xmlbeans/test/src/dom/checkin/CDataSectionSyncTest.java create mode 100755 xmlbeans/test/src/dom/checkin/CDataSectionTest.java create mode 100755 xmlbeans/test/src/dom/checkin/CommentSyncTest.java create mode 100755 xmlbeans/test/src/dom/checkin/CommentTest.java create mode 100644 xmlbeans/test/src/dom/checkin/DirtyCacheTests.java create mode 100755 xmlbeans/test/src/dom/checkin/DocumentFragmentSyncTest.java create mode 100755 xmlbeans/test/src/dom/checkin/DocumentFragmentTest.java create mode 100755 xmlbeans/test/src/dom/checkin/DocumentSyncTest.java create mode 100755 xmlbeans/test/src/dom/checkin/DocumentTest.java create mode 100755 xmlbeans/test/src/dom/checkin/DomImplementationSyncTest.java create mode 100755 xmlbeans/test/src/dom/checkin/DomImplementationTest.java create mode 100755 xmlbeans/test/src/dom/checkin/DomTests.java create mode 100755 xmlbeans/test/src/dom/checkin/ElementSyncTest.java create mode 100755 xmlbeans/test/src/dom/checkin/ElementTest.java create mode 100755 xmlbeans/test/src/dom/checkin/NamedNodeMapSyncTest.java create mode 100755 xmlbeans/test/src/dom/checkin/NamedNodeMapTest.java create mode 100755 xmlbeans/test/src/dom/checkin/NodeListSyncTest.java create mode 100755 xmlbeans/test/src/dom/checkin/NodeListTest.java create mode 100755 xmlbeans/test/src/dom/checkin/PISyncTest.java create mode 100755 xmlbeans/test/src/dom/checkin/PITest.java create mode 100755 xmlbeans/test/src/dom/checkin/TextSyncTest.java create mode 100755 xmlbeans/test/src/dom/checkin/TextTest.java create mode 100755 xmlbeans/test/src/dom/common/CharacterDataTest.java create mode 100755 xmlbeans/test/src/dom/common/DomUtils.java create mode 100755 xmlbeans/test/src/dom/common/Loader.java create mode 100755 xmlbeans/test/src/dom/common/NewLoader.java create mode 100755 xmlbeans/test/src/dom/common/NodeTest.java create mode 100755 xmlbeans/test/src/dom/common/NodeWithChildrenTest.java create mode 100755 xmlbeans/test/src/dom/common/TestSetup.java create mode 100755 xmlbeans/test/src/dom/detailed/AttrNamespaceTest.java create mode 100644 xmlbeans/test/src/dom/detailed/IDTest.java create mode 100755 xmlbeans/test/src/dom/detailed/ImportUnsupportedNodesTest.java create mode 100755 xmlbeans/test/src/dom/detailed/InsertDeleteNodesTest.java create mode 100755 xmlbeans/test/src/dom/detailed/MoveImportNodeTest.java create mode 100755 xmlbeans/test/src/dom/detailed/MultipleDocsTest.java create mode 100755 xmlbeans/test/src/dom/detailed/TextInsertDeleteTest.java create mode 100755 xmlbeans/test/src/dom/detailed/TextTest.java create mode 100755 xmlbeans/test/src/dom/detailed/w3c/alltests.java create mode 100755 xmlbeans/test/src/dom/detailed/w3c/ibmtests.java create mode 100644 xmlbeans/test/src/drt/drtcases/BindingTests.java create mode 100644 xmlbeans/test/src/drt/drtcases/MarshalTests.java create mode 100644 xmlbeans/test/src/drt/drtcases/TestEnv.java create mode 100644 xmlbeans/test/src/misc/checkin/CharUtilTests.java create mode 100644 xmlbeans/test/src/misc/checkin/ErrorCodeTest.java create mode 100755 xmlbeans/test/src/misc/checkin/RichParserTests.java create mode 100755 xmlbeans/test/src/misc/checkin/RuntimeSchemaLoaderTest.java create mode 100644 xmlbeans/test/src/misc/checkin/ThreadingTest.java create mode 100644 xmlbeans/test/src/misc/checkin/VersionTest.java create mode 100644 xmlbeans/test/src/misc/checkin/XMLBEANS412Test.java create mode 100644 xmlbeans/test/src/misc/common/JiraTestBase.java create mode 100644 xmlbeans/test/src/misc/common/ParsersBase.java create mode 100644 xmlbeans/test/src/misc/detailed/CharEncodingTest.java create mode 100644 xmlbeans/test/src/misc/detailed/CharEscapeTest.java create mode 100644 xmlbeans/test/src/misc/detailed/ClassLoadingTest.java create mode 100644 xmlbeans/test/src/misc/detailed/JiraRegression151_200Test.java create mode 100644 xmlbeans/test/src/misc/detailed/JiraRegression1_50Test.java create mode 100644 xmlbeans/test/src/misc/detailed/JiraRegression201_250Test.java create mode 100644 xmlbeans/test/src/misc/detailed/JiraRegression251_300Test.java create mode 100644 xmlbeans/test/src/misc/detailed/JiraRegression50_100Test.java create mode 100644 xmlbeans/test/src/misc/detailed/JiraRegressionSchemaCompilerTest.java create mode 100644 xmlbeans/test/src/misc/detailed/JiraRegressionTest101_150.java create mode 100644 xmlbeans/test/src/misc/detailed/LargeEnumTest.java create mode 100644 xmlbeans/test/src/misc/detailed/SampleRunner.java create mode 100644 xmlbeans/test/src/misc/detailed/SystemCacheClassloadersTest.java create mode 100644 xmlbeans/test/src/misc/detailed/SystemCacheTestImpl.java create mode 100644 xmlbeans/test/src/misc/detailed/SystemCacheTests.java create mode 100644 xmlbeans/test/src/misc/detailed/XMLStreamReaderTest.java create mode 100755 xmlbeans/test/src/random/checkin/RandomTest.java create mode 100755 xmlbeans/test/src/random/common/Random.java create mode 100644 xmlbeans/test/src/schemas/defaults.xsd create mode 100644 xmlbeans/test/src/scomp/attributes/detailed/AttrGroupTest.java create mode 100644 xmlbeans/test/src/scomp/attributes/detailed/GlobalAttrDefault.java create mode 100644 xmlbeans/test/src/scomp/attributes/detailed/GlobalAttrFixed.java create mode 100644 xmlbeans/test/src/scomp/attributes/detailed/GlobalAttrIdTest.java create mode 100644 xmlbeans/test/src/scomp/attributes/detailed/GlobalAttrType.java create mode 100644 xmlbeans/test/src/scomp/attributes/detailed/LocalAttrFixedDefault.java create mode 100644 xmlbeans/test/src/scomp/attributes/detailed/LocalAttrForm.java create mode 100644 xmlbeans/test/src/scomp/attributes/detailed/LocalAttrUse.java create mode 100644 xmlbeans/test/src/scomp/common/BaseCase.java create mode 100644 xmlbeans/test/src/scomp/contentType/complex/detailed/AnonymousTest.java create mode 100644 xmlbeans/test/src/scomp/contentType/complex/detailed/ComplexContentTest.java create mode 100644 xmlbeans/test/src/scomp/contentType/complex/detailed/ElementOnlyContentTest.java create mode 100644 xmlbeans/test/src/scomp/contentType/complex/detailed/EmptyContentTest.java create mode 100644 xmlbeans/test/src/scomp/contentType/complex/detailed/MixedContentTest.java create mode 100644 xmlbeans/test/src/scomp/contentType/complex/detailed/NamedTest.java create mode 100644 xmlbeans/test/src/scomp/contentType/complex/modelGroup/detailed/AllTest.java create mode 100644 xmlbeans/test/src/scomp/contentType/complex/modelGroup/detailed/ChoiceTest.java create mode 100644 xmlbeans/test/src/scomp/contentType/complex/modelGroup/detailed/NestSequenceChoiceTest.java create mode 100644 xmlbeans/test/src/scomp/contentType/complex/modelGroup/detailed/SequenceTest.java create mode 100644 xmlbeans/test/src/scomp/contentType/simple/detailed/BuiltInType.java create mode 100644 xmlbeans/test/src/scomp/contentType/simple/detailed/ListType.java create mode 100644 xmlbeans/test/src/scomp/contentType/simple/detailed/SimpleType.java create mode 100644 xmlbeans/test/src/scomp/contentType/simple/detailed/UnionType.java create mode 100644 xmlbeans/test/src/scomp/derivation/detailed/AbstractTest.java create mode 100644 xmlbeans/test/src/scomp/derivation/detailed/BlockTest.java create mode 100644 xmlbeans/test/src/scomp/derivation/detailed/FinalTest.java create mode 100644 xmlbeans/test/src/scomp/derivation/extension/detailed/AttributeExtensionTest.java create mode 100644 xmlbeans/test/src/scomp/derivation/extension/detailed/AttributeWCExtension.java create mode 100644 xmlbeans/test/src/scomp/derivation/extension/detailed/ComplexContentExtensionTest.java create mode 100644 xmlbeans/test/src/scomp/derivation/extension/detailed/EmptyContentExtension.java create mode 100644 xmlbeans/test/src/scomp/derivation/extension/detailed/MixedContentExtension.java create mode 100644 xmlbeans/test/src/scomp/derivation/extension/detailed/SimpleTypeExtensionTest.java create mode 100644 xmlbeans/test/src/scomp/derivation/restriction/detailed/AttrWCRestriction.java create mode 100644 xmlbeans/test/src/scomp/derivation/restriction/detailed/AttributeRestriction.java create mode 100644 xmlbeans/test/src/scomp/derivation/restriction/detailed/ElementRestriction.java create mode 100644 xmlbeans/test/src/scomp/derivation/restriction/detailed/ElementWCRestriction.java create mode 100644 xmlbeans/test/src/scomp/derivation/restriction/detailed/EmptyContentRestriction.java create mode 100644 xmlbeans/test/src/scomp/derivation/restriction/detailed/EnumTest.java create mode 100644 xmlbeans/test/src/scomp/derivation/restriction/detailed/GroupRestrictionTest.java create mode 100644 xmlbeans/test/src/scomp/derivation/restriction/detailed/MixedContentRestriction.java create mode 100644 xmlbeans/test/src/scomp/derivation/restriction/detailed/SimpleContentRestrictionTest.java create mode 100644 xmlbeans/test/src/scomp/derivation/restriction/detailed/SimpleTypeRestriction.java create mode 100644 xmlbeans/test/src/scomp/derivation/restriction/detailed/SubstitutionTest.java create mode 100644 xmlbeans/test/src/scomp/derivation/restriction/facets/detailed/FacetRestrictionTest.java create mode 100644 xmlbeans/test/src/scomp/derivation/restriction/facets/detailed/FacetsTest.java create mode 100644 xmlbeans/test/src/scomp/derivation/restriction/facets/detailed/ListRestriction.java create mode 100644 xmlbeans/test/src/scomp/derivation/restriction/facets/detailed/UnionRestriction.java create mode 100644 xmlbeans/test/src/scomp/elements/detailed/AnyTest.java create mode 100644 xmlbeans/test/src/scomp/elements/detailed/GlobalEltDefault.java create mode 100644 xmlbeans/test/src/scomp/elements/detailed/GlobalEltFixed.java create mode 100644 xmlbeans/test/src/scomp/elements/detailed/GlobalEltId.java create mode 100644 xmlbeans/test/src/scomp/elements/detailed/GlobalEltNillable.java create mode 100644 xmlbeans/test/src/scomp/elements/detailed/LocalEltMinMaxOccurs.java create mode 100644 xmlbeans/test/src/scomp/elements/detailed/NamedModelGroupsTest.java create mode 100644 xmlbeans/test/src/scomp/elements/detailed/NillTest.java create mode 100644 xmlbeans/test/src/scomp/idConstraint/detailed/KeyKeyref.java create mode 100644 xmlbeans/test/src/scomp/namespace/checkin/PreserveNamespaces.java create mode 100644 xmlbeans/test/src/scomp/namespace/detailed/AttrFormDefault.java create mode 100644 xmlbeans/test/src/scomp/namespace/detailed/AttributeWC.java create mode 100644 xmlbeans/test/src/scomp/namespace/detailed/ElementFormDefault.java create mode 100644 xmlbeans/test/src/scomp/namespace/detailed/ElementWC.java create mode 100644 xmlbeans/test/src/scomp/redefine/detailed/AttrGroupRedefine.java create mode 100644 xmlbeans/test/src/scomp/redefine/detailed/GroupRedefine.java create mode 100644 xmlbeans/test/src/scomp/redefine/detailed/MultipleRedefines.java create mode 100644 xmlbeans/test/src/scomp/redefine/detailed/SimpleRedefine.java create mode 100644 xmlbeans/test/src/scomp/substGroup/detailed/Deep.java create mode 100644 xmlbeans/test/src/scomp/substGroup/detailed/OneLevel.java create mode 100644 xmlbeans/test/src/scomp/substGroup/detailed/UserReportedTest.java create mode 100644 xmlbeans/test/src/scomp/substGroup/detailed/Wide.java create mode 100644 xmlbeans/test/src/scomp/substGroup/restriction/detailed/Abstract.java create mode 100644 xmlbeans/test/src/scomp/substGroup/restriction/detailed/Block.java create mode 100644 xmlbeans/test/src/scomp/substGroup/restriction/detailed/Final.java create mode 100644 xmlbeans/test/src/tools/inst2xsd/checkin/Inst2XsdAttrTest.java create mode 100644 xmlbeans/test/src/tools/inst2xsd/checkin/Inst2XsdCheckinTest.java create mode 100644 xmlbeans/test/src/tools/inst2xsd/checkin/Inst2XsdOptionsTest.java create mode 100644 xmlbeans/test/src/tools/inst2xsd/checkin/Inst2XsdTypeTest.java create mode 100644 xmlbeans/test/src/tools/inst2xsd/common/Inst2XsdCommon.java create mode 100644 xmlbeans/test/src/tools/inst2xsd/common/Inst2XsdTestBase.java create mode 100644 xmlbeans/test/src/tools/inst2xsd/detailed/ComplexDetailedTest.java create mode 100644 xmlbeans/test/src/tools/inst2xsd/detailed/DetailedLCDTest.java create mode 100644 xmlbeans/test/src/tools/inst2xsd/detailed/Inst2XsdDetailedAttrTest.java create mode 100644 xmlbeans/test/src/tools/inst2xsd/detailed/Inst2XsdDetailedOptionsTest.java create mode 100644 xmlbeans/test/src/tools/inst2xsd/detailed/Inst2XsdDetailedTest.java create mode 100644 xmlbeans/test/src/tools/inst2xsd/detailed/Inst2XsdDetailedTypeTest.java create mode 100644 xmlbeans/test/src/tools/inst2xsd/detailed/Inst2XsdMiscTest.java create mode 100755 xmlbeans/test/src/xmlcursor/checkin/AddToSelectionTest.java create mode 100755 xmlbeans/test/src/xmlcursor/checkin/AnnotationsTests.java create mode 100755 xmlbeans/test/src/xmlcursor/checkin/BeginElementTest.java create mode 100755 xmlbeans/test/src/xmlcursor/checkin/ClearBookmarkTest.java create mode 100755 xmlbeans/test/src/xmlcursor/checkin/ClearSelectionTest.java create mode 100755 xmlbeans/test/src/xmlcursor/checkin/ComparePositionTest.java create mode 100755 xmlbeans/test/src/xmlcursor/checkin/CopyTest.java create mode 100755 xmlbeans/test/src/xmlcursor/checkin/CopyXmlContentsTest.java create mode 100755 xmlbeans/test/src/xmlcursor/checkin/CurrentTokenTypeTest.java create mode 100755 xmlbeans/test/src/xmlcursor/checkin/DisposeTest.java create mode 100755 xmlbeans/test/src/xmlcursor/checkin/GetAllBookmarkRefsTest.java create mode 100755 xmlbeans/test/src/xmlcursor/checkin/GetAllNamespacesTest.java create mode 100755 xmlbeans/test/src/xmlcursor/checkin/GetAttributeTextTest.java create mode 100755 xmlbeans/test/src/xmlcursor/checkin/GetBookmarkTest.java create mode 100755 xmlbeans/test/src/xmlcursor/checkin/GetCharsTest.java create mode 100755 xmlbeans/test/src/xmlcursor/checkin/GetCharsType2Test.java create mode 100755 xmlbeans/test/src/xmlcursor/checkin/GetDocChangeStampTest.java create mode 100755 xmlbeans/test/src/xmlcursor/checkin/GetNameTest.java create mode 100755 xmlbeans/test/src/xmlcursor/checkin/GetObjectTest.java create mode 100755 xmlbeans/test/src/xmlcursor/checkin/InsertAttributeTest.java create mode 100755 xmlbeans/test/src/xmlcursor/checkin/InsertCharsTest.java create mode 100755 xmlbeans/test/src/xmlcursor/checkin/InsertCommentTest.java create mode 100755 xmlbeans/test/src/xmlcursor/checkin/InsertElementTest.java create mode 100755 xmlbeans/test/src/xmlcursor/checkin/InsertProcInstTest.java create mode 100755 xmlbeans/test/src/xmlcursor/checkin/IsAtSamePositionAsTest.java create mode 100755 xmlbeans/test/src/xmlcursor/checkin/IsInSameDocumentTest.java create mode 100755 xmlbeans/test/src/xmlcursor/checkin/MoveCharsTest.java create mode 100755 xmlbeans/test/src/xmlcursor/checkin/MoveTest.java create mode 100755 xmlbeans/test/src/xmlcursor/checkin/PrevTokenTypeTest.java create mode 100755 xmlbeans/test/src/xmlcursor/checkin/RemoveAttributeTest.java create mode 100755 xmlbeans/test/src/xmlcursor/checkin/RemoveCharsTest.java create mode 100755 xmlbeans/test/src/xmlcursor/checkin/RemoveTest.java create mode 100755 xmlbeans/test/src/xmlcursor/checkin/SelectPathTest.java create mode 100755 xmlbeans/test/src/xmlcursor/checkin/SetAttributeTextTest.java create mode 100755 xmlbeans/test/src/xmlcursor/checkin/SetBookmarkTest.java create mode 100755 xmlbeans/test/src/xmlcursor/checkin/SetNameTest.java create mode 100755 xmlbeans/test/src/xmlcursor/checkin/SetTextTest.java create mode 100755 xmlbeans/test/src/xmlcursor/checkin/StoreTests.java create mode 100755 xmlbeans/test/src/xmlcursor/checkin/ToCursorTest.java create mode 100755 xmlbeans/test/src/xmlcursor/checkin/ToFirstAttributeTest.java create mode 100755 xmlbeans/test/src/xmlcursor/checkin/ToFirstChildElementTest.java create mode 100755 xmlbeans/test/src/xmlcursor/checkin/ToFirstContentTokenTest.java create mode 100755 xmlbeans/test/src/xmlcursor/checkin/ToLastAttributeTest.java create mode 100755 xmlbeans/test/src/xmlcursor/checkin/ToLastChildElementTest.java create mode 100755 xmlbeans/test/src/xmlcursor/checkin/ToNextAttributeTest.java create mode 100755 xmlbeans/test/src/xmlcursor/checkin/ToNextBookmarkTest.java create mode 100755 xmlbeans/test/src/xmlcursor/checkin/ToNextCharTest.java create mode 100755 xmlbeans/test/src/xmlcursor/checkin/ToNextElementTest.java create mode 100755 xmlbeans/test/src/xmlcursor/checkin/ToNextSelectionTest.java create mode 100644 xmlbeans/test/src/xmlcursor/checkin/ToNextSiblingTest.java create mode 100755 xmlbeans/test/src/xmlcursor/checkin/ToParentElementTest.java create mode 100755 xmlbeans/test/src/xmlcursor/checkin/ToPrevAttributeTest.java create mode 100755 xmlbeans/test/src/xmlcursor/checkin/ToPrevBookmarkTest.java create mode 100755 xmlbeans/test/src/xmlcursor/checkin/ToPrevCharTest.java create mode 100755 xmlbeans/test/src/xmlcursor/checkin/ToPrevElementTest.java create mode 100755 xmlbeans/test/src/xmlcursor/checkin/TokensTest.java create mode 100755 xmlbeans/test/src/xmlcursor/common/BasicCursorTestCase.java create mode 100755 xmlbeans/test/src/xmlcursor/common/Common.java create mode 100755 xmlbeans/test/src/xmlcursor/detailed/CopyCharsTest.java create mode 100644 xmlbeans/test/src/xmlcursor/detailed/CopyTest.java create mode 100755 xmlbeans/test/src/xmlcursor/detailed/CursorGeneratedTypedObjectTest.java create mode 100755 xmlbeans/test/src/xmlcursor/detailed/CursorLocations.java create mode 100755 xmlbeans/test/src/xmlcursor/detailed/CursorVsObjectAttributeTest.java create mode 100755 xmlbeans/test/src/xmlcursor/detailed/CursorVsObjectInsertRemoveTest.java create mode 100755 xmlbeans/test/src/xmlcursor/detailed/CursorVsObjectSetGetTextTest.java create mode 100755 xmlbeans/test/src/xmlcursor/detailed/GetTextTest.java create mode 100755 xmlbeans/test/src/xmlcursor/detailed/GetTextValueTest.java create mode 100755 xmlbeans/test/src/xmlcursor/detailed/InsertAttributeTest2.java create mode 100755 xmlbeans/test/src/xmlcursor/detailed/InsertNamespaceTest.java create mode 100755 xmlbeans/test/src/xmlcursor/detailed/MoveXmlTest2.java create mode 100755 xmlbeans/test/src/xmlcursor/detailed/MultipleCopyFromCursorTest.java create mode 100755 xmlbeans/test/src/xmlcursor/detailed/MultipleCopyTest.java create mode 100755 xmlbeans/test/src/xmlcursor/detailed/MultipleCursorSetTest.java create mode 100755 xmlbeans/test/src/xmlcursor/detailed/NamespaceForPrefixTest.java create mode 100755 xmlbeans/test/src/xmlcursor/detailed/ObjectCursorInteractionTest.java create mode 100755 xmlbeans/test/src/xmlcursor/detailed/PrefixForNamespaceTest.java create mode 100755 xmlbeans/test/src/xmlcursor/detailed/PushPopTest.java create mode 100755 xmlbeans/test/src/xmlcursor/detailed/SelectionsTest.java create mode 100755 xmlbeans/test/src/xmlcursor/detailed/SetTextValueTest.java create mode 100755 xmlbeans/test/src/xmlcursor/detailed/ToBookmarkTest.java create mode 100755 xmlbeans/test/src/xmlcursor/detailed/ToChildTest.java create mode 100644 xmlbeans/test/src/xmlcursor/detailed/XmlLineNumberTest.java create mode 100755 xmlbeans/test/src/xmlcursor/jsr173/common/AttributeTest.java create mode 100755 xmlbeans/test/src/xmlcursor/jsr173/common/CharactersTest.java create mode 100755 xmlbeans/test/src/xmlcursor/jsr173/common/ElementTest.java create mode 100755 xmlbeans/test/src/xmlcursor/jsr173/common/GeneralMethodsTest.java create mode 100755 xmlbeans/test/src/xmlcursor/jsr173/common/IsXXXTest.java create mode 100755 xmlbeans/test/src/xmlcursor/jsr173/common/NamespaceTest.java create mode 100755 xmlbeans/test/src/xmlcursor/jsr173/common/PITest.java create mode 100755 xmlbeans/test/src/xmlcursor/jsr173/common/README.txt create mode 100755 xmlbeans/test/src/xmlcursor/jsr173/detailed/CursorAttributeTest.java create mode 100755 xmlbeans/test/src/xmlcursor/jsr173/detailed/CursorCharactersTest.java create mode 100755 xmlbeans/test/src/xmlcursor/jsr173/detailed/CursorElementTest.java create mode 100755 xmlbeans/test/src/xmlcursor/jsr173/detailed/CursorGeneralMethodsTest.java create mode 100755 xmlbeans/test/src/xmlcursor/jsr173/detailed/CursorIsXXXTest.java create mode 100755 xmlbeans/test/src/xmlcursor/jsr173/detailed/CursorNamespaceTest.java create mode 100755 xmlbeans/test/src/xmlcursor/jsr173/detailed/CursorPITest.java create mode 100755 xmlbeans/test/src/xmlcursor/xpath/CustomerTest.java create mode 100755 xmlbeans/test/src/xmlcursor/xpath/common/BaseXPathTest.java create mode 100755 xmlbeans/test/src/xmlcursor/xpath/common/XPathCommon.java create mode 100755 xmlbeans/test/src/xmlcursor/xpath/common/XPathExpressionTest.java create mode 100644 xmlbeans/test/src/xmlcursor/xpath/common/XPathFunctionAuxTest.java create mode 100755 xmlbeans/test/src/xmlcursor/xpath/common/XPathFunctionTest.java create mode 100755 xmlbeans/test/src/xmlcursor/xpath/common/XPathLocationTest.java create mode 100755 xmlbeans/test/src/xmlcursor/xpath/common/XPathNodetestTest.java create mode 100644 xmlbeans/test/src/xmlcursor/xpath/complex/checkin/ContainerCommentTest.java create mode 100755 xmlbeans/test/src/xmlcursor/xpath/complex/checkin/JaxenXPathTests.java create mode 100644 xmlbeans/test/src/xmlcursor/xpath/complex/detailed/DeclareNamespaceTest.java create mode 100644 xmlbeans/test/src/xmlcursor/xpath/complex/detailed/NodeCopyTest.java create mode 100644 xmlbeans/test/src/xmlcursor/xpath/complex/detailed/TypesTest.java create mode 100755 xmlbeans/test/src/xmlcursor/xpath/complex/detailed/XPathExpressionTestImpl.java create mode 100755 xmlbeans/test/src/xmlcursor/xpath/complex/detailed/XPathFunctionAuxTest.java create mode 100755 xmlbeans/test/src/xmlcursor/xpath/complex/detailed/XPathFunctionTestImpl.java create mode 100644 xmlbeans/test/src/xmlcursor/xpath/complex/detailed/XPathNodeTest.java create mode 100755 xmlbeans/test/src/xmlcursor/xpath/complex/detailed/XPathTest.java create mode 100755 xmlbeans/test/src/xmlcursor/xpath/xbean_xpath/detailed/AxesTest.java create mode 100755 xmlbeans/test/src/xmlcursor/xpath/xbean_xpath/detailed/NodeTest.java create mode 100755 xmlbeans/test/src/xmlcursor/xpath/xbean_xpath/detailed/README.txt create mode 100644 xmlbeans/test/src/xmlcursor/xquery/checkin/QueryEngineTests.java create mode 100644 xmlbeans/test/src/xmlcursor/xquery/common/AbstractRunner.java create mode 100644 xmlbeans/test/src/xmlcursor/xquery/common/XQTestCase.java create mode 100644 xmlbeans/test/src/xmlcursor/xquery/detailed/NISTSuiteRunner.java create mode 100644 xmlbeans/test/src/xmlcursor/xquery/detailed/NISTTest.java create mode 100644 xmlbeans/test/src/xmlcursor/xquery/detailed/StoreTestsXqrl.java create mode 100644 xmlbeans/test/src/xmlcursor/xquery/detailed/UseCaseTest.java create mode 100644 xmlbeans/test/src/xmlcursor/xquery/detailed/XQUseCaseRunner.java create mode 100644 xmlbeans/test/src/xmlcursor/xquery/detailed/XQueryTest.java create mode 100644 xmlbeans/test/src/xmlcursor/xquery/detailed/XQueryVariableBindingTest.java create mode 100644 xmlbeans/test/src/xmlcursor/xquery/detailed/ZipUtil.java create mode 100755 xmlbeans/test/src/xmlobject/checkin/AssortedTests.java create mode 100644 xmlbeans/test/src/xmlobject/checkin/CDataTest.java create mode 100755 xmlbeans/test/src/xmlobject/checkin/CreationTests.java create mode 100755 xmlbeans/test/src/xmlobject/checkin/DumbTest.java create mode 100755 xmlbeans/test/src/xmlobject/checkin/EasyPoTests.java create mode 100755 xmlbeans/test/src/xmlobject/checkin/InstanceValidationTests.java create mode 100755 xmlbeans/test/src/xmlobject/checkin/NameworldTest.java create mode 100755 xmlbeans/test/src/xmlobject/checkin/RedefineTest.java create mode 100755 xmlbeans/test/src/xmlobject/checkin/SelectChldAttTests.java create mode 100755 xmlbeans/test/src/xmlobject/checkin/SerializationTests.java create mode 100755 xmlbeans/test/src/xmlobject/checkin/SetTest.java create mode 100755 xmlbeans/test/src/xmlobject/checkin/SubstGroupTests.java create mode 100755 xmlbeans/test/src/xmlobject/checkin/ValidateTest.java create mode 100644 xmlbeans/test/src/xmlobject/checkin/XPathTest.java create mode 100755 xmlbeans/test/src/xmlobject/common/SelectChildrenAttribCommon.java create mode 100755 xmlbeans/test/src/xmlobject/common/StringXmlReader.java create mode 100755 xmlbeans/test/src/xmlobject/common/XmlReader.java create mode 100755 xmlbeans/test/src/xmlobject/detailed/CompareToTest.java create mode 100644 xmlbeans/test/src/xmlobject/detailed/CopyTest.java create mode 100755 xmlbeans/test/src/xmlobject/detailed/IsImmutableTest.java create mode 100755 xmlbeans/test/src/xmlobject/detailed/NilTest.java create mode 100755 xmlbeans/test/src/xmlobject/detailed/SelectAttributeTests.java create mode 100755 xmlbeans/test/src/xmlobject/detailed/SelectChildrenTests.java create mode 100644 xmlbeans/test/src/xmlobject/detailed/SerializationDetailedTests.java create mode 100755 xmlbeans/test/src/xmlobject/detailed/SetIdentityTest.java create mode 100755 xmlbeans/test/src/xmlobject/detailed/SoapFaultTest.java create mode 100644 xmlbeans/test/src/xmlobject/detailed/SubstGroupTests.java create mode 100755 xmlbeans/test/src/xmlobject/detailed/TestXmlReader.java create mode 100755 xmlbeans/test/src/xmlobject/detailed/TestsFromBugs.java create mode 100644 xmlbeans/test/src/xmlobject/detailed/TypedObjectCursor.java create mode 100755 xmlbeans/test/src/xmlobject/detailed/TypedSettersTests.java create mode 100755 xmlbeans/test/src/xmlobject/detailed/TypesTest.java create mode 100755 xmlbeans/test/src/xmlobject/detailed/ValueEqualsTest.java create mode 100755 xmlbeans/test/src/xmlobject/detailed/XmlObjectAbstractClassTest.java create mode 100755 xmlbeans/test/src/xmlobject/extensions/interfaceFeature/averageCase/checkin/AverageTest.java create mode 100755 xmlbeans/test/src/xmlobject/extensions/interfaceFeature/averageCase/existing/FooHandler.java create mode 100755 xmlbeans/test/src/xmlobject/extensions/interfaceFeature/averageCase/existing/IFoo.java create mode 100755 xmlbeans/test/src/xmlobject/extensions/interfaceFeature/methodNameCollision/checkin/NameCollisionTest.java create mode 100755 xmlbeans/test/src/xmlobject/extensions/interfaceFeature/methodNameCollision/existing/FooHandler.java create mode 100755 xmlbeans/test/src/xmlobject/extensions/interfaceFeature/methodNameCollision/existing/IFoo.java create mode 100755 xmlbeans/test/src/xmlobject/extensions/interfaceFeature/multInterfaces/checkin/MultInterfacesTest.java create mode 100755 xmlbeans/test/src/xmlobject/extensions/interfaceFeature/multInterfaces/existing/IReport.java create mode 100755 xmlbeans/test/src/xmlobject/extensions/interfaceFeature/multInterfaces/existing/ISum.java create mode 100755 xmlbeans/test/src/xmlobject/extensions/interfaceFeature/multInterfaces/existing/ReportHandler.java create mode 100755 xmlbeans/test/src/xmlobject/extensions/interfaceFeature/readOnlyBean/checkin/ReadOnlyTest.java create mode 100755 xmlbeans/test/src/xmlobject/extensions/interfaceFeature/readOnlyBean/existing/FooHandler.java create mode 100755 xmlbeans/test/src/xmlobject/extensions/interfaceFeature/readOnlyBean/existing/IFoo.java create mode 100755 xmlbeans/test/src/xmlobject/extensions/prePostFeature/ValueRestriction/checkin/ValueRestrictionTest.java create mode 100755 xmlbeans/test/src/xmlobject/extensions/prePostFeature/ValueRestriction/existing/ISetter.java create mode 100755 xmlbeans/test/src/xmlobject/extensions/prePostFeature/ValueRestriction/existing/SetterHandler.java create mode 100755 xmlbeans/test/src/xmlobject/extensions/prePostFeature/readOnlyBean/checkin/ReadOnlyTest.java create mode 100755 xmlbeans/test/src/xmlobject/extensions/prePostFeature/readOnlyBean/existing/FooHandler.java create mode 100755 xmlbeans/test/src/xmlobject/extensions/prePostFeature/readOnlyBean/existing/IFoo.java create mode 100755 xmlbeans/test/src/xmlobject/schematypes/checkin/EnumTests.java create mode 100755 xmlbeans/test/src/xmlobject/schematypes/checkin/GDateTests.java create mode 100755 xmlbeans/test/src/xmlobject/schematypes/checkin/IntTests.java create mode 100755 xmlbeans/test/src/xmlobject/schematypes/checkin/NumeralsTests.java create mode 100755 xmlbeans/test/src/xmlobject/schematypes/checkin/QNameTests.java create mode 100755 xmlbeans/test/src/xmlobject/schematypes/checkin/SchemaTypesTests.java create mode 100755 xmlbeans/test/src/xmlobject/schematypes/detailed/ListAndUnionTests.java create mode 100755 xmlbeans/test/src/xmlobject/schematypes/detailed/QNameSetTest.java create mode 100644 xmlbeans/test/src/xmlobject/usertype/averageCase/checkin/AverageTest.java create mode 100644 xmlbeans/test/src/xmlobject/usertype/averageCase/existing/SKU.java create mode 100644 xmlbeans/test/src/xmlobject/usertype/averageCase/existing/SKUHandler.java create mode 100644 xmlbeans/test/src/xmlobject/usertype/multipleItems/checkin/AverageTest.java create mode 100644 xmlbeans/test/src/xmlobject/usertype/multipleItems/existing/Room.java create mode 100644 xmlbeans/test/src/xmlobject/usertype/multipleItems/existing/RoomHandler.java create mode 100644 xmlbeans/test/src/xmlobject/xmlloader/detailed/JapaneseTextTest.java create mode 100755 xmlbeans/test/src/xmlobject/xmlloader/detailed/ParseTest.java create mode 100644 xmlbeans/test/src/xmlobject/xmlloader/detailed/PiccoloParseTests.java create mode 100755 xmlbeans/test/src/xmlobject/xmlloader/detailed/XmlLoaderBvtTest.java create mode 100755 xmlbeans/test/src/xmlobject/xmlloader/detailed/XmlLoaderMiscTest.java create mode 100644 xmlbeans/test/src/xmlobject/xmlloader/detailed/XmlStreamBeanReader.java create mode 100755 xmlbeans/test/src/xmltokensource/detailed/NewDomNodeTest.java create mode 100755 xmlbeans/test/src/xmltokensource/detailed/PrettyPrintNamespaceTest.java create mode 100755 xmlbeans/test/src/xmltokensource/detailed/RoundTripLoaderTest.java create mode 100755 xmlbeans/test/src/xmltokensource/detailed/XmlTextTest.java create mode 100755 xmlbeans/test/tools/lib/JWhich.jar create mode 100755 xmlbeans/test/tools/lib/ant-ext/ant-contrib-0.6.jar create mode 100755 xmlbeans/test/tools/lib/ant-ext/antexts.jar create mode 100755 xmlbeans/test/tools/lib/junit.jar create mode 100755 xmlbeans/test/tools/lib/xerces-2.5.0.jar create mode 100755 xmlbeans/test/tools/lib/xerces1.4.4.jar create mode 100755 xmlbeans/test/tools/lib/xsl/TestReport.xsd create mode 100755 xmlbeans/test/tools/lib/xsl/TestReport.xsl create mode 100755 xmlbeans/test/tools/lib/xsl/junit.css create mode 100755 xmlbeans/test/tools/src/tools/JUnit/JUnitXResultFormatter.java create mode 100755 xmlbeans/test/tools/src/tools/JUnit/JUnitXRunner.java create mode 100755 xmlbeans/test/tools/src/tools/JUnit/JUnitXTask.java create mode 100755 xmlbeans/test/tools/src/tools/JUnit/SimpleResultFormatter.java create mode 100755 xmlbeans/test/tools/src/tools/JUnit/TestReportMergeUtility.java create mode 100755 xmlbeans/test/tools/src/tools/JUnit/XmlResultFormatter.java create mode 100755 xmlbeans/test/tools/src/tools/JUnit/XmlResultFormatterImpl.java create mode 100755 xmlbeans/test/tools/src/tools/ant/BuildFileTest.java create mode 100755 xmlbeans/test/tools/src/tools/io/TeeOutputStream.java create mode 100755 xmlbeans/test/tools/src/tools/util/ClassCompare.java create mode 100755 xmlbeans/test/tools/src/tools/util/ComparisonError.java create mode 100755 xmlbeans/test/tools/src/tools/util/Diff.java create mode 100755 xmlbeans/test/tools/src/tools/util/JarUtil.java create mode 100755 xmlbeans/test/tools/src/tools/util/Log.java create mode 100755 xmlbeans/test/tools/src/tools/util/ResourceClass.java create mode 100755 xmlbeans/test/tools/src/tools/util/ResourceUtil.java create mode 100755 xmlbeans/test/tools/src/tools/util/SchemaFilenameFilter.java create mode 100755 xmlbeans/test/tools/src/tools/util/SchemaValidator.java create mode 100755 xmlbeans/test/tools/src/tools/util/TestRunUtil.java create mode 100755 xmlbeans/test/tools/src/tools/util/Util.java create mode 100755 xmlbeans/test/tools/src/tools/util/XMLFilenameFilter.java create mode 100755 xmlbeans/test/tools/src/tools/xml/Utils.java create mode 100755 xmlbeans/test/tools/src/tools/xml/XmlComparator.java create mode 100755 xmlbeans/testbuild.xml create mode 100644 xmlbeans/xbeanenv.cmd create mode 100755 xmlbeans/xbeanenv.sh create mode 100644 xmlbeans/xkit/README.txt create mode 100644 xmlbeans/xkit/doap_XMLBeans.rdf diff --git a/xmlbeans/CHANGES.txt b/xmlbeans/CHANGES.txt new file mode 100644 index 000000000..4140cddc3 --- /dev/null +++ b/xmlbeans/CHANGES.txt @@ -0,0 +1,180 @@ +Changes in V2.6.0 since V2.5.0 + +* Add new xml option CopyUseNewSynchronizationDomain used for copy. +This fixes the scenario when copy and access (ex. selectPath) are used +in a multithreading environment. +* Entitize \r when not in pretty print, this helps with maintainig \r +entities. +* Fix validation of integer value containing dot char. +* Fix chars in comments to avoid errors in IntelliJ under linux. +* Update durations to latest spec. +* Fix for compiling schema that contains complex type with simple +content that has facets defined in the base simple type +* Fix for Piccolo lexer when read method returns 0. +* Fix to preserve the CDATA bookmarks when copy from one xmlobject to +another. +* Fix bug when resizing circular buffer in saver's output stream +implementation. +* Fix for bug when not specifing type for a particle in derived schema +type and when minOccurs is 0. +* Fixed error messages when contain base and derived type names. +* Introducing a default maximum entity replacement limit of 10kb, it can +be controled by using the option XmlOptions.setLoadEntityBytesLimit. +* Fixed javadoc for inst2xsd and xsd2inst tools. +* Fix NPE in SchemaTypeImpl.getEnumJavaClass(). +* Added multiple entry points and refactored code for xsd2inst code. +* Remove org.w3c.dom files from xbean.jar. +* Add another xpath and xquery interface implementation. +* Add src/xmlinputstream classes org.apache.xmlbeans.xml.stream.* to +xmlpublic.jar. +* Make bootstrap run twice to avoid GUMP error emails. +* Fix for bug XMLBEANS-396: GML 3.1.1 generated code fails to compile. +* Fix for bug XMLBEANS-412: Pattern facet regex requires dash - to be +escaped. +* Fix for bug XMLBEANS-414: error cvc-complex-type.2.1: Element 'XXXX' +with empty content type cannot have text or element content. + +Changes in V2.5.0 since V2.4.0 + +* Exit codes for InstanceValidator +* Decimal precision handling fix in xsd2inst +* Option to perform additional, stricter Schema validation checks: XMLBEANS-350 +* updated pattern for dayTimeDuration +* Extended year min/max value limitations +* Support for date and time types with hour 24. +* NOTATION built-in type +* DocType fix when root element is changed +* "User types" feature - allows mapping of Schema simple types to custom user Java classes + http://wiki.apache.org/xmlbeans/UserTypes +* Nested enumeration type compilation error fix: XMLBEANS-381 +* Deadlock fix in generated impl setter simple and array +* Required attribute fix in streaming validator +* Many other fixes and optimizations + + +Changes in V2.4.0 since V2.3.0 + +* Pluggable XPath/XQuery engine support +* Upgraded support for Saxon 9 +* Added Schema compilation option to skip errors in case duplicate component declarations are encountered. +* Finer grained support for CDATA +* Tool to generate XPath for a given cursor position in a document +* added more fine-grained control over XML to Java name mapping +* Add support for JVM-supported encodings +* Adding XmlError codes +* Replace static HashMaps with WeakHashMaps +* Fix for XMLBEANS-309 Warnings on Generated code +* Fix for XMLBEANS-361 invalid NaN comparisons +* Fix qname marshaling when empty namespace +* Various other bug fixes + + +Changes in V2.3.0 since V2.2.0 + +* Improved Saxon support, Saxon 8.8 became the recommended version +* Added options to control use of CDATA sections when saving to XML +* Added support for QNames in Schema annotations +* Added support for new encodings: UTF-16LE, UTF-16BE, CP936/GBK. +* Fix: overzealous whitespace cropping after parsing entities like & (XMLBEANS-274) +* Fix: selectPath() with setXqueryCurrentNodeVar() option does not work for Saxon (XMLBEANS-276) +* Fix: synchronization problem with array setters +* Fix: Saver$TextSaver.replace method throws java.lang.ArrayIndexOutOfBoundsException (XMLBEANS-209) +* Fix: QNameSet generated by QNameSet.forArray(QName[]) can't be unioned with other QNameSets (XMLBEANS-290) +* Fix: java.lang.ArrayIndexOutOfBoundsException when saving XML (XMLBEANS-291) +* Fix: XQuery gives wrong result with Saxon 8.6.1 (XMLBEANS-275) +* Fix: bug during generation of complex types with simple content +* Fix: improved error handling during loading of Schema type system +* Fix: bugs in Duration serialization +* Fix: XMLCursor.getTextValue() +* Fix: Remove year zero from GDate, GDateBuilder and XmlCalendar per XMLSchema spec D.3.2 + + +Changes in v2.2.0 since v2.1.0: + +* Allow polymorphism in Extension Interfaces Feature +* Fix for circular buffer in TextSaver +* Tuned synchronization for multithreaded validation +* Updated to the latest XMLSchema.xsd - January 25, 2006 +* Better QName validation +* Fix insertion positions when using substitution groups with arrays +* Updated XmlBeans to work with SaxonB-8.6.1 in place of SaxonB8.1 +* Fix for regex validation in multi-threaded, multi-processor environment +* Fix for schema compilation error when restricting complex type with simple content +* Implemented XMLInputStream interface for saving a store +* XQuery external variable binding support +* Various other bug fixes + + +Changes in v2.1.0 since v2.0.0: + +* Fixed the issue whereby some IDEs would have problems with the TypeSystemHolder class being generated in the classes directory +* Better integration with Maven +* Implemented support for ID/IDREF in DTDs via DOM's .getElementByID() +* Integrated a patch that makes XmlBeans work in a sandboxed environment +* Added the ability to control entitization of characters when saving documents +* Fixed issue with memory reclamation in multi-threaded environments, which was delayed too much so it could be mistaken for a memory leak +* Added numerous new test cases and performance tests +* Continued improving performance, especially in the DOM support and XmlCursor areas +* Added column numbers support in our snapshot of Piccolo; validation and XMLSchema error reporting benefit from this and is of course usable from user code +* Line/column number is now also available for end-tags +* Solved a legal inconsistency surrounding our use of JSR173 APIs +* Fixed a lot of reported issues in various areas of the product + + +Changes in v2.0.0 since v2.0.0-beta1: + +* many performance related changes, especialy in the DOM and Cursor areas +* rewrite of the support +* Completed the implementation of Filer +* new documentation on xs:any, validation plus updates of the old docs +* many bug fixes, including perm gen memory bug + + +Changes in v2.0.0-beta1: + +* new store implementation, including native DOM implementation +* Piccolo is now the default parser.XmlOptions.setLoadUseXMLReader (XMLReader xmlReader) can be used when a diffrent parser is required. +* Sample xml generation from an schema file +* New failfast behavior for simple types, more consistent +* EntityResolver is setable in SchemaCompiler +* XPath 2.0 and Xquery support through Saxon +* java 1.5 generics for array properties added to generated source +* Simplified working with substitution groups by adding XmlObject.substitute() method +* "-noVDoc" command-line option for scomp to skip validation of contents +* uniform access to the getSourceName() method in Schema Object Model +* Cleaned up schema compilation APIs with a XmlBeans.compileXmlBeans() +* Added error codes and improved validation error messages +* Changed .xsb format and loading strategy to improve performance +* Ability to pass URLs instead of Files for Wsdl/Schemas +* Added option to pass in "##local" to -allowmdef +* Inst2xsd: support for xsi:nil and qname fix. +* adding getCurrentElementSchemaType in Validator for finding schema types of elements with xsi:type attribute +* adding ValidatingInfoXMLStreamReader for PSVI access on XMLStreamReaders +* added Location to streaming validation errors +* Instance 2 schema tool +* Support for arbitrarily nesting s +* New "schema bookmark" mechanism allowing one to tag user data on Schema Object Model entities +* Add ability for XmlSaxHandler to insert bookmarks while loading +* Added a diff utility that compares two jars (or directories) containing compiled Schema types +* Interface and pre-post extensions +* Enabled ValidatingXMLStreamReader to start validating from both current and next event in the XMLStreamReader +* Functionality to retrieve xml validation errors programatically +* Added saver options to not save xml decl +* Added ability to compile Schemas containing references to SOAP11 encoded arrays +* selectChildren and selectAttributes for dynamic getters and some wildcard scenarios +* Location in ValidatingXmlStreamReader +* Added a wrapper over jsr173's XMLStreamReader +* Added support for default value in XMLStreamReaderExt interface and implementation +* Adding typed value for QName case in the Validator +* Adding an utility for validation of simple schema types +* Improved the Validator to ofer PSVI info +* Exposed some of the XMLSchema validator functionality in the public interfaces +* Added support for XML Catalog, based on Apache Commons CatalogResolver +* Added XMLStreamReaderExt an extention of XMLStreamReader which alowes getting strongly typed java values from a stream +* Adds support for annotations in XMLSchema +* Added JSR 173 support + +* performance tests +* various feature tests +* samples and documentation +* packaging, licencing changes diff --git a/xmlbeans/KEYS b/xmlbeans/KEYS new file mode 100644 index 000000000..3430cdebf --- /dev/null +++ b/xmlbeans/KEYS @@ -0,0 +1,194 @@ +This file contains the PGP&GPG keys of various Apache developers. +Please don't use them for email unless you have to. Their main +purpose is code signing. + +Apache users: pgp < KEYS +Apache developers: + (pgpk -ll && pgpk -xa ) >> this file. + or + (gpg --fingerprint --list-sigs + && gpg --armor --export ) >> this file. + +Apache developers: please ensure that your key is also available via the +PGP keyservers (such as pgpkeys.mit.edu). + + + +pub 1024D/4159EADB 2004-04-21 Cliff Schmidt + Key fingerprint = 1275 9844 8970 06D9 E4CD FB35 CBA7 46B2 4159 EADB +sig 3 4159EADB 2004-04-21 Cliff Schmidt +sub 1024g/1312BCCC 2004-04-21 +sig 4159EADB 2004-04-21 Cliff Schmidt + +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v1.2.3 (MingW32) + +mQGiBECGsxcRBACoWau6x33CV1aCbiCfFLFJd0N8WLM6Vf3ez98Nu9jzj7yeP50G +oZg/vuu/ncDXCfii8O80LtVF16rWKG3xG40k+pQLytAdj2Gi0zj9vX9hSMY/+PJT +g24WVTWVkzqMP0jPGFZNoK/CC71o328R4NreJp/gPH7SPHxTm+Ogs9+1WwCgoICF +qDvSqFMrvHgoYRsmo03IZFkD/A1Q43sJcuiUkGnrq7VfhhHEIW6lK9pnGI3e72en +sO05HYpPvrpjhew9o/+av1xqb51EEZdbsvX02yWKa0k4tto6F8yh+yr/GdQcVK2t +dZ0OQ/ev05zUo/xbFlYiHuuiNg2ewLHCJNwUd1iqgljQfeC4XmrIB9EZJ9HJ/wAe +6c9iA/9vU7AUGXytShUYcvhKBlUSA6xm7X30lAb0RhiCuhT9T41C8ZBsYpeWdkbS +NdjxiXD1If4ukl0O65WssgS9x7H5iTUY0hRzBktt37GdAGj/bvTrsj8yKdJQLQEh +oAEkA+cyFCfeQuinzUAqUkAWpKIsFTLchpf611wEnASNeb/JUrQhQ2xpZmYgU2No +bWlkdCA8Y2xpZmZzQGFwYWNoZS5vcmc+iF4EExECAB4FAkCGsxcCGwMGCwkIBwMC +AxUCAwMWAgECHgECF4AACgkQy6dGskFZ6tvlHwCfRG+HMKTfkOP7cmtWUWLIdSXy +GhsAnR3oTuY9WvkTH4VmTAl9KnL6Z6GTiEYEExECAAYFAkCGtngACgkQaFp3yu5W +VQ7FTgCfWgsMYa8i+VYKxkX8fxNbdGmlQBcAoLJa1nvtbsFuByx6ZXc0Ew/nMIzV +uQENBECGsxgQBADuVMst3u8Z4dMy/opqS+P4zG/PpCbrvfragICglTyaSqEjnSiZ +G09Ojm5OwzikLLcme9CGnGY4lcxhREmpJDRp7Ga3RfvAKo2VkWPM/nRnoCGzkCbA +lQWuuShhc88oPgyTYzXmuLvhEeqcBD/GgT/Pl6pJNG5VDY95DbUvtgXBowADBQP/ +ds6xSj9y9o7jFcgc3laQlhieSxNQmlNw9eUG8X0kxu1rv9sputW8pF42Vom+AnwF +TsEySNx/ndeRXHn4HTtYnl4CFFlsPM2tEyfQIKV2k6Zxi5RG7/sGDHJaEtB0KGDV +Gv3yIc3158eJTAjDaDMvEJEjlB9dgTnD7V2H9ik/RwqISQQYEQIACQUCQIazGAIb +DAAKCRDLp0ayQVnq263NAJ9pTbtt8MlxS3SdsAsO8GYf+xEq4gCeM8qnD/hze4Co +BNHsPbcuKm4vDKQ= +=zpFH +-----END PGP PUBLIC KEY BLOCK----- + +pub 1024D/2EA8205C 2003/11/13 David Bau (III) + Key fingerprint = D1EC 3541 EDC3 740D 2659 0EE6 2D21 6C84 2EA8 205C +sig F88341D9 Lars Eilebrecht +sig 75A67692 Erik Abele +sig EE65E321 Martin Kraemer +sig 88C3A5A5 Philippe M. Chiasson (Canonical) +sig CC78C893 Rich Bowen +sig 2EA8205C David Bau (III) + +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: PGP Key Server 0.9.6 + +mQGiBD+z458RBADHgCoHKddKwHPuuBWP0h/Nk7cXoD5qBWXAn7Ps7K1PG0rsE2+c +2PRaNZLyeL23BbCJAq/oGcU+Hc2mzToaxv8WLFqszXZwtjG/wHJ3ug6Klbo2oOWl +XPYYLEOBppuqvbt8fel4SjfcsI0CBVeOs2KCg/htyU1HvbQFBn112PdLwwCg2Fv8 +TyLHJnf5VyhVdLVecqWMQ+MD/0x7ckZgoZ2nkHJVxRvsYOQYsi4jj3C55R9QDOzI +aevlvBWbb+bRmevA6hl3irHVxDVsP5KfzDE0dB5zvaBTCSKE1YFevzekRn9P7vRJ +hXjUxjd/tot+BQVZ5hX7ghIHpakIAwI6mCC3MS33gt1/Bb1s4g7yUw16rtmdClZE +XY13BACVSgO9LOg5pBFEopVEwLQLY5IYU04tojuCl7LbNQxLRBFaWM3S/dN0hr3V +wxk3UNdamOJshDq6QMqYSJ8S7wOwFP23YNdMvasGVayKG0EQBflRL3RC/QsvQ1W1 +PLNFU5WALBiSsNTpcRwn3VJm6xCSrI93QFzj78IDsIcNSXLQFbQeRGF2aWQgQmF1 +IChJSUkpIDxkYXZpZEBiYXUudG8+iJkEEgECAAYFAj/KcwcACgkQPo+38viDQdmL +nwPnYWiW7DBgZ1++NypQd7eckUqaj1NFOYSUxlxhaUQc5BLViQVEkfqNqFPkga26 +NdpVbJB6OK2hE4plIqkt442f4hxXtRCf7Vcht8xLcQy75PfqsFRI48lSixaUOvxp +vOVaQW9fDyjzmmxqn4r+P5Kg4gSes6XhNZ0+/or3KNqIRgQSEQIABgUCQBXdagAK +CRAVP6DNdaZ2knA9AKCokQmPF9Y3Cwm4xGcTsQbS7vqpywCdGcXkTBrjGcPA1FSt +hHgt3JDJrs2InAQTAQIABgUCP8d1mQAKCRA34/Rf7mXjIWbRBAC3+u6jEGB0E9K2 +6m2ft7hi/RrQ40qeyCinlXqsu/hmEXcMk1zrWw5UUvC3/VRyrsd9L/Tk+kaY/6+C +JJcju1zCDAJ8KoD96+V/CYBty8SFQAajHQnMo7VbNY3BAfZwnj4nGj7XgH2SqCJa +hFJoRHSafXpRLXHadyU+NffWgdw+D4hGBBMRAgAGBQI/umtMAAoJEMsyoQeIw6Wl +s/wAn02w9mkD+vbD8tHjRDVfIjxmy6krAKCOdlmoLtGw4E2jZ82cFNLr4kjrxIhG +BBMRAgAGBQI/uqDgAAoJEFz9N/rMeMiTHnIAoIMy5OTayTDGO83hbqREfyNs5CAF +AKCqZO8d1xWtzO2epkd0f968bos+I4heBBMRAgAeBQI/s+OfAhsDBgsJCAcDAgMV +AgMDFgIBAh4BAheAAAoJEC0hbIQuqCBcrjwAn0hY/JRGtht7aqOODA+6EwKheQT4 +AJ0S2EyVs+TR2pB61LgdyvkUVMJrpbkBDQQ/s+OgEAQAvK17K65ZLVg3BuVgl39l +Ha40tQgxX5MLf4j2/ztYRL3ZZzu43C+JCWBNPiO+Eo+j2kWekxnCfXWyU2RC3bI+ +ZeG4aMw7nhL9xboXI2Tc6/3kYyFHCOCqqwWJdXthUzbVKTx2+ySIemTME0gpyT3G +acFVusngeoMoo+Tz1s0XGrcAAwUEAJxgRmo0uIMr+Wn9s93oBc1wKVOZ+Wh4Qugi +52bmhB641Vtm8hPJcfEKpQFrMClaedsbMPANpJKHOq+D2QwG5tOKpJ1cQlDzVZ7u +ZDnrsInOIFZHBaiKVwlwTZylfQCpPoQtJGf30u6tLM9bLTU8wrASpwWC64S19yZX +73TyDV56iEkEGBECAAkFAj+z46ACGwwACgkQLSFshC6oIFzqmACeOQ7MmJn79fVh +qGs4bG1L93LlDPQAoIEhnRFsgSzaf6uq3Gb1dKJuIUui +=CkKL +-----END PGP PUBLIC KEY BLOCK----- +pub 1024D/65B0150D 2005-02-23 Kevin Krouse + Key fingerprint = 7F2C 0925 C047 10E5 7F8F 1545 FE5A 3279 65B0 150D +sig 3 65B0150D 2005-02-23 Kevin Krouse +sub 1024g/8E15E963 2005-02-23 +sig 65B0150D 2005-02-23 Kevin Krouse + +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v1.2.6 (GNU/Linux) + +mQGiBEIb4QARBACpfmwVKHLZQIB9VCxVLRkdf+UbZEdD+doj18rXtrYTc5gTOGCs +dHcS7XYs7Tr9+NOX+9EZm/6GZDmNGhRRAAUslqCTDxxtABp4AbKZTrDFDi2QCHSw +k2hPESljKXT/+GWr6UFsJWCzy68wPwJ+pxb+ZFGWA+6LE2/1bPmzoVTytwCgwIib +6R8fFMf+OmjRzSmS1rcIx+cD/iI+JCApblPNqVFNlefyfrFugXMCX1z6/UhPsUGH +hZyweF9XeyaKCy7ukdsqUNzJxP3l3A/n37n1Mxjh3vamkBXd5tNF9SeBbITKgTPR +p8THya8LQbDqL1yuKbVqvwaLnxTX+891/QxogSg7u7oGJeTWbNXwxQjxFx1ND3y7 +NKSkBACRlXtkh0k3xAy1bl2r/0YL2+sAP3YB9TbqqtRO1Pfy4dcyVn8Hz9b59HWU +AijHWbpgPXz1Kbym04Z952dSVfKtkBh6hmblxiNdMgNSMKlO5Oaov+1LY63KYEUv +eUgfxcFNy/JA8GyXoeh3izZkqC54XYgOAyfMoyevY8dLEEE+bbQhS2V2aW4gS3Jv +dXNlIDxra3JvdXNlQGFwYWNoZS5vcmc+iF4EExECAB4FAkIb4QACGwMGCwkIBwMC +AxUCAwMWAgECHgECF4AACgkQ/loyeWWwFQ2NQACggwJmOmylcszNu2f8y4ASgDeg +Ip4AniBqiSnGnZTJHGuN+zgWWgLNzb3PuQENBEIb4QMQBAD91lo6ba0wJr2tMAe+ +ftFFxWgAms53qscYlhoIJR2OnuF+2R+b9q1iYSrWaXXPTVxC7e8U/dbxKEjYLor+ +CBsHBavnFqd7HrFk1/FJMCeqHAm+hAUmRmuC9OrJHJqJWxAX0+T1j/8z4qSsCuMQ +Bd2c3IDrSWZRfh1LsL3NKSe7bwADBQP/VCX61WJ9zo0cHWNV4UEJjMALJFyqHE0p ++07P63g8hIcVHrNzI2qlnhPVlqTrX6JWHemUoEbZ9YbCGTw9qJvcJxdq2SoVOIJh +aRjmPbVIXnHII6a2pFqBIpJGny1ZRUMp6l5Xj9iZlii2/JGPB/9hrLuU8q/nQGwq +IuD+IE6nxIOISQQYEQIACQUCQhvhAwIbDAAKCRD+WjJ5ZbAVDfsYAJ4iFexRxVa/ +j7lg/9yNMHQAb5kWgACcCdYb4OWys4cLbAcXyNSQ0CD7AQI= +=wadS +-----END PGP PUBLIC KEY BLOCK----- + +pub 1024D/3926D7DD 2005-06-27 Radu Preotiuc + Key fingerprint = A004 7A3C 02DA 01B5 7974 1890 6899 C8E2 3926 D7DD +sig 3 3926D7DD 2005-06-27 Radu Preotiuc +sig 4159EADB 2005-07-10 Cliff Schmidt +sig 46914992 2005-07-13 Cezar Cristian Andrei +sub 1024g/408A5399 2005-06-27 +sig 3926D7DD 2005-06-27 Radu Preotiuc + +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v1.2.1 (GNU/Linux) + +mQGiBELAU70RBACoxk1aD4TCJ/o41BTXGdWCzIESuf1ph2V8jk/cLMBzxAUkl15V +2dQnrf/BUmcBIMx4HfTiNg9nevV+IpClFKZ2lZmAW3nuzc1uK7j7kI8Ba2BlOHLA +Vcg+2vGr2okKrR2tZv24brbXMnnECy9t7OY/O/AqIXE1mOV0/rPd3JayywCgzjCw +UJMFlXQimb/ICUIX0eqZWJ0D/2ozLxhHjfN2A8kIL39crXhYdgHbm6L7OrW5FYST +Yly0f5qDuPRmUubZiI33uglKTCfh5xu/MfKVtAeHjBu9AItWoybR43M8BINlB061 +Oef5jrl7hljAyP1YgEhM8gkeTtk0uC4RLH0sjLQUm1DtRU3Bkrzw7GsF3VhE+k2N +AxUSA/wJ+Gc/HkgpIWCyB7KAOZLlOXky5Mcgvygxx8ySn6q+mL9CrlI1qb9cWM5x +gPhRmPiIq8sQMfE/vSbgCjz3QcA6HZ/O7MRZNpse4pwyvDMiPTCQnYe1BK1mcuwx +rToZ2LMUfzz+qUu3Oge5eFZ51eeOGrv/Qef52FS3Ga9Je3TB8bQgUmFkdSBQcmVv +dGl1YyA8cmFkdXBAYXBhY2hlLm9yZz6IWQQTEQIAGQUCQsBTvQQLBwMCAxUCAwMW +AgECHgECF4AACgkQaJnI4jkm193QzwCgxTgw+XpEt43xDjDqEjCg8e9f5PYAoIdk +J2sGim/GtWLFMHfDxBl2K5e7iEYEEBECAAYFAkLRnZcACgkQy6dGskFZ6tvITgCe +JfYK7YGds2qTENfTECUO1eBssm0AnA0YBvDZgamgF01AvIF8HGOwTmq7uQENBELA +U74QBACLhAQWU5vv1O3gK4RonRBo3GmDCtPZNv5fKI20w4Si/nkh5sdmXfX4+ngF +lEsrpS0gr57cqJ6fEvRG9GSg2MyDKkvi3XuUEyMpFVAyOIBSjYZKT/NZMNtf7AAw +P5FUvo664UYYT2D4iBA1vXcerr/ak3pFpdkb1Fqd8H2KuD0NZwADBwP/e00tWaj0 +dqH1nN2dePkASlTXethFpkau20zuYsJ+6V52Hyqundj3UfrQUWW7KU+Qv5oAuEys +OJgbSWNwICIzXKZaSC2tlGwQa19410czAUoGfY6qfuIEcjvI2Byinj6aDekxAD66 +PUDu5raaGru8YBqtsG2N/JR8myBIiO1V6v+IRgQYEQIABgUCQsBTvgAKCRBomcji +OSbX3RcWAJ9dQxYs8U0xNrG1Ro9tYlNBjENzGACgk5KWLkU/aig/Ze77HCNYTg1M +VIk= +=UTi5 +-----END PGP PUBLIC KEY BLOCK----- + +pub 1024D/669C4AB5 2006-06-27 Cezar Cristian Andrei +sig 3 669C4AB5 2006-06-27 Cezar Cristian Andrei +sub 2048g/B3895278 2006-06-27 +sig 669C4AB5 2006-06-27 Cezar Cristian Andrei + +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v1.2.1 (MingW32) + +mQGiBEShFMIRBACP3XKE6an9nGr8OcBZAsMtTxpktCX1Xhbt3n17T9zhxR1gWSFx +nKCPf0VbAvu6TU059Xy1OMtNPYfa4aYE+GC2Gf1Du/2B/bRG4TORHtufubKnL7bx +Pw16DuBx+eyGWCrCfx/AfLKsYpgwsJLFj2972+FEY0XhKcDE2R6DKJQ6AwCgt8rF +8WRDkfsfFvzInGf0oIpBAPsD/jKKstZw8XGNp/net8fXWFoDTRxdMiRBanY6nAln +dQ8+vciRay22xQuSork3Fv2N5PdE7tLc93tAfwOd42ixP5jft2nxfMoAnN0N0Lby +f6I8052Q6P2tnGechSNWILGlUMH5eOeUhFuQRA0ijUD5iArz+4OAfAbIGCzm4uZ3 +vn1WA/46hKk07TUzV0/4NL5IpoZsBt5eZkquNCwNU5TijLglMp0DP0Fn2SH9R+0a +9IxDhO8rFXI2yf6SLI90GJYgxSCH1/JH/tWeGjditqqTdUky9Ji70ooviGvPwqa3 +0mjTqsJc7UtOUT0fcc2vX/OgWxOyJAqjDTm8MJ5nd8/1/1+tsrQoQ2V6YXIgQ3Jp +c3RpYW4gQW5kcmVpIDxjZXphckBhcGFjaGUub3JnPohZBBMRAgAZBQJEoRTCBAsH +AwIDFQIDAxYCAQIeAQIXgAAKCRB4voXZZpxKtaqKAKCtk1G98B2+0Wk3GWw+2VHz +FtJn2ACfcyrQmNHq/JAm/T+N97/eh/+y0R25Ag0ERKEUyRAIAMbRmykqZ4DAArqa +hIlK7ERu7Q34CdMnPl/+VA3buxq8AnBVw3oCAogm8UB/mx7lQjgBbHPSNwfrQfjq +1uSJrqrmSuyYwkjOmH1C0Gn2rODY6XDTzjcNA9bmO7CeY9ViblpQ2jnlPJtgwYi4 +96gz1hHEVayvpEPO+pLIc3mqQrNZWUP04vDrX2MSuTMjpX0wUd+1sq7jsknOjZ6D +No++mAJKgoqMGzWTVy32qqNNMmQf3+hopkqDTo3ngd5IW668yfliCehCSVYXihun +1avPFwcecuHYn3OBeYVAeTUzLaK1QePlbjB0MR/4ugT7ewHmHvNQJJNRNmlPBQPd +Ixj18EsAAwUIAKWK+8joa/S378yldSz4TN22DwJLUs84xawWs3iiYe6dlXyF1+eN +onz4IB/7U2B/x06LLK5bYN87qak16yAP4lxv9Wq/g3nZskjWyVTnQzyphhksWgkP +1CwR4+mGm3ayXbZhtpGiPjb4KJKg7evuimDgHplryV29QmGvmH6zIJkodYF1a/Q5 +SVuIdoC9XMy+avxBCgNaxfnUMk+NNihv+qD7hHPk81XiNdYpZbE4zUvIlBhGwJ8f +PRF/b9mla7AYDe5JAm1zux+WXyQ2BZyx6KFT0XaMm69HxUWapSi7COK+Qfu0m8sj +gSDDPNu9F6CiIgFf8XJV4CzDCj1X5GW/5zmIRgQYEQIABgUCRKEUyQAKCRB4voXZ +ZpxKtegFAJ4xHox0haKD6Ln4/2ntqS7p59Ni7gCfY599gXS/U+fQClWsZwnuXC/u +o3s= +=ZMn1 +-----END PGP PUBLIC KEY BLOCK----- \ No newline at end of file diff --git a/xmlbeans/LICENSE.txt b/xmlbeans/LICENSE.txt new file mode 100755 index 000000000..57bc88a15 --- /dev/null +++ b/xmlbeans/LICENSE.txt @@ -0,0 +1,202 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. + diff --git a/xmlbeans/NOTICE.txt b/xmlbeans/NOTICE.txt new file mode 100644 index 000000000..906cc4c96 --- /dev/null +++ b/xmlbeans/NOTICE.txt @@ -0,0 +1,29 @@ + ========================================================================= + == NOTICE file corresponding to section 4(d) of the Apache License, == + == Version 2.0, in this case for the Apache XmlBeans distribution. == + ========================================================================= + + This product includes software developed by + The Apache Software Foundation (http://www.apache.org/). + + Portions of this software were originally based on the following: + - software copyright (c) 2000-2003, BEA Systems, . + + Aside from contributions to the Apache XMLBeans project, this + software also includes: + + - one or more source files from the Apache Xerces-J and Apache Axis + products, Copyright (c) 1999-2003 Apache Software Foundation + + - W3C XML Schema documents Copyright 2001-2003 (c) World Wide Web + Consortium (Massachusetts Institute of Technology, European Research + Consortium for Informatics and Mathematics, Keio University) + + - resolver.jar from Apache Xml Commons project, + Copyright (c) 2001-2003 Apache Software Foundation + + - Piccolo XML Parser for Java from http://piccolo.sourceforge.net/, + Copyright 2002 Yuval Oren under the terms of the Apache Software License 2.0 + + - JSR-173 Streaming API for XML from http://sourceforge.net/projects/xmlpullparser/, + Copyright 2005 BEA under the terms of the Apache Software License 2.0 diff --git a/xmlbeans/README.txt b/xmlbeans/README.txt new file mode 100644 index 000000000..445390b14 --- /dev/null +++ b/xmlbeans/README.txt @@ -0,0 +1,57 @@ +/* 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. + */ + +Welcome to XMLBeans! + +Layout of the tree: +- README.txt this file +- build.xml ant build file for building XmlBeans code and utilities +- testbuild.xml ant build file for building and running tests +- STATUS essential info about the project +- xbeanenv.cmd sets the XMLBEANS_HOME environment variable on Windows +- xbeanenv.sh sets the XMLBEANS_HOME environment variable on Unix +- bin contains useful command-line scripts for Win and Unix +- docs contains several documentation files +- external contains external jars upon which XmlBeans depends +- samples contains ... samples +- src the source code for XmlBeans, organized by area +- test contains test cases and infrastructure +- xkit contains the README file for the binary distribution + +To quickly get started run: +"ant" to build XmlBeans or +"ant usage" to see the most useful build targets or +"cd bin" and then " -help" for a description of what the + tool does and what parameters it accepts + +For further information check out: +http://xmlbeans.apache.org +http://wiki.apache.org/xmlbeans +./samples//README.txt for running samples +./test/docs/* for running tests + +XmlBeans depends on the following external libraries: +- jsr173_1.0_api.jar +- jam-0.1.0-src.jar [http://annogen.codehaus.org/JAM] for the extension + feature using plain .java files +- tools.jar (O) from the JDK, dependency of jam-0.1.0-src +- resolver.jar (O) [http://xml.apache.org/commons/components/resolver/] + for apache-commons catalog files that are used in entity resolving +- saxon9.0.0.4j (O) [http://sourceforge.net/projects/saxon/] + for XPath/XQuery in XmlBeans +(O) means that the library is optional + +For licensing information, see ./src/license/LICENSE.txt +Updated: 11/25/09. diff --git a/xmlbeans/STATUS b/xmlbeans/STATUS new file mode 100644 index 000000000..41d2cdfa8 --- /dev/null +++ b/xmlbeans/STATUS @@ -0,0 +1,16 @@ +Project Homepage: + +http://xmlbeans.apache.org/ + + +Active committers: + +Cezar Andrei cezar at apache dot org +Radu Preotiuc-Pietro radu.preotiuc-pietro at oracle dot com +Jacob Danner jacob dot danner at gmail.com +Wing Yew Poon wing.yew.poon at oracle dot com + + +FAQ: + +http://wiki.apache.org/xmlbeans/XmlBeansFaq diff --git a/xmlbeans/bin/_setlib b/xmlbeans/bin/_setlib new file mode 100755 index 000000000..c3beccc8a --- /dev/null +++ b/xmlbeans/bin/_setlib @@ -0,0 +1,32 @@ +#!/bin/sh +## +## 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. +## + +if [ -z "$XMLBEANS_HOME" ]; then + XMLBEANS_HOME=`dirname $0`/.. +fi + +XMLBEANS_LIB= +if [ -f "$XMLBEANS_HOME"/build/lib/xbean.jar ]; then + XMLBEANS_LIB=$XMLBEANS_HOME/build/lib +fi +if [ -f "$XMLBEANS_HOME"/lib/xbean.jar ]; then + XMLBEANS_LIB=$XMLBEANS_HOME/lib +fi + +if [ -z "$XMLBEANS_LIB" ]; then + echo "ERROR: Could not find xbean.jar, try set XMLBEANS_LIB to the directory containing xbean.jar" +fi diff --git a/xmlbeans/bin/_setlib.cmd b/xmlbeans/bin/_setlib.cmd new file mode 100644 index 000000000..6344731e2 --- /dev/null +++ b/xmlbeans/bin/_setlib.cmd @@ -0,0 +1,28 @@ +@REM +@REM Copyright 2004 The Apache Software Foundation +@REM +@REM Licensed under the Apache License, Version 2.0 (the "License"); +@REM you may not use this file except in compliance with the License. +@REM You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, software +@REM distributed under the License is distributed on an "AS IS" BASIS, +@REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@REM See the License for the specific language governing permissions and +@REM limitations under the License. +@REM + +@rem Common script to set the XMLBEANS_LIB variable +@rem to the directory containing xbean.jar +@echo off + +if "%XMLBEANS_HOME%" EQU "" (set XMLBEANS_HOME=%~dp0..) + +set XMLBEANS_LIB= + +if exist "%XMLBEANS_HOME%\build\lib\xbean.jar" set XMLBEANS_LIB=%XMLBEANS_HOME%\build\lib +if exist "%XMLBEANS_HOME%\lib\xbean.jar" set XMLBEANS_LIB=%XMLBEANS_HOME%\lib + +if "%XMLBEANS_LIB%" EQU "" echo "ERROR: Could not find xbean.jar, try setting XMLBEANS_LIB to the directory containing xbean.jar" diff --git a/xmlbeans/bin/dumpxsb b/xmlbeans/bin/dumpxsb new file mode 100755 index 000000000..78ab2920b --- /dev/null +++ b/xmlbeans/bin/dumpxsb @@ -0,0 +1,33 @@ +#!/bin/sh +## +## 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. +## + +#XSB file dumper +#Prints the contents of an xsb file in human-readmble form + +echo `dirname $0` + +if [ -z "$XMLBEANS_LIB" ]; then . `dirname $0`/_setlib; fi + +cp=$XMLBEANS_LIB/xbean.jar:$XMLBEANS_LIB/xmlbeans-qname.jar:$XMLBEANS_LIB/jsr173_1.0_api.jar + +case "`uname`" in + CYGWIN*) + cp=`cygpath -w -p $cp` + ;; +esac + +java -classpath "$cp" org.apache.xmlbeans.impl.tool.XsbDumper "$@" diff --git a/xmlbeans/bin/dumpxsb.cmd b/xmlbeans/bin/dumpxsb.cmd new file mode 100644 index 000000000..39fb50b13 --- /dev/null +++ b/xmlbeans/bin/dumpxsb.cmd @@ -0,0 +1,30 @@ +@REM +@REM Copyright 2004 The Apache Software Foundation +@REM +@REM Licensed under the Apache License, Version 2.0 (the "License"); +@REM you may not use this file except in compliance with the License. +@REM You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, software +@REM distributed under the License is distributed on an "AS IS" BASIS, +@REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@REM See the License for the specific language governing permissions and +@REM limitations under the License. +@REM + +@rem XSB file dumper +@rem +@rem Prints the contents of an xsb file in human-readable form +@echo off + +setlocal +if "%XMLBEANS_LIB%" EQU "" call "%~dp0_setlib" + +set cp= +set cp=%cp%;%XMLBEANS_LIB%\xbean.jar;%XMLBEANS_LIB%\xmlbeans-qname.jar;%XMLBEANS_LIB%\jsr173_1.0_api.jar + +java -classpath "%cp%" org.apache.xmlbeans.impl.tool.XsbDumper %* + +:done diff --git a/xmlbeans/bin/inst2xsd b/xmlbeans/bin/inst2xsd new file mode 100755 index 000000000..987395412 --- /dev/null +++ b/xmlbeans/bin/inst2xsd @@ -0,0 +1,31 @@ +#!/bin/sh +## +## 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. +## + +#Instance to Schema tool +#Builds xsd files from xml instance files. + +if [ -z "$XMLBEANS_LIB" ]; then . `dirname $0`/_setlib; fi + +cp=$XMLBEANS_LIB/xbean.jar:$XMLBEANS_LIB/xmlbeans-qname.jar:$XMLBEANS_LIB/jsr173_1.0_api.jar + +case "`uname`" in + CYGWIN*) + cp=`cygpath -w -p $cp` + ;; +esac + +java -classpath "$cp" org.apache.xmlbeans.impl.inst2xsd.Inst2Xsd "$@" diff --git a/xmlbeans/bin/inst2xsd.cmd b/xmlbeans/bin/inst2xsd.cmd new file mode 100644 index 000000000..9d1a3d8da --- /dev/null +++ b/xmlbeans/bin/inst2xsd.cmd @@ -0,0 +1,33 @@ +@REM +@REM Copyright 2004 The Apache Software Foundation +@REM +@REM Licensed under the Apache License, Version 2.0 (the "License"); +@REM you may not use this file except in compliance with the License. +@REM You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, software +@REM distributed under the License is distributed on an "AS IS" BASIS, +@REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@REM See the License for the specific language governing permissions and +@REM limitations under the License. +@REM + +@rem Instance to Schema tool +@rem +@rem Builds xsd files from xml instance files. + +@echo off + +setlocal +if "%XMLBEANS_LIB%" EQU "" call "%~dp0_setlib" + +set cp= +set cp=%cp%;%XMLBEANS_LIB%\xbean.jar;%XMLBEANS_LIB%\xmlbeans-qname.jar +set cp=%cp%;%XMLBEANS_LIB%\jsr173_1.0_api.jar +set cp=%cp%;%XMLBEANS_LIB%\resolver.jar + +java -classpath "%cp%" org.apache.xmlbeans.impl.inst2xsd.Inst2Xsd %* + +:done diff --git a/xmlbeans/bin/scomp b/xmlbeans/bin/scomp new file mode 100755 index 000000000..68d29b143 --- /dev/null +++ b/xmlbeans/bin/scomp @@ -0,0 +1,31 @@ +#!/bin/sh +## +## 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. +## + +#Schema compiler +#Builds XBean types from xsd files. + +if [ -z "$XMLBEANS_LIB" ]; then . `dirname $0`/_setlib; fi + +cp=$XMLBEANS_LIB/xbean.jar:$XMLBEANS_LIB/xmlbeans-qname.jar:$XMLBEANS_LIB/jsr173_1.0_api.jar:$JAVA_HOME/lib/tools.jar:$XMLBEANS_LIB/resolver.jar + +case "`uname`" in + CYGWIN*) + cp=`cygpath -w -p $cp` + ;; +esac + +java -Xmx256m -classpath "$cp" org.apache.xmlbeans.impl.tool.SchemaCompiler "$@" diff --git a/xmlbeans/bin/scomp.cmd b/xmlbeans/bin/scomp.cmd new file mode 100644 index 000000000..e82a9e8e4 --- /dev/null +++ b/xmlbeans/bin/scomp.cmd @@ -0,0 +1,35 @@ +@REM +@REM Copyright 2004 The Apache Software Foundation +@REM +@REM Licensed under the Apache License, Version 2.0 (the "License"); +@REM you may not use this file except in compliance with the License. +@REM You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, software +@REM distributed under the License is distributed on an "AS IS" BASIS, +@REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@REM See the License for the specific language governing permissions and +@REM limitations under the License. +@REM + +@rem Schema compiler +@rem +@rem Builds XBean types from xsd files. + +@echo off + +setlocal +if "%XMLBEANS_LIB%" EQU "" call "%~dp0_setlib" + +set cp= +set cp=%cp%;%XMLBEANS_LIB%\xbean.jar +set cp=%cp%;%XMLBEANS_LIB%\xmlbeans-qname.jar +set cp=%cp%;%XMLBEANS_LIB%\jsr173_1.0_api.jar +set cp=%cp%;%JAVA_HOME%\lib\tools.jar +set cp=%cp%;%XMLBEANS_LIB%\resolver.jar + +java -classpath "%cp%" org.apache.xmlbeans.impl.tool.SchemaCompiler %* + +:done diff --git a/xmlbeans/bin/scopy.cmd b/xmlbeans/bin/scopy.cmd new file mode 100644 index 000000000..ff68c3185 --- /dev/null +++ b/xmlbeans/bin/scopy.cmd @@ -0,0 +1,31 @@ +@REM +@REM Copyright 2004 The Apache Software Foundation +@REM +@REM Licensed under the Apache License, Version 2.0 (the "License"); +@REM you may not use this file except in compliance with the License. +@REM You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, software +@REM distributed under the License is distributed on an "AS IS" BASIS, +@REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@REM See the License for the specific language governing permissions and +@REM limitations under the License. +@REM + +@rem Schema compiler +@rem +@rem Builds XBean types from xsd files. + +@echo off + +setlocal +if "%XMLBEANS_LIB%" EQU "" call "%~dp0_setlib" + +set cp= +set cp=%cp%;%XMLBEANS_LIB%\xbean.jar;%XMLBEANS_LIB%\xmlbeans-qname.jar;%XMLBEANS_LIB%\jsr173_1.0_api.jar + +java -classpath "%cp%" org.apache.xmlbeans.impl.tool.SchemaCopy %* + +:done diff --git a/xmlbeans/bin/sdownload b/xmlbeans/bin/sdownload new file mode 100755 index 000000000..118c717ea --- /dev/null +++ b/xmlbeans/bin/sdownload @@ -0,0 +1,31 @@ +#!/bin/sh +## +## 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. +## + +#Schema downloader +#Tool to download Schema files + +if [ -z "$XMLBEANS_LIB" ]; then . `dirname $0`/_setlib; fi + +cp=$XMLBEANS_LIB/xbean.jar:$XMLBEANS_LIB/xmlbeans-qname.jar:$XMLBEANS_LIB/jsr173_1.0_api.jar + +case "`uname`" in + CYGWIN*) + cp=`cygpath -w -p $cp` + ;; +esac + +java -classpath "$cp" org.apache.xmlbeans.impl.tool.SchemaResourceManager "$@" diff --git a/xmlbeans/bin/sdownload.cmd b/xmlbeans/bin/sdownload.cmd new file mode 100644 index 000000000..3d2b60359 --- /dev/null +++ b/xmlbeans/bin/sdownload.cmd @@ -0,0 +1,34 @@ +@REM +@REM Copyright 2004 The Apache Software Foundation +@REM +@REM Licensed under the Apache License, Version 2.0 (the "License"); +@REM you may not use this file except in compliance with the License. +@REM You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, software +@REM distributed under the License is distributed on an "AS IS" BASIS, +@REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@REM See the License for the specific language governing permissions and +@REM limitations under the License. +@REM + +@rem Schema downloader +@rem +@rem Tool to download schemas. + +@echo off + +setlocal +if "%XMLBEANS_LIB%" EQU "" call "%~dp0_setlib" + +set cp= +set cp=%cp%;%XMLBEANS_LIB%\xbean.jar +set cp=%cp%;%XMLBEANS_LIB%\xmlbeans-qname.jar +set cp=%cp%;%XMLBEANS_LIB%\jsr173_1.0_api.jar +set cp=%cp%;%XMLBEANS_LIB%\resolver.jar + +java -classpath "%cp%" org.apache.xmlbeans.impl.tool.SchemaResourceManager %* + +:done diff --git a/xmlbeans/bin/sfactor b/xmlbeans/bin/sfactor new file mode 100755 index 000000000..0554b5ee7 --- /dev/null +++ b/xmlbeans/bin/sfactor @@ -0,0 +1,34 @@ +#!/bin/sh +## +## 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. +## + +## Schema Factoring tool +## +## Factors redundant definitions out of a set of schemas and +## uses imports instead. + +if [ -z "$XMLBEANS_LIB" ]; then . `dirname $0`/_setlib; fi + +cp=$XMLBEANS_LIB/xbean.jar:$XMLBEANS_LIB/xmlbeans-qname.jar:$XMLBEANS_LIB/jsr173_1.0_api.jar:$XMLBEANS_LIB/resolver.jar + +case "`uname`" in + CYGWIN*) + cp=`cygpath -w -p $cp` + ;; +esac + +java -Xmx256m -classpath "$cp" org.apache.xmlbeans.impl.tool.FactorImports "$@" + diff --git a/xmlbeans/bin/sfactor.cmd b/xmlbeans/bin/sfactor.cmd new file mode 100644 index 000000000..27c632122 --- /dev/null +++ b/xmlbeans/bin/sfactor.cmd @@ -0,0 +1,31 @@ +@REM +@REM Copyright 2004 The Apache Software Foundation +@REM +@REM Licensed under the Apache License, Version 2.0 (the "License"); +@REM you may not use this file except in compliance with the License. +@REM You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, software +@REM distributed under the License is distributed on an "AS IS" BASIS, +@REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@REM See the License for the specific language governing permissions and +@REM limitations under the License. +@REM + +@rem Schema Factoring tool +@rem +@rem Factores redundant definitions out of a set of schemas and uses imports instead. + +@echo off + +setlocal +if "%XMLBEANS_LIB%" EQU "" call "%~dp0_setlib" + +set cp= +set cp=%cp%;%XMLBEANS_LIB%\xbean.jar;%XMLBEANS_LIB%\xmlbeans-qname.jar;%XMLBEANS_LIB%\jsr173_1.0_api.jar;%XMLBEANS_LIB%\resolver.jar; + +java -classpath "%cp%" org.apache.xmlbeans.impl.tool.FactorImports %* + +:done diff --git a/xmlbeans/bin/svalidate b/xmlbeans/bin/svalidate new file mode 100755 index 000000000..13a6ad6b0 --- /dev/null +++ b/xmlbeans/bin/svalidate @@ -0,0 +1,32 @@ +#!/bin/sh +## +## 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. +## +# +# Streaming Instance Validator +# +# Validates an instance against a schema. + +if [ -z "$XMLBEANS_LIB" ]; then . `dirname $0`/_setlib; fi + +cp=$XMLBEANS_LIB/xbean.jar:$XMLBEANS_LIB/xmlbeans-qname.jar:$XMLBEANS_LIB/jsr173_1.0_api.jar:$XMLBEANS_LIB/jsr173_1.0_ri.jar + +case "`uname`" in + CYGWIN*) + cp=`cygpath -w -p $cp` + ;; +esac + +java -classpath "$cp" org.apache.xmlbeans.impl.tool.StreamInstanceValidator "$@" diff --git a/xmlbeans/bin/svalidate.cmd b/xmlbeans/bin/svalidate.cmd new file mode 100644 index 000000000..551a952f3 --- /dev/null +++ b/xmlbeans/bin/svalidate.cmd @@ -0,0 +1,34 @@ +@REM +@REM Copyright 2004 The Apache Software Foundation +@REM +@REM Licensed under the Apache License, Version 2.0 (the "License"); +@REM you may not use this file except in compliance with the License. +@REM You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, software +@REM distributed under the License is distributed on an "AS IS" BASIS, +@REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@REM See the License for the specific language governing permissions and +@REM limitations under the License. +@REM + +@rem Streaming Instance Validator +@rem +@rem Validates an instance against a schema. + +@echo off + +setlocal +if "%XMLBEANS_LIB%" EQU "" call "%~dp0_setlib" + +set cp= +set cp=%cp%;%XMLBEANS_LIB%\xbean.jar +set cp=%cp%;%XMLBEANS_LIB%\xmlbeans-qname.jar +set cp=%cp%;%XMLBEANS_LIB%\jsr173_1.0_api.jar +set cp=%cp%;%XMLBEANS_LIB%\jsr173_1.0_ri.jar + +java -classpath "%cp%" org.apache.xmlbeans.impl.tool.StreamInstanceValidator %* + +:done diff --git a/xmlbeans/bin/validate b/xmlbeans/bin/validate new file mode 100755 index 000000000..62a75fa03 --- /dev/null +++ b/xmlbeans/bin/validate @@ -0,0 +1,32 @@ +#!/bin/sh +## +## 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. +## +# +# Instance Validator +# +# Validates an instance against a schema. + +if [ -z "$XMLBEANS_LIB" ]; then . `dirname $0`/_setlib; fi + +cp=$XMLBEANS_LIB/xbean.jar:$XMLBEANS_LIB/xmlbeans-qname.jar:$XMLBEANS_LIB/jsr173_1.0_api.jar + +case "`uname`" in + CYGWIN*) + cp=`cygpath -w -p $cp` + ;; +esac + +exec java -classpath "$cp" org.apache.xmlbeans.impl.tool.InstanceValidator "$@" diff --git a/xmlbeans/bin/validate.cmd b/xmlbeans/bin/validate.cmd new file mode 100644 index 000000000..d2fc31831 --- /dev/null +++ b/xmlbeans/bin/validate.cmd @@ -0,0 +1,33 @@ +@REM +@REM Copyright 2004 The Apache Software Foundation +@REM +@REM Licensed under the Apache License, Version 2.0 (the "License"); +@REM you may not use this file except in compliance with the License. +@REM You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, software +@REM distributed under the License is distributed on an "AS IS" BASIS, +@REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@REM See the License for the specific language governing permissions and +@REM limitations under the License. +@REM + +@rem Instance Validator +@rem +@rem Validates an instance against a schema. + +@echo off + +setlocal +if "%XMLBEANS_LIB%" EQU "" call "%~dp0_setlib" + +set cp= +set cp=%cp%;%XMLBEANS_LIB%\xbean.jar +set cp=%cp%;%XMLBEANS_LIB%\xmlbeans-qname.jar +set cp=%cp%;%XMLBEANS_LIB%\jsr173_1.0_api.jar + +java -classpath "%cp%" org.apache.xmlbeans.impl.tool.InstanceValidator %* + +:done diff --git a/xmlbeans/bin/xpretty b/xmlbeans/bin/xpretty new file mode 100755 index 000000000..2deb8c674 --- /dev/null +++ b/xmlbeans/bin/xpretty @@ -0,0 +1,30 @@ +#!/bin/sh +## +## 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. +## + +#Invokes pretty printer + +if [ -z "$XMLBEANS_LIB" ]; then . `dirname $0`/_setlib; fi + +cp=$XMLBEANS_LIB/xbean.jar:$XMLBEANS_LIB/xmlbeans-qname.jar:$XMLBEANS_LIB/jsr173_1.0_api.jar + +case "`uname`" in + CYGWIN*) + cp=`cygpath -w -p $cp` + ;; +esac + +java -classpath "$cp" org.apache.xmlbeans.impl.tool.PrettyPrinter "$@" diff --git a/xmlbeans/bin/xpretty.cmd b/xmlbeans/bin/xpretty.cmd new file mode 100644 index 000000000..aa1f5816f --- /dev/null +++ b/xmlbeans/bin/xpretty.cmd @@ -0,0 +1,27 @@ +@REM +@REM Copyright 2004 The Apache Software Foundation +@REM +@REM Licensed under the Apache License, Version 2.0 (the "License"); +@REM you may not use this file except in compliance with the License. +@REM You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, software +@REM distributed under the License is distributed on an "AS IS" BASIS, +@REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@REM See the License for the specific language governing permissions and +@REM limitations under the License. +@REM + +@echo off + +@rem Invokes pretty printer + +setlocal +if "%XMLBEANS_LIB%" EQU "" call "%~dp0_setlib" + +set cp= +set cp=%cp%;%XMLBEANS_LIB%\xbean.jar;%XMLBEANS_LIB%\xmlbeans-qname.jar;%XMLBEANS_LIB%\jsr173_1.0_api.jar + +java -classpath "%cp%" org.apache.xmlbeans.impl.tool.PrettyPrinter %* diff --git a/xmlbeans/bin/xsd2inst b/xmlbeans/bin/xsd2inst new file mode 100755 index 000000000..c3e43f400 --- /dev/null +++ b/xmlbeans/bin/xsd2inst @@ -0,0 +1,30 @@ +#!/bin/sh +## +## 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. +## + +#Schema to instance tool + +if [ -z "$XMLBEANS_LIB" ]; then . `dirname $0`/_setlib; fi + +cp=$XMLBEANS_LIB/xbean.jar:$XMLBEANS_LIB/xmlbeans-qname.jar:$XMLBEANS_LIB/jsr173_1.0_api.jar + +case "`uname`" in + CYGWIN*) + cp=`cygpath -w -p $cp` + ;; +esac + +java -classpath "$cp" org.apache.xmlbeans.impl.xsd2inst.SchemaInstanceGenerator "$@" diff --git a/xmlbeans/bin/xsd2inst.cmd b/xmlbeans/bin/xsd2inst.cmd new file mode 100644 index 000000000..a1a3d48a2 --- /dev/null +++ b/xmlbeans/bin/xsd2inst.cmd @@ -0,0 +1,32 @@ +@REM +@REM Copyright 2004 The Apache Software Foundation +@REM +@REM Licensed under the Apache License, Version 2.0 (the "License"); +@REM you may not use this file except in compliance with the License. +@REM You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, software +@REM distributed under the License is distributed on an "AS IS" BASIS, +@REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@REM See the License for the specific language governing permissions and +@REM limitations under the License. +@REM + +@rem Schema to instance tool +@rem + +@echo off + +setlocal +if "%XMLBEANS_LIB%" EQU "" call "%~dp0_setlib" + +set cp= +set cp=%cp%;%XMLBEANS_LIB%\xbean.jar +set cp=%cp%;%XMLBEANS_LIB%\xmlbeans-qname.jar +set cp=%cp%;%XMLBEANS_LIB%\jsr173_1.0_api.jar + +java -classpath "%cp%" org.apache.xmlbeans.impl.xsd2inst.SchemaInstanceGenerator %* + +:done diff --git a/xmlbeans/bin/xsdtree b/xmlbeans/bin/xsdtree new file mode 100755 index 000000000..03e140b9a --- /dev/null +++ b/xmlbeans/bin/xsdtree @@ -0,0 +1,30 @@ +#!/bin/sh +## +## 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. +## + +# Invokes type hierarchy printer + +if [ -z "$XMLBEANS_LIB" ]; then . `dirname $0`/_setlib; fi + +cp=$XMLBEANS_LIB/xbean.jar:$XMLBEANS_LIB/xmlbeans-qname.jar:$XMLBEANS_LIB/jsr173_1.0_api.jar + +case "`uname`" in + CYGWIN*) + cp=`cygpath -w -p $cp` + ;; +esac + +java -Xmx256m -classpath "$cp" org.apache.xmlbeans.impl.tool.TypeHierarchyPrinter "$@" diff --git a/xmlbeans/bin/xsdtree.cmd b/xmlbeans/bin/xsdtree.cmd new file mode 100644 index 000000000..7ec049722 --- /dev/null +++ b/xmlbeans/bin/xsdtree.cmd @@ -0,0 +1,27 @@ +@REM +@REM Copyright 2004 The Apache Software Foundation +@REM +@REM Licensed under the Apache License, Version 2.0 (the "License"); +@REM you may not use this file except in compliance with the License. +@REM You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, software +@REM distributed under the License is distributed on an "AS IS" BASIS, +@REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@REM See the License for the specific language governing permissions and +@REM limitations under the License. +@REM + +@echo off + +@rem Invokes type hierarchy printer + +setlocal +if "%XMLBEANS_LIB%" EQU "" call "%~dp0_setlib" + +set cp= +set cp=%cp%;%XMLBEANS_LIB%\xbean.jar;%XMLBEANS_LIB%\xmlbeans-qname.jar;%XMLBEANS_LIB%\jsr173_1.0_api.jar; + +java -classpath "%cp%" org.apache.xmlbeans.impl.tool.TypeHierarchyPrinter %* diff --git a/xmlbeans/bin/xstc b/xmlbeans/bin/xstc new file mode 100755 index 000000000..80abf1c29 --- /dev/null +++ b/xmlbeans/bin/xstc @@ -0,0 +1,30 @@ +#!/bin/sh +## +## 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. +## + +# Invokes XSTC + +if [ -z "$XMLBEANS_LIB" ]; then . `dirname $0`/_setlib; fi + +cp=$XMLBEANS_LIB/xbean.jar:$XMLBEANS_LIB/xmlbeans-qname.jar:$XMLBEANS_LIB/jsr173_1.0_api.jar:$XMLBEANS_LIB/resolver.jar + +case "`uname`" in + CYGWIN*) + cp=`cygpath -w -p $cp` + ;; +esac + +java -classpath "$cp" org.apache.xmlbeans.impl.tool.XSTCTester "$@" diff --git a/xmlbeans/bin/xstc.cmd b/xmlbeans/bin/xstc.cmd new file mode 100644 index 000000000..f024a5a9e --- /dev/null +++ b/xmlbeans/bin/xstc.cmd @@ -0,0 +1,30 @@ +@REM +@REM Copyright 2004 The Apache Software Foundation +@REM +@REM Licensed under the Apache License, Version 2.0 (the "License"); +@REM you may not use this file except in compliance with the License. +@REM You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, software +@REM distributed under the License is distributed on an "AS IS" BASIS, +@REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@REM See the License for the specific language governing permissions and +@REM limitations under the License. +@REM + +@echo off + +@rem Invokes XSTC + +setlocal +if "%XMLBEANS_LIB%" EQU "" call "%~dp0_setlib" + +set cp= +set cp=%cp%;%XMLBEANS_LIB%\xbean.jar +set cp=%cp%;%XMLBEANS_LIB%\xmlbeans-qname.jar +set cp=%cp%;%XMLBEANS_LIB%\jsr173_1.0_api.jar +set cp=%cp%;%XMLBEANS_LIB%\resolver.jar + +java -classpath "%cp%" org.apache.xmlbeans.impl.tool.XSTCTester %* diff --git a/xmlbeans/build.xml b/xmlbeans/build.xml new file mode 100644 index 000000000..2505a36dd --- /dev/null +++ b/xmlbeans/build.xml @@ -0,0 +1,1182 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + +
+
+
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/xmlbeans/docs/guide/antXmlbean.html b/xmlbeans/docs/guide/antXmlbean.html new file mode 100644 index 000000000..bc0b228f7 --- /dev/null +++ b/xmlbeans/docs/guide/antXmlbean.html @@ -0,0 +1,346 @@ + + + + + +xmlbean Ant Task + + + + + + + + + + + + + + + + + + + + + +
+

xmlbean Ant Task

+
+
+

Compiles a set of XSD and/or WSDL files into XMLBeans. This is useful for + building an XMLBean JAR from XSD and WSDL files. If desired, the task can + also generate the source code that makes up the XMLBean type system specified + by the schema files.

+

Note: This task depends on two external libraries not + included in the Ant distribution: one called xbean.jar, one called jsr173_1.0_api.jar. + Both can be found in the XMLBeans developer kit at http://xmlbeans.apache.org/. + The build script will need to include a taskdef for xmlbean, which could look + like this:

+
+
+
+
<taskdef name="xmlbean"
classname="org.apache.xmlbeans.impl.tool.XMLBean"
classpath="path/to/xbean.jar:path/to/jsr173_1.0_api.jar" />
+
+
+
+

It is possible to refine the set of files that are being processed. This + can be done with the includes, includesfile, + excludes, excludesfile + and defaultexcludes attributes. With the includes + or includesfile attribute you specify the + files you want to have included by using patterns. The exclude + or excludesfile attributes are used to specify + the files you want to have excluded. This is also done with patterns. And + finally with the defaultexcludes attribute, + you can specify whether you want to use default exclusions or not. See the + section on directory + based tasks in the Ant + documentation, on how the inclusion/exclusion of files works, and how + to write patterns.

+

This task forms an implicit FileSet + and supports all attributes of <fileset> (dir + becomes basedir) as well as the nested <include>, + <exclude> and <patternset> elements.

+

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AttributeDescriptionRequired
schemaA file that points to either an individual schema file + or a directory of files.  Not a path reference.  If multiple + schema files need to be built together, use a nested fileset instead + of setting schema.Yes, unless a fileset element is nested.
destfileDefine the name of the jar file created.  For instance, + "myXMLBean.jar" will output the results of this task into a jar with + the same name.No, default is "xmltypes.jar".
downloadSet to true to permit the compiler to download URLs for + imports and includes.  Defaults to false, meaning all imports and + includes must be copied locally.
No, default is false.
classgendir
Set a location to generate CLASS files into.
No
srconly
A value of true means that only source will be generated.
+
No, default is false.
srcgendir
Set a location to generate JAVA files into.
No
javasource
Generate java source compatible with the given + version. Currently only "1.4" and "1.5" are supported.
No, Default is "1.4"
classpathThe classpath to use if schemas in the fileset import + definitions that are supplied by other compiled XMLBeans JAR files, + or if JAVA files are in the schema fileset. Also supports a nested classpath.No
classpathrefAdds a classpath, given as reference + to a path defined elsewhere.No
includesComma- or space-separated list of patterns of files that + must be included. All files are included when omitted.No
includesfileThe name of a file. Each line of this file is taken to + be an include pattern.No
excludesComma- or space-separated list of patterns of files that + must be excluded. No files (except default excludes) are excluded when + omitted.No
excludesfileThe name of a file. Each line of this file is taken to + be an exclude pattern.No
defaultexcludesIndicates whether default excludes should be used or + not ("yes"/"no"). Default excludes are used when omitted.No
debugIndicates whether source should be compiled with debug + information; defaults to off. If set to off, + -g:none will be passed on the command line for compilers + that support it (for other compilers, no command line argument will + be used). If set to true, the value of the debuglevel + attribute determines the command line argument.No
debuglevelKeyword list to be appended to the -g command-line + switch. This will be ignored by all implementations except modern + and classic(ver >= 1.2). Legal values are none + or a comma-separated list of the following keywords: lines, + vars, and source. If debuglevel + is not specified, by default, nothing will be appended to -g. + If debug is not turned on, this attribute will be ignored. + No
optimizeIndicates whether source should be compiled with optimization; + defaults to off.No
includeAntRuntimeWhether to include the Ant run-time libraries in the + classpath; defaults to yes.No
includeJavaRuntimeWhether to include the default run-time libraries from + the executing VM in the classpath; defaults to no.No
forkWhether to execute javac using the JDK compiler + externally; defaults to yes.No, default is true
executableComplete path to the javac executable to + use in case of fork="yes". Defaults to the compiler + of the Java version that is currently running Ant. Ignored if fork="no"No
memoryInitialSizeThe initial size of the memory for the underlying VM, + if javac is run externally; ignored otherwise. Defaults + to the standard VM memory setting. (Examples: 83886080, + 81920k, or 80m)No
memoryMaximumSizeThe maximum size of the memory for the underlying VM, + if javac is run externally; ignored otherwise. Defaults + to the standard VM memory setting. (Examples: 83886080, + 81920k, or 80m)No
compilerThe compiler implementation to use. If this attribute + is not set, the value of the build.compiler property, if + set, will be used. Otherwise, the default compiler for the current VM + will be used. + No
failonerror Determines whether or not the ant target will continue + if the XMLBean creation encounters a build error.
No, default is true.
verbose
Controls the amount of build message output.
No, default is true.
quiet
Controls the amount of build message output.
No, default is false.
typesystemname
The name of the package that the TypeSystemHolder class + should be generated in.  Normally this should be left unspecified. + None of the XMLBeans are generated in this package. Use .xsdconfig files + to modify XMLBean package or class names.
No
noupaDo not enforce the unique particle attribution rule.
No, default is false.
nopvrDo not enforce the particle valid (restriction) rule.
No, default is false.
noannSkip over schema <annotation> elements
No, default is false.
nopvrDo not validate the contents of schema <documentation> elements.
No, default is false.
ignoreDuplicatesInNamespacesComma separated list of one or more namespaces + in which duplicate definitions are to be ignored. + No
+

Example

+
+
Be sure to define the task in your script, like this:
+
+
<taskdef name="xmlbean"
classname="org.apache.xmlbeans.impl.tool.XMLBean"
classpath="path/to/xbean.jar:path/to/jsr173_1.0_api.jar" />
+

The following builds all the schemas in the schemas directory and creates + a jar called "Schemas.jar". (Note: both xbean.jar and + jsr173_1.0_api.jar must be on the classpath when the task executes).

+
+
+
+<xmlbean schema="schemas" destfile="Schemas.jar"
+    classpath="path/to/xbean.jar:path/to/jsr173_1.0_api.jar" />
+ The following compiles the schema "ourSchema.xsd" into the default + jar "xmltypes.jar".  If  any imports and includes are defined + by remote URLs, they are downloaded during the build. +
+
<xmlbean schema="schemas/ourSchema.xsd" download="true"
classpath="path/to/xbean.jar:path/to/jsr173_1.0_api.jar" />
+
+
+

Using a fileset

+
+
+
<xmlbean classgendir="${build.dir}" classpath="${class.path}"
failonerror="true">
<fileset basedir="src" excludes="**/*.xsd"/>
<fileset basedir="schemas" includes="**/*.*"/>
</xmlbean>
+
+
Gathers all the files in the src directory except XSD files, along with + every file in the schemas directory, and compiles them. The fileset can include + schema files that refer to previously compiled schema components.  The + fileset can also contain JAVA files.  The classpath parameter defines + the classpath necessary to resolve compiled schema and java references (and must include xbean.jar and jsr173_1.0_api.jar).
+
+ The built classes will go into ${build.dir}.
+
+

Related Topics

+

None.

+
+
+ + + diff --git a/xmlbeans/docs/guide/conGettingStartedwithXMLBeans.html b/xmlbeans/docs/guide/conGettingStartedwithXMLBeans.html new file mode 100644 index 000000000..325d5c74f --- /dev/null +++ b/xmlbeans/docs/guide/conGettingStartedwithXMLBeans.html @@ -0,0 +1,531 @@ + + + + + +Getting Started with XMLBeans + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Getting Started with XMLBeans

+
+

XMLBeans provides intuitive ways to handle XML that make it easier for you + to access and manipulate XML data and documents in Java.

+

Characteristics of XMLBeans approach to XML:

+
+
    +
  • +
    It provides a familiar Java object-based view of XML data without losing + access to the original, native XML structure.
    +
  • +
  • +
    The XML's integrity as a document is not lost with XMLBeans. XML-oriented + APIs commonly take the XML apart in order to bind to its parts. With XMLBeans, + the entire XML instance document is handled as a whole. The XML data is + stored in memory as XML. This means that the document order is preserved + as well as the original element content with whitespace.
    +
  • +
  • +
    With types generated from schema, access to XML instances is through + JavaBean-like accessors, with get and set methods.
    +
  • +
  • +
    It is designed with XML schema in mind from the beginning — XMLBeans + supports all XML schema definitions.
    +
  • +
  • Access to XML is fast.
  • +
+
+

The starting point for XMLBeans is XML schema. A schema (contained in an + XSD file) is an XML document that defines a set of rules to which other XML + documents must conform. The XML Schema specification provides a rich data + model that allows you to express sophisticated structure and constraints on + your data. For example, an XML schema can enforce control over how data is + ordered in a document, or constraints on particular values (for example, a + birth date that must be later than 1900). Unfortunately, the ability to enforce + rules like this is typically not available in Java without writing custom + code. XMLBeans honors schema constraints.

+

Note: Where an XML schema defines rules + for an XML document, an XML instance is an XML document that conforms + to the schema.

+

You compile a schema (XSD) file to generate a set of Java interfaces that + mirror the schema. With these types, you process XML instance documents that + conform to the schema. You bind an XML instance document to these types; changes + made through the Java interface change the underlying XML representation.

+

Previous options for handling XML include using XML programming interfaces + (such as DOM or SAX) or an XML marshalling/binding tool (such as JAXB). Because + it lacks strong schema-oriented typing, navigation in a DOM-oriented model + is more tedious and requires an understanding of the complete object model. + JAXB provides support for the XML schema specification, but handles only a + subset of it; XMLBeans supports all of it. Also, by storing the data in memory + as XML, XMLBeans is able to reduce the overhead of marshalling and demarshalling.

+

Accessing XML Using Its Schema

+

To get a glimpse of the kinds of things you can do with XMLBeans, take a + look at an example using XML for a purchase order. The purchase order XML + contains data exchanged by two parties, such as two companies. Both parties + need to be able to rely on a consistent message shape, and a schema specifies + the common ground.

+

Here's what a purchase order XML instance might look like.

+
+<po:purchase-order xmlns:po="http://openuri.org/easypo">
+    <po:customer>
+        <po:name>Gladys Kravitz</po:name>
+        <po:address>Anytown, PA</po:address>
+    </po:customer>
+    <po:date>2003-01-07T14:16:00-05:00</po:date>
+    <po:line-item>
+        <po:description>Burnham's Celestial Handbook, Vol 1</po:description>
+        <po:per-unit-ounces>5</po:per-unit-ounces>
+        <po:price>21.79</po:price>
+        <po:quantity>2</po:quantity>
+    </po:line-item>
+    <po:line-item>
+        <po:description>Burnham's Celestial Handbook, Vol 2</po:description>
+        <po:per-unit-ounces>5</po:per-unit-ounces>
+        <po:price>19.89</po:price>
+        <po:quantity>2</po:quantity>
+    </po:line-item>
+<po:shipper>
+        <po:name>ZipShip</po:name>
+        <po:per-ounce-rate>0.74</po:per-ounce-rate>
+    </po:shipper>
+</po:purchase-order>
+

This XML includes a root element, purchase-order, + that has three kinds of child elements: customer, + date, line-item, + and shipper. An intuitive, object-based view + of this XML would provide an object representing the purchase-order + element, and it would have methods for getting the date and for getting subordinate + objects for customer, line-item, + and shipper elements. Each of the last three + would have its own methods for getting the data inside them as well.

+

Looking at the Schema

+

The following XML is the the schema for the preceding purchase order XML. + It defines the XML's "shape" — what its elements are, what + order they appear in, which are children of which, and so on.

+
+
+
+<xs:schema targetNamespace="http://openuri.org/easypo"
+    xmlns:po="http://openuri.org/easypo"
+    xmlns:xs="http://www.w3.org/2001/XMLSchema"
+    elementFormDefault="qualified">
+
+    <xs:element name="purchase-order">
+        <xs:complexType>
+            <xs:sequence>
+                <xs:element name="customer" type="po:customer"/>
+                <xs:element name="date" type="xs:dateTime"/>
+                <xs:element name="line-item" type="po:line-item" minOccurs="0" maxOccurs="unbounded"/>
+                <xs:element name="shipper" type="po:shipper" minOccurs="0"/>
+            </xs:sequence>
+        </xs:complexType>
+    </xs:element>
+    <xs:complexType name="customer">
+        <xs:sequence>
+            <xs:element name="name" type="xs:string"/>
+            <xs:element name="address" type="xs:string"/>
+        </xs:sequence>
+    </xs:complexType>
+    <xs:complexType name="line-item">
+        <xs:sequence>
+            <xs:element name="description" type="xs:string"/>
+            <xs:element name="per-unit-ounces" type="xs:decimal"/>
+            <xs:element name="price" type="xs:double"/>
+            <xs:element name="quantity" type="xs:int"/>
+        </xs:sequence>
+    </xs:complexType>
+    <xs:complexType name="shipper">
+        <xs:sequence>
+            <xs:element name="name" type="xs:string"/>
+            <xs:element name="per-ounce-rate" type="xs:decimal"/>
+        </xs:sequence>
+    </xs:complexType>
+</xs:schema>
+
+

This schema describes the purchase order XML instance by defining the following:

+
+
    +
  • +
    Definitions for three complex types — customer, line-item, and + shipper. These are the types used for the children of the purchase-order + element. In schema, a complex type is one that defines an element that + may have child elements and attributes. The sequence element nested in + the complex type lists its child elements.
    +

    These are also global types. They are global because they are + at the top level of the schema (in other words, just beneath the schema + root element). This means that they may be referenced from anywhere else + in the schema.

    +
  • +
+
+
+
    +
  • Use of simple types within the complex types. The name, address, and description + elements (among others) are typed as simple types. As it happens, these + are also built-in types. A built-in type (here, one with the "xs" + prefix) is part of the schema specification. (The specification defines + 46 built-in types.)
  • +
  • A global element called purchase-order. This element definition includes + a nested complex type definition that specifies the child elements for a + purchase-order element. Notice that the complex type includes references + to the other complex types defined in this schema.
  • +
+
+

In other words, the schema defines types for the child elements and describes + their position as subordinate to the root element, purchase-order.

+

When you use the XMLBean compiler with an XSD file such as this one, you + generate a JAR file containing the interfaces generated from the schema.

+

Writing Java Code That Uses the Interfaces

+

With the XMLBeans interfaces in your application, you can write code that + uses the new types to handle XML based on the schema. Here's an example that + extracts information about each of the ordered items in the purchase order + XML, counts the items, and calculates a total of their prices. In particular, + look at the use of types generated from the schema and imported as part of + the org.openuri.easypo package.

+

The printItems method receives a File + object containing the purchase order XML file.

+
+package docs.xmlbeans;
+
+import java.io.File;
+import org.apache.xmlbeans.*;
+import org.openuri.easypo.PurchaseOrderDocument;
+import org.openuri.easypo.PurchaseOrder;
+import org.openuri.easypo.LineItem;
+
+public class POHandler
+{
+    public static void printItems(File po) throws Exception
+    {
+        /*
+         * All XMLBeans schema types provide a nested Factory class you can
+         * use to bind XML to the type, or to create new instances of the type.
+         * Note that a "Document" type such as this one is an XMLBeans
+         * construct for representing a global element. It provides a way
+         * for you to get and set the contents of the entire element.
+         *
+         * Also, note that the parse method will only succeed if the
+         * XML you're parsing appears to conform to the schema.
+         */
+        PurchaseOrderDocument poDoc =
+            PurchaseOrderDocument.Factory.parse(po);
+
+        /*
+         * The PurchaseOrder type represents the purchase-order element's
+         * complex type.
+         */
+        PurchaseOrder po = poDoc.getPurchaseOrder();
+
+        /*
+         * When an element may occur more than once as a child element,
+         * the schema compiler will generate methods that refer to an
+         * array of that element. The line-item element is defined with
+         * a maxOccurs attribute value of "unbounded", meaning that
+         * it may occur as many times in an instance document as needed.
+         * So there are methods such as getLineItemArray and setLineItemArray.
+         */
+        LineItem[] lineitems = po.getLineItemArray();
+        System.out.println("Purchase order has " + lineitems.length + " line items.");
+
+        double totalAmount = 0.0;
+        int numberOfItems = 0;
+
+        /*
+         * Loop through the line-item elements, using generated accessors to
+         * get values for child elements such a description, quantity, and
+         * price.
+         */
+        for (int j = 0; j < lineitems.length; j++)
+        {
+            System.out.println(" Line item: " + j);
+            System.out.println(
+                "   Description: " + lineitems[j].getDescription());
+            System.out.println("   Quantity: " + lineitems[j].getQuantity());
+            System.out.println("   Price: " + lineitems[j].getPrice());
+            numberOfItems += lineitems[j].getQuantity();
+            totalAmount += lineitems[j].getPrice() * lineitems[j].getQuantity();
+        }
+        System.out.println("Total items: " + numberOfItems);
+        System.out.println("Total amount: " + totalAmount);
+    }
+}
+
+

Notice that types generated from the schema reflect what's in the XML:

+
+
    +
  • +
    A PurchaseOrderDocument represents the + global root element.
    +
  • +
  • +
    A getPurchaseOrder method returns a PurchaseOrderDocument.PurchaseOrder + type that contains child elements, including line-item. + A getLineItemArray method returns a LineItem + array containing the line-item elements.
    +
  • +
  • Other methods, such as getQuantity, getPrice, + and so on, follow naturally from what the schema describes, returning corresponding + children of the line-item element.
  • +
  • The name of the package containing these types is derived from the schema's + target namespace.
  • +
+
+

Capitalization and punctuation for generated type names follow Java convention. + Also, while this example parses the XML from a file, other parse + methods support a Java InputStream object, + a Reader object, and so on.

+

The preceding Java code prints the following to the console:

+
+
+
+Purchase order has 3 line items.
+ Line item 0
+   Description: Burnham's Celestial Handbook, Vol 1
+   Quantity: 2
+   Price: 21.79
+ Line item 1
+   Description: Burnham's Celestial Handbook, Vol 2
+   Quantity: 2
+   Price: 19.89
+Total items: 4
+Total amount: 41.68
+

Creating New XML Instances from Schema

+

As you've seen XMLBeans provides a "factory" class you can use + to create new instances. The following example creates a new purchase-order + element and adds a customer child element. + It then inserts name and address + child elements, creating the elements and setting their values with a single + call to their set methods.

+
+public PurchaseOrderDocument createPO()
+{
+    PurchaseOrderDocument newPODoc = PurchaseOrderDocument.Factory.newInstance();
+    PurchaseOrder newPO = newPODoc.addNewPurchaseOrder();
+    Customer newCustomer = newPO.addNewCustomer();
+    newCustomer.setName("Doris Kravitz");
+    newCustomer.setAddress("Bellflower, CA");
+    return newPODoc;
+}
+
+

The following is the XML that results. Note that XMLBeans assigns the correct + namespace based on the schema, using an "ns1" (or, "namespace + 1") prefix. For practical purposes, the prefix itself doesn't really + matter — it's the namespace URI (http://openuri.org/easypo) that defines + the namespace. The prefix is merely a marker that represents it.

+
<ns1:purchase-order xmlns:ns1="http://openuri.org/easypo">
+    <ns1:customer>
+        <ns1:name>Doris Kravitz</ns1:name>
+        <ns1:address>Bellflower, CA</ns1:address>
+    </ns1:customer>
+</ns1:purchase-order>
+
+

Note that all types (including those generated from schema) inherit from + XmlObject, and so provide a Factory + class. For an overview of the type system in which XmlObject + fits, see XMLBeans Support + for Built-In Schema Types. For reference information, see XmlObject + Interface.

+

XMLBeans Hierarchy

+

The generated types you saw used in the preceding example are actually part + of a hierarchy of XMLBeans types. This hierarchy is one of the ways in which + XMLBeans presents an intuitive view of schema. At the top of the hierarchy + is XmlObject, the base interface for XMLBeans + types. Beneath this level, there are two main type categories: generated types + that represent user-derived schema types, and included types that represent + built-in schema types.

+ This topic has already introduced generated types. For more information, see + Java Types Generated from + User-Derived Schema Types. +

Built-In Type Support

+

In addition to types generated from a given schema, XMLBeans provides 46 + Java types that mirror the 46 built-in types defined by the XML schema specification. + Where schema defines xs:string, xs:decimal, + and xs:int, for example, XMLBeans provides + XmlString, + XmlDecimal, + and XmlInt. + Each of these also inherits from XmlObject, + which corresponds to the built-in schema type xs:anyType.

+

XMLBeans provides a way for you to handle XML data as these built-in types. + Where your schema includes an element whose type is, for example, xs:int, + XMLBeans will provide a generated method designed to return an XmlInt. + In addition, as you saw in the preceding example, for most types there will + also be a method that returns a natural Java type such as int. + The following two lines of code return the quantity + element's value, but return it as different types.

+
+// Methods that return simple types begin with an "x".
+XmlInt xmlQuantity = lineitems[j].xgetQuantity();
+// Methods that return a natural Java type are unadorned.
+int javaQuantity = lineitems[j].getQuantity();
+
+

In a sense both get methods navigate to the quantity + element; the getQuantity method goes a step + further and converts the elements value to the most appropriate natural Java + type before returning it. (XMLBeans also provides a means for validating the + XML as you work with it.)

+

If you know a bit about XML schema, XMLBeans types should seem fairly intuitive. + If you don't, you'll learn a lot by experimenting with XMLBeans using your + own schemas and XML instances based on them.

+

For more information on the methods of types generated from schema, see Methods + for Types Generated From Schema. For more about the how XMLBeans represents + built-in schema types, see XMLBeans + Support for Built-In Schema Types.

+

Using XQuery Expressions

+

With XMLBeans you can use XQuery to query XML for specific pieces of data. + XQuery is sometimes referred to as "SQL for XML" because it provides + a mechanism to access data directly from XML documents, much as SQL provides + a mechanism for accessing data in traditional databases.

+

XQuery borrows some of its syntax from XPath, a syntax for specifying nested + data in XML. The following example returns all of the line-item + elements whose price child elements have values + less than or equal to 20.00:

+
+PurchaseOrderDocument doc = PurchaseOrderDocument.Factory.parse(po);
+
+/*
+ * The XQuery expression is the following two strings combined. They're
+ * declared separately here for convenience. The first string declares
+ * the namespace prefix that's used in the query expression; the second
+ * declares the expression itself.
+ */
+String nsText = "declare namespace po = 'http://openuri.org/easypo'; ";
+String pathText = "$this/po:purchase-order/po:line-item[po:price <= 20.00]";
+String queryText = nsText + pathText;
+
+XmlCursor itemCursor = doc.newCursor().execQuery(queryText);
+System.out.println(itemCursor.xmlText());
+
+

This code creates a new cursor at the start of the document. From there, + it uses the XmlCursor interface's execQuery + method to execute the query expression. In this example, the method's parameter + is an XQuery expression that simply says, "From my current location, + navigate through the purchase-order element + and retrieve those line-item elements whose + value is less than or equal to 20.00." The $this + variable means "the current position."

+

For more information about XQuery, see XQuery + 1.0: An XML Query Language at the W3C web site.

+

Using XML Cursors

+

In the preceding example you may have noticed the XmlCursor + interface. In addition to providing a way to execute XQuery expression, an + XML cursors offers a fine-grained model for manipulating data. The XML cursor + API, analogous to the DOM's object API, is simply a way to point at a particular + piece of data. So, just like a cursor helps navigate through a word processing + document, the XML cursor defines a location in XML where you can perform actions + on the selected XML.

+

Cursors are ideal for moving through an XML document when there's no schema + available. Once you've got the cursor at the location you're interested in, + you can perform a variety of operations with it. For example, you can set + and get values, insert and remove fragments of XML, copy fragments of XML + to other parts of the document, and make other fine-grained changes to the + XML document.

+

The following example uses an XML cursor to navigate to the customer + element's name child element.

+
+PurchaseOrderDocument doc =
+    PurchaseOrderDocument.Factory.parse(po);
+
+XmlCursor cursor = doc.newCursor();
+cursor.toFirstContentToken();
+cursor.toFirstChildElement();
+cursor.toFirstChildElement();
+System.out.println(cursor.getText());
+
+cursor.dispose();
+
+

What's happening here? As with the earlier example, the code loads the XML + from a File object. After loading the document, + the code creates a cursor at its beginning. Moving the cursor a few times + takes it to the nested name element. Once + there, the getText method retrieves the element's value.

+

This is just an introduction to XML cursors. For more information about using + cursors, see Navigating XML with + Cursors.

+

Where to Go Next

+
+
    +
  • +
    XMLBeans provides intuitive ways to handle XML, particularly if you're + starting with schema. If you're accessing XML that's based on a schema, + you'll probably find it most efficient to access the XML through generated + types specific to the schema. To do this, you begin by compiling the schema + to generate interfaces. For more information on using XMLBeans types generated + by compiling schema, see Java + Types Generated From User-Derived Schema Types and Methods + for Types Generated From Schema.
    +
  • +
  • +
    You might be interested in reading more about the type system on which + XMLBeans is based, particularly if you're using types generated from schema. + XMLBeans provides a hierarchical system of types that mirror what you find + in the XML schema specification itself. If you're working with schema, you + might find it helps to understand how these types work. For more information, + see XMLBeans Support + for Built-In Schema Types and Introduction + to Schema Type Signatures.
    +
  • +
  • +
    XMLBeans provides access to XML through XQuery, which borrows path syntax + from XPath. With XQuery, you can specify specific fragments of XML data + with or without schema. To learn more about using XQuery and XPath in XMLBeans, + see Selecting XML with + XQuery and XPath.
    +
  • +
  • You can use the XmlCursor interface for + fine-grained navigation and manipulation of XML. For more information, see + Navigating XML with Cursors.
  • +
+
+

Note: The xbean.jar file that contains + the XMLBeans library is fully functional as a standalone library.

+

Related Topics

+

XMLBeans Samples

+
+ + + + diff --git a/xmlbeans/docs/guide/conHandlingAny.html b/xmlbeans/docs/guide/conHandlingAny.html new file mode 100644 index 000000000..72e58e238 --- /dev/null +++ b/xmlbeans/docs/guide/conHandlingAny.html @@ -0,0 +1 @@ + Handling xs:any with the XMLBeans API

Handling xs:any with the XMLBeans API

Compiling schema for use with XMLBeans generates a kind of custom API specific to your schema. This API includes types with accessors designed to get and set parts of the XML defined by the schema. But if you've compiled schema that includes xs:any particles, you may have noticed that XMLBeans doesn't generate accessors for these these particles.

For example, imagine the accessors generated by compiling the following schema snippet:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns="http://xmlbeans.apache.org/samples/any"
    targetNamespace="http://xmlbeans.apache.org/samples/any" elementFormDefault="qualified">
    <xs:element name="root">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="stringelement"/>
                <xs:any processContents="lax"/>
                <xs:element name="arrayofany">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:any namespace="##any" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:element name="stringelement" type="xs:string"/>    
    <xs:complexType name="ListOfStrings">
        <xs:sequence>
            <xs:element ref="stringelement" minOccurs="0" maxOccurs="unbounded"/>
        </xs:sequence>
        <xs:attribute name="id" type="xs:string"/>
    </xs:complexType>
</xs:schema>

After compilation, you'd have the follow methods for Root, the type that gives you access to the <root> element:

addNewArrayofany()

getArrayofany()

getStringelement()

setArrayofany(Arrayofany)

setStringelement(String)

xgetStringelement()

xsetStringelement(XmlString)

What's missing? There's no getAny or setAny. How do you get or set the <root> element's second child? As it turns out, you do this by leaving behind (at least for a moment) JavaBeans-style accessors, and picking up any of a number of tools the API provides. These tools include:

Using Cursors to Add XML

As described in Navigating XML with Cursors, with an XmlCursor instance you can traverse your XML instance's full infoset. A cursor views XML as tokens, and you move a cursor from one token to another as if they were cars in a train.

The following example illustrates how you might, in the course of building out the <root> document, create a second child element <anyfoo> where schema specifies xs:any. You add the element by creating it with a cursor, then (in lieu of a setter) using the XmlCursor.copyXml or XmlCursor.moveXml method to put the element where it needs to go.

// Start by creating a <root> element that will contain
// the children built by this code.
RootDocument rootDoc = RootDocument.Factory.newInstance();
RootDocument.Root root = rootDoc.addNewRoot();

// Add the first element, <stringelement>.
root.setStringelement("some text");

// Create an XmlObject in which to build the second
// element in the sequence, <anyfoo>. Here, the 
// XmlObject instance is simply a kind of incubator
// for the XML. Later the XML will be moved into the
// document this code is building.
XmlObject anyFoo = XmlObject.Factory.newInstance();

// Add a cursor to do the work of building the XML.
XmlCursor anyFooCursor = anyFoo.newCursor();
anyFooCursor.toNextToken();

// Add the element in the schema's namespace, then add
// element content.
anyFooCursor.beginElement(new QName(m_namespaceUri, "anyfoo"));
anyFooCursor.insertChars("some text");

// Move the cursor back to the new element's top, where 
// it can grab all of the element's XML.
anyFooCursor.toStartDoc();
anyFooCursor.toNextToken();

// Finally, move the XML into the <root> document by moving it
// from a position at one cursor to a position at
// another.
XmlCursor rootCursor = root.newCursor();
rootCursor.toEndToken();
anyFooCursor.moveXml(rootCursor);

You might find that this build-and-move-cursor-to-cursor pattern is common when you're creating or moving XML when accessors aren't available. For example, you could do the same sort of thing when your schema defines a type that you want to place into an xs:any space in an instance. The following code adds a <stringelement> element as a child of the <arrayofany> element, which schema defines as containing a sequence of xs:any particles. The <stringlement> element is simple, but it could just as easily be a complex schema type.

// Create a simple <stringelement>.
StringelementDocument stringElementDoc = 
    StringelementDocument.Factory.newInstance();        
stringElementDoc.setStringelement("some text");
XmlCursor stringElementCursor = stringElementDoc.newCursor();
stringElementCursor.toFirstContentToken();

// Add a cursor to mark the position to which the new child 
// XML will be moved.
XmlCursor arrayCursor = arrayOfAny.newCursor();
arrayCursor.toNextToken();

// Move the new <stringelement> into place.
stringElementCursor.moveXml(arrayCursor);
stringElementCursor.dispose();

Using XPath and the selectPath Method to Find XML

XPath is a convenient, direct way to get at specific chunks of XML. In the XMLBeans API, you execute XPath expressions with the XmlObject.selectPath or XmlCursor.selectPath methods. The example in Java below assumes the following instance conforming to the schema introduced at the beginning of this topic:

<root xmlns="http://xmlbeans.apache.org/samples/any">
    <stringelement>some text</stringelement>
    <anyfoo>some text</anyfoo>
    <arrayofany>
        <stringelement>some text</stringelement>
        <someelement>
            <stringlist id="001">
                <stringelement>string1</stringelement>
                <stringelement>string2</stringelement>
            </stringlist>
        </someelement>
    </arrayofany>
</root>

The following code uses XPath to reach the <stringelement> element because there is no accessor available. It then shifts the XML around a little, moving <stringelement> up in the hierarchy to replace its parent, <someelement>.

public boolean editExistingDocWithSelectPath(RootDocument rootDoc)
{
    String namespaceUri = "http://xmlbeans.apache.org/samples/any";

    // Put a cursor at the top of the <arrayofany> element.
    XmlCursor selectionCursor = rootDoc.getRoot().getArrayofany().newCursor();

    // Use XPath and cursor movement to position the cursor at
    // the <stringlist> element.
    String namespaceDecl = "declare namespace any='" + namespaceUri + "'; ";
    selectionCursor.selectPath(namespaceDecl + 
        "$this//any:someelement/any:stringlist");
    selectionCursor.toNextSelection();

    // Create a new cursor at the same location and move it to 
    // <stringelement>'s <someelement> parent.
    XmlCursor editCursor = selectionCursor.newCursor();
    editCursor.toParent();

    // Move the <stringelement> element to this position, displacing 
    // the <someelement> downward. Remove the <someelement> XML, 
    // effectively replacing <someelement> with <stringlist>.
    selectionCursor.moveXml(editCursor);
    editCursor.removeXml();
    editCursor.dispose();

    return rootDoc.validate();
}

Using the selectChildren Method to Find XML

The XmlObject.selectChildren method you can retrieve an array of the child elements of a specified name. The method is overloaded to take java.xml.namespace.QName instances or strings as parameters. The following code (based on the instance used in the preceding example) simply finds the <anyfoo> element, an xs:any, and replaces it with an <anybar> element.

public boolean editExistingDocWithSelectChildren(RootDocument rootDoc)
{
    String namespaceUri = "http://xmlbeans.apache.org/samples/any";
    RootDocument.Root root = rootDoc.getRoot();
        
    // Select the <anyfoo> children of <root>.
    XmlObject[] stringElements =
        root.selectChildren(new QName(m_namespaceUri, "anyfoo"));

    // If the element is there, replace it with another element.
    if (stringElements.length > 0)
    {
        XmlCursor editCursor = stringElements[0].newCursor();
        editCursor.removeXml();
        editCursor.beginElement(new QName(namespaceUri, "anybar"));
        editCursor.insertChars("some other text");                
        editCursor.dispose();
    }
    return rootDoc.validate();
}

Using the DOM API to Find XML

Through the getDomNode method (exposed by XmlObject and types generated from schema), you can get a live DOM node representing your XML. For example, calling myElement.getDomNode() will return a org.w3c.dom.Node instance representing the XML bound to myElement. If you're already familiar with DOM-style access to XML, this can be a familiar alternative for handling xs:any instances.

Using the instance introduced earlier in this topic, the following example adds a new <bar> element between the first and second children of the <arrayofany> element. The code also ensures that the first and second children are <stringelement> and <someelement>, respectively.

public boolean editExistingDocWithDOM(RootDocument rootDoc)
{
    RootDocument.Root root = rootDoc.getRoot();
        
    // Get the DOM nodes for the <arrayofany> element's children.
    Node arrayOfAnyNode = root.getArrayofany().getDomNode();

    // You don't have get* accessors for any of the <arrayofany> 
    // element's children, so use DOM to identify the first
    // and second elements while looping through the child list.
    NodeList childList = arrayOfAnyNode.getChildNodes();
    Element firstElementChild = null;
    Element secondElementChild = null;

    // Find the first child element and make sure it's
    // <stringelement>.
    for (int i = 0; i < childList.getLength(); i++)
    {
        Node node = childList.item(i);
        if (node.getNodeType() == Node.ELEMENT_NODE)
        {
            if (node.getLocalName().equals("stringelement"))
            {
                firstElementChild = (Element)node;                
                break;
            }
        }
    }
    if (firstElementChild == null) {return false;}

    // Find the second child element and make sure it's
    // <someelement>.
    Node node = firstElementChild.getNextSibling();
    do 
	{
        if (node.getNodeType() == Node.ELEMENT_NODE)
        {
            if (node.getLocalName().equals("someelement"))
            {
                secondElementChild = (Element)node;
                break;
            }
        }
        node = node.getNextSibling();
    } while (node != null);
    if (secondElementChild == null) {return false;}
    
    // Create and insert a new <bar> element.
    Element fooElement = 
        secondElementChild.getOwnerDocument().createElementNS("http://openuri.org","bar");
    Node valueNode = 
        fooElement.getOwnerDocument().createTextNode("some text");
    fooElement.appendChild(valueNode);
    arrayOfAnyNode.insertBefore(fooElement, secondElementChild);
    
    return rootDoc.validate();
}

Related Topics

Getting Started with XMLBeans

\ No newline at end of file diff --git a/xmlbeans/docs/guide/conIntroToTheSchemaTypeSystem.html b/xmlbeans/docs/guide/conIntroToTheSchemaTypeSystem.html new file mode 100644 index 000000000..bd0f20673 --- /dev/null +++ b/xmlbeans/docs/guide/conIntroToTheSchemaTypeSystem.html @@ -0,0 +1,229 @@ + + + + + + +Introduction to Schema Type Signatures + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Introduction to Schema Type Signatures

+
+

When you compile schema, the API generated from your schema is integrated + with the XMLBeans type system that represents the underlying XML schema. All + together, these types make up the schema type system to which your + code has access. When handling XML based on the schema, you typically call + methods of the API generated when you compiled the schema. However, for the + cases when you want to get information about the schema itself, you use the + schema type system API.

+

In the XMLBeans API, you have access to the system itself through SchemaTypeSystem + and related classes. These make up a kind of "meta-API," or a view + on the schema. You can use the schema type system API to discover the type + system at run time. See the reference topic on that interface for an overview + of the schema type system.

+

Schema Type "Signatures"

+

A schema is made up of schema components. Schema components are the pieces + of a schema, such as a type definition, an element declaration, attribute + declaration, and so on. To mirror these in the schema type system, a SchemaComponent + instance represents a component in the underlying schema; separate components + have corresponding types. For example you would have a SchemaType + object for a CustomerType your schema defined, + or a SchemaGlobalElement + object for a global PurchaseOrder element. + You would also have a SchemaType for built-in + schema types, such as xs:string or xs:datetime. + XMLBean provides a "signature" to describe each type. You can retrieve + this signature by calling the SchemaType class's toString + method.

+

The toString method returns XMLBeans' version + of a unique signature for a schema type. This string is useful for debugging + because it describes a given type even when the type doesn't have a name. +

+

Note: It's important to remember that this + signature is an XMLBeans convention, rather than a standard from the schema + working group. The working group has not yet standardized a signature for + XML schema types. As a result the signature you'll see from XMLBeans is subject + to change — whatever the schema working group comes up with in the end + (if anything) is probably what will be used by this API. In other words, don't + write a program to decode the signature.

+

You can use the following description to understand how a signature is constructed.

+
+
    +
  • +
    Global types. If the type has a name, it's a global + type. The following form is used:
    +
    +
    +
    T=<localname>@<targetNamespace>
    +
    +
    +

    The "T" is for "type," of course. "localname" + is a convention used by qnames (qualified names), which include a local + name and the namespace URI (if any). So an example might be:

    +
    T=customer@openuri.org
    +
  • +
  • Document types and global attribute types. These correspond + to a special anonymous type containing one global element or attribute. These + special types are generated by XMLBeans to represent global types declared + with the <element> or <attribute> tag in schema. Because such + types are types, but are declared as elements or attributes, they require + special treatment. The following signature form is used: +
    +
    +D=<document-element-name>@<targetNamespace>
    +R=<attribute-type-name>@<targetNamespace>
    +
    +
    +
    +
    +
    Note that these are also the signatures of a type returned by a FooDocument.type + or FooAttribute.type method call.
    +
    +
  • +
  • Anonymous types. If the type is anonymous, it is defined + as an element or attribute, or within a further anonymous type. In this case, + the signature is built by establishing the local context (in order words, + what is the anonymous type nested in?). From the local context, the larger + context is built recursively. In other words, the signature is built by giving + not only the anonymous type itself, but also by describing its context. +

    The following rules are used for building a signature for an anonymous + type.

    +
      +
    • It might be an anonymous type defined inside a local element or attribute, + which in turn is defined within something else: +

      If the element is form="qualified" + (the usual default):

      +
    • +
    +
  • +
    +
    +
    E=<eltname>|<signature of the type within which the elt is defined>
    +
    +
    If the element is form="unqualified":
    +
    +
    U=<eltname>|<signature of the type within which the elt is defined>
    +
    +
    If the attribute is form="unqualified" + (the usual default):
    +
    +
    A=<attrname>|<signature of the type within the attr is defined>
    +
    +
    if the attribute is form="qualified":
    +
    +
    Q=<attrname>|<signature of the type within the attr is defined>
    +
    +
    +
      +
    • It might be an anonymous type defined a simple restriction, union, or + list definition:
    • +
    +
    +
    +
    M=#|<signature of the containing union type>
    +

    (The # is a number indicating which union member it is, by source order + — such as 0,1,2, etc.)

    +
    B=|<signature of the containing base type for a restriction>
    +
    I=|<signature of the containing list type>
    +
    +
    +
      +
    • +
      In the future if anonymous types are allowed in some other context, + there may be more codes.
      +
    • +
    +
+

An Example

+

So, for example, if you have a type that describes the list items within an + attribute of an instance that looks like this:

+
+
+
 <root mylist="432 999 143 123"/>
+
+
+
The schema, if done with lots of nested types, could look something like + this:
+
+
+
+<schema targetNamespace="myNamespace" elementFormDefault="qualified">
+    <element name="root">
+        <complexType>
+            <attribute name="mylist">
+                <simpleType>
+                    <list>
+                        <simpleType> <!--This is the type that the signature is for -->
+                            <restriction base="xs:nonNegativeInteger">
+                                <totalDigits value="3"/>..
+
+
+
+
The signature for the simpleType indicated in the example would be:
+
+
I=|A=mylist|E=root|D=root@myNamespace
+
+
+

You could read this as:

+
+
+
"The type of the list item | within the type of the mylist attribute's + type | within the type of the root element | within the document type for + <root> documents | in the myNamespace namespace".
+
+
+

Note that the signature structure mirrors the Java class structure generated + by XMLBeans when compiling the schema. In other words, if you were to compile + a schema that included the preceding snippet, you would be able to access + an instance of the schema with Java code like the following:

+
SchemaType sType = RootDocument.Root.MyList.Item.type;
+
+

Related Topics

+

Getting Started with XMLBeans

+ + + + diff --git a/xmlbeans/docs/guide/conJavaTypesGeneratedFromUserDerived.html b/xmlbeans/docs/guide/conJavaTypesGeneratedFromUserDerived.html new file mode 100644 index 000000000..40d2274fa --- /dev/null +++ b/xmlbeans/docs/guide/conJavaTypesGeneratedFromUserDerived.html @@ -0,0 +1,471 @@ + + + + + + +Java Types Generated from Schema + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Java Types Generated from User-Derived Schema Types

+
+

When you compile XML schema, the resulting API is made up of two categories + of types: built-in types that mirror those in the schema specification and + others that are generated from user-derived schema types. This topic provides + an overview of the Java types generated for user-derived types, describing + the methods the Java types provide. For more information about built-in types, + see XMLBeans Support for + Built-In Schema Types. For specific information about the methods exposed + by generated types, see Methods + for Generated Java Types.

+

In general, an API generated from schema is an intuitive means to access + XML instances based on the schema. You'll probably find that for most uses + it's unnecessary to know the rules for generating it in order to use it. However, + for those cases when it's unclear what's going on behind the scenes (or if + you're just curious), this topic describes the rules.

+

Note: The XMLBeans API also provides a + way for you to get information about the type system itself — + in other words, about the API and the underlying schema. For more information, + see Introduction to Schema Type + Signatures.

+

Each of the types generated when you compile a schema is designed specifically + for access to XML instances conforming to that part of the schema. Start by + taking a look at a simple XML and schema example. The following schema describes + an XML document to contain a stock price quote.

+
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
+    <xs:element name="price-quote">
+        <xs:complexType>
+            <xs:sequence>
+                <xs:element name="stock-symbol" type="xs:string"/>
+                <xs:element name="stock-price" type="xs:float"/>
+            </xs:sequence>
+        </xs:complexType>
+    </xs:element>
+</xs:schema>
+
+

The following is an example of XML that conforms to this schema.

+
<price-quote>
+    <stock-symbol>BEAS</stock-symbol>
+    <stock-price>59.21</stock-price>
+</price-quote>
+

When you compile this schema, you get two generated XMLBeans interfaces: + PriceQuoteDocument and PriceQuoteDocument.PriceQuote.

+

From the schema point of view, the generated PriceQuote + interface represents the complex type you see inside the schema's + price-quote element declaration. Looking at + the XML instance, you can see that this complex type translates into a sequence + of two elements, stock-symbol and stock-price. + So it's not surprising that the PriceQuote + interface exposes methods such as getStockPrice + and setStockPrice to set the value stock-price + element.

+

The PriceQuoteDocument interface, on the + other hand, represents the price-quote document + that contains the root price-quote element. + XMLBeans creates a special "document" type for global element types. + A document type provides a way for you to get and set the value of the underlying + type, here represented by PriceQuote. The + price-quote element is considered a global + element because it can be referenced from anywhere else in the schema. For + global elements, the XMLBeans schema compiler generates an interface whose + name ends with "Document." This is because an XML schema has no + way of defining a "root" element; any global element can be the + root.

+

The following bit of Java code illustrates how you might use these interfaces + to get the stock price contained in the XML.

+
+public static float getStockPrice(java.io.File orderXML) throws Exception
+{
+    PriceQuoteDocument docXML = PriceQuoteDocument.Factory.parse(orderXML);
+    PriceQuote quoteXML = docXML.getPriceQuote();
+    float stockPrice = quoteXML.getStockPrice();
+    return stockPrice;
+}
+
+

This code loads the XML from a File object, + converting the parse method's return value + to a PriceQuoteDocument instance. It then + uses this instance to get an instance of PriceQuote. + With PriceQuote, the code extracts the stock + price.

+
+
+
+

The XML schema specification provides a rich set of rules through which + you can derive new types. When you generate interfaces from your schema, + XMLBeans uses the schema's rules to determine how to generate interfaces. + The following describes some of the guidelines by which this is done.

+

Names for Interfaces

+

Interfaces are generated for schema types (both simple and complex). Anonymous + schema types result in inner interfaces inside the type interface in which + they are defined. Their name comes from the element or attribute in which + they is defined.

+

Names for schema types become Java-friendly names when the schema is compiled. + In other words, names such as "price-quote" become "PriceQuote." In addition, + a schema's XML namespace URIs become package names for XMLBean types generated + from the schema. The way this name translation is done is described by section + C of the Java API for XML Binding (JAXB) specification at + http://java.sun.com/xml/jaxb.html.

+

Here are a few examples:

+ + + + + + + + + + + + + + + + + + + + + +
Schema Target NamespaceXML LocalnameFully-Qualified XMLBean Type Name
http://www.mycompany.com/2002/buyerpurchase-order-4com.mycompany.x2002.buyer.PurchaseOrder4
http://myco.com/sample.htmlSampleDocumentcom.myco.sample.SampleDocument
http://openuri.org/test_case_1test_typeorg.openuri.testCase1.TestType
+

When there are name collisions, the generated types will have names with + numerals appended — for example, "TestType2".

+

Global Elements and Attributes

+

In schema, global element and attribute definitions are those that are + declared at the top level of the schema (that is, immediately within the + schema root element). Because they are global, + they may be referenced from inside the schema by name. The creditReport + (not the creditReportType complex type) + element defined in the following schema is an example.

+
+<xs:schema targetNamespace="http://openuri.org/samples/creditReport"
+    xmlns:cr="http://openuri.org/samples/creditReport"
+    xmlns:xs="http://www.w3.org/2001/XMLSchema"
+    elementFormDefault="qualified"
+    attributeFormDefault="unqualified">
+    <xs:complexType name="creditReportType">
+        <xs:sequence>
+            <xs:element name="bankReport" type="xs:string"/>
+            <xs:element name="taxReport" type="xs:string"/>
+        </xs:sequence>
+    </xs:complexType>
+    <xs:element name="creditReport" type="cr:creditReportType"/>
+</xs:schema>
+

XMLBeans generates a separate interface for each of these. Also, global + element and attribute types are somewhat unique in that the schema compiler + will create special types to hold the globally defined element or attribute. + The names of these types will be appended with "Document" (for + elements) or "Attribute" (for attributes). You can retrieve the + element or attribute itself (or create a new one) by calling the accessor + methods that the special types provide. The following example would create + a new instance of the creditReport element.

+
+// Create an instance of the special document type.
+CreditReportDocument reportDoc = CreditReportDocument.Factory.newInstance();
+/*
+ * Use the document type to add a new creditReport element to the XML instance.
+ * Note that the type returned by the addNewCreditReport method is the
+ * creditReportType complex type defined for it in schema.
+ */
+CreditReportType report = reportDoc.addNewCreditReport();
+
+

Global User-Derived Types

+

A user-derived type is one defined with a complexType + or simpleType element in schema. User-derived + types at the top level of a schema are global. XMLBeans generates an interface + for each of these, as it does with global elements and attributes. These + interfaces include methods through which you can get and set the type's + values, including any nested derived types it may contain. The following + schema snippet defines a user-derived complex type called itemType, + along with a priceType that uses it as the + type for an item child element.

+
+<xs:complexType name="itemType">
+    <xs:sequence>
+        <xs:element name="name" type="xs:string"/>
+        <xs:element name="amount" type="xs:int"/>
+        <xs:element name="price" type="xs:double"/>
+    </xs:sequence>
+</xs:complexType>
+<xs:complexType name="priceType">
+    <xs:sequence>
+        <xs:element name="item" type="ps:itemType" minOccurs="0" maxOccurs="unbounded"/>
+    </xs:sequence>
+</xs:complexType>
+<xs:element name="price" type="ps:priceType"/>
+
+

By default, the generated Java type for itemType + would be an interface called ItemType. With + this type, you would be able to get and set the values of its name, + amount, and price + child elements. However, a user-derived type (as opposed to an element or + attribute) is always intended for use as the type to which an element or + attribute is bound. In other words, it's contained by an element or attribute. + While you can create a new instance of a user-derived type, the new instance's + underlying XML is a fragment. As the generated API would make clear, the + itemType becomes the return type of a get + method, or the parameter of a set method.

+
+// Create a new price document.
+PriceDocument priceDoc = PriceDocument.Factory.newInstance();
+PriceType price = priceDoc.getPrice();
+
+/*
+ * Create a new instance of ItemType and set the values of its
+ * child elements.
+ */
+ItemType item = ItemType.Factory.newInstance();
+item.setName("bicycle");
+item.setAmount(12);
+item.setPrice(560.00);
+
+/*
+ * Use the new ItemType instance to set the value of the
+ * price element's first item child element. Notice that the set method
+ * here is an "Array" method. This is because the item element
+ * is defined with a maxOccurs="unbounded" attribute. It can occur
+ * many times as a child of price.
+ */
+price.setItemArray(0, item);
+
+

Nested Elements and Derived Types

+

When your schema includes named types that are declared locally—within + the declaration of another element or type—the schema type's generated Java + interface will be an inner interface within the type it's nested in.

+

For example, the following schema snippet defines name + and gender elements nested within a person + complex type. In particular, note that the gender element is defined as + deriving from the xs:NMTOKEN built-in type.

+
+<xs:complexType name="person">
+    <xs:sequence>
+        <xs:element name="name" type="xs:string"/>
+        <xs:element name="gender">
+            <xs:simpleType>
+                <xs:restriction base="xs:NMTOKEN">
+                    <xs:enumeration value="male"/>
+                    <xs:enumeration value="female"/>
+                </xs:restriction>
+            </xs:simpleType>
+        </xs:element>
+    </xs:sequence>
+</xs:complexType>
+
+

The generated interfaces for person and gender would be organized in source + something like the following. Of course, you wouldn't see the source, but + you can see here that the Gender interface is nested with Person. Also, + notice that it extends XmlNMTOKEN, mirroring the schema.

+
public interface Person extends XmlObject
+{
+    public interface Gender extends XmlNMTOKEN
+    {
+        // Methods omitted for this example
+    }
+    // Methods omitted for this example
+}
+
+

You could create a new instance of the Gender + type in this way (there are also various alternatives to this):

+
+// Create a new Person instance.
+Person person = Person.Factory.newInstance();
+/*
+ * Set the gender element's value using the
+ * enumeration generated from the schema.
+ */
+person.setGender(Gender.FEMALE);
+

User-Derived Simple Types

+

In addition to the 46 built-in simple types in XML schema, a schema can + include its own custom simple types using xs:simpleType + declarations. These user-derived simple types are always based on the built-in + XML schema types. The built-in types can be modified by restricting + them, taking unions of them, or making space-separated lists + of them. Each XML simple type is translated into a Java type that provides + access to the underlying data.

+

Unions

+

In schema, you can use xs:union to specify + a simple type that is allowed to contain values of a number of other simple + types. XMLBeans generates a type for a union, just as it generates a type + for any other schema type. At run time, you can discover the underlying + type of an instance of a union type by calling the XmlObject + interface's instanceType method. Once you + have determined the type, you can cast an instance of a union type to the + actual underlying instance type.

+
+<xs:simpleType name="intOrString">
+    <xs:union memberTypes="xs:int xs:string">
+</xs:simpleType>
+
+

Given the preceding schema snippet, you could set the intOrString value + to, say, 6 or "six". The union of xs:int + and xs:string makes both allowable.

+
+// Create a new instance of the type.
+IntOrString intOrString = IntOrString.Factory.newInstance();
+intOrString.set("5");
+// This code prints "XmlInt" to the console.
+System.out.println(intOrString.instanceType().getShortJavaName());
+
+

Restrictions

+

XML schema restrictions on simple XMLBeans types are enforced. So, for + example, it is illegal to set a number outside its restricted range.

+

Numeric Type Restrictions

+

In schema, you can restrict numeric types to allow, for example, only a + particular range of values. For such a restriction, XMLBeans tailors the + resulting natural Java alternative. For example, suppose you have the following + element defined in schema:

+
+<xs:element name="number">
+    <xs:simpleType>
+        <xs:restriction base="xs:integer">
+            <xs:minInclusive value="1"/>
+            <xs:maxInclusive value="1000000"/>
+        </xs:restriction>
+    </xs:simpleType>
+</xs:element>
+
+

The type is restricted from xs:integer, + but because the number's range is limited to between 1 and 1000000, it will + fit into a Java int. A long + or java.math.BigInteger would be too big + for the need. In other words, the getNumber + method generated for this type will return an int, + rather than a BigInteger or a long.

+

By the same token, an long can be compiled to an int if the totalDigits + attribute is <=9, or the min and max attribute values are within 32-bit + 2s complement range.

+

The single primitive XML type xs:decimal can be restricted in several ways + that influence the resulting natural Java type. For example, it can be:

+
+
+
    +
  • +
    +
    Compiled to a BigInteger if its fractionDigit + attribute is set to 0.
    +
    +
  • +
  • +
    +
    Compiled to a long if its totalDigits + attribute is <=18, or the min and max are within 64-bit 2s complement + range.
    +
    +
  • +
+
+
+

Enumerations

+

In schema, you can derive a new type by restricting a built-in type so + that only a finite set of values are allowable. Where schema does this by + restricting xs:string, XMLBeans generates + a special Enum type. With an Enum, + you can select the enumerated value either by its String + value or by a numeric index. The index's value is determined based on the + String value's order in the schema. Having + an index can be useful in Java switch statements.

+

For example, suppose you had a document containing price elements whose + type was the priceType defined in the following schema snippet:

+
<xs:complexType name="priceType">
+    <xs:sequence>
+        <xs:element name="item" type="ps:itemType" minOccurs="0"
+              maxOccurs="unbounded"/>
+    </xs:sequence>
+    <xs:attribute name="threshold">
+        <xs:simpleType>
+            <xs:restriction base="xs:string">
+                <xs:enumeration value="Below10Dollars"/>
+                <xs:enumeration value="Between10And20Dollars"/>
+                <xs:enumeration value="Above20Dollars"/>
+            </xs:restriction>
+        </xs:simpleType>
+    </xs:attribute>
+</xs:complexType>
+

Using types generated from the schema, you would be able to write the following + Java code to "switch" on the threshold attribute's enumeration:

+
+/*
+ * Use the intValue method provided by the Enum type to determine the threshold
+ * attribute's current enumeration value.
+ */
+switch(priceElements[i].getThreshold().intValue())
+{
+    // Use the Threshold type's enumeration values to test for an attribute value.
+    case PriceType.Threshold.INT_BELOW_10_DOLLARS:
+        zeroBuffer.append(item.getTitle() + "\n");
+        break;
+    case PriceType.Threshold.INT_BETWEEN_10_AND_20_DOLLARS:
+        tenBuffer.append(item.getTitle() + "\n");
+        break;
+    case PriceType.Threshold.INT_ABOVE_20_DOLLARS:
+        twentyBuffer.append(item.getTitle() + "\n");
+        break;
+    default:
+        System.out.println("Yo! Something unexpected happened!");
+        break;
+}
+
+

Related Topics

+

XMLBeans Support for + Built-In Schema Types

+
+ + + + diff --git a/xmlbeans/docs/guide/conMethodsForGeneratedJavaTypes.html b/xmlbeans/docs/guide/conMethodsForGeneratedJavaTypes.html new file mode 100644 index 000000000..9763cf98f --- /dev/null +++ b/xmlbeans/docs/guide/conMethodsForGeneratedJavaTypes.html @@ -0,0 +1,275 @@ + + + + + + +Methods for Types Generated From Schema + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Methods for Types Generated From Schema

+
+
+

As you may have seen in Getting + Started with XMLBeans, you use the types generated from schema to access + XML instances based on the schema. If you're familiar with the JavaBeans technology, + the conventions used in the generated API will be recognizable.

+

In general, elements and attributes are treated as "properties" + in the JavaBeans sense. In other words, as you would with JavaBeans properties, + you manipulate parts of the XML through accessor methods such as getCustomer() + (where you have a "customer" element), setId(String) (where you + have an "id" attribute), and so on. However, because schema structures + can be somewhat complex, XMLBeans provides several other method styles for + handling those structures in XML instances.

+
+

Prototypes for Methods in Generated Interfaces

+

Several methods are generated for each element or attribute within the + complex type. This topic lists each method that could be generated for a + given element or attribute.

+

Note that whether or not a given method is generated is based on how the + element or attribute is defined in schema. For example, a customer element + definition with a maxOccurs attribute value + of 1 will result in a getCustomer method, but not a getCustomerArray method + — after all, only one customer element is possible in an instance + document.

+

Note, too, that there may be two sets of parallel methods: one whose prototype + starts with an "x". An "x" method such as xgetName or + xsetName would be generated for elements or attribute whose type is a simple + type. A simple type may be one of the 44 built-in simple types or may be + a restriction in schema of one of those built-in types. Of course, an attribute + will always be of a simple type. For built-in simple types, an "x" + method will get or set one of the types provided with XMLBeans, such as + XmlString, + XmlInteger, + XmlGDay, + and so on. For derived types, the "x" method will get or set a + generated type.

+

Single Occurrence Methods

+

Methods generated for elements or attributes that allow a single occurrence. + An element is singular if it was declared with maxOccurs="1". + An attribute is singular if it was not declared with use="prohibited".

+
+Type getFoo()
+void setFoo(Type newValue)
+
+
+
+
Returns or sets the value of Foo. Generated when Foo is an attribute, + or is an element that can occur only once as a child.
+
+
+
+
XmlType xgetFoo()
+void xsetFoo(XmlType newValue)
+
+
+
Returns or sets the value of Foo as an XMLBean simple type. These methods + are generated if Foo's type is defined in schema as a simpleType.
+
+
+
+
boolean isNilFoo()
+void setNilFoo()
+
+
+
Determines or specifies whether the Foo element is nil (in other words, + "null" in schema terms), meaning it can be empty. A nil element + looks something like this:
+
+
<foo/>
+
+
These methods are only generated when an element type is declared as + nillable in schema — it has a nillable="true" attribute.
+
+
+
+
XmlType addNewFoo()
+
+
+
Adds a new Foo as an XMLBean simple to the document, or returns Foo's + value if one exists already.
+
+
+
+
boolean isSetFoo()
+void unSetFoo()
+
+
+
Determines whether the Foo element or attribute exists in the document; + removes Foo. These methods are generated for elements and attributes that + are optional. In schema, and optional element has an minOccurs + attribute set to "0"; an optional attribute has a use + attribute set to "optional".
+
+
+
+

Multiple Occurrence Methods

+

Methods generated for elements that allow multiple occurrences.

+

An element may occur multiple times if it has a maxOccurs + attribute set to "unbounded" or greater than 1. Attributes can't + occur multiple times.

+
Type[] getFooArray()
+void setFooArray(Type[] newValue) 
+
+
+
Returns or sets all of the Foo elements.
+
+
+// Get an array of the all of the purchase-order elements item children.
+Item[] items = myPO.getItemArray();
+
+
+
+
+
+
Type getFooArray(int index)
+void setFooArray(Type newValue, int index)
+
+
+
Returns or sets the Foo child element at the specified index.
+
+
// Sets the value of the third item child element.
+myPO.setItem(newItem, 2);
+
+
+
+
+
int sizeOfFooArray()
+
+
+
Returns the number of Foo child elements.
+
+
// Returns the number of item child elements.
+int itemCount = myPO.sizeOfItemArray();
+
+
+
+
+
void removeFoo(int index)
+
+
+
Removes the Foo child element at the specified index.
+
+
+
+
XmlType[] xgetFooArray()
+void xsetFooArray(XmlType[] arrayOfNewValues)
+
+
+
Returns or sets all of the Foo elements as XMLBeans simple types. Generated + only when the Foo element is defined as a simple type.
+
+
/*
+ * Returns values of all the phone child elements of an employee element,
+ * where the phone element has been defined as xs:string.
+ */
+XmlString[] empPhones = currentEmployee.xGetPhoneArray();
+
+
+
+
+
+
XmlType xgetFooArray(int index)
+void xsetFooArray(int index, XmlType newValue)
+
+
+
Returns or sets the Foo element at the specified index, using an XMLBeans + simple type value. Generated for an element defined as a simple type in + schema.
+
+
+
+
void insertFoo(int index, FooType newValue)
+
+
+
Inserts the specified Foo child element at the specified index.
+
+
+
+
void addFoo(FooType newValue)
+
+
+
Adds the specified Foo to the end of the list of Foo child elements.
+
+
+
+
XmlType insertNewFoo(int index)
+
+
+
Inserts a new Foo at the specified index, returning an XMLBeans simple + type representing the new element; returns the existing Foo if there's already + one at index.
+
+
+
+
XmlType addNewFoo()
+
+
+
Adds a new Foo element to the end of the list of Foo child elements, + returning an XMLBeans simple type representing the newly added element.
+
+
+
+
boolean isNilFooArray(int index)
+void setNilFooArray(int index)
+
+
+
Determines or specifies whether the Foo element at the specified index + is nil.
+
+
+
+
+
+

Related Topics

+

Java Types Generated + from User-Derived Schema Types

+
+ + + + diff --git a/xmlbeans/docs/guide/conNavigatingXMLwithCursors.html b/xmlbeans/docs/guide/conNavigatingXMLwithCursors.html new file mode 100644 index 000000000..404e8aecf --- /dev/null +++ b/xmlbeans/docs/guide/conNavigatingXMLwithCursors.html @@ -0,0 +1,222 @@ + + + + + + +Navigating XML with Cursors + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Navigating XML with Cursors

+
+

XML cursors are a way to navigate through an XML instance document. Once + you load an XML document, you can create a cursor to represent a specific + place in the XML. Because you can use a cursor with or without a schema corresponding + to the XML, cursors are an ideal way to handle XML without a schema.

+

With an XML cursor, you can:

+
+ +

When you're finished using a cursor, your code should call its dispose + method.

+

Creating and Moving a Cursor

+

With an XML instance document bound to XmlObject + (or a type inheriting from it), you create a new cursor by calling the newCursor + method. The XmlCursor + interface represents a cursor. From a cursor standpoint, an XML document is + a collection of tokens that represent the kinds of things that can + appear in XML. These include attributes, the start and end of elements, + comments, and so on. Each piece of information in XML is represented by + a token type.

+

Note: For a more complete description of + XML tokens, see Understanding XML Tokens.

+

For example, the following code loads the XML instance described above + from a File object, then creates a new cursor. + The toFirstChild takes the cursor to the start + tag of the batchWidgetOrder document element. + The code then prints the type for the token at the cursor's location, along + with the XML the cursor represents—in other words, Token + type: START / and the batchWidgetOrderElement + and its contents.

+
public static void insertCursor(File orderFile) throws Exception
+{
+    BatchWidgetOrderDocument xmlDoc = BatchWidgetOrderDocument.Factory.parse(orderFile);
+    XmlCursor orderCursor = xmlDoc.newCursor();
+    orderCursor.toFirstChild();
+    System.out.println("Token type: " + orderCursor.currentTokenType() +
+        " / " + orderCursor.xmlText());
+}
+
+

Note: The XmlCursor + interface provides many methods you can use to put a cursor where you want it. + For a list of those methods, see XmlCursor + Interface.

+

Adding + Elements and Attributes

+

The XmlCursor interface provides several methods + you can use to add elements and attributes to XML.

+

One way to add new XML is with the beginElement + method. This method is designed to insert a new element at the cursor's location, + and do it so the cursor ends up between the new element's START and END tokens. + From this position, you can insert attributes (they're automatically placed + in the start tag, where they belong) and insert a value. Here's an example:

+
+// Create a new chunk of XML.
+XmlObject newXml = XmlObject.Factory.newInstance();
+/*
+ * Insert a new cursor and move it to the first START token (where the
+ * XML actually begins.
+ */
+XmlCursor cursor = newXml.newCursor();
+cursor.toNextToken();
+// Begin a new item element whose namespace URI is "http://openuri.org".
+cursor.beginElement("item", "http://openuri.org/");
+// Insert an ID attribute on the item element, along with an attribute value.
+cursor.insertAttributeWithValue("id", "4056404");
+// Insert "bicycle" as an element value.
+cursor.insertChars("bicycle");
+cursor.dispose();
+
+

This example results in something like the following:

+
<ns1:item id="4056404" xmlns:ns1="http://openuri.org/">bicycle</ns1:item>
+
+

Using Stored Cursor Locations with push() and pop()

+
+

When you want to move a cursor around, but want to keep track of a former + location, you can use the XmlCursor interface's + push and pop + methods. The push method pushes the cursor's + current location onto a stack of locations maintained for that particular + cursor; the pop method removes the location + from the top of the stack and moves the cursor to that location.

+

For example, consider the following <employee> element, used in the + example below.

+
+<employee>
+    <name>Gladys Kravitz</name>
+    <address location="home">
+        <street>1313 Mockingbird Lane</street>
+        <city>Seattle</city>
+        <state>WA</state>
+        <zip>98115</zip>
+    </address>
+    <address location="work">
+        <street>2011 152nd Avenue NE</street>
+        <city>Redmond</city>
+        <state>WA</state>
+        <zip>98052</zip>
+    </address>
+    <phone location="work">(425) 555-6897</phone>
+    <phone location="home">(206) 555-6594</phone>
+    <phone location="mobile">(206) 555-7894</phone>
+</employee>
+
+

The following Java code illustrates how you can use push + and pop to put the cursor back to a saved + location after a bit of traveling.

+
+/**
+ * Pass to the trySelectPath method an XmlObject instance that contains
+ * the XML above.
+ */
+public void trySelectPath(XmlObject xml)
+{
+    /*
+     * Inserts the cursor at the STARTDOC token (the very beginning,
+     * before any elements).
+     */
+    XmlCursor cursor = xml.newCursor();
+    // Moves the cursor to just before <employee>
+    cursor.toFirstChild();
+    // Pushes the cursor's current location onto the stack.
+    cursor.push();
+    // Moves the cursor to just before the "work" <phone> element.
+    cursor.toChild(2);
+    // Moves the cursor to just before the "home" <phone> element.
+    cursor.toNextSibling();
+    // Moves the cursor back to just before <employee>
+    cursor.pop();
+}
+
+

Of course, you can call push and pop + multiple times. Each new call to the push + method pushes the current location onto the stack. As you call the pop + method, you're always getting what's on top of the stack. So if you called + push three times before calling pop + — 1, 2, 3 — calling pop three + times would get those locations in reverse order — 3, 2, 1.

+

The push and pop + methods can be handy as an alternative to creating new cursors that are designed + simply to mark a particular location while you move another cursor around. + The resources required to maintain a location stack through push + and pop are far less than those needed by + cursors.

+

Disposing of a Cursor

+

When you're through with a cursor, your code should call its dispose + method to indicate that it's no longer needed.

+

Related Topics

+

Understanding XML Tokens

+

Getting Started with XMLBeans

+
+ + + + diff --git a/xmlbeans/docs/guide/conSelectingXMLwithXQueryPathXPath.html b/xmlbeans/docs/guide/conSelectingXMLwithXQueryPathXPath.html new file mode 100644 index 000000000..648cde6bd --- /dev/null +++ b/xmlbeans/docs/guide/conSelectingXMLwithXQueryPathXPath.html @@ -0,0 +1,340 @@ + + + + + + +Selecting XML with XQuery and XPath + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Selecting XML with XQuery and XPath

+
+

You can use XPath and XQuery to retrieve specific pieces of XML as you might + retrieve data from a database. XQuery and XPath provide a syntax for specifying + which elements and attributes you're interested in. The XMLBeans API provides + two methods for executing XQuery and XPath expressions, and two ways to use them. The methods are selectPath + for XPath and execQuery for XQuery.

+

You can call them from and XmlObject instance (or a generated type inheriting from it) or an XmlCursor instance. + As noted below, each of the four methods works slightly differently; be sure to keep these differences in mind when choosing your approach.

+

Note: Both XQuery and complex XPath expressions require additional classes on the class path, as noted in the sections that follow. Also, be sure to see the XMLBeans installation instructions.

+

Using XPath with the selectPath Method

+
+
+

You can execute XPath expressions use the selectPath method. When you use XPath with the selectPath + method, the value returned is view of values from the current document — not a copy of those values. In other words, changes your code makes to XML returned by the selectPath method change the XML in the document queried against. In contrast, with XQuery executed using the execQuery method, the value returned is a copy of values in the XML queried against.

+

Note that XPath itself does not provide syntax for declaring prefix to URI bindings. For user convenience, we allow XQuery syntax to be used for such purposes. You can consult the latest XQuery draft when using syntax for declaring namespaces.

+
+

Note: By default, XMLBeans supports only very simple XPath expressions. To execute complex expressions — such as those with predicates, function calls, and the like — you will need xbean_xpath.jar and the Saxon jars (see below) on your class path. xbean_xpath.jar is among those created when you build XMLBeans from source. You may need to download the Saxon jars yourself.

+
+

Calling XmlObject.selectPath

+

When called from XmlObject (or a type that + inherits from it), the selectPath method returns an array of objects. If the expression + is executed against types generated from schema, then the type for the returned + array is one of the Java types corresponding to the schema, and you can cast it accordingly.

+

For example, imagine you have the following XML containing employee information. + You've compiled the schema describing this XML and the types generated from + schema are available to your code.

+
+<xq:employees xmlns:xq="http://xmlbeans.apache.org/samples/xquery/employees">
+    <xq:employee>
+        <xq:name>Fred Jones</xq:name>
+        <xq:address location="home">
+            <xq:street>900 Aurora Ave.</xq:street>
+            <xq:city>Seattle</xq:city>
+            <xq:state>WA</xq:state>
+            <xq:zip>98115</xq:zip>
+        </xq:address>
+        <xq:address location="work">
+            <xq:street>2011 152nd Avenue NE</xq:street>
+            <xq:city>Redmond</xq:city>
+            <xq:state>WA</xq:state>
+            <xq:zip>98052</xq:zip>
+        </xq:address>
+        <xq:phone location="work">(425)555-5665</xq:phone>
+        <xq:phone location="home">(206)555-5555</xq:phone>
+        <xq:phone location="mobile">(206)555-4321</xq:phone>
+    </xq:employee>
+</xq:employees>
+
+ If you wanted to find the phone numbers whose area code was 206, you could capture + the XPath expression in this way: +
+String queryExpression =
+    "declare namespace xq='http://xmlbeans.apache.org/samples/xquery/employees';" +
+    "$this/xq:employees/xq:employee/xq:phone[contains(., '(206)')]";
+
+

Notice in the query expression that the variable $this + represents the current context node (the XmlObject + that you are querying from). In this example you are querying from the document + level XmlObject.

+

You could then print the results with code such as the following:

+
// Retrieve the matching phone elements and assign the results to the corresponding
+// generated type.
+PhoneType[] phones = (PhoneType[])empDoc.selectPath(queryExpression);
+
+// Loop through the results, printing the value of the phone element.
+for (int i = 0; i < phones.length; i++)
+{
+    System.out.println(phones[i].stringValue());
+}
+ +

Calling XmlCursor.selectPath

+

When called from an XmlCursor instance, the + selectPath method retrieves a list of selections, + or locations in the XML. The selections are remembered by the cursor instance. + You can use methods such as toNextSelection + to navigate among them.

+
+

The selectPath method takes an XPath expression. + If the expression returns any results, each of those results is added as + a selection to the cursor's list of selections. You can move through these + selections in the way you might use java.util.Iterator + methods to move through a collection.

+

For example, for a path such as $this/employees/employee, + the cursor instance from which you called selectPath would include a selection for each employee element found by + the expression. Note that the variable $this + is always bound to the current context node, which in this example is the + document. After calling the selectPath method, + you would use various "selection"-related methods to work with + the results. These methods include:

+
+
    +
  • +
    getSelectionCount() to retrieve the + number of selections resulting from the query.
    +
  • +
  • +
    toNextSelection() to move the cursor + to the next selection in the list (such as to the one pointing at the + next employee element found).
    +
  • +
  • +
    toSelection(int) to move the cursor + to the selection at the specified index (such as to the third employee + element in the selection).
    +
  • +
  • +
    hasNextSelection() to find out if + there are more selections after the cursor's current position.
    +
  • +
  • +
    clearSelections() clears the selections + from the current cursor. This doesn't modify the document (in other words, + it doesn't delete the selected XML); it merely clears the selection list + so that the cursor is no longer keeping track of those positions.
    +
  • +
+
+

The following example shows how you might use selectPath, + in combination with the push and pop + methods, to maneuver through XML, retrieving specific values.

+
+public void printZipsAndWorkPhones(XmlObject xml)
+{
+    // Declare the namespace that will be used.
+    String xqNamespace =
+        "declare namespace xq='http://xmlbeans.apache.org/samples/xquery/employees';";
+
+    // Insert a cursor and move it to the first element.
+    XmlCursor cursor = xml.newCursor();
+    cursor.toFirstChild();
+
+    // Save the cursor's current location by pushing it
+    // onto a stack of saved locations.
+    cursor.push();
+    // Query for zip elements.
+    cursor.selectPath(xqNamespace + "$this//xq:zip");
+
+    // Loop through the list of selections, getting the value of
+    // each element.
+    while (cursor.toNextSelection())
+    {
+        System.out.println(cursor.getTextValue());
+    }
+    // Pop the saved location off the stack.
+    cursor.pop();
+    // Query again from the top, this time for work phone numbers.
+    cursor.selectPath(xqNamespace + "$this//xq:phone[@location='work']");
+
+    // Move the cursor to the first selection, then print that element's
+    // value.
+    cursor.toNextSelection();
+    System.out.println(cursor.getTextValue());
+    // Dispose of the cursor.
+    cursor.dispose();
+}
+
+

Using selections is somewhat like tracking the locations of multiple cursors + with a single cursor. This becomes especially clear when you remove the + XML associated with a selection. When you do so the selection itself remains + at the location where the removed XML was, but now the selection's location + is immediately before the XML that was after the XML you removed. In other + words, removing XML created a kind of vacuum that was filled by the XML + after it, which shifted up into the space — up into position immediately + after the selection location. This is exactly the same as if the selection + had been another cursor.

+

Finally, when using selections keep in mind that the list of selections + is in a sense "live". The cursor you're working with is keeping + track of the selections in the list. In other words, be sure to call the + clearSelections method when you're finished + with the selections, just as you should call the XmlCursor.dispose() + method when you're finished using the cursor.

+
+

Using XQuery with the execQuery Method

+

You use the execQuery method to execute XQuery + expressions. With XQuery expressions, XML returned is a copy of XML in the document queried against. In other words, changes your code makes to the values returned by execQuery are not reflected in the document queried against.

+
+

Note: To execute XQuery expressions, you must have the SaxonB 8.6.1 versions of the saxon8.jar and saxon8-dom.jar files on your classpath. These are two of the jars from inside the zip file saxonb8-6-1.zip + which can be downloaded from the Saxon web site. + If you build XMLBeans from source then the saxonb8-6-1.zip file and the two Saxon jar files are available in the external/lib directory.

+
+

Calling XmlObject.execQuery

+

As with selectPath, calling execQuery + from an XmlObject instance will return an + XmlObject array.

+

The following example retrieves work <zip> elements from the incoming XML, adding the elements as children to a new <zip-list> element.

+
public boolean collectZips(XmlObject empDoc)
+{
+    String namespaceDeclaration =
+        "declare namespace xq='http://xmlbeans.apache.org/samples/xquery/employees';";
+    // The query is designed to return results, so return
+    // true if it does.
+    boolean hasResults = false;
+
+    // The expression: Get the <zip> elements and return them as children
+    // of a new <zip-list> element.
+    String queryExpression =
+        "let $e := $this/xq:employees " +
+        "return " +
+        "<zip-list> " +
+            "{for $z in $e/xq:employee/xq:address/xq:zip " +
+            "return $z} " +
+        "</zip-list>";
+
+    // Execute the query. Results will be copies of the XML queried against,
+    // stored as members of an XmlObject array.
+    XmlObject[] results =
+        empDoc.execQuery(namespaceDeclaration + queryExpression);
+
+    // Print the results.
+    if (results.length > 0)
+    {
+        hasResults = true;
+        System.out.println("The query results: \n");
+        System.out.println(results[0].toString() + "\n");
+    }
+    return hasResults;
+}
+

Calling XmlCursor.execQuery

+
+ +
+

Unlike the selectPath method called from a cursor, the execQuery method doesn't return void. Instead it returns an XmlCursor instance positioned at the beginning of a new XML document representing + the query results. Rather than accessing results as selections, you use the cursor to move through the results in typical cursor fashion (for more information, see Navigating + XML with Cursors). The models are very different.

+

As always, you can cast the results to a type generated from schema if you know that the results conform to that type.

+

The following example retrieves work <phone> elements from the incoming XML, then changes the number in the results.

+
public boolean updateWorkPhone(XmlObject empDoc)
+{
+    boolean hasResults = false;
+
+    // A cursor instance to query with.
+    XmlCursor empCursor = empDoc.newCursor();
+    empCursor.toNextToken();
+
+    // The expression: Get the  elements with  elements whose
+    // value is "WA".
+    String queryExpression =
+        "for $e in $this/xq:employees/xq:employee " +
+        "let $s := $e/xq:address/xq:state " +
+        "where $s = 'WA' " +
+        "return $e//xq:phone[@location='work']";
+
+    // Execute the query. Results, if any, will be available at
+    // the position of the resultCursor in a new XML document.
+    XmlCursor resultCursor =
+        empCursor.execQuery(namespaceDeclaration + queryExpression);
+
+    System.out.println("The query results, element copies made " +
+		"from the received document: \n");
+    System.out.println(resultCursor.getObject().toString() + "\n");
+
+    // If there are results, the results will be children of the fragment root
+    // where the new cursor is positioned. This statement tests for children
+    // and moves the cursor if to the first if it exists.
+    if (resultCursor.toFirstChild())
+    {
+        hasResults = true;
+        // Use the cursor to loop through the results, printing each sibling
+        // element returned by the query.
+        int i = 0;
+	    do
+	    {
+	        // Change the phone numbers.
+            XmlCursor editCursor = resultCursor.newCursor();
+	        editCursor.toLastAttribute();
+	        editCursor.toNextToken();
+	        editCursor.removeXml();
+	        editCursor.insertChars("(206)555-1234");
+	    } while (resultCursor.toNextSibling());
+
+	    resultCursor.toStartDoc();
+	    System.out.println("The query results after changes: \n");
+	    System.out.println(resultCursor.getObject().toString() + "\n");
+
+    	System.out.println("The received document -- note that it is unchanged. " +
+            "Changes were made to the copy created by the execQuery method. \n");
+    	System.out.println(empDoc + "\n");
+    }
+    return hasResults;
+}
+

Related Topics

+
+

Getting Started with XMLBeans

+ + + + diff --git a/xmlbeans/docs/guide/conUnderstandingXMLTokens.html b/xmlbeans/docs/guide/conUnderstandingXMLTokens.html new file mode 100644 index 000000000..6d72c0777 --- /dev/null +++ b/xmlbeans/docs/guide/conUnderstandingXMLTokens.html @@ -0,0 +1,189 @@ + + + + + + +Understanding XML Tokens + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Understanding XML Tokens

+
+
+

An XML cursor (an instance of the XmlCursor + interface) moves from token to token as your code moves the cursor. When you + move a cursor using a method such as toParent, + toFirstAttribute, toPrevSibling, + and so on, the cursor moves to the token fitting the description. If there + is no appropriate token to move to, the cursor remains where it is, and false + is returned to indicate that it didn't move. For example, if the cursor is + at the ENDDOC token (the last tag in the document), a call to the toNextSibling + method will not move the cursor and will return false + to indicate that the move was unsuccessful.

+

Note that while you can call the XmlCursor.currentTokenType + method to find out which token type the cursor is at, you might find it more + convenient to use a method such as isEnddoc. + The XmlCursor interface provides several methods + that make it easy to discover whether the cursor you're moving is at the token + you're looking for. These methods, such as isStart, + isAttr, isText, + and so on, return a boolean value that indicates + whether the cursor is at the token type in question.

+

Tokens are represented by constants in the TokenType + class, an inner class of the XmlCursor interface. + Each has a constant you can use in switch statements to perform by-token actions. + The following table lists the token types:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Token TypeSwitch ConstantDescription
STARTDOCINT_STARTDOCRepresents the start of the XML. Always the first token. The document + element itself is represented by a START token, not the STARTDOC token.
ENDDOC INT_ENDDOCRepresents the end of the XML. Always the last token.
START INT_STARTRepresents the start of an element.
END INT_ENDRepresents the end of an element. The END token has no value, but marks + the element's end.
TEXTINT_TEXTRepresents text.
ATTR INT_ATTRRepresents an attribute. ATTR tokens are allowed to appear after a STARTDOC + or START token.
NAMESPACEINT_NAMESPACERepresents a namespace (xmlns) attribute. Also only allowed after START + or STARTDOC tokens.
COMMENT INT_COMMENTRepresents a comment.
PROCINST INT_PROCINSTRepresents a processing instruction.
+

As you use a cursor to navigate through XML, you can use one of the convenience + methods described above to discover whether you're at the token you're looking + for, or use the XmlCursor.currentTokenType method + to discover the current token's type. The following figure illustrates example + locations for token types:

+

+

Switching to Test for Token Types

+

Here's a bit of code illustrating how you might use a Java switch + statement to test for the START token type.

+
+// Take an incoming XmlObject and insert a cursor.
+XmlCursor documentCursor = xmlDoc.newCursor();
+
+/*
+ * Loop through the document, passing the cursor when it stops at each token
+ * to a function designed to discover the token type. Continue the loop
+ * as long at the cursor is at a token (until it reaches the end).
+ */
+while (!documentCursor.toNextToken().isNone())
+{
+    /*
+     * Use the intValue method to return the int corresponding to the
+	 * current token type. If it is the value for INT_START,
+	 * then you have a match.
+	 */
+    switch (cursor.currentTokenType().intValue())
+    {
+        case TokenType.INT_START:
+        // Print out the token type and a message.
+        System.out.println(cursor.currentTokenType() +
+            "; cursor is at the start of an element.");
+        break;
+    }
+}
+// Be sure to dispose of a cursor when you're finished.
+documentCursor.dispose();
+
+

The scope of an XML cursor is the XML document in which it is created. For + example, you can create a cursor at the orderItem element in the example earlier + in this topic. If you then use that XmlCursor + instance's toNextToken method to move the + cursor until it won't move any further, you'll have reached the ENDDOC token. + In this example, that's at the </batchWidgetOrder> + tag. In other words, the cursor's scope is not limited to the element at which + it was created.

+

Related Topics

+

XmlCursor.TokenType + Class

+

Navigating XML with Cursors

+
+ + + + diff --git a/xmlbeans/docs/guide/conUsingBookmarksToAnnotateXML.html b/xmlbeans/docs/guide/conUsingBookmarksToAnnotateXML.html new file mode 100644 index 000000000..9eaf3d3b3 --- /dev/null +++ b/xmlbeans/docs/guide/conUsingBookmarksToAnnotateXML.html @@ -0,0 +1,97 @@ + + + + + + +Using Bookmarks to Annotate XML + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Using Bookmarks to Annotate XML

+
+
+

You can use a cursor to insert bookmarks that annotate XML with markers containing + information you design. These bookmarks aren't written into the XML itself, + but in a sense "hang" from the location where it was inserted. In this way + you can associate arbitrary pieces of information with specific parts of the + XML.

+

You design your own bookmark classes by extending XmlBookmark, + a nested class of XmlCursor. + You can design your bookmark class to contain information specific to your + needs.

+

In the following example, OrderBookmark is + an inner class that extends XmlCursor.XmlBookmark. + It merely stores a piece of text.

+
+/*
+ * The OrderBookmark class includes a constructor through which you will
+ * insert your bookmark's content. It also includes get and set methods
+ * you can use to retrieve and change the content.
+ */
+static class OrderBookmark extends XmlCursor.XmlBookmark {
+    public OrderBookmark (String text) { TEXT = text; }
+    public String TEXT;
+    public String getText() { return TEXT; }
+    public void setText(String newText) { TEXT = newText; }
+}
+
+

You can use instances of this class to store bookmarks at places in your + XML. The following excerpt of code creates a cursor and an instance of the + OrderBookmark class. Then it uses the cursor + to insert the bookmark at the cursor's current location.

+
+    XmlCursor orderCursor = xmlDoc.newCursor();
+    OrderBookmark thisBookmark = new OrderBookmark("foo");
+    orderCursor.setBookmark(thisAnnotation);
+
+

Related Topics

+

Navigating XML with Cursors

+
+ + + + diff --git a/xmlbeans/docs/guide/conValidationWithXmlBeans.html b/xmlbeans/docs/guide/conValidationWithXmlBeans.html new file mode 100644 index 000000000..40bb9c9ed --- /dev/null +++ b/xmlbeans/docs/guide/conValidationWithXmlBeans.html @@ -0,0 +1 @@ + XMLBeans Tools

Validation with XMLBeans

An essential part of schema-related work is validating instances based on the schema. XMLBeans provides a number of ways for you to ensure your instances are valid, both at the command line and programmatically at run time.

Validation, XMLBeans-Style

XMLBeans' schema-oriented approach to handling XML makes validation an important part of its work. However, XMLBeans has a specific approach to validation that's helpful to keep in mind when you're working.

Validation features include the following:

  • Generally, XMLBeans validates when you ask it to. It doesn't validate while parsing -- nor, by default, while your code is updating the bound instance along the way through, say, set* methods (although you can change this behavior).
  • You can validate programmatically or by using one of the command-line tools provided by XMLBeans.
  • The validate methods return true or false to indicate whether the instance is valid. You can also capture error information if you want to when validating programmatically. To do this, you specify an error listener.
  • You can tell XMLBeans at parse time that it should validate during calls to set* methods. Note that this means validation after parsing, not during, and that it can slow performance. Also note validation would not occur as changes are made by a cursor.
  • XMLBeans does validate schema when compiling the schema through scomp or the xmlbean Ant task. (When you're compiling schema programmatically, you can disable validation with the XmlOptions.setCompileNoValidation method.)

XMLBeans Validates Only When You Ask It To — Generally

Given XMLBeans' focus on schema-oriented work, it's natural to assume that it might check up on you as your code is making changes to an instance — that it might prevent your code from doing something that would render the instance invalid along the way. But, by default, it doesn't. The design of XMLBeans assumes that an XML instance might go through multiple invalid states before changes are complete. As a result, generally speaking, XMLBeans keeps quiet while changes are occurring.

Note: The exception to this rule is that XMLBeans validates your schema when you're compiling it using scomp or the xmlbean Ant task.

XMLBeans Does Not Validate an Instance While Parsing It

But it's not hard to get the impression that it does. For example, imagine that you're parsing an XML instance using a statement such as the following:

MyXmlSchemaType myXmlBean = MyXmlSchemaType.Factory.parse(myXml);

If the namespace declared in the myXml instance doesn't match the target namespace of the schema from which MyXmlSchemaType was generated, parsing will fail with an error message. Likewise, you'll get messages for other mismatches between the shape of myXml and the XML shape described by the schema.

But these failures and messages don't result from validation. Instead, all XMLBeans is doing is a not-very-deep check to see if the instance shouldn't be bound to the XMLBeans type generated from schema. In other words, the checking done at the parsing stage is simply a "low bar" effort to avoid trouble down the road.

Validation, on the other hand, is designed to verify that the instance conforms completely to the schema.

So you can validate in any of three ways:

  • On request, using a validate method.
  • On the fly, using the "validate on set" option.
  • Using one of the command-line tools.

Tools for Validating

XMLBeans tools for validation include command-line tools and APIs.

Command-line Tools for Validation

Among the many command-line tools XMLBeans provides, you'll find two that are specifically for validation.

  • validate tool — A validation command-line tool in which you specify the instance to validate and the schema to validate it against.

    You'll find the validate tool in the bin directory of your XMLBeans installation.

  • svalidate tool — Identical to the validate tool, except that svalidate uses a streaming model that supports validation against much larger schemas.

    You'll find the svalidate tool in the bin directory of your XMLBeans installation.

APIs for Validation

XMLBeans APIs provide ways for you to validate on request — say, after your code has finished editing an instance and before it passes the instance elsewhere. You can also specify that your calls to set* methods should validate on-the-fly the instance that is being edited; you do this as an option when your code creates the XMLBeans schema type instance.

Validation When You Ask for It

Both the validate methods described here are available from any XMLBeans type generated from schema during schema compilation (because all such types inherit from XmlObject). Both methods are designed to validate the instance that is bound to the type from which the method is called. For example, if your schema defines a <purchase-order> element with <item> children, calling the myItem.validate() method will validate the <item> instance bound to Item. This includes the <item> element's children, but not the <purchase-order> element or the <item> element's siblings.

Both methods return a boolean to indicate validity, and one of the methods lets you specify options for validation, such as capturing messages about why an invalid instance is invalid.

  • XmlObject.validate() — Returns true if the instance is valid.
  • XmlObject.validate(XmlOptions) — Returns true if the instance is valid, using the specified XmlOptions instance to customize validation.

    In particular, you can use the XmlOptions.setErrorListener method to specify a Collection instance with which to capture messages pertaining to invalid instances. For an example, see the Javadoc for this method.

    Through the XmlOptions class, you can specify options to use during validation. The options include the following:

  • XmlOptions.setErrorListener -- Specifies a Collection instance that XMLBeans should use to store errors that occur during validation (or, in other contexts, during parsing and compilation).
  • XmlOptions.setValidateTreatLaxAsSkip -- Tells XMLBeans that it should skip elements matching an particle with contentModel="lax" during validation.

Also, see the section on validating as you go for information about using the XmlOptions.setValidateOnSet method.

Retrieving Error Messages About Invalid XML

When you'll be validating with one of the validate methods, you can specify a java.util.Collection implementation as an error listener. As validation occurs, errors are added to the listener. After validation (and if the instance is found to be invalid) you can examine the errors. Here's an example:

// Set up the validation error listener.
ArrayList validationErrors = new ArrayList();
XmlOptions validationOptions = new XmlOptions();
validationOptions.setErrorListener(validationErrors);

MyDocument myDoc = MyDocument.Factory.parse(pathToXml);

// Do some editing to myDoc.

// During validation, errors are added to the ArrayList for
// retrieval and printing by the printErrors method.
boolean isValid = myDoc.validate(validationOptions);

// Print the errors if the XML is invalid.
if (!isValid)
{
    Iterator iter = validationErrors.iterator();
    while (iter.hasNext())
    {
        System.out.println(">> " + iter.next() + "\n");
    }
}

Validation As You Go

By default, an XML instance will not be validated at run time as your code makes changes. However, you can change this behavior for limited on-the-fly validation. To do this, you specify the "validate on set" option when you create the XMLBeans type instance — you do this with the XmlOptions.setValidateOnSet method.

When you specify this option, XMLBeans with throw an exception when your code invalidates the XML through a set* method. Note that you can't specify an error listener for use in conjunction with this means of validating. Also, with "validate on set," only simple schema types will be validated. Schema types not validated by this approach include, for example, those defining elements with attributes or elements with children.

Because its functionality is limited to simple schema types and it validates for set* method calls, you should regard this validation approach as a debugging tool, rather than an alternative to using a validate method. For example, you might use it to determine which errant bit of code is creating an invalid chunk of XML.

Note: This sort of validation is not supported during changes you make using an XmlCursor instance.

Among the methods you can use to create an XMLBeans instance — the parse methods and the newInstance method — you'll find versions that take an XmlOptions instance as a parameter. Specifying this option would look something like the following:

XmlOptions validateOptions = new XmlOptions();

// Tell XMLBeans you want to validate on the fly.
validateOptions.setValidateOnSet();
// Create the new instance, specifying the option.
PurchaseOrder newPo = PurchaseOrder.Factory.newInstance(validateOptions);

// ... Code to edit the instance via get and set methods ... 
\ No newline at end of file diff --git a/xmlbeans/docs/guide/conXMLBeansSupportBuiltInSchemaTypes.html b/xmlbeans/docs/guide/conXMLBeansSupportBuiltInSchemaTypes.html new file mode 100644 index 000000000..89fdb16e2 --- /dev/null +++ b/xmlbeans/docs/guide/conXMLBeansSupportBuiltInSchemaTypes.html @@ -0,0 +1,343 @@ + + + + + + +Java Types for XML Schema + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

XMLBeans Support for Built-In Schema Types

+

Just as with types in XML schema, the XMLBeans types based on schema are arranged + in a hierarchy. In general, the hierarchy of XMLBean types mirrors the hierarchy + of the schema types themselves. XML schema types all inherit from xs:anyType + (which is at the root of the hierarchy); XMLBeans types inherit from XmlObject.

+

In XML schema, xs:anyType is the root type + for two type categories: built-in and user-derived. Built-in schema types are + common types defined by the XML schema specification. User-derived types are + those you define in your schema. This topic lists the built-in types provided + with XMLBeans. For information about user-derived types and the Java types generated + from them, see Java Types Generated + from User-Derived Schema Types.

+

The following figure illustrates the hierarchy of types, showing both built-in + schema types and their XMLBeans parallels. Notice, too, that nearly all of the + built-in types are also available as natural Java types.

+

+

Java Types Representing Built-In Schema Types

+

As you can see from the figure above, all 46 built-in schema types are represented + by an XMLBean type provided with XMLBeans. When using built-in XMLBean types, + keep in mind that:

+
    +
  • Since XmlObject corresponds to the xs:anyType, + all Java XMLBean types inherit from XmlObject. + Therefore all XMLBean types share the XmlObject + interface’s ability to create an XmlCursor + at the position of the object. They can also render the XML as strings or + streams. +
  • +
    Where there is a corresponding natural Java type, the XMLBeans type provides + a way to get the underlying XML's value as the natural type. See the table + in this topic for information on how natural Java types map to XMLBeans + types.
    + +
  • Values assigned to built-in XMLBeans types are validated in keeping with + the rules of the schema type they represent. So, for example, an attempt to + assign a negative integer value to an XmlPositiveInteger + will throw an XmlValueOutOfRange exception.
  • +
+
+

The following table lists the built-in schema types, along with their XMLBeans + and natural Java parallels. Unless otherwise noted, natural Java types are + in the java.lang package; XMLBean types are + in the org.apache.xmlbeans package.

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Built-In Schema TypeXMLBean TypeNatural Java Type
xs:anyTypeXmlObject org.apache.xmlbeans.XmlObject
xs:anySimpleTypeXmlAnySimpleType String
xs:anyURIXmlAnyURIString
xs:base64BinaryXmlBase64Binarybyte[]
xs:booleanXmlBooleanboolean
xs:byteXmlBytebyte
xs:dateXmlDatejava.util.Calendar
xs:dateTimeXmlDateTimejava.util.Calendar
xs:decimalXmlDecimaljava.math.BigDecimal
xs:doubleXmlDoubledouble
xs:durationXmlDurationorg.apache.xmlbeans.GDuration
xs:ENTITIESXmlENTITIESString
xs:ENTITYXmlENTITYString
xs:floatXmlFloatfloat
xs:gDay

XmlGDay

java.util.Calendar
xs:gMonthXmlGMonthjava.util.Calendar
xs:gMonthDayXmlGMonthDayjava.util.Calendar
xs:gYearXmlGYearjava.util.Calendar
xs:gYearMonthXmlGYearMonthjava.util.Calendar
xs:hexBinaryXmlHexBinarybyte[]
xs:IDXmlIDString
xs:IDREFXmlIDREFString
xs:IDREFSXmlIDREFSString
xs:intXmlIntint
xs:integerXmlIntegerjava.math.BigInteger
xs:languageXmlLanguageString
xs:longXmlLonglong
xs:NameXmlNameString
xs:NCNameXmlNCNAMEString
xs:negativeIntegerXmlNegativeIntegerjava.math.BigInteger
xs:NMTOKENXmlNMTOKENString
xs:NMTOKENSXmlNMTOKENSString
xs:nonNegativeIntegerXmlNonNegativeIntegerjava.math.BigInteger
xs:nonPositiveIntegerXmlNonPositiveIntegerjava.math.BigInteger
xs:normalizedStringXmlNormalizedStringString
xs:NOTATIONXmlNOTATION Not supported
xs:positiveIntegerXmlPositiveIntegerjava.math.BigInteger
xs:QNameXmlQNamejavax.xml.namespace.QName
xs:shortXmlShortshort
xs:stringXmlStringString
xs:timeXmlTimejava.util.Calendar
xs:tokenXmlTokenString
xs:unsignedByteXmlUnsignedByteshort
xs:unsignedIntXmlUnsignedIntlong
xs:unsignedLongXmlUnsignedLongjava.math.BigInteger
xs:unsignedShortXmlUnsignedShortint
+
+
+

Related Topics

+

Getting Started with XMLBeans

+
+ + + + diff --git a/xmlbeans/docs/guide/tools.html b/xmlbeans/docs/guide/tools.html new file mode 100644 index 000000000..5af2b0304 --- /dev/null +++ b/xmlbeans/docs/guide/tools.html @@ -0,0 +1,542 @@ + + + + + + XMLBeans Tools + + + + + + + + + + + + + + + + + +

XMLBeans Tools

+

XMLBeans includes several command-line tools you might find handy as shortcuts + for common tasks. You'll find these tools in the bin directory of the XMLBeans + installation or source tree.

+
+
dumpxsb (XSB File Dumper)
+
Prints the contents of an XSB file in human-readable form.
+
 
+
inst2xsd (Instance to Schema Tool)
+
Generates XML schema from XML instance files.
+
 
+
scomp (Schema Compiler)
+
Compiles a schema into XMLBeans classes and metadata.
+
 
+
scopy (Schema Copier)
+
Copies the XML schema at the specified URL to the specified file.
+
 
+
sdownload (Schema Downloader)
+
Maintains "xsdownload.xml," an index of locally downloaded XSD + files. URLs that are specified are downloaded if they aren't already cached. + If no files or URLs are specified, all indexed files are relevant.
+
 
+
sfactor (Schema Factoring Tool)
+
Factors redundant definitions out of a set of schemas and uses imports + instead.
+
 
+
svalidate (Streaming Instance Validator)
+
Validates a schema definition and instances within the schema.
+
 
+
validate (Instance Validator)
+
Validates an instance against a schema.
+
 
+
xpretty (XML Pretty Printer)
+
Pretty prints the specified XML to the console.
+
 
+
xsd2inst (Schema to Instance Tool)
+
Prints an XML instance from the specified global element using the specified + schema.
+
 
+
xsdtree (Schema Type Hierarchy Printer)
+
Prints an inheritance hierarchy of the types defined in a schema.
+
 
+
xmlbean Ant task
+
Compiles a set of XSD and/or WSDL files into XMLBeans types.
+
+

dumpxsb (XSB File Dumper)

+

Prints the contents of an XSB file in human-readable form. An XSB file contains + schema meta information needed to perform tasks such as binding and validation. + "XSB" stands for XML Schema Binary.

+

Syntax

+
dumpxsb myfile.xsb
+

Options

+
+
myfile.xsb
+
The name of an XSB file.
+
+

Example

+

The following command and output example use an XSB file generated by compiling + the schema (in EasyPo.xsd) that accompanies the SubstitutionGroup sample.

+
dumpxsb PurchaseOrderDocument.xsb
+

Output:

+
PurchaseOrderDocument.xsb
+  Magic cookie: da7ababe
+  Major version: 2
+  Minor version: 22
+  Release number: 0
+  Filetype: FILETYPE_SCHEMAPOINTER
+  String pool (2):
+  1 = "schema.system.s633ECC92E6CC0ACA137B11B7B38CA3A8"
+  Type system: schema.system.s633ECC92E6CC0ACA137B11B7B38CA3A8
+

inst2xsd (Instance to Schema Tool)

+

Generates XML schema from XML instance files.

+

Syntax

+
inst2xsd [options] instance.xml*
+

Options

+
+
-design [rd | ss | + vb]
+
The XML schema design type to use for the generated schema.
+
rd — Use russian doll design; local elements and + local types.
+
ss — Use salami slice design; global elements and + local types.
+
vb (default) — Use venetian blind design; local + elements and global complex types.
+
+
-simple-content-types [smart | string] +
+
The manner for detecting content types (leaf text)
+
smart (default) — Use a likely type, such as xs:byte + for a value of "123".
+
string — Use xs:string as the type.
+
 
+
-enumerations [never | number] +
+
Whether to use enumerations.
+
never — Never use enumerations.
+
number (default: 10) — Use number as the threshold + for enumerations. Specifying "2" will create enumerations for elements + with no more than two different values.
+
 
+
-outDir [dir]
+
The directory for output files.
+
dir — Directory path. Default is '.' (the current directory). +
+
 
+
-outPrefix [file_name_prefix]
+
The prefix for output file names.
+
file_name_prefix — Prefix to use. Default is "schema". +
+
 
+
-validate
+
Validate input instances against generated schemas.
+
 
+
-verbose
+
Print more informational messages.
+
 
+
-license
+
Print license information.
+
 
+
-help
+
Print help information.
+

Example

+

The following example generates schema0.xsd from Purchase-Order.xml, with + salami slice schema design, simple content types detected where possible, and + enumerations limited to elements with four different values.

+
inst2xsd -design ss -simple-content-types smart -enumerations 4 Purchase-Order.xml
+

scomp (Schema Compiler)

+

Compiles schema into Java XMLBeans classes and metadata. Schema-related work + with XMLBeans begins by compiling schema to generated Java types. You can use + scomp to compile schema from the command line. XMLBeans also provides an Ant + task, xmlbeans, which you can use to compile schemas. + For run-time schema compilation that doesn't generate files, see the org.apache.xmlbeans.XmlBeans.compileXsd + methods.

+

For more information about the types resulting from compiling schema, see Java + Types Generated from User-Derived Schema Types, XMLBeans + Support for Built-In Schema Types, and Methods + for Types Generated From Schema.

+

For more information on getting started with XMLBeans, see Getting + Started with XMLBeans.

+

Syntax

+
scomp [options] [dirs]* [schemaFile.xsd]* [service.wsdl]* [config.xsdconfig]*
+

Options

+
+
-cp [pathA;pathB;pathC]
+
Classpath specifying classes to include during compilation.
+
pathA;pathB;pathC — Class search path of directories and + JAR files.
+
 
+
-d [dir]
+
Target directory for CLASS and XSB files.
+
dir — The directory path.
+
 
+
-src [dir]
+
Target directory for generated JAVA files.
+
dir — The directory path.
+
 
+
-srconly
+
Do not compile JAVA files or jar the output.
+
 
+
Note that XSB files are needed in order for CLASS files compiled from the + sources to be useful as XMLBeans classes. To get only JAVA files, + use -src to specify a directory for the JAVA files. To get JAVA and XSB + files in the same directory, use -d to specify a directory that will + include both. To get JAVA and XSB files in separate directories, + use -src for the JAVA file destination and -d for the XSB file destination. +
+
 
+
-out [jarFileName]
+
The name of the output JAR that will contain the result of compilation. + The default is "xmltypes.jar".
+
jarFileName — The name for the JAR containing generated + files.
+
 
+
-dl
+
Permit network downloads for imports and includes (this permission is off + by default).
+
 
+
-noupa
+
Do not enforce the unique particle attribution rule.
+
 
+
-nopvr
+
Do not enforce the particle valid (restriction) rule.
+
 
+
-noann
+
Ignore annotations.
+
 
+
-novdoc
+
Do not validate contents of <documentation> elements.
+
 
+
-compiler
+
Path to external Java compiler.
+
 
+
-javasource [version]
+
Generate Java source compatible for the specified Java version (1.4 or + 1.5).
+
 
+
-ms
+
Initial memory for external Java compiler; the default is "8m". +
+
 
+
-mx
+
Maximum memory for external Java compiler; the default is "256m". +
+
 
+
-debug
+
Compile with debug symbols.
+
 
+
-quiet
+
Print fewer informational messages.
+
 
+
-verbose
+
Print more informational messages.
+
 
+
-version
+
Print version information.
+
 
+
-license
+
Print license information.
+
 
+
-allowmdef "[namespace] [namespace] + [namespace]"
+
Ignore multiple defs in given namespaces. Use ##local to + specify the no-namespace in that list.
+
 
+
-catalog [fileName]
+
Catalog file to use for resolving external entities. With this option, + scomp uses org.apache.xml.resolver.tools.CatalogResolver for + resolving. Note that to use this option, your classpath must include resolver.jar + from http://xml.apache.org/commons/components/resolver/index.html). Copy resolver.jar + to the XMLBEANS_HOME/lib directory, so that the script can pick it up from + there. You can use the sdownload tool to ensure that + required schemas are present for compilation.
+
fileName — A path to the catalog file.
+
 
+
dirs
+
Directories containing XSD (and possibly XSDCONFIG) files that should be + compiled.
+
 
+
schemaFile.xsd
+
The names of XSD files that should be compiled.
+
 
+
service.wsdl
+
A WSDL file for which types should be generated.
+
 
+
config.xsdconfig
+
The name of an XSDCONFIG file. Use an XSDCONFIG file to guide the naming + of generated classes and packages. Without an XSDCONFIG file, scomp uses the + schema's type names and URI for classes and packages.
+
+

Example

+

In the following example, scomp compiles EasyPO.xsd, guiding type naming with + po.xsdconfig. scomp puts generated CLASS and XSB files into a classes directory + one level up, and JAVA source files into a src directory one level up. Source + files will be compatible with Java version 1.5.

+
scomp -d ..\classes -src ..\src -javasource 1.5 EasyPO.xsd po.xsdconfig
+

Here, scomp compiles all of the contents of the schemas directory and puts + the generated files into poschema.jar one level up.

+
scomp -out ..\poschema.jar schemas
+

The following example generates JAVA source and XSB files from the schema + in EasyPO.xsd. No CLASS files are generated, and the JAVA and XSB files are + put into src and xsb directories, respectively.

+
scomp -srconly -src ..\src -d ..\xsb EasyPO.xsd
+

When the schema features imports or includes and you want to use a catalog, + you can tell scomp to use the default catalog resolver (org.apache.xml.resolver.tools.CatalogResolver); + you specify a catalog file with the -catalog option, as in the example below. + (Note that this requires resolver.jar, as noted above for the -catalog option.) + In this example, scomp compiles schemaThatUsesRequiredSchema.xsd into myschemas.jar, + resolving imports from requiredSchema.xsd through xsdownload.xml. The sdownload + tool is executed first — this ensures that requiredSchema.xsd is present + for compilation, but does not actually download requiredSchema.xsd unless the + URL at which it's found isn't already cached. This is more efficient than using + scomp's -dl option, which attempts to download every time.

+
sdownload "http://some.org/requiredSchema.xsd" 
+scomp -out ..\myschemas.jar -catalog xsdownload.xml schemaThatUsesRequiredSchema.xsd
+

When a schema features multiple element declarations of the same qname, such + as multiple <xs:any> particles, you might want to disable to "unique + particle validation" rule, which would ordinarily invalidate the schema. + To do this, use the -noupa option, as in the following example.

+
scomp -out ..\myschemas.jar -noupa schemas
+

scopy (Schema Copier)

+

Copies the XML schema at the specified URL to the specified file.

+

Syntax

+
schemacopy sourceurl [targetfile]
+

Options

+
+
sourceurl
+
The URL at which the schema is located.
+
 
+
targetfile
+
The file to which the schema should be copied.
+
+

sdownload (Schema Downloader)

+

Maintains "xsdownload.xml," an index of locally downloaded XSD files. + URLs that are specified are downloaded if they aren't already cached. If no + files or URLs are specified, all indexed files are relevant.

+

You can use this tool when using scomp, in conjunction + with scomp's -catalog option, to ensure the presence of schemas that are required + for compilation because they're imported or included. This is an alternative + to using scomp's -dl option, which would hit the Internet on every invocation + of scomp. When you use sdownload with -catalog, the download occurs only if + the URL is not already cached. See the scomp section for an example.

+

Syntax

+
sdownload [-dir directory] [-refresh] [-recurse] [-sync] [url/file]
+

Options

+
+
-dir directory
+
The directory for the xsdownload.xml file (the default is "."). +
+
directory — The directory path.
+
 
+
-sync
+
Synchronize the index to any local XSD files in the tree.
+
 
+
-recurse
+
Recursively download imported and included XSD files.
+
 
+
-refresh
+
Re-download all indexed XSD files.
+
+

sfactor (Schema Factoring Tool)

+

Factors redundant definitions out of a set of schemas and uses imports instead. +

+

Syntax

+
sfactor [-import common.xsd] [-out outputdir] inputdir [-license]
+

Options

+
+
-import
+
The XSD file to contain redundant definitions for importing.
+
common.xsd — A path to the file.
+
-out outputdir
+
The directory into which to place XSD files resulting from refactoring, + plus a commonly imported common.xsd.
+
inputdir
+
The directory containing the XSD files with redundant definitions.
+
-license
+
Print license information.
+
+

svalidate (Streaming Instance Validator)

+

Validates the specified instance against the specified schema. Unlike the + validate tool, svalidate uses a streaming model through + which you can validate much larger instances with less memory (if the schema + permits it).

+

Syntax

+
svalidate [options] schema.xsd instance.xml
+

Options

+
+
-dl
+
Enable network downloads for imports and includes.
+
 
+
-nopvr
+
Disable particle valid (restriction) rule.
+
 
+
-noupa
+
Disable unique particle attribution rule.
+
 
+
-license
+
Print license information.
+
 
+
schema.xsd
+
The schema against which to validate.
+
 
+
instance.xml
+
The instance to validate.
+
+

validate (Instance Validator)

+

Validates a the specified instance against the specified schema. Compare this + tool with the svalidate tool, which is useful for validating + very large documents.

+

Syntax

+
validate [options] schema.xsd instance.xml
+

Options

+
+
-dl
+
Enable network downloads for imports and includes.
+
 
+
-nopvr
+
Disable particle valid (restriction) rule.
+
 
+
-noupa
+
Disable unique particle attribution rule.
+
 
+
-license
+
Print license information.
+
 
+
schema.xsd
+
The schema against which to validate.
+
 
+
instance.xml
+
The instance to validate.
+
+

Example

+

The following simple example validates PurchaseOrder.xml against EasyPO.xsd. +

+
validate ..\schemas\EasyPO.xsd PurchaseOrder.xml
+

In this example, MySchema imports types from another schema and also includes + multiple particles defined as <xsd:any> types. The validate command here + locates the external schemas for importing (providing there is network access + to the schemas) and ignores the validation rule whereby multiple particles of + the same qname render the schema invalid.

+
validate -dl -noupa ..\schemas\MySchema.xsd AnInstance.xml
+

xpretty (XML Pretty Printer)

+

Pretty prints the specified XML to the console.

+

Syntax

+
xpretty [options] file.xml
+

Options

+
+
-indent numberOfSpaces
+
Indent the specified number of spaces.
+
numberOfSpaces — The number of spaces to indent.
+
 
+
-license
+
Print license information.
+
+

xsd2inst (Schema to Instance Tool)

+

Prints an XML instance from the specified global element using the specified + schema.

+

Syntax

+
xsd2inst schemafile.xsd -name globalElementName
+

Options

+
+
schemafile.xsd
+
The schema file defining the element to print.
+
 
+
-name
+
The name of the global element
+
globalElementName — The local name of the global element + to use as the root of the printed instance.
+
+

Example

+

The following command and output use the schema that accompanies the SubstitutionGroup + sample.

+
xsd2inst easypo.xsd -name invoice-header
+

Output

+
<eas:invoice-header xmlns:eas="http://xmlbeans.apache.org/samples/substitutiongroup/easypo">
+    <eas:ship-to>
+        <eas:name>string</eas:name>
+        <eas:address>string</eas:address>
+    </eas:ship-to>
+    <eas:bill-to>
+        <eas:name>string</eas:name>
+        <eas:address>string</eas:address>
+    </eas:bill-to>
+    <!--Optional:-->
+    <eas:product id="3"/>
+    <!--Optional:-->
+    <eas:comment>string</eas:comment>
+</eas:invoice-header>
+

xsdtree (Schema Type Hierarchy Printer)

+

Prints inheritance hierarchy of types defined in a schema.

+

Syntax

+
xsdtree [-noanon] [-nopvr] [-noupa] [-partial] [-license] schemafile.xsd*
+

Options

+
+
-noanon
+
Don't include anonymous types in the tree.
+
 
+
-nopvr
+
Disable particle valid (restriction) rule.
+
 
+
-noupa
+
Disable unique particle attribution rule.
+
 
+
-partial
+
Print only part of the hierarchy.
+
 
+
-license
+
Print license information.
+
 
+
schemafile.xsd
+
The file containing the schema whose hierarchy should be printed.
+
+

Example

+

The following command and output use the schema that accompanies the SubstitutionGroup + sample.

+
xsdtree easypo.xsd
+

Output:

+
xmlns:xs="http://www.w3.org/2001/XMLSchema"
+xmlns:eas="http://xmlbeans.apache.org/samples/substitutiongroup/easypo"
++-xs:anyType (builtin)
+    +-xs:anySimpleType (builtin)
+    | +-xs:string (builtin)
+    | +-xs:normalizedString (builtin)
+    | +-xs:token (builtin)
+    | +-type of color element in eas:clothing-type (enumeration)
+    +-type of element eas:invoice-header
+    +-type of element eas:purchase-order
+    +-eas:product-type
+    | +-eas:clothing-type
+    | +-eas:book-type
+    +-eas:name-address
+

xmlbean Ant task

+

Compiles a set of XSD and/or WSDL files into XMLBeans types. See xmlbean + Ant Task for more complete documentation on the task.

+
+

Related Topics

+

Getting Started with XMLBeans +

+
+ + + + diff --git a/xmlbeans/docs/images/conCursorTokenLocations.gif b/xmlbeans/docs/images/conCursorTokenLocations.gif new file mode 100644 index 0000000000000000000000000000000000000000..de66d389119a029b40b3098044a86a6ba2896a68 GIT binary patch literal 17745 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 tag. */ +span.langinline { + font: 100% Courier New Courier mono; + font-family: "Courier New", monospace; +} + +/* The listplain style narrows the margin between the formatted line and the one before it. + It is to be used when creating a second paragraph in a list item, along with the indent and + unindent buttons in Dreamweaver. */ +p.listplain { + margin-top: 0.7em; + margin-bottom: 0; + padding: 0em; +} + +/* All text in the navtitle style should include a link to another topic. + The navtitle style is used in navigational node topics, in Class reference + topics, and in Method reference topics. For example, in the "Topics + Included in this Section" section of a navigation topic, you include the links to all of + the topics in that chapter, along with a brief description of what you'll find in each. Use the + navtitle style for the linked text. It differs from a normal paragraph style in that it does not + include an extra paragraph break between the link and the descriptive text. */ +p.navtitle { + margin-top: .6em; + margin-bottom: 0em; +} + +/* The navdesc style is used in navigational node topics, in Class reference + topics, and in Method reference topics. For example, in the "Topics Included in this Section" + section of a navigation topic, you include the links to all of the topics in that chapter, + along with a brief description of what you'll find in each. Use this style for the descriptive text. + It indents the text one tab stop and keeps the margin between this style and the navtitle style small. */ +p.navdesc { + margin-bottom: 1em; + margin-left: 1.9em; + margin-top: 0em; +} + +/* The notepara style indents your text to the tab stop for note + text. You should always begin Note text with the word "Note:" in + boldface. */ +p.notepara { + margin-left: 2em; + margin-right: 2em; + margin-bottom: 1.5em; +} + +/* The partname style resembles the navtitle style in that it keeps the next paragraph flush with it. + You use it when you list the parameters in a reference topic. It is also used currently in the + glossary to designate glossary entries. It renders text italic. + The partname style should always be followed by the partdesc style.*/ +p.partname { + margin-top: .6em; + margin-bottom: 0px; + font-style: italic; +} + +/* Use the partdesc style when you describe the function of the properties, parameters, or exceptions + listed in a reference topic. It is also used currently in the glossary to designate glossary + definitions. The style indents the description slightly. + The partdesc style should always follow the partname or attribute style.*/ +p.partdesc { + margin-bottom: 1em; + margin-left: 1.9em; + margin-top: 0em; + +} + +/* The point of the proctitle style is the same as the point of the relatedtopics style. + It applies to all headings that begin with "To [do something]". It looks identical to the h4 style. */ +p.proctitle { + font-size: 110%; + margin-top: 1em; + margin-bottom: .6em; + font-weight: Bold; + +} + +/* Use the relatedtopics style, for the words "Related Topics" at the end of a topic. + It looks identical to the h4 style. */ +p.relatedtopics { + font-size: 120%; + margin-top: 1em; + margin-bottom: .6em; + font-weight: Bold; +} + +/* The syntax style renders text bold. Use it to style all syntax lines under the + Syntax heading of reference topics. */ +p.syntax { + font-family: monospace; + line-height: normal; + font-weight: Bold; +} + +/* Use the syntaxindent style to indent sub-properties of syntax declarations. */ +p.syntaxindent { + font-family: monospace; + line-height: normal; + font-weight: Bold; + margin-left: 1.5em; + margin-top: 0em; + margin-bottom: 0px; +} + + +p.fileurl { + font-size: 8pt; +} + +p.modifieddate { + font-size: 8pt; +} + +/* The syntaxpartname character style renders text italic. Use it to designate + syntax elements in reference topics.*/ +span.syntaxpartname { + font-style: italic; + font-weight: normal; +} + +/* These specifications dictate the margins and width of tables. */ +table { + width: 90%; + margin-top: .6em; + margin-bottom: .3em; +} + +/* The background of header cells is grey, and the text is bottom-aligned. */ +th { + padding-left: 8px; + padding-right: 8px; + background: #cccccc; + text-align: left; + font-size: 80%; + font-family: Verdana, Arial, Helvetica, sans-serif; + vertical-align: bottom; +} + +/* The text in normal table cells is top-aligned. */ +td { + padding-left: 8px; + padding-right: 8px; + background: #ffffff; + vertical-align: top; + font-size: 80%; + font-family: Verdana, Arial, Helvetica, sans-serif; +} + +/* This style creates space above and below table text between paragraph and the table borders. */ +p.tabletext { + margin-top: .6em; + margin-bottom: .6em; +} + +/* The editor uses this style when creating template guides to designate a style annotation. + You probably won't want to use it anywhere else in the guide. */ +span.template { + color: #FF00FF; +} + +a.toc-node { + font-size:11px; + color:000000; + margin-left: 0px; + margin-top: 0px; + margin-bottom: 0px; + white-space: nowrap; + font-family: Tahoma; + background-color:#FFFFFF; + text-decoration:none; +} + +/* The userinput style renders text monospace.Use this style to highlight text that a user + types into a text field. */ +span.userinput { + font: 100% Courier New Courier mono; + font-family: "Courier New", monospace; +} + +/* Standard HTML tags. */ +ul, +ol { + font-family: Verdana, Arial, Helvetica, sans-serif; + list-style-position: outside; + list-style-image: none; + margin-top: 0em; + margin-bottom: 0em; +} + +/* Standard HTML tag. */ +ol { + list-style-type: 1; + margin-left: 2em; +} + +/* Standard HTML tag. */ +ul { + list-style-type: disc; + margin-left: 1.5em; +} + +/* Standard HTML tag. */ +li { + margin-top: 1.3em; + margin-bottom: 0em; +} + +a:link { + color: #3366CC; +} +a:hover { + x-text-underline: normal; + /*begin!kadov{{*/ text-decoration: underline; /*}}end!kadov*/ +} + +a:active { + x-text-underline: normal; + /*begin!kadov{{*/ text-decoration: underline; /*}}end!kadov*/ +} + +a:visited { + color: #803380; +} + +a { + x-text-underline: off; + x-text-overline: off; + x-text-line-through: off; + /*begin!kadov{{*/ text-decoration: none none none; /*}}end!kadov*/ +} +a:link { + color: #3366CC; +} + +a:hover { + x-text-underline: normal; + /*begin!kadov{{*/ text-decoration: underline; /*}}end!kadov*/ +} + +a:active { + x-text-underline: normal; + /*begin!kadov{{*/ text-decoration: underline; /*}}end!kadov*/ +} + +a:visited { + color: #000066; +} + +div.footer { +} + +.buttonclass +{ + font-size:10px; + height:20px; +} + +.formclass +{ + font-size:10px; + height:17px; +} + + + + +/*DEPRECATED*/ +p.codeblock { + font-size: 100%; + font-family: monospace; + line-height: 1em; + x-text-tab-stops: repeat 1in; + white-space: nowrap; + color: #000000; + cursor: text; + padding-right: 1em; + padding-left: 1em; + padding-top: 0em; + padding-bottom: 0em; + margin-bottom: 0em; + margin-top: 0em; + x-text-underline: Off; + /*begin!kadov{{*/ text-decoration: none; /*}}end!kadov*/ +} + +/* DEPRECATED */ +p.bulletindent1 { + margin-left: 1.5em; + margin-top: 0; + margin-bottom: 0; +} + +/* DEPRECATED */ +p.bulletindent2 { + margin-left: 5.1em; + margin-top: 0; + margin-bottom: 0; +} + +/* DEPRECATED */ +p.bulletindent3 { + margin-left: 4.3em; +} + +/* DEPRECATED */ +p.indent1 { + margin-left: 1.5em; + margin-right: 1.9em; +} + +/* DEPRECATED */ +p.indent2 { + margin-left: 2.9em; + margin-right: 1.9em; +} + +/* DEPRECATED */ +p.indent3 { + margin-left: 4.3em; + margin-right: 1.9em; +} + +/* DEPRECATED */ +p.numberedindent1 { + margin-left: 2.2em; + margin-top: 0; + margin-bottom: 0; +} + +/* DEPRECATED */ +p.numberedindent2 { + margin-left: 6.3em; + margin-top: 0; + margin-bottom: 0; +} + +/* DEPRECATED */ +p.numberedindent3 { + margin-left: 10.5em; + margin-top: 0; + margin-bottom: 0; +} + +/* DEPRECATED */ +p.tabletitle { + margin-left: 0; + font-weight: Bold; +} + + +/* These styles are used by the search results page */ + +.search-node { + font-size:10px; + color:000000; +} + +a.search-node { + font-size:10px; + color:000000; +} diff --git a/xmlbeans/external/lib/jam-0.1.0-src.jar b/xmlbeans/external/lib/jam-0.1.0-src.jar new file mode 100644 index 0000000000000000000000000000000000000000..158a0239f1d55139e1676f090d47551be6f850a8 GIT binary patch literal 173899 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 z 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

P8O*}gWpIgw#(DU`t-4gfBhrM?MuX^f6 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

dTLiHd1SwY!99^z#7U?@Q^ewLnCVd> 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

ibXp%n;+}|rf$)pM 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≶o;WWa*x@ENi=$)Ft=X)RYf`3fipMYa z0@)hoG1po|y^0LJ#vP!#gQ8n0wDP#2<+M^5qLQY0le_UCz&8^+*f=>199fdP4fsDr zn>0Fy-B>gAGSjB?w|bB)Lx*s&Ce(e~AW-1I!>u&3s=`i@BJB_cgN37e9uULYW-2!S zAh)t~8j@v!6+^ywes0R2dn7S2*58{x#}%Tl7?|=ID+&6jHW3zE-$31PU;GjBNy<5Bw!2TYlRrxlf<^bIwj%cu3GgOlw033^}mz$TnX|V zQ2Lq8?aq-}nkHPsPX){NrC1JHca12<{Vy}>m!pVxAfc=UxM^7cSH{11J^G((>OW8G zf84t5=5(+=Z(yMO>WruwU@2GMj>_bPp#@{W-wD_+=&HZmx)Sq$U4I$2PhV7Fp4Yoi zW-{DPjAvrn*(ohudG%SBCO}LrbX7Qr9$gTJjW{k~4Z~dIeNVcUO50~Nt3_l>>9(Tp z91w)E`Mc9xiTrA{)W>@8Q+D-KS}DWUCS#S!oPxQErIw)6rlTnI>I{q(n`{Fd97P&M ziqT;?Hn9z4!K%S#FLk?stmRbk9fwJEc?P+{A~bH1+Wst*Li~w(an54V+RwzgQ<}|c z9&dYkxT*Z!1}UmLi`6aM(tgWf_WP= zUrZj*7%K}Wx8@^VtW0J4&U3IKFrk>s;3Gl#D*D>TR+R7-O-3>@0ZnG%&?S_`Om{zz zt>ZOQr(R)B;ZOc#F#AYQfbDH#UcfntcF1`-iOO>^V zRuh_`U*E!`v!@wlwT|iTTGxHUZFH5a7Jq8uF>+Eos;{U~E~hDYTc7lp%L_Fj@j9F{ zJ+Ot)gJAb92B+}_!z(0>pV<%yqlZPZs+CxR4|w z-OaXX4($Fry%=vMlauzlwXBo3;YcmS4ZgD?H$&|F&)Nc`g6}$5I*>?6pnS*pwU>n) z*aHYuE@kK=tH^s=|MDpI^7XK=ZBTCpj@vK5K>q*!>+z2!eF3m{qP^HV8N`BYJki7@ zC`i9Y3e={f&F7f)R>##rlNgIq#FiZSSLQc=Yf9{XODJC;=jjbDuVO`d zQH{-P=)+5oo+*ErB>B>#D^p@`H?ZjH*9I)wc4KEuD1;!n8Fy~Ns&>KAmF~vBiB^*q zkN?)yq0Q=oTi8c;lBREe=%p+0N%H zWLXDYQ8k+7T*j~HJ1P){MwwLmtfh%T4%p^m;PY&jiVvos>>=#8%it6Z=6?Lr-cAfn zJz=F{<4?zNi(@4;*@^GVi<4Wpzsqx-rDeI{E9W67_fwm3T)ejgcz5(Vqb~F$K8$f^ zrbh=F1qqh^2OJva208t3kJaoDnY2Rp4K|$v^2o)^3;5h-M<(;Q-8o!X<@vtkSHo>5 zR$v52xIRu6o-4eOQ`QP!Rny$k;xB*NUWd0k=QIjWN7s~U;+_Rlad#IxNpMlFvrJvZ z(}Avy-^H(GGmh*dj4-%1Xl`8vFC%j*7wx|#&gH6#_L*Q@G##2PIAB_QwCL7h^C<}g z8MDV4yGIfiUKnxV>LlpeI8T@NJ7BF-Ol)rLd6_RHnSaJJE%S9tVV9#;Ro$XawW-|{ z`L>^o^6eAcyPsC5&Un~*y1iWtuL@kQKE`jb2iXBT^QL}Ueq|ILG{`W3xhC#Ab`M$( zHZ9APh{{=EZdTVI*$AiYpzP>87$1FsUD=YU-*#n*e$aX#zsdW-bDQDC1(v15=Im@{ ztWX#ZW}wP=?2KY++`Vwmo>|R&>KlxorIK*I%#X-e>>h{9Wl+U@5KA*xs#0*V1o%3W z5p{P3`F^e-H5gOjf)`(2(D)d5k^81-kZ& z49h5!eCN&=h*8@lEUgIr4OHy;PVog)EY*8$oOI&Wm^aP9y&>Q`)os0N-#hyQ6#U}` z*mq^1c*+brw{g^1Pm%*b#i`y&JOFt3)6qj1ng`n^cR(b{4(24V726E3<>a|q^X!jf z)_?gXN%Kdtrz*UBz~{FQe10Jndk|Q=LmTcdx5fhh$R;MCE@Hm(^KgNiOZG{rKuhWB z6z7V~3#s@ZtkhTTHYNA+>l$usM=SKLMjEKyaGi*@z7PDaA~eQvU~C1{#8Y+Hmq!-g z_RT%Qro|&;|Jf3)8oLFtm)t%)wJmET`D_bS-U<5J_q&r$4|h6qsNXxOCxq-Vd3sI} z525uPoRiSkYf^)&0WQyWY&rBIGXxDYA`zAB4|IR;V@}u3?85-@Z~(OF|6*kDck%GY zJpONfPX0gqoM=d}CaR=yXhA?eMS$tAX%%b4A@%k%f7fE5SJ!qmT=!)hzDgrP%b4Bd z1kiG=$xHEb@Az6>-_rZIzFDdx=m{nfqw$Ac4BAjYG1gnJTk;oM{A$VODYXj&_f{4r z2YrzKJHOj;LkHdLZ<#6tKPm=?8g_nB)=7((C=@nWaD$B8YRRy=15-2^fCMZHpE1kB zidA#1C{ddmPGvpp2=uQO^;_fdH3agx2Drf$V^BqDd!~4G+?Ru9B6W60A7k5Aq3Bbe zq&2qD1u<)jSWZjc2Gb?jPZdwUW3bK2=C4{+ww+JWnL_`zAfy3t(&g30(+3Oa$QSA8CA8GXKr5#t1|E8-~=BPzSLOF%0oo{w_2e{0^EyiqY%aE-6P4 zf^#cZBJO4Q=dr6t5=b3?&HpO&m-nbl^Yxl(pz|^Z8uowj9`%Qf^N+pN0r& z8ezJ8z>yXR*wg+1r_BEsI0g5w;1pv4egQ2Bu9RAUWZZIE`zy8O)hvImr$pW1YQT>| zcsZ*f+8KOP&bq!6`XHeM=lLLR2IMs*XCS*mCJ#vL75go*w=;?rWsPTu5%sMT8TRyj z&wBN0`4{5lN)&ZacDrhHus((lT`i88SfD$s~(An z-#MX(R?>OJg&Ao267iyuRop@=QP^YG4ENt~E=<(p@X`rz^br*|#MJAuxF2|?GmO?l zZ)xbgRg}8-(8@=sQCsX_6g;qC!D2N;(~QkBJTnq!6vo9Qs8L_+#)mWmsh>qkKW_3p zZca;UfIm!1^PWeV!$4g7$c#trGwLfPPPt;^4bT%G4BPgv;u&uQ{tVf$%E~x|7OY<4 z$f8&%BDdzszdr|?e~0_nt@1DsWbgs(x#wz303YG83!Qqr@spx)8*d;xTP#DrIyLGy zAI4N2AD#1KkurzJk-V0>@AJ*qN;l%4(?C8E<>D)sC>)_IDr``Nk;9w`r1K;XZ@P?w zDQRQeOp`W?t$hdE;TJ~!!q|B!6j|;`cwb zBH>3w3V5-E(eH^LrMzus4vZ_>msytW_C-b0GQT%I8|a_!UYWD2y$3id@~v}A z-HoT8*Xvk`WLl~X4O4!_$1la7wmLlB;kGHW^El#L*b@7j(v@iQcV^VJP;{sgQTvxs zcLYEc5*7KM)Ic5Z?DlZsEKi*PX?{Z%!wV&bvt))?BSCt}XCU(^IGf0WDILNd_=Txr zo%}RK8|SH^M%zrIUD*`H8f)}WX?haFByN`D0TouwJT#l8CY?9*nfaja9{li zQu+9?^ZpNz%Jy#{m6IH-K3o8#Vw;q;2KEO?CAXAT9{{QJmpt=)mVD9>*D zmFG?{F-J=jAfNLW8*WCGDFq0!NPT9@ECcd-Ne6102AC`3!&#ie znk5<9=aaOZrJQ^TSu7TsxMk_pVkd%Oeet)~!bn&j^>bxdZ`I1&j;Gm)mtEoCWn1D4 z!*ImmoKe7iH`((YjOqBghy=`UB$26+Yd+m5d3!;1p^<6l{tczVP}?OL`X@@I3P7m{ z|Atc08YcP!rGjW-Y0+KIqj9NVFV217ryoU_$v#DU|5!AIHjp3!%yD{EfH}@0)EJ*G z-glE@XiW46Y#^_9tWr;+k~0|ZaX!LoEwh1nY)0z-mM1(LG8l8$$%-9U}05KqGI-t(H*%jn4zm* z8|)`AuCb<2lAuW*U4GB&CDVUT1;kh|;N>1{05KM+C*jiGy~-~!7P<1hUZLD5atPrs zQyiC7@~IYe8ApokdlD(17InD;@RYOkPGG(=8H^1%T4#m!Ts5y8xn8R~JhH0nZzFs} z?R)(5w^Ry19DYZ8HXi&9r84q@QW^Oz$oHXXzFsw;72SpxOnu!|0rjJzT{X$ewASKSL`I&5q!2CdTuAVGPofmN?jIlN0B9T z;Ea-<*(6;|CEDIoKd&0+CUj@?;fj({T$|vy;~H;0e*KJx{K8V%UTNL$`3p;B`5!}^ zpIjR8;#W@jqRjS z)3C9vHnx-Vb*;Vj*=t>#=fC&K)0;H6-<)&IG2ihUN@%YPYegX}NXX#Kg@thiXu?R| z&@se==0r6Bcerh(T4}mz(IZrFR1!p@@WS$qYNt(Klp-!vGW~k>s&(T*VY1D$=gsd8 z+6c)JMTuz{3Y~EqEBVr#GzrU*>?+hxeu%lmM2BHmy;FsmG{j;j!&D0A;pUFEax{AA zQ(bP3r4fXvEAXl3t-MmS(1;Y!#Rw-Sj?x|txdd=f+QS#vvp;$CYmHCHW`9Mx@$N$* zTc}iFwbO0Ijs`I1SYa-49aUHS2CK-A!b>zz4!)0BXIZx%^VKPqu(@ZKg@VKUKX8TQ zm>PY)vbQx+>rJ{H!;4<(MHN0GwG2QGSBVS=3z+v84Io1gCn)ZDJP0h%J2-}WQ#}4k zVjA^L3s9Ou>`ao3V_C5Dk788w`ym_Ag%bZwj71@GQ`e=G{xa1?xYfACp1Vwnj9ZzU zpN&P4=hd_qiF6|DgjKF2hW5gkB1k@~`KKbQ+idy#;R@OOYn-&&P)$<#2zqBD4d3u` z+4p5tfA+RC*p9+O)dU{xMiCYn84CwJR~iRpx{OO#GQ|&&y9V%_KT5V3>fub&%}Waq zVR3Rd%flA5Qf#t}&kJ28w^h%==B)2c}Z}pCMmd}wM+$TFzF@V z!7fYn7!%_bv(B?+7*vIp{RvLZ$8jh)87c{Y2O<8% zPi9CPBGs{-W8#yDG7~{i!H=jG75gQ0_$G9Xs`#_49FDkNt)!E5=jZDwshD8ivH+Uh zS$UYzJ0GXEK~M%dE$MF%kMPrwl_Cg}#)(cLpf{N_lEw8bD zX&ghQ(C=j!*hhXt#$TzD%4ZV?CC8!Ck)x5cdWE5&HDX^HqPn~K&``_GzHU89vhYgUyp zXRDhigP^a6t=e8b(7Iv@J$X3(sq2F{==VECW+65c1b%3(*gZyHEKK)_reJ z{hnSQU_XR=eF_Sj!>cxxA0DT3D9GryUmY<)@O01Mk%4nn>9lvLVZ>@oCmxqjmqAwJ zBM2ig`<&H;5ZF&2KiceW-Y+cw5s+>rc9dF_Ney!^jhDWZSYCKRP z8mGJe1-gqx5xo1<2eRwijX9TVdAlHmk=BzgRM<7DX8R9Tnk71R>C(d~^8D`MoNtI> zaEg}Fgn|4US~ALCsfZoHv9Z5Z%78+D#zIg_|o4+aG$F<$sU| zO?S#PJ`lXL_?Gv4DU)TaC^yq6U}Bp9IoJ7Ui3qGUP7eP{eeN%nor9rkkHcTFG)kES zHF3jAnj>hsV+M#+h;0NMBR}+gnqD3T81vL6+uF}q_dn?gXB?UhMYvEvuyW{`WX)kvdT@r?ZQj$POg;FaK@JyK2Ppqd#mAQSqgjTu*Q5Z0T<7~~06i`AcRdD6~t zS6#j(mHYDdP-EDY#~izV_Zl&D23Ln4)iTZ~y_dk-Sd4Z2CV}fex@g;Yp;5&CrLa1` zz!*NI?`APPg2SXRmcP)56-s;V!N`VOSeQQlc$%tZ?AIe$y? zd4MV4{)^Q;+Ch0|^;uUfJuezPyx>lG*d&v}%SC&^N!#iVC*o=U3)#urk{Pfebh`m^ zLeFL_3G)rP@DBS1i!QYB^ABPRybA8+%D!q9EMxxP(9Z0T`_~ZH-iMX%h?HT)3Rq;h z7srAEA7?qxVPr(le8noXQCwc;lF#V3+ZJP0HrY0f4Jug?1WP~Zw_T9+Qeef5W?oeR@iky{Q zQo+HEzE@!m&c@h*WcpgeM3PZLseOTE37WEJXm_YU(yotkrvn^~^l%3fB$?x}5|@An zqMRR&rY4sZ2UA^VylO_8VXh6sicao^YAIzv5|4**;Y<_T;Kn0q9iR9d+FdrHApQD} zYpjb~6?Q0ajYWa~uRwTzE#-eLV@-RYf)OnM!^#77TBUYQV+DqNPKiyoxM^ydMqaog zNJf;lim_E10?NUIxuYQZ?CeqT`3wKB>dWRu_Q8D--+CMGQfQKs6c;6*Cos&pKQWfW zn;iJ|bjA1%^V}6rQi+8KCDa!Bi)p_QcaXfFUGJ$RcpL&}T!7urdofA%@Us4eckm;+ zaikU6E0=u2IqdL{pVY6{e#OPv!*_Y|7ZglxERkSMw9UECEZ0Zjeubm)5Y~#b+%H$J zON(??@85FYIv7o**QIM1Rr6^qNiNP1?t|-08h*8ypx5!}Pi=(wZV=F-a@1$i@ui3D@}(cn*R=JWHGRnfO;J&JiKT-7YQsr^X2Mna)ey`mVV1oBIB6UNm9~hk1iL`ZL2v-jZt(Y znu)QtkmH9K%Hq*uGRgYX>{a}gWL8<6gIVeghS%x+ib^RwB=!PwcIT_Kk8VvOT zJ#1SSKgy|Li$G`27r1Zo+?h!!KR~%NxL41pDT~0Hwp*p=)CcCosm#-lRAkcfn$&4f zNBpW+uQi|FUDIiz+W%hfOeRwsLx&{o7d6S2fhI)(N2ZEMMhZFt_E8S_?NWZ*)vsV@ zl&t&f0?yFaGift+H0@ZiPW(yC)R>m~gi*@_OH2zlzvO|Idxidd_4MpdwWYgrr8`e# z0lo2RJ-0nuNnCMd{k6Q@s&3zoN4589zU-b_KRVD z41rN-`6xTAn3APW&h>!42TCEnUOvUEey1RPrluqX{8DOPWvt{gLsp5+WBD-q3rGe3X; znQx^6x%C703k~1GI>uF+YW+jb!cvBIOZ^_t*9+@!usIGsG1c&7KQDYT1St0sQzkbB z;3qf1rYN6s&HWI{uoNp_S-o@26u(Zf$&ykn3 zuZ3P?Um#8h;oxrgB+gzWrvijyd;%mlrV555;C}}89`&6$4btf6+1f z*S7Z0*{huYAYsELODmY|hjlj&z*b0!a`ZJG@z~kQNG%{q4tNH8mc12tDQmb*%_&MJndHi^NfxRuU ze|HgE|ItNUl!5~7X=srd7tDv+K{JL*%o-N^N*p-cl`&ekz^bMX%w9oe%8LQ6?tDz1 zaiuE=HxU8%sl(fzYgL&`RufW^>m)uR?Vyx^rq2aXdH$uKov-)_2nC4Co`)^>r*~Os9Yhxzdp-7^NXG*D{<9K*ftn z(3s_#V-E4pZ=6KMS@6Laq4MohI3Ely$(-cD2GwLaYHQE z8uiE2%UH(R;b%NqZsrF!>^_*$nq}V!2I1fI6E&iEX{JspbZyT#f{o`r#b; zE>Is)KVUK-!c9I?g*7DM$lf|^4*(AI?zc3Lo~x7U+wH*D7vNaT0P8?>=sPix60IXl zGZqh0576J)f+d*uUfeWJ4(H{wyErFDT=8du@pnbEdw z0e?C55S@-+5Ek_wD=bIDmkkc@wsYm3K>VZGW5G#aRw<2O(0G=-KQiSxRLZvZEt`}O z{^~qxa4rNvggS(`HV{ju+b{Q=kG8Lqy2zNrD`ZC8`ZKPg7(2Ww4WlyZi zGZBSMoF*jxsU}&zQ(v)d!YY&dBsN3Ts1{jjQyDN2IDQHzR1F=KS8sg$b?d@>I0lB3 z=~9<^5I-Tj*?}R)vxGX@H~qF-Uz%pGs^5oS*u_3{d6%(eQPJbUv36p%ayz)9(^;0B z)uhiZU_WPSp|)weYKoyXXpD2CmDw9VoO)`8m^(BxjKO}*a^qAKO-WIkEcf<(6!rdf z@OsD?hM&_-_O8@9)OAPqKG@gSFF%#M!n^q@MX1zBdn}Xl^AU?5lkfB?0c_;+RGqOV zek}dN%8ixkh^*hB(q=Z?@w;&$Xg2Wg*jONR{x_jZtWGclm$jq)1c*F{PkemaeVct_ zy>MFC86n;vtoF@loWYOUHcgF_Y>4q8N$>f%!jZl9j3D)5S95rLj6#@WXSqqGIfez1 zyxh~hubTJjvRWP*zeaHw#zF6rm7T-)bloKRabKTjAIIo20#SUO-%)&MWZ@h;h;xuv zsQjpvU)Y>KzIf0|PQ{t=U4P238X6wv>LSm&Uzv~7jNE_TDwfPHHr$^_z>l|GKL91`>=^^!B*ZMYso?)mjA>G{jHWFU3&$dWn>mY01 zVZP{)8dn`@MbFyGi`kZtG*K9%nNm=}*7O~DoeWl;!qW|MdrLh{h9$5f7oRCa3u%(% z6LY~^o%&lN(Y@#1L==)Bu4@3|Iwse_?u5yq$QbvB?>WPJ6O7OooTd|~ zPQshdK>)C+3*8kV-{m0M<-mYAfP3E$S}o|R82EqvXrQ*Z?J8xpO)+94f;$i@J$rux zy{!(b4IQW_u79{oTx~Ig>cPEw!J_mnI%99E!SWW|$0aiF&f9#Xx)_Jr;$_}A(qev8 zSpA^*Vur_$UkJW#;>Nv?pAT@H_($OUFeutE9xabv8OsWo`whedd?TLW7?|ICGNeq- z?}6))n&k2`P0Ea`K9{Msik5rr#hgZN5IxC)E=ECl?x48O1irQr!q$c^2>5Y)NQ!p) zCHVIv^t-yNTNvOz0e=)rL&m;6-H-!JdH~}$y@nV<=pF{O)1j0HDGOfR!{a5=- z(^f@YJqQ2s>^}{o0%e_iG&V8u>;e1)zCFBx_JU|YFb6NORa;7}f7_%;VcTbE{kUTN zS(IusF7!bdZmT-f7ljSFJro=uW!Lb>Lz)jmi4w@PP7+mNYwSWk!Hrn;^kG}j1}M$M zh8g>B`i#2EId~NqlqA~PB}zt8u@h8DC@XPhBa5fZicDs-uQ*+&mA8oS+JztK1{8h0 zYn_3|s6EHBlRn8-_Zm)MxARR7E8?u+xM) zK5;)io9PXBb%waAJq#dVNr>aS4WHXQ;<~2mnq{4WuXyB4_|;7gqS;KP2AFolcG*P+ zXhswb;Fa_%gGpLv%A^-vFP>}dZN#l;hEEWovtsYhk~XME-Pn|f#D6#rqzFT97q@TP z#^pf7y8IQ{>lO92OriW7wtz`43gdILuEjWFobpCRnUL?EzsJ!4tP;m}?`NzqP=dz^ z0z*zd-PLlFNu8XDKPL1K;bf>KCNt#_7n%IMfAn3WQ6vMm7-5)xbGc^o-vNAdJ@QHF zKLYssJs(~~IMTTWdY?dR6@dUgZBiR-I1s>h1OoV|A&}qv!n|n9{uRJy1p@eC%0K{L z;&%Wa3kcu`{^Qsm&Gj&t1T-QSpb`20`(t0y#nIjA-!K0EDG=>ZsWyC-I2y7 z-_6CJZ|H#L;!g$3>wNh+nV(0mQgWLWYit6G=OU4P9dsM$`gh(k-_vW=8t-crH;8p3 z$nCf~DfM|r`CX!4#zN-xuHSY4p$~NlYtMh{Ls;@{khLn7nE{q1_V3yQ^}%y2EBP~I zg5}DC;`QiySwk(OnA2dKK#K7nw5CN9G1+f`K9m6Tp~(OGq5MM}jsoxfK!6iKed3sK{OBMG3xm}v2;yVUD1gJ<* z6e+ylan67J0PIf?3y+oy2fk#kxY*j14FLU_w_!=Z%lh!^Oi>Wj2|)vM|3Z&)Tgub) zeKbzmz>PPu0g|zHC_1u+cq_@*EGWjP+VzhHoyA)fVd>EA@*buWZhAHr*nLtqO!iCO zIcZiN$w2iqasTI^hZ1#aQ?%G!+q-zL`BFF13r(?dOXlfzm3lbj5sJFp3Ww6T6uNYn ztYZcxnIJtg?un^(X(bG!$Y08epKnZz%Xe|oe#UUnP31M$H`Yqni|)cF*`~#lb2Vw2 z1mB`G;Tu>Bq^=h(lpEw*7#MC@kNNHBtaY9j@2G~F!Drr0$&rux!NS)d*-2lvd|9yw zF$*i1!~vh@qUtt|AW)QW#xWpYTudz5i)GHNG}Kn$L?GEaNn5p0&vt%N7|p6vI;r7q zQ1f`eGiqGqVzfBN+^kKJR!X6?)!t#yyrO5#GQE8-F+y>;CQZ8dWn`*;Nbg2fU5tF~ z!bic-Q0mFwYifTGZ@qiQmy*b<5+OG2rmwT7bb~8z&Q(L%aQCVAy$15kio~OB;(EK5 zYm0f+_fgLZD@e}06T8ZY1=S5p9{3vM&JM$oH1`GPfH@8|m5~ zrQY0NH^1VEC=QU4kAlJ$P+K9ggdnux+rS=sqYbRc96^R_iA4;62>>`?0>Df3_XGeK zg%JhQN9*9a5Vi!ylR4EX6^m$d{eUP{xaC{uD9?dghi0^P-p)It#~mynANqShl(?04 za@Bg&O?yzkOWVX+maYMedJx-Z(AKW0SnF8tRo0!YD(!$A@)t3R(t|9L2s_7-_ObfI7!d706lNSaVB&d@n2*OoxG<#t4gM5_ctB#lga)FV+}meYzJ7`Obs>g9j9&Z~ z$nNoA?s@y}(oLsItqyc*ce1PFre7JOeVt|-&aH=?`0`^(PE!we8i@@{_!;{B@xR_| zft~IxJl*Gg4wx3rg-Kw2HlPdTD-sFVA&$TQ2wHqkp*MnX|6;R&K>fTDac0ejbnkJl zLdm=-O!zy_xgq|qIH%Of7wHQC_er=vQ#|jj1ib9OB01j{*c=cyUE!-d$0HxGdWmg6 zfBv24r2Zq%2~3ves60<1TjC#(P4xe+VM&i@Kvd@yEd8D542^qlIF#1tg3Pv!!Y z_5Y&V{V&D%$AS7Uxu{_eVAX+lp}}Jc`GR7p=v#27%1Enb`jTac3br&9cwrnn>&k74 zw&LiewXsu(kic(~%h+W%Av2B>_eFSzEM#M$mUrt1d<7vu{^8YR8(D>GNu7TCN4Qp|FxZ9V%>)!LsQ z{Knnk>$~w4I}dHGb>^ZB7!TcRcBPTK%(GA|G6$e6W^x~BHU%tl2PFqsAl{OH^-sRVVWS@4h+j~S{7=>8Lh%2C#f>2(b zwMMGw5LvBc08pLptiK=haXyT^zHBf0@^fd3cX~rjx3tqZC1q2F-CFwczK& zxlT*pS$TtDUJ%$kyc|rJ=FJ8tf(Cf8TQW#q`dU9Z)aS6-lA?~%-B&prfc<29&fh89=S4n|pLzxwlVPb)~{$!pK-w`Hksp2jJEo{}Ov zn_VR_%l`V6mcFHKdh2aFlEj-z`2|y(4i^8Ec>hGG)Gs~=&OiFYP*D{Om zr$aVAfnM}FNwbL zcO>jRk&yiMP4BCyADWS#2}#BqRy2wr^s%70N}&R#dJw0x?6wM10PZNt*(Pgb-cI#^ z?|Z?I=#iDJj2F=#-pJ?41cY?9HQ&Dx&yx#$4I7Br6dha$h1-~N#W6(+j1K(p5;C&5 zX#2_g7Uq~U)M{5TW_aB@R!Pnq)E&+dIpE{BGbGPFx)(%b5ay&sGCWa)gOEFDnh#EF z;#mF1|L}CN_&0E80llsT=ykFGQHK57tNSZd`=7eq8Z;&TGO?MV7;Vc%K^Gyf$q!sQX&OFu0v6B*huSuZCkoEw?0v$q3^z8{%@-7j;N z(z9nUwl{Tz(~Z!t@|H6uK@u$jVXG2qT=JV~c0;D=01^_N_FyV`1=}EcoQ-&EMuO zxMP4T!^u0i30fdhD;t?&>^QR7rk4a@&E_O{lE|y4DA{w|U59}G6a&QVa zi2kR!d%;eK(F`0)zX0(r^Z)m&`G<(N^;}`Y8YV2UmS0IQ$Pf9!JVce?Vdt>)p)Sp% ztHiAs)2Arpy*eJfyYsOTukLLeDB(MSuL2u$pz0rdTu5I25$l3ypetoyn(~zIW?j#pWRh$e?J4FFQ4B~e*hue zSAB2+%}rR47Yg528y*IBc8N_7hfbp<^Hhy;k8iU+gH%92e1$L>jdm z&p%PCCb~_(l1k=i#@x!Fi!rNEXyDP@lB*VI#4XOI3WL}oxeKlX1{XiKx100K*!v=4 z(#7KV&d#@)Z&qq`^99M4y+=B%25_qix@}*P{e^zxR^4$=#$2AfUKXv_FXp)Hl0k#I z_u7a2aKKNIYr*mG^M-DE)mmmd9cpjEXYSm)QI=Z2fEc1M;dbUOZOZLebm)G(1(!bY zGE-#hH|8(@d0*?%@2$sP$&R^!E!yuCE-OH_ND zrW{CF($6)u{_*McwiUIN3uT>cTo!?g$kWqmo{jZi*!Jl6Fpd@E8cmrJ`WhtXJK7_> z0_jB=3&+Z$jLMj2W33%*nA}HlqbsQQr%Q4p(op=Y?d2T}tz&H${C*p2qTS0fxi;12 zf+Pvr?D7_jIJ3@J0^eHL4@`sT6iu3|va0GjJ%7eWWgG5EFXjbMk$%>{fGgFSA z;R9jBGc3SOTrQu%TroV5%7aB|00(HR(Ex2#=MUOy5e==@^D#w2^6vA>dVYV}^8i3w zrHe;cF&(YbK!aAgpoo;>U#s4P??e|uE1N^(QP!+X?QABEqb&Ut$s@oe`k4OtqNU2* zJksa&ywO`}n$gwPTe`4XklZDmJnH)XEr{$cgc|FE@Ma+CR5a!a)24R(hRf969KtKY zuBKF?V16a+YuNRqR(Lqu5CPr$YM(BNV1t%gOlV(uG2arBE{ZL@p_mN}gW&YK zbh|2(a~iJc_L&%Mcf2b>6G z50nbhI0K9$-oByRGtBD?TQ0pTAyo`tadQtdK55bM;F8{o?+hqEaPEyoDFp}&J!5pz z8%>O44i?HXTNtWM@G)2hC{XpFnC5<<1=;u99W(jC`^O*r)F)PHQw*b-4MEj=`KT>1 zq8)}Z{FS+{Qa-gQQuW}Q24Gfmp7h|lnAGhW#4M(#ob=r7cD{&QbTF^qIX7@#uBTi@ zk)I8E`AcJ;g?kCec(ICHgkYV~A7lAbT5OU|#>h@WOoKSoxls?D$VRWnOqn4#KvHmm zzS@0z^TWZxM<6|4Lft$#kGOEh1i80^Vw_?p*V;js{lf#B0X0yK1x(&qz~ud3t&P9V)IX(r$$vV% zJLQEc@5O%u`$fUfy_uB6egjvr{KRihIhu9}vN~wf6nAaOnGa!icu@rb;3{T?kgSxI zOU}|-<_5qSIR2v)G2?5r!?iJAtS)v^3u`MVeQYG$>9zsR0|A;HM@{Y8C=-kuM`SHz)WSk8ue_HM~r>40M_p{f=B~V<9rmtgi~z_bNW#tQ-WcG zB-%TyFDfFfi0X6JjZ`Phvrnusv!T_Imb-1-52jcNt8n?Sx)FV2LeKQEb2eA%!1rcb z`29#NC-N5;WSm__-0C$r^vrI1CHnP;D{j}XDs!mW?h9yr7@YW7BPlOFMv+Ywcrkbf zUmi8q&<%>uF8QlXaN@Bss0{eyGzFtH(=UF(t2z!=wm_C=^nD4Yq{-dJ?l-fO8_3CM zogoQ(GA7gGUtOn4jXq-JOhX?l_d@t?8b?@1o5at`%WwXa)~N#yOM@XC-tBw~U)dT{ za8Gye&Ht%^3GQ1X7Q!9P5U#7H790C~TZ(O)|qNZC;LtuUc4>yp*3DW3RgfK)PP zt;et0eNKq!%k95}6cKsaiInk4-p94DRVu6vcv zD)qum1X)7IKVqL{F>*L?Er#|_J!;a2*}6v5$V{m+e+mX#3H#(*5da{oY53NA>ofVL zy8!Dm?2|5%^8nj3`s=;vT>#N91t9vxi{WgqmKj4xkuAvfBIB@+3x4ZHy(43?qGM*! zrY>KpY*u9e(a*oe-CY|}r{Ng88+dG&Yu@^nXPOTV%P~eZ>Zb8+AxPT~27!i4K2fn- zq}%xjb@6E(Q_V0??Bo`b&i}V?REgvg^{gDTGfK5fcEPCoV%#;xacGy2H~)E?ZV6^$ zeEVn*b|jeAP4^Z0?_Z1X7_v_-ARPb4sepffE&tGr`oN?d*6*xAGQ*o5rs!`)=hJH4>E@ObAAOlPyFy3jo^je(musJw_;8o=N^0@C3? zHoT0)?#37?kNn&lWCiYpA~1y+Uz79dlQ9i{ZqspLspj=F!h+47O59Ot5%!*pbmd-S zma5aCu=aw5{sM=Kdiq9vm5q6-V1`M=q%L?coEdyFqvj~LL(Nee%G#2GY`N~RQl@BFOwtxi z&2#rlIJf)2dQCrjxr!;h2^&@~R*;;N4tDs=sL+Ko_^akPAMKUzYO#tz=nD{wd`=#JrwlYasW@lx?=-Vl&W#~Al42wB zQ#P~jtTQV(+RHzyyAD@2??1l+a{(SbW8?Td%UL(W&Bwa->W@F)3W_JfftD7eZAY-K z#vJ&Nd7sBLiF8lTbI)2sWYa)EH3pKtvaS`0XPF@C2T|9|ODP@k%$eNipl<2ZDOFj= zsK`B*`b6U%f1A8ybW88=y_+24(Q+g2yMtka91&A_!ZrC1GnTaw#{WY0$^S<7X_8FT z?7&C5>HrpRwFH3MU-s5Jd5%HrL3YmV6_32i2Ao_s+CLm#$MPKC5&&{`MQ(+1F#6l! zHTVPZM>#j)uhL229Du8dv%kR$1j_1>m~Rs+9`34_TMS_sCHyw}=O8w0fvlGc=O6y= z+05hTb9tF9i-9|y-`!4}=RxUm`9QbRfNoqf>AHZz%`duJLTnP59 z$Yr_ct|b$$(*ekXn!dr;7ap_RWllxvantQG)ml+&H}u~l0SS+L@9wh`oH!k})9#*0 z87*q176g1agpy#nUI_obCGs7Pi`N5c@$7#a3HWPE{Fle8_Gf#xYOU_~OLg>ekYI*( z^fmDJ?_o*QkdlM@P(r#B?0IK_`W=s!;%Ab))Pa1&Ax=~vjWWSdMMxiOoV>=$>U-Me zdAiCg7!dFPV+3=ge>j+fbvgt+$EDJW*>8q-cR>VEh09Y)Cg)jzi%32um66IsxrGdh zwTsz2z7}H*Si59ntWvlVeV(hPVG3`pU$KYk<8-HEqm;ddZ?eqy+l+mE;w;kYWMkMw z8wXxApFbFj$(tj_k`_@!wA*W~lJZuc+07(Gs8mhhky_BM@sEB3PY+|-5J7pHE2)_29HR5di(> zx>h&@Ii?JnInCXzxpe=!I;d8yN=TsqNdX$J!@Q$}U`eNbAzPVOn%FdTYFtGbB*<1t ziw>Ccq#s{d`M%GReWY87qG852NFzG^c{DBb%P1m- z#s0y-4;iiG#6H&VmQSc@&e)n??b+%EIIeXJ9PLCMmmx%Zq{19hulAS3n=Ky_>!dQY zc~hCKZc$buk1<+c8&mGV_mB~zcO3pjp+doAXkVcyrUE(6N`yWZz5fc9^iO_&MD~^I z8K5R%0gb@%e>Rpx>>N#PRn6W05|Mu)*d2hTC+xNFoH5F=aLe%Y;1~1I&@jmqspnJH zDDeuvny{tyxT!+}2T_R zbP_n4lQ8UGR)wwuC%bm%%!6dT$=diTIUhhxqDU3C=6W13aDL6Va`K`k1~;S?V%#7w zW5cN~yz0pQI^|zZ?;Bh&4Q;X&*EswBPQ;`F|L4_tLZ#3SwDvaw7Q0WW&gSiulFn!1 z`_aZY-&#vZvvq#6{J-mSt8_2IHf~-@6Y}y*huRyXqK7SSs4#s|6xGXwPhF=kgX%kJer}&J{s`QoKlz z|E34zq!i?d>t%?}4qpwnHOqi6?=lZqm2*)W{^g8`=WCA_B_|35#WriAyzFu-0q19+4F z_X(7Le?tFImS+GH8Vg`T7vC(GYOmDwEn=C{CU_{-;M$eoo7y+TiOh@4q+a?exX7-N zdsy(=KOzhW_U82h-A_RmAQuqOeXwK(M8yC8xd4G~ZCD#pI9+BVi;(gEwCI_4;2M9@ zF`6Fee@XqJ;qxs~)Sy7;2TXLj8Ji4H3Rb7hI%x$t(=LojQ$p92)?}BMgDsQIUDaBs&GUAe z7n8N*9#BrqDom)F&1ome>hfi)%?y@7R@yjkPQ|(I_^{Ntg+*xa`Vr;RYP7o8QcG(YkcLm1jwA@d+Jb`2= z#tFfEed9bnkdQ`7l3jHv4&cHxytgYUS&z4w2%ilr)h*YlH1Ryr%Qb91qWxGh_1BUj zrHYtwGZJELl9N>%Rjn-PFh+)(b%m;jKSqEvT9Q@S8&_YcN^bYzKT-d3Lo9B`QL5@& z1pSEujECtog>%axce32Op_rkzB)=rH*J&Z4Kq7-TkNwk0uN2$GG%~|MkKan6`fGdn zlU(tK)KX6IQH*hG1oMWSl_!8q(-r593(a4{ZTAuSz?HJkLrrx(ceCoP6sm*T&2Soi zt!>P~&c*B_|KJ2pPtW&HX|8g%(L@4{ShHF5HqG)&A0z!WycZ!a#05+>zToA!VvfC@ zK$t$K#_wRjz|3!B1uHN$_u#?I@3h7i2CLvn8V@*wP#~HUoSqw97+r0iD{UE*#-VZS zw1!ziGceUmB->#ewjH9mJ5fj-s@53viu*4Y&N}pv! z_oRZDQ^ugf-S)v3RHQqcZG+X}IDWgf&W&&~WcMGSgrq}UyA17xD|jfIep|OZ`*&Gp zT~bvGR<)W;Pnto;pj>f~tH+e*M7D$6su67q5ZJ%TRrshu-3T8boKX<#cBpSBJMugd z`vop(crl@gCchUQL`bi&m!AeM=F4_;qRlsv7T@k1w)gw2`U1V028Yg|0%;^y+ zKmO+5E+P1}5Ajzo|NAY5G13!*p3@<4zR9?*!@OKIo`HJ-bt zGWXiuWJY8-f=@*;4GS|wX`$)1^$olYS7WRltSfmv-2sqFBINMkC2(wTl~{?F!Vo+X zti=S${i5jcY&wT24-TlF%Tc)zyywRqW!V)43{(X`@X$rdkHD^M zHPT=0$UUSmw+KBC!ZO>&eB{-1CrdKM&g_bkh(%7bjzjLbUawy_m5|1@#xPomtg7H= zjZdph1pnqtR4TUWCK^`W=`A5KM$uY-vb;qmsu&$J{uSl|fzyseRY3QPhv9jXCdv6H z`|s7fhFnM|=I*MqBFn|8whD5RBcqF%Mf4rZLKtgnQ_T9rOIjCKFok<-I2=24%@z1Qy*iA$%zu|zpkrnba&!$+4)SvGcDS% za~jJK>C>JP=!yd7T_Z{BErqKZAm7cG1EP}vhhHf`1+ zk#$szO^Q#t^a}l@HM*HlNk9zOaVjH9&h@ZN+0mh2ew8FMZEgyLq$64k7V3&HVr4*e zxxCRN!h4%BkFSYqu_b(WSoBn5cYR|um=ETMZi$4R7F%+H{WYx#Qy3mGwLOk`>LbVv zQ^_1?N+XtPKmTg{izKz=!_A4PuDoAJeZ}$2RI0+U^3_Sf3v0&i2!auVN@xL9Tu}6n zAGD$6MbQX+(a?JGBY{zLk5f;$f4{)N#PwG30gIsn5FMib^J4g$?kG_kb(j%C<42`* zPHqK87O7HHh(4eamGXsJc}GZ8s39McsDq8xvC81%@z&!@y}~RCX%o%+p>4F;m?WxD7p*SFSN z>+3&^l{Lg<1!;EZY`S*wi(uD#6hQbOQyq+3xf>*HFG$Qxv^Lef38|zdky9 zn53$>sG@aAdcr_cr5YJtT6Qpha6#M*u)g(jJ9A819JaV`uc1<#|t!GBb zJj@4CHJw%-AbxxGzBc)tW$g#qM1STi#v&oxNDr85lDu){cr?9%um5ltC^FdPpMZ~Z z5!k8!@07uRtKmO)>c6}NUDX*Sq*sJ0dEKv7QNbi6VD`eONW%H~BH+TK<1BCj%w;Ea z7}KHBAgTe0liy=P1h~4ncj8@Elc8wPAPz-68!USq?~eEWtOI!88A<%Ho9c0gjBwxr z$p=m1lLADMms&hAp9T}2D5*rD7m6gU#NKd5aAPnucrsifxbg^WxNuGj-Ikdgz#LRR zPZ7@C1E2J`MdLGtn$+S&M_FHQHah&itT3{<(s^!xH5ZkMx#|*&=dXTG<6Vp`qPj%a zFD5_iV!pyw;a&6#L!Z!8F5APHmXeQNN;3IJgjlAb-r9NOBA=+}P_tgV?m7;qr&xqc zFP2HLo@{+#7-!hrXi#pstohWW93v4X=^CU zV-oVI6nb3~XGsI&)C2kY0oU6&Rip;EhFs z-Y=h}9_vWTy@Ig88)ytn;tB-MNh)GL*z81nUvuSG{;_uR(T;(Yvw^9^$Y7ARv$WZD zv>8G|BHYXr-AtX%D6!z`__d-nh@;&dky9RBR!ieYTsDkGaED&!7TkC}S=dNbQeDah z8u%|+N&1SLs5To%=xF0hm!ccX3hW_9!7MmXOfW>2ERAAVmmapSHt#if2W(I()vuP3 zHF%W^(~dWA9-?JX@u0D=eUjfkK@?>x%)Mj7XJuwf3q7dR&c-zVbh`^}8z7eWryN9@yl zSR!xCHM7`4NF49$q;4^ROU`TPW5_HNcSxwNHOQwAP}%~dpITi$NQpcITj6(;HphDv zzP|epW?GBVOk!UHFse~skO$ts^x-x=}%MMiN(2`gZt`+GBq>o#Q62cD+vb{HJ_UL5Z zwr$(C?TYP6&YL;sT6@oV+Sl4%`+Rq4|BGCWcZ~j^|2m$byNn9IpJa4;*v(zX}JI!nNu^sP8Jr8XrYuYg1w`%sJH*avX*c_EmNFS%0sl+N>w8yJ z;hGaR?^c9Z#K{UWNBgXFf5+KMYkQY1j#r8=iqlwk)paE~Ofp)60cfgXld`33t*=Lz z_XsN+@FEst8@DlTey|V!-m&E-Q-1@=3zyrTYCMjzTsJT%ywdk8QNH-?<)Y+A#OPvltpybLWzuQYkBY*q27$7xm8!uCJ|i4$C*u@yugVP`)8xdG(D{XTEhF| z_xXV;b{}U6OZ0tLM{baR?r4 zfjA=r7gl>?WqUBBSrN*ZMLUYE@zciU5&~z=2i_0uketN zD=iN>clxgYq3)Dm@gs^*{)2YJak$aU$Golqlcz!^!^G-5*&L|AcX1I%WJ z?lZyAE2ocswU;WjT}M1<0rsZYQUHUBUdJ*S%h!*nM=lVUT`$@KGkJI1;7kJ};tXrB zzLub@m{I)9*NY&fXCan*##w-@{bR{;mSLq}8t#MuLsPGez2mNgG*^Eow}^O@SnKK} zX8Zg6{a$SXqXoolc6xP*6{N8ONP{|As>$Y>ash9T?$E546^r=uXvY=#2&XK)rDbM-qwGrfoUI^9T zQ1H*AIbhHqc|hsWm1z-kkmG_5;=|E~XGmgKS|ev^jMct7swIIJT1nLtxTdM40eMi= zsq=>#bsZU3&A`c1yncHovdELo`uYWHa|iiug%-hpUCJOqdp}uFurN}wzDETn8g8}Q zx}~(&)qbPDtQOKNS=BsJ>Dchj)oXLN-P?{GZ?za33CB;^5R2A>?_l=pbr9|~J?)OX zd1mO#XdQfv7*UYMka5kGd7Q9xt(fF1*xxVKwIq26Hozh(J^+El_y2Zs|Js{T0%RER zA-{oDttRyI_d|z5wV3j)gDSRp7tImQ%g1RUXAad#R<*2?v_eyObqoH+_$u+m?<@MI zOpt(DAPb@II9hc%}+~m#DD-NG0>sfxuRGryj%%+SM&;S;! zQ*UAm;_D9ts)ywMxVV3Rdg|zm`a5_CvFp>=d*fqx36^LE*$UXt*1Oe)Ae$Z1Och zfximY3%AV*;+Sf*%NoT#iucu?^yxS&w?Gk%y_1dZ4fkyeRpT~lLSI4J(uZhL1;1VN zs9F3SkersBF)=1Po>`RSCuXu6aiWQXK|5kfS*1AUm&18?kyFAR@rBaWMqMaV^VxCPRXbF_%i1FnCua+z_h`eiH)=x!UEPCw;9+(hM&R8gL{IoE z#7&5!8uQ6CyRzY|R7|H_e(Jbm1##MqRH07U1~QUfYf08pHM3)i#TVE+F;nm2S9mr!y9Y@pKZ78@AK~Q{%Ea4Q(5oZ4mpsH?RFj+2yD_Fm@179$WTb^~cdS zYPlX7bzWf^-D)-Sd%(eV#F96Y>KrexUHHKfxCrfoN z5DCUb>PXofbYZ-GNo6%;?JC(O|eg2jt|(Kr*#Werp28uT4*FZ8)jr#8#!puEy{#$CwKi zk`CP$3%4@r5>sh{KBG3hra$uY^hjebnzV!Q!8Y*3;>74D!j&Ln zW8uY#`Z$xM6#9^H*2Xz;tHrT(&X<@qqu?Ym+-W6k2WPnl=a9H(3JE+p27k1$0zHfk zBnx5?_M~cw??3lp!aB=CO09l@D$wtrr6}yF36KL*6==Q29cEBYBv#=Q{RE69Tk4ND z)p=U#O%+QD)ai;G8uwVgWZ`DVE87~j^~LzBFlrkl>y0=ORcK|JJtU1bx%r)gFxY4Z*QL5a(Thjw6lm!1NmY+x5j%3i87ZIG+Y?tC4wTNg06 zdUb2T3M}L6odS5Y^Xe$qn;a<*YUYQa#XIItWAaCFitC;u2t33-cd96$3Cb{e`)~#d ze_NBisvbd9MpVt$mW`+$SvH5=m!6r&CN;f@k{PB?W;Yyni_nXo9j5hG9YpO_!i+m$ zG(I6Yrw=Ec0P^_KeQ`@Z8LCPj9t=0a#zkYsWl?tVg-5it-^26p2|Uk@S)vecJgrx2 zb?xw^MG1+iX^KUqy_wN5-&A7_=_1s%dL#(FJ(O|Y)7vvwU;jub-WP_=`U^hCOiXUm zd|abgA#-fv)Omx6!QSi)!T?WrtYhW^21tsV!e-YSJ}NwR&PDI1B{csZhg`l_R6!8^ z`FIfEmsrujf}Q-#dmz7qL_cSS?0gyqLhcil#uxRO+%YBhdu@nT+o@lArEg0JT8uQgAkS zG5L&54E%0VS1vj3U^ai4KBEr>cl0H5AV|R<6Z}ib9&Eq_9~NNFTA1O9bVEA8$V;<) zj?hTFObeINW@wUlgb^U7NAK}$9|45F0mk{aC6*nB>gDsPBL&9QMwv!ayFHE4s(4XjvYArDN>-tm5-> zt6{i$(i~~3dW9lQy-^WMv(*B-VcRkW|^vbu)rgpUdZ9_Cd@n_Xf3#?QnL1~smRgc(!V%QjFq8f(^ zstGHr&ZmAAvxK(h2{Ht_*_T9R2#G$@Utye*xyEJ_*|&3nyaYp}yYsQT>_bH7-J(n* zc;Y(-KavHXanl}&`34I#$uRnZ9}#f`($l;M`W0nK6t0+iey;O%(bbh4J;kF~Fp4ajK8QP5*Hm4I6YMqTU4T{gMCXN%*lGNpHwsO zz7vXJEk)q7mhXN474r9RR@(C(yXpW7a4r}bQ3tP*mUjt<&60Dp>~{?ZuWE`&BQU=g zc?!J|Bmgif9nBLZBRDu=mV1`g&#p|W>kDSxneN^RJC8)pS+mYGq*!`-Nd?Get;He$AAp#!(m(U#wg8f3AkY`df8> ztcG&_M?ipooRhzG(Z>`2*bDXEg!G9==naxDFRxdg`(}YgO^FI3flq^;g@kERKJuN3 zI4pI&skN?HC1W?B@y-7Y-}ah z6NnyG`SZedEMKsIB?POkf)9;n`)F?=z)2K!s23FE#*OU!7#_3^65izjic5aU;X@G1 zqs@eqn1V?}pO`VG=BSp>QlgZkUWq9rEG05u$|6vXHs7LPd&w7Hk{p_EX5K#oS2|{Y z2-(M^3<=rGvHm?ZXr8dv>Bn>zSE~tuZKJ9AyyiM%`cs5m#6G}81ZsN1trR6w?N048 zN=8CDrIXv>7r!vu4E!8i0>(0Gx>4^?yVksbfZDPDh)lc8Pa36KZZ_5^yG7sw%=ebz zpus9ypkb=arh1t5*fHV8jnYqX3F`B^0Gr1ud|2~t!?D5+frHz0m`OPoWAgmA3v$O5N!u=xH8vazkM3eEliaGx>b}IfDplZc1XV zznv;2zDwK5RarZu%jsQ81-p>GDl4_6HMlo5gL=#DO!<+VO0A?h;kW-c+i~XPbcUi` zdiSa&IUN}gcF*7;ji82snhnxd{<$&dcOkZ z@s!+0+}M|wEbw6P^TgCX$^M2z2&(K7z&7bt*dYy};F5M%qGT9#xx2`YebWmKC@oxe z*MFM-{(7CwU$d;N^Wo8vxz6cndo7Ny50x$5ZG!My6SN|^Rp*gxvsIIbnt~egF3!G zLhtZy^JwNVz-^&yrKp&37dd<}ixw^~wk}sKT3}A=O}ZWJk+@{k2Diy{1C_9u;O=WT z&K*j=o_!b;%34PFflS*a)YcLD-u6ra|D^7%+3!}3a9slP-f(jB~Nj>NgwPkQKQ|5Sf)HT+M^pew79bQFR&<-R8xXN|421g@}bDnw&E zN~erCE?%;}%?NgxZY7@^F2FF|o(HfNx<9eFH{r+sD%|(PS@ikP1Td9%W&7hhlkK5D zLS`g;Cp4S-!DiW-YB;rExJRD(TRYhU4pPsBi2LT?@Wv?@*#im@p0K+|-q?eHCLT$L z7=b(8j@uWiz|9cQ$03P<>99}gTQtIngn+%!TO;Ne>h3|lnC33t`Ae^_aN`)1fEZ_n zYl)`5$F==$U+1IHtbazi91n4mutZ*MN_E5K@5D1b7kUQFO-ku95wAr`%voGK;m}p^ zp;kh=vxdi%TEFT1y&2LzBro)VigE^Yng8d;|G(dd|5B8Hc0oRht^|!MeiVd1lAH-` zRdP`J{t9wl#~F=j2ej>|JBR*z#U&M{OW;qsYIiWkvFU!uc=Iy(fCofcoyJEuFw+!I z;=&ciB|C#YxkG!NpY53I{encwcr*YE2@lxKwTFy_(T&n^!-WrxKn&!LyA0-2XBiuU zzsHD~_Wa2d9{-wEg2mFiw(Z*MK)H6w-!4hDxI`Q&6et-l(vP#rI_#lLV-Hico|4N( z=}J`BV^r2LQ^e6=B2xLeQ~L|~HsVN{D?wBbm-uj18SGniK%6!s&T4J0F^pEpk_@Ux z*r^A}>MoW;V~?Ly?oJem#{G%Uu!==Bdibu+v(fs$Fi{lTMoFYb>SK~-46`6i<#N+2 zV|BYgj0IPMJ>lVMV+@jg(*AWgL>7(FJ-_L9Do`!U6G!^%ViFDU{%2tKspy{(&E|Fbu@xMS(68{E8B?Euw6=?G%y3Hhn|slAkG%{R*W-PAdfj@SV>CQ^ZFR62+Au4c6C6X)d=;uYmo{cMc(hZ3;+; zVw=3V8hCr#y-@*r`Jn=6Mq8}a*tCW+HjLQ}4m1FmoRhx6WFfh?Q`-i(;r_9M(R6?; zXL?)_>2od@Mp1GEyTVckBo~!o#i3hKP<}y>_RGO>4Ft+apIQfa_fRJzY|S5EeL4 zC6TTMh)Fdz4W_lc`S`bDknNI*&XjC^DVT5e26X;q%@W$P{|h3)&kQJM`w@p9uN0~y znT)5@1y_o$WsDro8Q}V9fdKQl-R9n7DR`i%jv*()V76G3!a93X;Y+9;K4f- zqxmFx2BoOTjyeB~`Y%lE(}hbQH&%6+AmSD-#P#1KEoOpFcALLxT3+C%#enJOK1@V% z;>0j!wP4!MhlE*%b7(6@Rg-b|&XRr_;Mp*<0)e)r9^#t;S1sHU`i0TKYDznyaXXf?JK7=m6FUbR1Ua>Jz-1xTEsI%8U!1zF8}Zn#R0rT`_ms@ zB2w9I`R=0GS|$9&D&a#?J=A?Qk=$=sOIZ*FEF(?Yx78eXsY3p7JzBGqGJn4wCFYzZ zuK@>$0&qR5{f|rS|BnOo_s@Tydekfad8$?cRH>u}|7$t*tZzVMqUaTMJKtpULxZtr zlr;PL$357Zj<^3KLsvi~@NqK$RqIGZA{6os;m>^M1{; zcs;%HPzTM!Cbdt4V1qOft1wC=o2Ny65c?8={Rt6Z*^(OS7{xGt?YVK`8rh;q$@KPV z!Wx4fDlqJri9Z>LjT*1@dNQI{q(&aExF?n3|c621}1Pc!4v@S)Xs>vbUJ; zf0-ZPVi^=DIS5e9A|NFZXKp0) zi~RHv@~rv>2ziD+rGf&*?tT8|26Jda8x6W~P}Glj44J)zKA$E?Bbl|K7h?3n{71<1 z9COKT%(#C4fiW`g+hNBV`okJhp9{2$((l*vSJV`VgCz4oFEGZ$%_-KqP9ySczW$?cFjA=;5JhjzD;(_~I zEJ-iwz`oaMjV6%Q%gm1n1{vE)YL?A@muJy8RB5N>%tT0C>DG{wLAcIr&1;xvlLdCu z-aK&FydpbZY@@8nTW(3-ctYcJwy%MOCA=8O8SCOhLvl@__0gC0m0o5$$P^ zbE87at&=L$8*Vi2-25BpE&smg?6C4r#}m{8RRIz=htZdDBV`$C{V_qv`6!3LUvuO! zaRa^>my80GOR;n~Q4^`5ENASf!^ke2;oJ?Pu1eK3t%PlbzC82$17dSikYV=d>$KZV zddYxP9t6D&3WYC5PzB>?Y*ZxYv?nBC%)fGKe_^^$Acu84cVyUvk3(g*RCrC1jEy*l zy962|2VwSSpATe*>X-0|m7^+HjOEXj8gh3lKu&%~uIi#kUykvcAL=%p_i5aJYRhr8 zLWSyoeLejQyPFe!=-fSJCYUDNSA0Tr(bP|+e@;w2>>NVa`_wxqBMcuQp&Bt`<_QHS z6WO9OCtYjrCgrBBeh5}vcYrOq+^~Dn;T+Zfjvgc5owaq7+W)% z2SG|gPN77aKOEzLc5jNRUCc}#G6dfnZ$54rU4iUoLA}_8Un_&MUXiV8eaq;CF=6!1 z5Z*A<_MWBo<#R8_v_^jw(IIwYgad^ekV$S6{KfFlC!t(syNK*wKs(7}>!w8ub(edk zN*UZP1blnx7G`MwQ7(n3`zU}y!Oec^p)85ob=k3zA+1Zy`x03?$T`pv^nT#^>ur!T z+@U}lLMB#MKLTC<^XL@^$wsGdDS>v_qS_vRTSPa4Rq&1I4k>}3xGgRXLS{FeZfDdl zlV!e>RSN)mGU|Y8#Wms#f11ccpazsTdPVq|NpR5YHWeQvx?zeJV(J2c(ZBsiejV9# zvS@Z#o~5{D(!$>3e~VT9;7&*XUMA@Sv=RO@G|Ar|fPV{%f3y=m@&u6w-~XLGE&f;b zw5Ir%6jnBfCb8k4))y-oq<_){*V#bufN-Oofv&v${XrD@k)tR9WWg;Ta9ji(FdHK$ ztcwAr=DCwlQ4WL2iKk3J{PY;d+wV<0DL`V>$E^ zJ=D;(gkvT2l@PTH0J308j~PYV#FWJ~m0iK^v5^l`+Bn=HwVT!~m8+hgS-maAq{HlV zxNUyk{I&Wx1?O#6nVABr!_`WhVau9*VL5-jZ8F2GvFjTT-X`_pau#Rq6FRF+1*z6Q0Ool3 zzRNdUYxNG&FwgTQ+nOwt@)}kd3erH0;af%}uiQGP3)b5P_k;v)0b#VS3$yFWUj{W+ zjhB!&awJ*CsaWZbXz3W;n{=)dD);f{SxNz>(_`BGu^;w^G&P&?%8|y-7x&b|(hxYi z0KTB{kJQ@U(%X(!Ed54>TG#IS(^8mU9J71(iegUK((p#9>NnZnl#v-El;>$L)#!e~ zj|AbNC5l5?71|)WV!9y9lNU^b+hSM+68-dRA|7j@$Lc}vF^9T|peNBAF_G+&G(b{- znYEEjyB29z)EKh5_LU$h)K_R6;SOwVkU!!taNq(N_V&x!KCdV5}lGq=5yZjC;h6A7b z!4}*E;-sj)^E(GPPK8nzSKV+*}|Si955uw&V>v%0j!Jy1;^H7Y>Kbw+r`Z zheR!sv43Mdi|prVN?eg1aeA00&t?kDdnk*v7k<4w6HA^dB*^{>vx89oFxzR(dn)!7 zL3Bb^hmhDslH{qG%%uwtTQpS0H^$-%Z_dG4RHzr?wg-X;@CF>F13J7*j)19t^HCzA zz7DfEc7m7ccv{Se7mA)INThgDt*KG-(IO%MQ!>t7X4D}-=|$7S?Q4K^FgQ16JAFYo z)=`x5WW!=tsQBjU|HRG=c>~E(t9e@pQA<~1gsa5lB(`rQn3UNy9C-7Pm!eAhB;mi5 zsF>baIM=o=f2BjzCbOFiwxM9E-MnXosI4R4|3bYU3AItD_!%n7F!RwluT2FuIJ7FOk+e1@@9@ zuES#hA%nc27~;9gKk6dgBgYz7{of%!H5y<}x=rd_o?;snpXC_yfN=Qvz5ipf%PEtV zo&abu=mW-8{Qr;A<}WRybn>BP-q#rxE#elx?bDb}OV@#-Ao3vxLJxdOLG;TM#bdL} zgP%dg_KN;+pW=lBb}e$l4=a2>V=?f@-mkfxb9CBG*8XWe#fHYH+f~P0tQCx>7PcY! znW|PaRA^I*V$ejhEe%#aMSO%bKq4vHGztXv)O>iAwS}%XBmnthlck%TU|A5=56mv@$=zKkHSNgO zkMFxpDPH8~Dl<3|VL|gSTO}#MHiV|y7Neq@w_}O%8lN&)x`*;|T9bEOur1MMNip~# z7ob_QwThe(AwR!MwF-b!v-H{r$I`s4`t*k>Rb%`xS6u}}b7I6gchO7W{-_3D@c~b{ z{8pO0k`1nIfRCZzOs=OsKqMPJps&Zj7L3RS2Z(0+XgE~RC5{B-8;{-~85weeam*R_ zFDZvxNJ(QfScTjIP}aK?2N;1em7g&HfzSX!O%@q!(pIOPZvPxQ8EQilzyRLK}?l{IA(F675=->RD6-h1#VKGKz+;Va=?H|Z}81n59*x$pa~hN!={ zAdac(A%En$WooBYe`@)8O=k;Z@d@6;IEW4-gC@nfMXxNyAjJPM1D%{gI9Ih`dsWyf z^9T`h7tnPuyq)2{d_J-Nb{ai^A1G>@v;azspHUsDyEz>#ahkh7j=SWR7kmRbycXb* zXFFq@_vJBg47Uak|KJtnxghxSItT+lvrp*}@k%7>vqjwktOMeB^pj-{Px0746hf|g zOx_Hja{SMbcYi4ac|$vUTN49&6Dvza7i+_R4W{z{JMzv#fgEq22pLWOTT`0C-M1`2 zmI*PE(oU0O!?5zbWu0T!Zxmyf{(pDRCyQTB}X>wvQDf(5fJ1oYbb{ zos_T>0Jfwzg$AurlNlqUA99jWCpCL=kQ*1WQ#4l8I{t|fhs+c4Nr-jmh+yASL_r+6 zQYZln<50fz?UyQjnUl<;1}?ECtY5^w8B^Jcz3%M$I%;7L^G6)V>zRw2eTLEXPBjS^DL0=QNW&` zN|4+D2b!8a1T)vk1<5eFy1Fa3ybT>WIX-z6u}w0bzE1*L4nELalZ@#o*ABXal(w2iRrS%+lI z6m62tK~;>d(ys#?{ZjvLZi&#ZJHwA)>i?Ch{O6hZr>ax|P+14x$v_AZdW8V?#{N*u zBF28@a_@W#AR&b=YsC5m=@3`;#BqZfI(GbP3mQLa}XDfQmeNX08AQs7MV4$~L?1JsyFwKU8EQjFCba87q5i>xv`6W-~q)H|8?Y z_&^nIy}gI(>Q4af4lt-XL#a^VT9iV!w;sq_feE_K(!x6xCbIN7F|-`43T5rJuB8+x zCy`$SSGg5f2&g@9W-2+`7I*4%|sdBk3ueELLve#s|^=sm; z;^OHMN^V(e98>OeeEpD#vHE)E_9__@$soZk4SK=0cCO)s^x2fB(?h>$q4I5v*)lxF zOliUJnWhjxMA9j9rrZpFh{)81Y^@zC?HRm8r%XhEh}6lqL370vijyZVWcX~WcH~d= zv$lzBEQ9_9AR@6LZtCe#^h!*qdn9*BZDAyAU;rXAS5bow_cG=~M9M`1M5J+q{E=&s z!~I_W{USg_N+X^YJoa3k;yT$S{JL(TYPv~iYQ?AtP4Sw=vd=ASV$gcdFUiIFU3~bR z>n{#+lFrE^Z~hk}&!Uqbtd6tu6S#8jAfU5j|I_`_E{`40sd|A!vTkZ0m0iT7gb z;g-7D7Iq+F3RKF`0AqX!qB{vTZDNeGK9hlo5LHA-z7fLLZnv8hccO*(}7t_CswxlHb*$CV0 z_Ru%JK-U@fiHPbz=aH=0{wjxPq@!8I_=z7@m->pY0{kZF_x_7Gh3GVJi)pZnZbvxF zjmdkGd5ff_5g;Im{t%FFe+bCJsiX8a*kqj){|kR_w`za*wg)^{$9Ps!`fnG35Vjb` z@4$a=!sgVVLCOOJBnF@f`yUI)e_V@y3dj%A9Y8=1zB_HL{Or;F%D^W`)52kq92!hS z%&0|=fr-QL7+SYJPW`KQ2DQe6P=_jnPX~Q7`7s-yAsOc^{QXJKeziZOZE`%^Zob?s zE?NPhUJ(aCjtwPA#kQvmU{?$$$pEGrLrolDD9}ij`SgLSNY_YENav#DjNW`M+b-Ni z?84~RvOQX0#ipv!c=qVRxzb@wV~ej@#aJ}Gu9J5SCrKaUDrus{CBjHXzcy2j24fL3 z7^0^h4XE-*Sg7$i^T^IMJ1Jaqi~<3sUoD+zs%@rW-ID!I8gN#f+j_`L%HLlyfJ|El zInGLfJ6eySdQc>f!s?MwQ#psD*m5^ZK~3!Pw`G5&t0ri- zIBtji<;T`XPvM%&6}UL3lia!%ik=`Xaw<@so{v=DcX=x5oiVmRll?Vb*Azw}Qn$pr z*h1l~drr?Ixdex;pwvj-kP(cDdhcDmTp??b8VwBO`&+7h(vRz+7xkN;VDRX+PaR#( zAw9<6cLu8t3;oc&bx{)SRCOhIuL2(Fc%N|;ABGvjzR0p1o4leAh%I*1PO`yN61)w^ z`?OF{SY{=FemYtUG)fiH3BaX&)MQJXjaeqzOL za=wfJ#2+=Fqx(Nk+5JoW{ddI|FQ;WSOOMR+!5HzezzMff79QaI_WcVyH}aKylD}d= zkaDcEy?o_e+){jO#Hr2|2n4b7p$I|6EdS^?{-K%nj={mf2VAe0w_niS9(Bh{eM)GH znwpilp;)YI_BN|RvD+qTm((})7|-rwyU~|n%po8u$#kg78XTt^QXj%`WCV>qfqk7--xVKzLx*)}gs1J7ukiIen* zVM5Lx%JGZlmKtPW+Ynjs08{mU>b-YKmOTt|%>kneQw_H(R$66zC?EL9C2@1r*S8@r z-&*OhkEB`d*MeWYL{E8l4cMMYLpqMR<;Rv0`!A`dpSTVAgd_PI&hr^ZwbKtE^`3C3 z?e}KubT73jNF`}vj!%vR`#6@JDpbH8R8yl0nR9LcYe>AtMGf~6M~&w5+p*yh zxHO*fUf*vu%xAD0!(TbrcRLI$I-9g+Ie}^BZ z!WZ$lN9I@dftadNVkG{!h#LY^rm#dhh#J9Mkf`G`^Si$NNlB|vwlz|=K`AqYu$Hra z{g3R{zI(>CPJq$_0jweY&qEIX`vLiq{H42Pd4A^g=@sG-Md9b?{}(;PrW+JZ6WJ;Cr~>&+)4*a3$ghJDwx(oCsZGz3rkYbVcCFVOVKQxQQLBi% zHPxT*Cm>mHJLtEGz)gfV9T>Kh-9 z+@VZMqsTqmuokjV1Al1lm!Mp15SpiFG!B;pB4U{spVi8blgO4bzQ=mRQj%DtG?&Od zSQkped3Td?xDG@BgH`2jUQh}Kjm+F8EE`9BG3IU9D_KxJnMATcNa8Y&44fWO%iJcd zJ4bS4&PILkiz=)cmEyZyD}3X(dbl;pUy|Uo3xOsRCFZWL*-Yw|hzayhnwwOhNajOK z4h0&s_20w7QIlqmV{IV7PUJw!K5ZsjYQkMB3PG>mflKPN#z6<3M{p)syG%xGWJp)d z`wJMm@?udhXpq6S>n7g0baXYgNUOdb(60^MEVc#COxzaYZ@Ta7x*l5TsVKDtKGWKn zIQwn2uVXqIWx-v4>87Mf20gyQAcK*lt1DyQ!j9e;GGydqRi~x zXmKuCfnniZZI+Hosii*nE-~kT(MiCzWRoSrpTG`Iy__1+ZS=ZsPcMJi{ zYsP|UsKfYfr{dtKx`(!19tPp3c$rs-lKNy?%10UR(x!1-#?_R0%LDGE=x{FFt(BCk z71{_@0HMy&?l2nw1ZkYN6Kf^2vnvd0F!Jc6c~Q`a|N7`fUVNhm*gE!qJQbqb>f((eYGd(1m1CZ)oCm9Z7oolv#bLF!p5P5}QfQ!z*Jj8vV z>fTunUYMoX9y8=#Mxs0W-GTE)RLWwYHsg@r+{T#Z+uc` zWik~bz0yqDvp>qLc-l-C^a$i7y8eZ;M`rVNPdecGS4x}zi%K7NyG4d_3Rxeo>}$kO z)=lZt?PNJUmCU3R(w;Rv2UYO4ND>qoPb^-7BUbJ z+ke_G{CGV7Y7(kGIek$=ek+)hoB>-Yh!;Z429Xj%%2Mn?tpkCIr~O7*8XEhZ9C%nV zSxh|irQ_nIBdqoFF`w7vBOusX#HHy31_-w&O<@1Lts zI|HhKD#5M*6vGoKXJ9L^E9Ea616+Jas9{#+^9 zU39_i!a~*I+8|+fCLl`z!|~;3slG(h#%aq0Yf9cAH)K@q@8&dLmX38|P8akzT=9ADUcV-t z3xCLM)gcE-O7MIQTXZC@(T5yWPfP3{`jifKlJ3x;8lq`YZ#`ERisCJT z9dNEvcWO*4WwCCx)-dbg2HA5XaZ8s5M05G|UbKcE&!s(ej26lNe2!@`op)`R zO77pMv8zlftTj(|+vk1`D^Q8TQV`L?P+Q}AP+!<9%B?6cuM<+7ODmzMe=qRp8Zu-` zNhdk6u#~t(H?=t?>CkZQuUR`zgNrO?Z8UWKPT9|xvu`rT$B;HfS}!QgH28%=KWR6| zCXq56rB={|J`+m}3Tj$_kvy@IbAP(N`d2|fYPWpA42NBs(&{xRK9My_AD7({`7br3 z#FE{K<@7ZpH4aRbjl?p7jYMwqaGZqExRRXs+GizJGUl~J;?m%bjZ8-#REIVXQh5_mbOVjgO+N6C3767aHuovN^*em;5os;!RN=cI>J1ZJ~D)7UNWtt zGga_ism;Vn6@r#Ll7!o_SL!b3cgpwt5D7YId0#zCdId5qudMU+pHwzYQRbrx&Yj{p z49Gn}HqU59_39{Y%F?|o@wh5_RO&u2eKh$N#7NY^nfsmTcqKf+LO5Xj2L(>~Qn)MB zjI!PRULh6EoVS@&cS$nmDGU^i17V9==xQxGoSM3F<1ZtG)Pf^GFFU{Xj-NrcO4WQK zZfz7e;jFrajWujK`L*M=z!44KD#z1#PRL@t+BWu?c6=-pxWi>YbKFuwv72$-YGi|I zNyFZ_HKrUnD-pCO%lXJDgnbFw{KsSf?=dhsYz^S zoH~-B61q`TbG%KXT3A1AAM&8QpEKkndGRMKlAEe0)(xwEY~T1;D^5Goi)u%Ji-wCQ z_|5ruZQjvF2D*^5a4upv-NHUC^zUsFJC>eb{q;hK(BqrH-7p@+B&*-h&yCjTu7G%X zg9VV_Yu^yph_1BnZ@yy3JM)gR+%x?Q@1wR48BF4h*hPX(i*k;6;_%D}qL|)!0+AN0 z+ZLs!2W*>=C3~eDk{rk|yu;k!b@?IT_4Fd)>AmGTOYZDC^Y6rtd4)d7Fuh|O@Q%J7 zCcU?95e1_`ptOnZ5@X_fDrW{=!>bd*qA^@dfsz{|;tyZ^2-mbj^a*|j_l14L%7*^I z34RsXoOopAjSw6ak_d@)38fCnH609U57ftR;g7g-4t>Re3d*nQLpO~9@%tZA9h@QC z<|B_>5>U(W{coP5f6w{<3a^ zG5X3_H{ZFZ%7fu&WerjM==LZfaxArcjX@GP>7dSEiIeQ1l0D;~3SU_>&CNNM0zcs6 zEP<_dp_Sq@+3d+NAMkNFP4LzxtKClmLAMVD&u*Q!58-bgiIaB^sP+dlw*dIK7yv#l zk_S_Ib6n}CfH;$aiRNllB@=h=!cU|zNr+)MiBWRaZm^O8*c+6gxIKEE0W&Dyz*v4? zTE#YWe%|!^13pgw0UuxRN%n$-qimAQkZIs=c=~f;P;t{;(Bd69p#$+tkzVn4&Fn@c z!jm6U?R-f>Y5;>tjufZLhruKSR9`do>0tx{(r@+uHkfpbzoXRvD!U>;Whe6gbX@*X z;r-iXf)czfQ2Z~KiTQj(9X?1=osVLcXnnmT>ui-h@6P#5fr@KHqxK^pk$etIgN|GK zC6~JcV0CRBh5@PhRegA?m6YzXVQl31_3>~Mpl7@xt6sK9*Ny|2k)QQ2l#$7=4=r#z zcJ$(dSOB@?O})Kf@H#hD%iw<2Dn3@oj|ty8`!lH3Dnw|0A~t1UQ7uUe^5GreUsTU?tQz*gAlrwPpQex;l+DKY zkUZG&pBI=QmjXh`&lTN5f}k6Of5ILgaqA>0Rs*y8Fo7GAO=;yvg#8R{?t%LwlpMuj z+|Isqra*(YA;|$4na!f-%aKNr3AL=;7Vakv{ORRSZ74=_77lW3s;PCi0_if}SSJ*> zzWRv3hGe)g&zJulqTI z-N3lDSyQHEp=iTeE&!}8$S%~Zj}_{BIFzWvdetTD9J)E%QVXso!) z$@y)pwxpN&xSG)?6TWnPS&ln|Ee_W7$nbcZ0bNE)mnxYdVUg@|w-h7tH?nKRuY_}{ zUF^dF)=Q>`h9^a;FvT15Lkgd<7()g!E7?WEM?$aLPk6A&uktlU7o39#|Rd0AEJ8;p}baO19Gm zMS@H6=5mERd8mCA(}(STVn9F7{(1`%?tpdXAdYw$``xE273E;xV$^^o@&(PjgYV0b znB}RNXXFXX)4|cURZXjP`_~0*ivUsYP&8o>hr0MKsz)YoO3PBVZNb`=a!q-z7@JLv z?>QKFcstsOKXxuOTJ1?vZVGd?9b?{-G+KR$Q|=N4Cn^QwGk){N?LFxtf$1VVb|N12 z6Iq~JR}Ovz)+EAx1;6IX8-hMM_U$D2O_i`s3P>c+1Ume!Or%#@x)eI6@l!-2pRk;C z3w=OR7Hz|K_wls9_uQfk0CSAG--IPF<`&&dNA;l<`X*qFB)xru^E#QDc^`cdI0Q;9 zAry7^eQ45SuR6;%cn<(`oB`q`dN@PuDb(+{=w6;`1UE|$eDF9bT2qBdkH7$*YO+Co z2ZW6y?id?P;Pr@nK1>57jHgHbkuaXL_QXQ)COqbXJpq}<`(Zx;#FKwgJa^YVU!&@y z8%(3~rnJt80(@`$<2yHn)A^U3Mg57)uKt2MCourZ(XuZbIM4jI2j#;VTF=FRJ8y6Q z#*v%aIhF86*b|s&@&(Eoz-EF$;7)bmhJq#B8DeI=E;BGaOYn!y!~js$-5LV$<6UTa zF{6N}zw>ujOiU(ok-gfNp~)@OFV=_rPv%Su-P?%l7xj|TkcAun!<-R zQR&rS@idWbcYsLw(&~kNg1M%e+~r$l=!ptK!lf4-4MchBh7;giF|iH23dNgq$Td;D zXx^~JiN(?`QZd=XWVt41xSe-Vyk9Tq)u?wIYg3mDH;sziV7ycQ5oF=5eUpmPF`f>* z{TUti6K&CZH&urrIxfZfDeJkcZd^mlyV;9`SjEI45CV<@Kd zS;MD45lf%m9q78Ju|e}(Xr-XqV#qnzBv5TcF^p;co@rjNKz($MGuadp86)yiwdV_l z3_~wHh8xoVVeK8G>rmTv?KWm(tFdj{P8!=*8{{CfTj`?d|_kEw2&cl{?(8kGrM-J0L4R%S5df{etY=IQIjw#d6lHGVf-{Bkc zT%yHGq5|poNHXNP^V!{PyaQ6wu1$C|#)1X9>4NL!w!o3T zNMVjHgTHm|B0RAf9400{IsYsURZvN@aF&oVbPd1!boUIDC~Z z6&cta0pqU@9ifUxzyv73{~HZMX6{uC%E_xX#e7>XTIuHKziyBxQV zqhg%l1j2UR!dokc)Bv+^9JVy|vN(-h7SHI(?0AE_@sYdg`&l)_3>kT2t_gcA;d}<| z9(yhHeoPJR0oEH_!j1^ke!CmyW%;`!Wsl=;O|UPO?l0eiH;ZiBwrAfAx-#Sr_@ozd20;m&N z>X=`CPK>AhIqebdf+wr(;xI6pw5~8U-%AJVtv*3JL$9KUD}QHPb!!IQ>SMcTZ63OcuSY0ch3u+FDE}#l1m4wv zfc|`A@s+`?DjvD8oCvr!?S8&AQxoDCdm}RhcM-!zC~u*Cl=6kir$@o&5_k5{dj23T zA`?GTce!WyxJmVf--T_8iRWpGaoQgg!zJE?i+caGn}!b(0WH0Vf<%vStN9)J%&gMzkQx{# z$UqaK|GcO9f5wWat+UO)uEZ}^b|~UNH&1?-3`}Gt?9T-}n)ogh)=)NnWU>;tb99)H z12|(*7PYTi>Q(%$F zQAhr=Z^HlSQIC5RMCl{keUWoQq>se$snr2KbtCVnYMDs2mF z2}K@!2Q&n%Ya-?QlZ8^b`dMh1^W*v>@nf1yHQj-q2`!qi|36K{4m9eo}Rw~biW3>;HR?;DyMoy!VzS4(C&9GVePLo7)J5& zaFfoPePPT}oAvzz)`9n>UW@c@7BIdUb_6+OAFe>N5PA5WInOD$9gW>7z?H_g6)Ekh zU82s%sW(y>ikhy)+P(8v!U4t|FeQ!2Dl_=4@)^N_K13}En9qLKa4H;qz zQ$0d{f5Rsq)KAWq{M^iW#f}(v6BZLX+#Vsl^md+|mV8|dP(2{FDb!O;nt>V?ql}$; z$`ig{{pxyGQ zrodES$kt}bHt%K}`!MFa*9Z}u>DX9B3iHNA=$X|xkdVt4smd1ri6LYX)tB-u@|Fr8f)m`1g8SXgnSX_yx7Fsr&|dU zh>aS*(yncKap!wkkKTB_z0C6Y*z7BXk(+!u2;W|$PZ%Xi2k<6mLiu+L59^UJ5aV12P3N(jIigsxL9u#prb#E`^nYnOjsXe zzHBECVm`^sYiZ(A94V%GK7k*Z_Zdh6$Fk!fxAnVf4bFyS6HD33uvil@P5xtu(gk)$BdxSVQ?KRNg_;5>{R8-CKkIeby&!2ak`{Ufg@YgvWW8#yEs^pC^-{ z>hV9^@3LeX4Kbf(A@H9PL3-}9E}{bs{YSn7!hvtXi^N-~RxI}8?N>cfs3xIK`fbsz zrnq~qv9QUUfUic3^|(wwvkmq>drMq+N`zDercdpV`rVHGcITh_)3!f}+ZFmcD>z+6 z8<7KHEMs7rUU(A!%f)NhIwxJf58Btx5H;}0suAD^Reyfay56D{;)D1Vzo($}=n}rA z2J=aFcv*NfvrDnXP6)~e^9HZ)fNP8Wpwn=_iBJ!L^0uRQGa7lTPw3H=aI4IX+DSgb zs8@DyCXVlS4(LO0^K&|vJ1^BZtfzw{$@ATKfgelQ20#FEGorI!#BlCN?)hY_qTBt8 zQa^K@QCdWV0Xm3{CO+_;$Iukmd91 zC%3QGqX8T^&1iEH=_^e*X}ocKU2}9;!~rhfP*~sz=HRu!U>{AP0*bMUn9g=;1U(pE zYz^IXyaDw3_iD-=X=p8Ed}d$4l5hA3qm_8S9SP6^>aE#{`8ndRScO}6omatTcKFPi zRc`}y`Zk-=kaIpK)0TL(E* zJ7hsl`r&bQs{QPsxYCiemicCsKwGB7Zd9}WZJ>U!>_CJ|rz{n{?^uktFsanp>SbU; zBVh;RM^MbUXjuDMNo(|n{w_&>j}Zzv|ox0uZ?rVV~GrP?XiDUPAZgOOEHc;3XLP=$i`1)9q+UmTk7y9wSaUZc(! zxOcVZ#KBYGoYQ!-EEQ*YJ@{5F>q=`swB$4Zf6KF`2d`+47|eEV@9%*O<8i#g zeNa_%kmewq&;2t41s0l!4=iF8!E?Orn|(OEG=>1fEwnfs_Ruc&?k)041p9!;ijUrD zkC33R!ujTvK7riVp6{4-#tGNZhr@fyn(q>PyJo;GXE=A~eaw;}aeaP5;Y7U{Rq^N; z#e$;m;#ZJ^QQv_CK!qrK!46C#-44_}6P3towEG22y%!D7Xa@Ny>fveSf_O5D77!ax zaME@^$mINUj9rmSWQ4W3kjfdB|i3f9eZQI>*hZlZPa?5|TFi5kXCTnl~;d4W#i?J_Y=g@es- zWjYO~iNegx(p+0Z3s5izV7yabfA7J!Vz8bs!oD!(O6)M*qi2rSDy7COJy#FYH~#X| zEm1YINVrpS6Oe@S;+V6}abiXmT2^?+G4t0MP~n0+F)n0o2SpRp zs29M+b|Nf7IGoix5G2c$16KOkCOm*q(yBnmdb=^4yO`UYfrrfQS54C!y`9%yMON^e zo!u`DI}1aG=Bj+u*5c1ffC9;lrJbCRW55@Ar?G8Z3cRb2krw=sCh5FJ)hCf&tsD>y zj}!&-9X|qAPp$43)p;FN<0$&_lp}mum+g-sYZ&A&K_Zp?+z%a0AzG9}kodwy;}u9z zr*(5X8lQkk^b2e`a9^VH<)hqm*VZPNj)RPB_6CZG3`z0{xJd-{@sCkD zhwW}Z(A{@|@iW_99S<@GZ5$*@yK^8f_#uV8j(Ljz{r0};16}rP5CeMaHL`A$AtQh# zvDE=@Y<+#(G$<`?y}fs$Y`uMO;&i>eXCjU9ZdVo65*5o|m}^5@71l(GAxWm945w5{ z;l920yGD_QhbMzcvb!j4$qH-fm#`o>6=&(0umXRj5ehVFvzn;fQW<6CH3gfA>A87) z@(>v;PBM3rf*($u+T#k2k`t)v(t4xAr9mbO^N+4ojMm1B?rJ)2{$LE-J>)iMA?l&|)(cjX zB9+*RsAvq$BKYWXU^W@L(vaJXjyA-nb+@H!4;unuJzab~s-URnquuEqhIUcL3F(So4p)L^ zUsrOtmlX9navjkZ8yc?g6t={I$4{lYtg95QjIl+Ca7J< zR=J51e@l&cXKh=u1<*`vdhA)TmGN1Pqt$a*w~V7AA>6WI@fvh-0v7)mvRu&`{2?t0 z5ygl-use=t1AFD&LpF9Yc64?&b`x8+-Q+=2T(xVSo=2VWSiGACR&we+64)j!VIuYW_cv%mHA1p)Ak9V zE=H6+MyG8wYo2`Ld!oJl^Yihm3|lg3x&?^6!Ac)lZ%uMr9>TcKUJI+SE4;O^7tHe| zY^3{nsYesV);R<^mS($~aHz*Mv2Qa>!}C<_4hKh*62-i#NSh3#V}Mh4pGWo#FnN!` z-?^jcTrBXxxz$&i6a$yZx3A1T3$H;1UGet1stZF6C7(NSZJ7o5HlK!gI1qTa)NtQ= z%aepw6K~w25y=Ew=MlH(343x8aOKH;%Ntz&E!y`94x-;;=)WPz?R+E$J}}0*+Ge;& zMO8^Z;97RLiHUNey@WbAB7>K2;a-mVrnq83Gxy=FV4p~)Mo9P_NTS;&GfCe2DJ3Hx z`@U`#E4<42J|OX&T)Qw;)zSRWc2ba|LI1@ga25s;`s+sc>!GmF6FtcI(N(hVlLKd+ zx)XQzS=eaG)L2Se;LR3TGMY9b1HxF!K<*ZJvW_C>Ey~x!WQDij54TX6s0{q1X6WH> znEEcF2jlXW8;tM|l@h}95lVhOcJ&=TL9+>q3Yu2%tnJk7#G2ONO9**ym zJDL@e&DNX6_t=krHJ5zvM9%vtf~K4Ok`&ETBc1s@Hu#aA`x2nE9B1VO=M_qvwFvco z4tmjzt0ec%IyAW_`ZJ=Y6CdIQMD7*#?^kV>^r%w}uzjNsoXh*4)JT56)PGtu{~M31 zLgoL;<7$5bfr>|uV@8W?C+SBp)l%j7+Cl89);o1W`jL3%afQGny+apDU-Cl>8Fw2q z_Y@ECp#S=H^dkQOJU&)IK|-*vIt+Q1s|Ht~LAcFm9d{Zx>WwTA$px~SFS~FS5*M2Q zrW9`5R~DM2>Sic@6`bD{MSZ+D6OI8im6cQ)`cUZ1(=Ck0oSZNQC%jW$AW_8DZKDN( zhILcqs>V3P;P6I*X)3SNSAjJRk4c`e6pEjUcJJb5Hh&#-_EPtG*b1Lld=azIOuT4Q z)gBbD8O)MNvmqyL)UVY4&_Y{y%I}S9S0eTt-NH7`G~Fq}_ywc-m2TBr@CntnUD$|- zC1FNBZ*v{c)-29Md729@@(rT~9q|w;&-%Z>hE?BV0R98qx>j6jEAc8Kt_0KXH&M3#PC@Dg=nT;XXwxM%|pQ1vg^9d^Ay6 zDaxV7TFV2h3%{r_jKtyfdP*Y!dO08}0peANg;8`|S1e=>%!KbUv&X`h|1cN(afEBZ z2RsvdKnWu8KS*c)?M(blg%o_zvO@;q1OVWT-HSwv(hZBH#juu3nkaFLEHyT%EP_@- z!k$biI%G~GOwuk%Fz-@cGtc^-KgF@8Xp$=%%t3D%njAYXwGY#uu5VA-KgeIvK*CFd zulLqQal5aJw)lE9XAQyOA2T?A!8FZx+uGKZXE4?ajiLpCFp`%-vi9JC6CJ)9EN^&1 zYT}{OTI}3Fm#bGSc@iAk)w#fhDcicX?lCcM$*45Dw<#lF6GnDwZXgDE2obNOKP93< zfVXDIZ~8^1kzUrK)P7Mi25Rf!q+I&+=>eO^e!<Q(DrjTi@=R+S2 zkkTRwq_m)@-(!}bb_%};U{C@nEjX}g$$2Z7RJkGH^@qi+bdeG=&rk~#-h!!a%ZyB` zc0ewd#X#{Bl4XX%8JLP}ZtUV3^r-p17jRL~0aAn? zo0*x+X07s5(OG((AkD!^jQP_TqCV+o85|cv(Y+yaqXMW8r;H(xFaSgI{yqx8p7{Xr z6JxHvOi#1_5L`@oF=}96Hl2E+{VbWQ&JLAZZ}#{#&|aS#h77Z}Zc#NTqN$D&vz4i_ z&h|=H*ONNJa)1WPwnZ$elZrZ!WQxcC|L#@hqbQoY5JXJCmwl5E%m2W~n^Blqx7e^jfrufTc2-NYmJkQ183<Q?8 zswEPH3cD__KeDMYlo(=L02Ft#A#v}#KDE*$>CzrU9?V)LNDsi7qK%ihg}DRXJ||o) zg0we)^0*G&i-@|a)um{E^Je2N&=(wF<{?M3A8Qn`aFh6{At)w_9uAi=)TA|lRzLI0 zquHWVy%!ekyt!1Lvw0fpWonux+$ecnlRXgzCs)Geq&TQalkxT^w*jL}mauKt!6bu& z9FVb=0dC+MlgOwMPh5=Ti~hm<DZg)+bO|qG+&cxQ>x7RZ!>X z0!wT2XY&5(W;&j&iRE^ZDGT|xCPsB^?pFD^Ssu}i zzZkb9eg|!oy^W*RxMLZKxO2W~Mbx0wT7oP#!B`%#k)1X9a_`kiKSz-V7Ua|iq#Uu_ z(7?qAL|ICBI^LY~uex3y@Obqu8LwPUM5w0CessQPvQEk@Vfg0pGtzI!2g6(2;?I6sNiLCRtVlgltiyIi4l({Ni}Yn5i^YLYzzOgP_|G9of6qYwMXva} z9bm=3>;Q58g=SQwC;-|43dm}ahFD|G^Ne411hMF&45!4nH>NS z&=_hkidKca{sS7~zT`N$SI=OYO-JofB^c5V3N!Pxfo|n7V^*P4=aBB6VkXX>^0l3dlHP?e$1hz6Z(maPUjvV0vG-cGw{9B zuFd7qmt?+#B zyt- z2sg2c7{Vhro0{{J3oY*Wjz6CG9ZPc8z(azv%WWBIDs9+`?WZO&edDDH{ylc&n+wS| z{2~XkT4lXIA&pc%LeG64k6ei-DaUt&jI*K-!-r=yvork1h6|bVWBhNEU;g1S*zu#j zu?HBfH^6B9pVmwM6|H~020+VSMZ`C`l8r_h)G!PIk$50yMW=F5vprrYKyoG-*^4~BLW=UE(2OkMsjy%mwJDHiy4qu;M_Q-uXQ4Ny;$OAIz`vDyI zL};R1QR2ywyAJ%B0twjz)6tyJu*m47G>kybitgbgNWkl0ZF3yE^U^_Opvf%SU6>iS z4WN3-)*eujdp^(7k)y`AX?uQK^+1(OJZx23L%_&+9x_;99IV6m*Rf!RP>`Hf5Oo}7; z)+M1nG}qv|NjByxQI`!|dBm0rO_u>oqS9e#d5O2LQEFXT6cIUd)C~Y9oT#K0Fu$-j zuadXPu%N18)1tCe<-aPJgNvp%=x9t@KJ4}}%z~|&w0FbT{vmMMrVYQU>|)Xs2vStv z8kck<-DCawg><8~V%*SFay=+e1OtK&1zcPP*Jp;}`o6Ke3Qjp8)nZtAs?7Ke%%VUxm&-T+<^~ zaEiV|Np7Pkt`lSRdXY#(d1hEG$M3`h%`w52UN)kzo!3=_-tF zkx6_odAbcieq*NM=c>^rih$2vXggih7oo9T6BS;)a0RnZyx!gL;cIBbP$N85q;?$6 zjIC-&`2-BnS^Pe&;sSNOja|e&SRG?Rk;L9-z!*KztqaC-RUvi<>#w% zoW?`1XR+H{yXbj8qtk0DHEy4^k;X6=#A%~dx_5ic)ktb4sgwbw3P2-v9#ry|h!T4l zt8^8{eXH8f)RSk<_OK+kg6)PdlX3{+_@R0 z4c6>1v6qkE4_l|_Ofi`@wxj6XlaBXF^wrPsC#n@bz)@GBgUBfBzbSGTOlz+4 zxS8^#&QTvRZyP1^aPxp~v7SqjZ9q(K)uN4CIi|R}X)JQ2wtj#U0wXxJucZFk!$3r@ zljAP!808Ul?^OzF(bh`eRqiKH*hgzMVRY;qbfgYxn6YNU*$Hdov5-Q2`o$`W)|wwB zX9V-qo&KwHp9~aNh=E3Farh9pS34HlKgJkd<8ab9JIOD`V%^EDr^}3 z_lRS=vr=rL1kg*nEz^DPfzj&y`PVrl(B8nRIcN?2LVdY3C!)=?#mr!>7Zk80*dN!g z`0eA<3RpHpA`GUNJTJ+c|MRVS{p zuX^^KVlGCa&v)l|l$EX)Zb4EEu(7Cp?p-R(c~*~6ul%FbPrvvsq~X0AY;seCjq}y=F{fBA7&aKmspG4*Vj2v;fg9IypX8_Ljz%xO)rp1MvpOG>m22o4DRHHCTDu? zDS#W_;=V`SXXnh6M)(LOFFTZq<{3juz0f0Qu(U^eteGts(*UO|zg2EHuS3LR?^>-| zzT=Xj>&1UGZc6=GQYzcOKuEFZ$g*d>8@nQ{Uxjjt3mbf`8$y(!LUC{+H+q8779EKR z=0TR<=igfYzhlQESeoSo7(2K?>7n-j7(0Ij(H{}@PuZ;X+b-j+y%6386vsrH4FX5u z^EnAfmD8?Yu4DoX$_dN$Nxo_lWldQ>-b$BYyS=*r&u!jxR9&u1F&dPmbmP8 z<8!=w6zp*zzohWNL7QLR2$byy<}?AhqYetAnm%~(ZupQ)iLPj5z>{2geiT3n*Ppgg>F}M0ts{E5_ ze{%@>9bVEAIXSPums>74 z9Kwrm%|$us402^7_9om@75Oi?CwE)Df<+8iTK&=FIM6;jrN#C6^r7kU!{9Yl1fvAu zFjDU|6q!ALAS9BEAyr_oqRd{5Zwf=M8;!nPce^h+9Ido!r*Uy%S#zohQ~zvX$ttCe z1MUJ6kV&qtcvERYz`)W5=|R;eFjyO2TU)fxU;K4t+OgD->uaJIpjI?O17NS{T&FrR ziSkR6C}l)fHsS@7+7Kt41jE%4!1HxvzT%7P1$69iH+0cEDu)Xwg zC$dR^WaojOTnqsDJ*1B}mvpWqRKyX)B#qDnpwMFZiCr!YMM`Rh8;;&#OW0n{xU_JY zp`;W>p75-|`HVMdiB;M02Sl2(s^4sc8H=(GJr?J}rqWlg36WR4a&ymVWyh%mzkYd{ z?mA5L7()qV?AR>87fIpS2wokkqx@QB`*!Zc6RA+vIz}1;jczHpshUxS6OY)}DEcnt z1lLcvYOEw?9<*_?6?9d!P!dB|AoN(RutlT^BR?or)ZldkL6{iJ4Ki}xUo|6gK-Ivl zA3eB*_dVjqI9poTpFli}%(*G+BiAcaU9q0A*Y!=jZo7go%6@V9U`;?nFj()q7lo6M zJPR3$O6&_6a+0eC^}}Y!zLe12Wg?yUW)lP%zKiSI__ zb%|Vbz|$GU;K1p$2iEFtRH(Z|o|xwPnRm2L(ev_uFd^0r6sNDL;7aVQs-!aYb3K#U zsIx3jsEyzq%MZ`~UYArH@tM~*MA4>xx+(1e;a5jJ%bakOobMHvt=qC_8Lo%@T%Ycp z`*O4v{wLg9NXGr0D@Hw@!|3hCU{?+TLJ}yfSmPqZ5APA)5HF!_;@eQNm!Eq0h$NWx zrq>+~pn5*-Pz!y06?jC9k>5V>O!5v0?BG^Az~74A6G>~oTkpX>dq4mJ<`D?xozVZby;jCf z#Q{qX)W+^@&{r9@CjSN>hbSTjnHyd!aYS5tF zNr_c)a0c6=!h6k5+M>1`U{_jbrRj-b?V`9u3GiCX?KjusAM<}X-hP1+kby~3T7=A9|z1%3Ip(QJ4O-Zy$GZM#x`BfI9T zoaPvXfKurUjoDgArExK4?iRdLE0VVmz=5;RV&k<+b5-bmEnS!lFitMr(E;o>esL|c zLU+Bt4gXQ-Zf#Vimj?V%*`zf$N)ApwPpTKdC*h;mqNWWF0;k9z^35UCGV2y}GO7x7 z_Qj%-(z1G(gfCqv0(6p!7j&3kBhY44UE6o&)y(GJy2a*Kl7%~XTRrdr2sqUi_aQWo zYXb{$8oXv0_nfOLse0iwc6KLKOw<|9r0SHHTJRDWN^zY7)ZEhj+8=}J(MEZij z=z1kS2b2S}LA~I(LF{ zmX~~Wy8DqwVo7fG;*$bx50>b9+md*?0l$}rHpFv1#C&i75V;e4tjEHCMo94KyYd(G zvfuVKRUX4$-UlBj`Jkm6;k`x9*9e1r@Nc}p#6h<{l{#Zaf14I;sKI>}9bOIwL|R=( zm;AP`5gUGT;30I7D*?LKq!F4Cl)B(6ac>b1_+Wj-A7l)@jk7cZI^KM*Lr~%7FL1et z-|d3tBnYN+;LCAI6z+oOd{Jn)4Owjg+TGCYzp}_JcKA#cM;;7c3J>xr-M{gc{X9?X zwF~mh>brIBESm59x-UG%F;C z_ygXNUMWgP%h*fS<~W(2Vs|)hmy9HN z8`x%;)K7wBh%TsMCJR^8D_vIl@QYKPFV-wi_Y8Gc%I6m z&Mp(ou~OTGr|wxo#U@N!VW~A3MYxAlhy}CXf$mYo+OZV)pt&*sseMUvci1h09NE;E z2VB&QD3P>#0@MEX1H(Ez@rC8ipk;}+ws%YGX9Lwi++!}#p9aSkV{D;>v2+HygN`%| z5t*4DSV{Jrog?pueoEAae>h$1rD&}aElN;#!!KE6PGyi@E5i-c9l!s;0wg$6^8>)8 z>kEWJq#}x0kkI^!=VcE*C|aNlcg}7}u(hUB5u@!fMU(~0jVUVJQw4d#24x!20Blb# z25a|m*bp!w7Er>jkxCGnM%HuH6-GjDsMw{xjvz#3cdD-WHr~A4)keU7XCLhvp4o?W zJLcy0T)DEIX=A1}TEH(mZe!ib!$nn!Aghw8YYg8MoWWyhh?4|RV`c|!!?PZ%)QDsE zVG@ogYGTCrx{>ku{SuI;tBHiw|yWBQ6lgF@kAm-`PaT*cK z9ZEmu3|M7e(lH{}G5yR6!@M|)_~A>au8fKIzsc|4Gz`%(iqXN}*&VPl!1^D{Z&7QL z--Us{Y5@uVZf*^%1^hu>^=t_-LQI;Ll8E8VFYR|Yw~nhg+b}=(eflqNYsP$3l0ene zl@zZR)5D3T%dE~1%fd~e@PBSQlAZi(+tCR#v;U86$C{}ko=m8}ysb0H{_wUQ1$tY* zc@rt+d<8W0K>JJt1eQ5WH-Yg25_Yr_IL2)+(WTa2fGLQEF3RhWVi~y zFGT4DF+kj^6vZ6=aWXj&w~C`Sq6u7cy#2lA2+FIR_lpR9PTO*!?zg42I0D>6PG*Wa z5Vv})631IBfZ@tx-D`CGS_aZr0Zsz+nrq?642YN+?9+L~Z>&By3?}@X5zsQ(BcB0U z=BOajL!S{)ij!3c#tJMu7)aRy4Xx>@IwRynWKPX9e#HH0XdQXTlOT0Cg?X~ELA)9p z`RtiEGZ!#7#+i=!YjE^s%^O_<5d6Nt!)3qS`>9&SEXWh3c-Qetq0c=`=!W&?+=HNJ z6P_>c?F1D2VawJF(WBhjpeE$lJe+a~L<#iFD)%QCO&#jtM* zYp7N>37Ub_6yLyMQA;$(bZ!0g={V!2b%(HqX0Y@gdw*nYXX(ET24h53{mR32jf*E) zr?WRZabte{nsnyvo#i!rakI45_5N|2C!NpJ7r`S&yntYdvC2SDn;&@x02NL|6IxBv zD~qHm@~9rT0AxcX0_0gdrKaubJRBR3l-KmZ_6lag_H2*q1tVn(*-upy6xZe^zV*$f zsdW5U;CaiIyT=M&NI92B+#i#RRKqJyW=q?uR7+`-DMRm?bB$!xHdV-4fU=Fx-(F~K zn7)!7`boAr#iQ*2XIY`JgbJNko{DkRIY%a2ep-Ai0nOhZOIib+XXTCvZr;i-n8c;^)>tvF?9LfxY zqGMGsHpRu*LqoV4L7BsHdHgD15Lb?0?8uJ0TR2UqZsW35nB1e~>flf5<`#H6)6)5b zvFU*U*Ks%x^fOdv;jg;}glY+GqElI`@%f4SM}Fwv2{PW@qXICI6>!+ySM zvL!h5B-bfKTPNn#8J<69vgmbk^R7W~Rxs^2P%ryVMKC&h43pLHR*0!+lZf59w@FSh zzQX1>hJMd8NT6+56(>#;bTQigOdGZcW!392f@u=hr1=$G>k~J<*uSq8y zm`O*Z;-7@z*vh;VGA67QKV$m2)h)m4CtIifLR^Z|m9FL-9GsnTHIKIEM$hq{^jk$RYT zf7tH$q&I8$ef;uTG<68yThuml357uMLE_7Ujc!uE^H8j_V`yu*TcQtrpvg6E6a+fq zIcAi2J@kG6vT!;Zda2WqNpk|2Efo0`PgiI6yU2aq$D1#K={pZ!q4%-SZd84FkkO;Q z@21(4wr$gwdU@nutx;~xxl!Jn?-a-xlK6I(vn2{IDGd^`*rfM&<+?29yAdC}Qe}}< zOy&V4pA+u^uF%4yk>ycQz8mv_Cq$KG`V`RNP=Wf7{~ygyb||&SeO+|W-Q}qSD#49- zM<^BUu1c4SxZNh@NsKG8u@_fG8yayonyXPB|QmPAEv^q*Fl*NMzF`#hE9^hw+jM&bXZnwp>R)*#Hq~ zQW~%(TT5HLLtYO$6Xw<0QonSYjZ~~kDxW^j5EI0#VZ_8~n2yfeM42aCp4_Nz0+DkWPxXe)H-QD!e45kyB z$4}H)aDmj)st{|3ygoJ7bSVwYs+^V_Dq~IoHz4=ehYp4^CiXva(dd>VNr$*5$zHUoJG@Tf|Jt;y_%b0-z^sve+JG54W3IntgvXh2BiE2QS0Dj@N%s>cj;iNk zcU@FHa`_7hfBxzZM03YurN&kiUU|=0tIa0t&Dw=n%AEd{j6TRtC+Jk+x`IuaW4SD{=nK|{I$D`6(S>qGlX-srcG&p=}PuNPfNo`90 zRO*=N3ggDWjnMJh1<`e#;`s9Bz*8tdIYkjQ7vWkX?@4UhlDDi`Rr4S%(r`3t5>g?z z;!)VM&^$me>@-bx3jHPa*fk~OJ#Tk+_c z_BmJUMc;8+wCMH`-OHiE>pOW@u+4)+#o}E69Gw+yDF7>z^0EozXnk6<-qYDf+~S1w zw483LLOtBnoL(#R7emo3*>?n`jf#QE%mq|!?1Gkpi*UONtIllBcb6k7EM`mRxwIb= z_vI?Ed+8{vm6=Vq^?P5a93@vnA&N4bl(l4W$tlU(Lv`sruh$cuiDL7dKB*T?6r#++ zBR4!OasusXNT*u*$yz=aEN-59bJb^%xqqT>98uz^b1`197!r}>9+E4FgJ0zU{vkE1 zh+#J1f?Ib|{K6^a?CK=%*mcA?uR2$WFt9AK(I9D;?G~FCt(2$cJkeY*R#%G9FOuS) zRw(;p?xnsz)yWxCQZHymPR_aE>+I5klPq~9Src$q7o4El(_`g}I5;?C!Z_&Iu{+{@ zen-=iXezo|f`x2OVv+9yx9&L|wC-vgFXR-&xkI>r7&p4yYMVzS_oA#2IN)2$6)z+Z}dk7CYA+pZZhQQV&r?MmY+y%mchpxqzMxTsE zHIRy!j-12gO1w=8w6yD!6Hu#7mkOym#fI0tZ^8TM?S*=ErZ$`7ka*G^_zCkdDMNPG z+^xYB5wV~0=3(;kdnrU0lyJo)X>K2R-}JYm-Cv=7CiRQFrI3s2`%Bb`)S-pS6k+6W zGxd@=ovyCx{krzA)m|fW>+99M3@`cae_3r`y1##Tz6w$$DaBRrt$tawUU~hLUg6v~m-4PRPiv?NWJ;s)Q;O}z4uSLY zZHc$-m3AuV*Onv0MYxW*`!*$rA7rBVs64-HRJf75TRwh6>qGawT4|1Opw8@j)W+(< zRb$W%Jz}&)*>pM6Z^9jZhInP?#7ef6cZujm*61cGX+B@o zP)CFv;u}uTJK0W`#-kn5n^w>}+fJ8GW*6wCv1iiVR^$UiC&r~wyZqzB*ezt>d-mNH z{VM|0dqD5|_x%?G&%o=v-uLAF7Y9%O>$u+c_$&U%DF$!V$1Ie$qigU%dYE_VN0>de zYu3Rk*ms;qvc0A&o55f-0u3Ia|yK)t=O<>!Aq+KOrZkrTi~mIs)~{^uLY|H@bX>P!BW(EiQ8$6`*Y(?U}_RVi@n zG~G-5>%lozmUi-QC@dba$t+AN=NAYkuyvj$_Wf z`T737xu0=g*BIxpdAAW&3)D5i6;NCQbxnbkZmgJ@xy^4*{psypz<470NfKaVJ02m1rbjA$DV;`Qn%b2FtmMo;cXh@JsUO z=V*OAa;wKaV9vNA4v@JG0Q{cR@!62MZ5OeEzPLCCuE~Rv$j3U5kxZDeUuN&BwL3r< z`jMkZ3mkOUW$mBeDh*r?DE719d4M{WoHMua2k9x9{M$o0@UE2x)*%1B72?lx^2hsD z&2C8m`Rf>mqyYA&`bWP>Suv=!>}oON_ZCwmOiIgaqJeVX$KR+7si_rEVThWntovbT zI&YC)k-nl;$3;)Qmw_=NW{y2t=|1BFWaLx{?yzep<1iGyiSr>Xg z=d>SLsM3||vr_Ay$cKy+7OCYjE_qH?6z9kgN?D}rLL*VcjuBh`svib_D4KRGpHSs! zl1h`FNjDT7X{fb~!MB?2S*xW4!y^O<{~;%{y5&`tp;1UAKRFTRSYKk z6gdjXjj~OCM(i!iAN9kjPruaFi*o68AU5{R_S@ngk!Zv%hy6kx{S1cJ?LBDT6Jn6< z@nM(R>hFlPgQ~7e-4a|osfB`vPqsuCz=bevz^`(VTMkFTc$GryWO1y{rcX|dD1+v}*EuPl*gpWgo3N0FdbMR5ST^_HCdFtsGyo0#web3uNw$up)0OUXW@ ziBbH~)IG6~bU3eFsXm;lqHu)ippw8FPqJ{iX@b*-G?qU=I^N9FuoZGF=23vebY;YK{W%OEhq zna5N+uia9@I?&iL^L?X5ssnF~1f5PU{iTykd&SJcK(f=sxtl-Gp8=i&{*jAor(-Q6 z%GZVNd-`Y!+iUlJIDjxA?c*5DE;?O zU~sO14Z*Sdm5EJ1iw7%FwcMeyiAfKW=ayV0T3zE0J|D^c(4O&zfC~6fO#k!K!4wqyUy|MT+|F8S$uAs7aYQ3L3a8X)&Nia% zGNI(WwaoT=u!bshSJsUq{_WAYtx+GoC)e(KhWt0XCNIC!{{EfOcGnjnEtt*gol@e? zssh0FNC-!N6j^v`BDuvu>U1J(#aq|6x@w`hMIpo!a`(s{zJ(|S*dEykt!U>hfv{bt z-PHBR#G88!uc*&Zvw{(=@TgrG4@7s?zkeLKZs%3F^C_WQ)6 z5Qk_fh{2T39kSY6Cko$_l)gL}!`*Rk` zH_?uGB%iYWA1kWjCm9W#IWNZYKp)z0 z4ciLEw&WYqgnPx1TVLvTVCzb6ELLQ$XBF0D-wum8&DVenQ^+0g|#P^7~H!XR?V z2Emdsd-E8ija~$4ji8Wk=odv%h$GrFpa`bBkHJ zP(5t8B|vRt$80R$9cz87PE5w}Dsf`0pS;yzZ#%4tfTvbxfqkju@%oOOKaK`=a=Sfa z>RRcbRe9lx3bE97C?`Rkc^<~1LOISSgS&mG{YUiV{F<724;YtzeCA#V5r-Zx2fvUJ z6Ll6&icLWJ24XHUmm+;ADUd@#$(a2x?TUqBAzX15VrYlDh5mMFhWJ@sPmSqhITb- zB~d$C@9{GAj0>+!%2K{|66lv64`(A0-{P_TVyPwKr=zUtQKLW>{P_;=I@A*e5a6V7 zUn+r$@RZ)LL|SB-HOoNa6VA$DF&sMwt|Dyb(Dt~JWSuMXf-7l&>lhIuE~N=@9bcn~ z>eTzL$5QpvSJsD6>a+8?VvzT*cB7SR?TzI*PF!0;9(`b7xyH#we>}m_3)t~LLx8`a`3!9T zN8jV$rQr(#9Jx;7{a*<1e<;KM_B|f_qLln^Whh2OR6RL5yi|92zVjG9ruF(LL!%GV za#6X?rYMZUGU+fZ)Qv?IrmQnQub}8^d|MAU%vX)b=41Vr6*7!IOT>CX4v~HQ^%L*m z4;e0~?`uYVE19~oZ=;H_*45ibOA!g@HC3In~Q4E_hV4?kP99^8by%HB1vKDgO& z*qOM}v6bZ@Hx?7hg0@wzSvv~enMj0+b2HA9ial~=M3$gMhE&GE%-oF9TZ{>4q~={+ zZEZ}338|+1CV;~jIRE-50X*0~79fC|xW5Gm;9`+41n`E(f3O{SGjHy|P=6D^GxXI7 zS1BSDnD#UYhcl^$l*uPZQV#V=nG3t$&|7}lgxr1)<ccE7G)_ui)OaT9% zPRkzxQN!tjAo|x;(Wz1ky@w1z1cB~C6U15+`SkHcDXMJP+8ork`}&O8YBz)@mLJvk z*?+jMORbUSvwlOvE&C~hySku}xT2pckp$b9I_30zC1KaY&~TUV`RQ?2>lNK=N4#ZU zwU!8wJ8yA&;hVRfEhAk@T*c?*qX7Kd$$5Tj-3+((K^x(O;w<#dD$-uv{C9()>--%0 zH*8JO&#iyV=2wW~r0l-`PT|;2V!e}o1l~wF zZBrqOAGewlUSKL+R9xy7W*M_&f7pjvW%+d@SHk&?M=*2fTMFo9LhbiN982DHogs}S zH2V-{-(x-VFJJffCO|Kfp5^0D6q&^Ka9xk8wn|_YoYd?Sm;XqQbK+P^uW`MlR*Nb0 zr-jTiOd5|4v(p!NN3s^c=vbRTd7W(*5*t5t($5YKffWfpoXeDAG3)bDD|Aj?qm6K; zB*uL_Cyd4VA7#EC~S)_e6cMTv-h$7 zgR*97dw5wc?~UAEL#|pQYp7l_)>8M}^3png36;!9RZ1Q>!%%EbvWrh6O&8>)@afq^ z!~i_;q2tWNd{kQu9$Iuu`yBjRTzzdUV~8L?Ar7`9Xx~!`v-Gz^IrsA?_~YQ(<2t%H zcl&hsBzR+#Gtfa^f*USb(pth_e^AP(A7X+J4~_C(<}5*U*0Zvr5;&2>6ek#N4B8`2w?Pz(Uich(h< z7EXd{{>u9Xc+k2cNir3!4C2=iV%%~Ik|ds=EH_s38=| zRPhqke-@M9UwGyhO@$}Xc?IG99QujY(xmIF8Mo)q=QuB?Gxms8d_m1mN@!28`&#F? zG?VCVXVBI^%9xR68-r>@T4tTA6)9xR-h}B4gBz?`<;Kj20g}{Tvw!1Z|yT>=o{&g^=Z)>y+ z>YP<~bkkaL?WqDFgSTJ+H(Dstv)Db>|U7@ZEuvEB-H&*nG$d_>AnXFl<`Vg(}zN^Fita5msn;MVTAtgv#5%z?Li~q`r zHfVHs@un1!e(WT{C})TK*CzRLhJ3TF(Cr;w#Ltq~=7PRWHi3=nyw8*2L*>46Jnk%C zqk^qB{ur%nusJ3N017c5P>BCN9Ql8^75_(-NFn=H;I~R7`-n=cYytql<#f+b8h%(D zM7kNDz)_|3&xz@dqxCwGc#>_J(?;j{{6i(OGB#B`-mZ>my~-`059J9lvLO||u!Or! z*Qbx{^5E*{JN}FaPyEF(3o@LDD>nVb8AJc|v*)1;7a8a80?!W+1-kK(ct;G`St}$) z=w%O|`B@V|_koAha|L!??}6l=x?T#E7>oxjF16bd4SY!d4L3-oCVtPLNkZ6a20(!O zS$u8XQ944cBO?n3C+GT{C`SuM;i-+zL}eE0#UnIC6CZZGFhL2TQ9#cbY87O@QL+dx zvuJX_Eyi;2H?(E;;-quwLG@WDj9_gQZA3G9@x(oE4Q3 zPw#gIVE~BlowH;ehFYR!!;qz;wa(uK@Rr4jX4^5_00I1xLGvq%MF8HnJj2|E?WB!8 zBC398s6vOMrw`FKD03SWH02Xe3Un}l%N(c6Z140yZ8^JOf@m3Zh+P~(7F0FE8;0swc&;g>}k!Y#&~U1=4t$4rPHq|3lnDG~HOW)|xK_y6@l?%cz) zNMW_yxm{XXioN$mDE9KSp+aAm8vCg>xlnjohdgL9`ItpCU9 zA<*^y+Ya;98gb+6w|ZYxe8CfZ1>!I>qa25xF1nGhz%K zf3&8Av#xr%|AN*=OCg!HS?EQ@rjc@CL$$;Z_Ffa+ z8DtAxX0RSIkDuTlUTI+n)hD}*Q$-=~GJW=KTi5LV9y!No(g-8&<0Q(1+5m%5ENTfF z871HOILCnD;PmUFVM30-qkK6o@GO`O;UNMN5x=Ar+Qq)RhUpx+I3^sOWi61eF2!+r9n5c?MF659Z96r z{n!p3#l>CvP!sO&fx~Hx)0~{b)$|{(og-gdF~J}l&%f;9I~_ro8g<+nd+^V@y}^!|ibz7zVA?(G+3<9(v&SFDq8#G!*~ zpweOLSG!jnnKqrjNw9!PBeA(O^Ir5D7T_TMBZq6Dq-$LQ2t*=adieR@Uk(55l>8|T zm0n=O&mZ0(2CNGf00eGI)AT{qf?7T`DrCAuzPDlpvx^c8zC9zB%NmQ;yX>i(HFzE2 z=|Apl*UuN>x6cz+s23y*KV}E^sdFVAjXtHWHXjXd{T>~*6VHR)fv4RN20neX)MNHz zwrL^kGy)1Bf%?bXcTR%yNb9NZmVkcupU6B?>+eCIgLwy3O7qkNN3DrDBkNKsbCs?) zXy!~&s@fffW9|}sLn72f$BEqA7|J>TbUXJ?b1KW?+!e3+EXN2 zv?o*CRLE_bbW0V0H0^SOqg>d|ai*o^ei%N3-@dHlCj&MwbxqKZ!jpP=^0<-H{cwko z>5|IYb#{<~<&tT{;17GS0BiF%j4)I)L0l0c>#u$AMORBC)u8P#YHQ8on=K@5`w&)A z0;go}qP$tN_Z;P@PE4HUE-mclf9Y_hW*&q(yXL8d_Rn!r8Y$dzV|tb0utTl&&RCn4Dvk>C1!VU`iL`)N5C_vajAsmxW6vf`P6Zv!ywp+DI&vyo{gD-7`LyYc^t5@AJ z&>nLzLuZ!bdxoU7#j%&w8SFY?p{w`3PsLXQ5eD%_;7%2A%ZOoKmQO0T z6Lc*zR)?Y9KHM9Xl=lVW;;bTrIXXM)I-oUX3cXoH0}qv^GlZ34@B;hfQRSUiqWz#@~U z+xwcy61%6Zz)@24e2RXzF5f3HrRv2MZ41c4!W5vob4>JHNq6-7^y$dxX+GeiUWm7Q z1(;!q98cml%KDP?(nXVLU;NeKf3<^_IO0ZZpy`dC>g4YKYyx~ZgmHSkuU||uWj8p{ zop$uA@W!c351I-<*XMn_)mQm@Pm#l{PF8Ba)xi5v*`B@RdLcU@cklGL+3B>>^-IpEbR3`m%sP+FgHQX)L zgNETVo=kN+;ofz^wRQD+zW)W*j-8qt*;9i|!bntRMCXS^{>8}pL!E3rH#jUK^hq|o zZxb{$v?0o}ob>Op;iZ7IjWc?XG%z;I87%3Ccf^3mT8Y(;FTMXfwMK2}fh@G-@TH?= zJpcR7g+nD7V|J>_i>$K)d3PRh+5(O4wm1a~sm?9Oi3G~Kx%`|7jeyNL(^QKvzZMdE9xq2%wt5Okd}VB7EP|Xq9(`ITjhvtMOuX0!4txF)q;!p`TM`v)XSGw-_`#mbPuCYq1sL)_O*uFYQ2`m71vjH5=(J@Cuh9jWYu3fkgBTJKvTli8V@=2DiBPXYXE- zorvc@;CFqu+4%o2s?OfP(hjI~`PV-8zYYFgRNY^lF7IqUeOBkA#24I&$Vcj{sgkIz zbjqp$J89bh`rPX;vk=xgYvRn=w`U?a$K~T;e*KTN?gjvze|1a>2S-5rZad8 zc%4TMTf@QxlfU~KH5yolS3|jo>2ZwZMBTp!nVQ{3uoz~+rRiT?on2)<5N55a6redW zzcjjpBaZt5jV>YoOQXx}|JLZ@_}vz+qFAS8m}SpAB5gK*gJ1!gW@Mw}!jGr}wvqbz zkFnoJQYq@9{|8m~uczdHQ*~+|L1;O(vK1x9U^OcQv#ruWete<1>7U52Ym)Te1rJyb z(^%ABVvn6KhOY@rTe&x!IUoBU{8n|uj0m-X!lUa8`i?udPlkq0h8JU1K;@tHTSq*e z&b}5Ag1PWV<=JwA(zJlHf_Fs(#ewBConVM80?uTehIkO?B3(w9JVtwUcT>ec4o+bW zW{%+ldz0d1Xravfj%$nTs9l$>eU&Wr;dQg7QxM!rKKg_1%66>Y;_QPaKv^I{J0f@u z0ra@XIZ?W3slV!Q>Kog@kV4$X;jn~@hXq>?3Azk^yCs|<~VQ8mP_ephM+W4aMDQh zw3OG~L?Yq7CzK`PS4l0B(`cF#sT&L>DCKnU0)E-a|F< zYGP*AQdnJO5sjw!&-eu>rKywL~y{s&pXFa#@I z&b`-TketxWhqfJ*oOjJDrWy2+^R}7G%0d%$2kiEf4!$hrOELGU;WMCLpndcWy6p~z z{s9vK?1LMsOH_^(!@_X}ocC19N-)x}H;HCvyH{%+^-ax2Pd9PZ7Jt&!IhGrn&EhRp zO4TUr=K=d*4!m5tub%_j5U(a#SYT8S_thXYH22p|wc7|fegV_IUqTl~6j_3ay6_s_ zMw&&D=`#|hJ(wjVT_s4NiXrPn9+LMC=M<6?HF32KbNR7r!yoroun0!8(^@&n!5sWQ z@uT-(G`31UXWqyAyAyt*kyRn^ZO-RQJ&PdyIrv)E9Vzzc)l>0eoiMbNp!?Xm``QwJ zP48JQB#si+PzD&H9v&t$+~%q*rZB-JoD(JaJ)q8Cne;*+E+uedT6S}ej(dECtT=mHU5x)CLy{mhq#(FP51O=xwAO# zOS%=LabO*`2lK}7036`}HqW~#b@-<#*yp$?w)k}+5gw0#C+rjO<@--OD-m(lM*KVb z9+%aVT=T$JaE zBY>OG681mSbpLV_{zKC#Spe@^WY1V#7Ap%e0oCdfc{z!05{uVrF!K0(pTR_Ys4Wzh ziNL5V9rs5;po8c0svB&nYo9)=)Xnemi28aYd9`Or&Eue1h>;sxaVKDz_!D3 zeHWc(t%k<>suw3cjx zQw!noBi|*gsVrl4Y1IHzXfUivfzB~>k%h7vQ!xgEg;w5pmTtB`D<8kHrx~(zYI(+* zG>LO^)%-}+PqAiv!-0nXJ;NIQQubZ_03{B{Zedw2a|@?S`KCIgK^PNBsHJsSlPt`6 zYNrFGAD=JNh)TR`WISp><4CbECIhh);=Ua7t)DXY&d~P`8FEQDJ)*+u<9KGVr z9o42-6~>=GBRhTN=XV0nea>6TIhx4*HnPj=N1`J#IT&It^2g{Q%u(F;XIFASZ+eEdj=oX; zu~bS1hxe`50gM8)FZ``MWxja;9-+&_70MxpR<4v*L+PEkKV^PcUPmeeh28m84a}Bt zd0uW16ETJ9DWn+AuUB5?s@I9@vw>G*y&K23M)ir$7U&O#bL^Pi$i}?{ z)|J9cPE_c}tyP#l3p$Q8Z#q_#8iwO@i`@>4Y|?%*Wzc!r%UowTQFb%$C_mhANaSKr z>a&YU?k&}0T%r`(ll39eNFSRzE#K2=4BCC%cW6iW7G>EIc8+_ zFUU-fJFE(&fM@9QwlTQ}EPU`uf%A}Z_|=WfM6L8U!F~|$rqF-k{e90X*5x+P4Gepc zfno2zpYQ-A9>Bu>M-}+LWFF06{>nVQCx5$~>QfI+@bVZa{FleT-$uN$5eTX#hJZhG z>A(D;IPhxqM;k%GMY#WrJXT}CMMdwrq>r$z$)$b~kTx`-sviVPkeEsj@nOK*mhX2S z-wh-~XMrGnVuqJ1?bR9MIb|q@T`kllfKH%evy%j+jFNAa)5(T5HF>!#@9jrw8^dKI zO;82KBDT6B&qj)8o61rTUlU4IEpjSGxN1xh0YPt?MAUA50Zu7*ex zak1k?JFezBG$(iSpt12^XuMq|#6*)QdkKF99{V)Fc^s|BdOSeF**0u*Y)=I?#>{X- zY)?5h%GXHazS?J6WW-;3sBA&k+g`MrA0o#o5{(-5t;1^qorUz+rLv=XmPQzc%5U*XvS1-;%pZ&FXZzjS33wp!n1NnL0xiN-*E7VU zl{LnLGM@B`TU<&lC@7|KS$vxDl>&w&(<29_7};5 z^@}5xMbG>qIK6Bm_J|oO$ZB=(}zTtOq2cV0U`Vf`%*Zu5VNy9Hw z-QlCrFTWlhZ+Ty-e~amra32pPy5LssmW3YLc*uB1Nl+YAP6AL7>ICKy)(H_=ruMq} z$laqlEkL;6dDZD~lvsn4KM%p~Qa2UvGq==_)VS8jt~Kr(3)Lu29K0<#iN0f~YZG|Xgf?8aNw7!4BDzWaeV_s|mJLW-NjF5wb;9 zctY2oZ0^xH%o>lSvkKHbg;%F)f-GZenCDoAZS|9I3mLcXLjBak-~YGj?;RKCz3*B5*l4nZ`KsjlirOEptol@`JS|eYEh7uei{PFxW`aPXBDl0& zqHIQc{D7iHH&l^uqy$N#1l1-;x3?_V=!{CE$;8bq%oJ)AJnBb_=SIlgKIeCaaj_5i zct+N-rDIcV#-5}6tq31?^Qk6$u@&&=xVOmLY`-F>`4V%2^OoHlM|HCDx6*F#tt|=G zjII;Ib7TX{`AgHm%vfbD-!iRE8X9Ue29r|2=F-U9*=}Vd%C9ss0h6 z!s)6(ja4{uE82y}d#k!TO&MU4`}i04!vBSPAq4%*wdEFr$-?_#&UyvlUa-FT&Ap)b zi+e!`L>^(I)S;fLV4q39vn8)5k=!34UVM*-uAlODuf?Zb_gvCX<)#~>82PZVD_hQQ zVviCs8mSfWb06WZiDX@Jc!T@&*Q2I-JD0|keOVmQuJywo-$NK$4w-IXl=}>9`04-c zwbt*e?=QI@BmZC6OzQ0-PZ>c0WqZm>%5P-fj0@yNpnIbcw*1VODq_un_DAa4wtgdG z`aPfXk#0PL=Bg#s=-5x+k6Y|^Q|-ovmlIaKTAyE?AsixJZF-{1$yCB;#)B|Hs5uD< zbhy{LsCG!W!sEd%P*Ox(G36iEF~HDu4|4~Ot1~#^oQS9xL@-*`R2_Zr_gD&(b*Ri1 zh$YGn{NUA#ltQ@XB!q`1@-wYuAapv3Pb?3GLMu^-7wEn6bhC$rO4SQ6oBeDT^RsPv zq-~QjlxR^|@B2t(qer6;oBPMJh@3D8t~dLgo#-iJ4I-o%G7U)Qgx*O=u;w2H*+xFt z7-tp@qo#ZkFw3=*MfU3yf1707b*4ev|6%>CCnif@3I0}{Q&NRx|H-pJ=tHTUAL47n5x{Co3^gP*3N~0Ve{I>DRhx$>yqvZ1*xH3sRoO9@BrLb?`J-kpVRxPNi|ml zbr?v4Un)FBhGtn-s~`e6ef{#&=~y$U-X%Z}r`iaplbV3@WOJh-eAZ86!#D#H!z4KwQ2! zGPZNa(o1deu^E&6M3PHKGQhA*%p3Zu+v)%q9K&>j3GcZ$y}NqcUHek;vpzjX%r+@z&n@s6`h=^`&yJe~O2!5dc-pIQ@Cdb2D$M<`HL|puj`~X5G z2Il&IriuPSWg>WB<=J3;nF5`bO~Ru^ef#YPSc_mml0^p6L~Nxg78@^h;BfI?Jx~ZD z*1N*^hR1wS-+blGP3Ek2_D6=7u5aBN8&$OHovoT)T@f_Z!{SZl?+wC|QCw@0tVV&uM+!x_{mx{sqDv|vVnsj(yz zv_g91!?Whi6lp1XgNtK}gXxY$WdM)CA~kd+zbNy8eSYi>y(B-e8sHFM`nBhsv8eO` zCqOb@DIsawJ7a0yc1<@y=O^G0n9Yq&9Tauj$p2_kQte~0Y-5cEizNZ-+bUDKJN$Vu z$N0-N;q>RtT+;1tg8-jc#w9d?j&j1R$39;0R~pe{`8t@J$VqP8srZ<@445e+7{x3X z5vRU%mNcU1MqW2*NWzjIm_@szrkDoK_8`RaFlh4!VJfQ0CV@?Pom9c(B>qttUEeW1 z4C3i`*T%FHnydHVH?5CvXAi^4Rv*9mS#^UCD)(bhUTF*vqE(0;8U!hb)P=owsg^t! zuSR308uUR|k~|Yi#cwJ%e7OI^DsWIHaN7JI50(FZfc}t`KdqJofL`J_0FlZ6@CGL& zlwQcY+Q%iQy|=NX*orWsX53Mu?=X2Qv60O&V1=5W?+raZ5fL~N@Ha_BMCAENSL7W8 z63`h))@@fiH$S40WC)chi$}WKG|Qh$vi(hDMjx{;j^1 zqSK6kDyW>Ov+^C9pfcim)Vm_?y}oU5O{q0lkY=#fkaAd&n#-s)0e4glrJw}u;k`qt zg1BMWVQdygPGy0Do$3rZn|)TcnH>b{dqzjks%~nhZ}>bGXz#}3n5lT$R0hunD^nQ@ zwq#Ys)TtBR8_bnc8)Ys;`>1f1B~iNeAS8UVhg!;G!2Ur^%WtGo#x_m%ebjOfi0@99 zWY%se!W7L{E6~nx@7^J-D?=LYC6w$m&_=c=!GMT7njkD#`VHpohqff_Hq1ciC-Tv; z?P@UYYC(=pJsYKtHuOtO{uY+kn{b7*ft`;%98Ez?XihU4FPi3Azq zFVv3@7VlLX1xwMKbM7$;>8`B&>5&hSs*5P&etuDy5VC95nNp5PE3sn3w!$_wEDaCIWMiyc$x7+Mvun}h z6RFzQT^P~MDXQ+BDgbv64lN4v)ijJXk~#3F@`nsE;4J}qhegm#`Hh^9JWy0w^ovfS z&IXOEaIo9)Q&q&$noC@mRS?t?2Pgew>$5SLkSPAq;28#S$qN68Gbc&hlSywRkpM1x;oR7rr}_mw@glsPUN}_hkq1HXn}S%1mA`BQ zFdlpUcUXL^7J5GEHL0yR6YDWIfNg+L_lSjq;|y(sR|bQ661iy)y7{yQ6IwMTQ?Yo~ zlxdj))%5!Hjm(z^hx1ps*=DR3cJMOP9SNV7n^-?3%kX*_0h~25aLo4C*x83&SG0+E z7ZKs${VEi}ei6b7{aCoRXFQ#EvWoG zQR#0oWH#x3+0@wa1wC_ZJb|Z1v*pbIGv+uTa0GDHWPWqjP;78}WCAbcesk6Wesk7J z98Y35+5*||d`N6~Ug#Qap=>XlwfMyb;h;7Q8&8N$htt(6Q$6;JrhtlYd4RcA;Ng~Y zc1qYfwkeQuDq2&9eb4`U%B+=sEwi2!-RTu_mzoJ$H`-ttbshkJF#r1E9H=As!J~Sk zKOOaDqvzwm01!F4Y-0^O#_)t1$a9QH>u&hUiPE2EdVzFu9N}U*#FfJo9+)NpM2;pD z=s1ME1P^9e&hYR7xw+Qt^h``^NGCjp+c+m21prh21xNkz(vHJm34i&vRs+|g@V_rN z|MqSDeNp}$A^gwp>=YZlC=7LmJ2Eu#yESkqAGXi0p}r9)1np%g^!RlF#T#l1O_43$ zS6Z*pc>XHga3my77fQFM9yvN1c4JIU`FVf1J}|%@Q1SBMle`xh~bXzr($uN1kYf=@rEm%c%N9+{K3O z-@$fhbR;4my{46594%szIA@WTCjb}9P?iTM*HXU2uRi9y;2F;BDb=k60qh(--WmG8Jn9KmyQ$r0AE zi(wc!kw=Bit-W{^xA5JZ>l?BDB$jUVK20?4@Ok656C_-kY%Tr}qllWx^`4z#ntBND zx!=`xfnlh0J|vH}4zv2scvs_Om0&NebY&c2OvI6Qq%j(E3L;MRyXR7=U6xv7jzx|< z>ktKO8rgtMD^y0nf^x0N!%>Y{a5Fn;S+t1d?>7$DAO~Z|99tDzzw+n=wr0wA!n5Js zg;*yV_%WwLPbWYfKxG*RnT}<~8cNg0s<;YQJf%=SaWQ;I{pxT+S;w38bWU5I`Z}&6 z=)K>wE;wvRgS)M&UXn3Mh=FE3}zx(O) z!y^v;$qEI&bsQC0ocMFC_B@x3j|_Kn^iMH_O!P|Hu!w z;yzAuV{%Mkod3*}qAk6Duj@@n$0BCSp&J4!IUKLD(>-lY zTxKAFpPLA2)VgJ?qMu{1^4%Xb%JL1>k1oLB^#dN>g8%=A_pirz4iLlq%TLv=Dx^b~ z_DKdY7;XYpup26fBf%Kd8-ngGXjykicB5nR9^-HJ`UZ=50xbIZZ0_4sx3N>MWxL1C z-MF$>x##6*S!`t+e4wo!m|knq9%qQSjH39xE);czh*Lp45)^egx}3GfH$EA8`tS34 z)44CX5Rq|kK?FqCsy@P4&|e^Ox{Cm(J)ONUCu|3u;*C$^09JD&{&4Q0@;A2(m5hWT zC6hibpGIj1^RX~oI{R%>t?woiWsxSe=58B3v1WnVF=}uo3@Bcd`9V?Cqz!EGq@E5# zD4P1_7Z#=3s$JB>bW~AFgy*J5Zp`L&>*x|g#-JKHxOTR$8czvBhW@4z+?ClyTge$r^l|19_yhHm{h(637KDZfs=l` z!PAKM0TMa%7wseZ0~q4NXsz;&riA7!-;%0>A&N)cx|==jmhBF@M}*9eG0_FifFpTi#4_X+jjm5mXAYOju>T5OU`*frCQ;t^Ev zQ-vDS=Yr%Oz=o0o(>bW1Q+OwbMO;Jv1s0J+50{phs$aRA5_I1F-8$*DWmTZvtwwlK zVN-=7*^Z*pY$Z}9Lu`cJ-U3p7!G4K~rM29adS_(_$`%HQMzSSD^Gehihl}6Le`wqz zs@W+ANAm`~dT6~e*1)Z?4=T!nyGgiatlYT=S|{GZkFMtxv?l7$e1uO>uLkKqA->9y zkxhI>e1+}yYyVAKLqVlhuTVqrd(>|biSdzqux{%_UFto?O9+8OFu2iL-baN0p8 zRDrMg+sMi?wSrxi*abb(*dZ}6j)fvc}7>!{)RxPPgw7d zynrYmI?L3k3uQl*?=O%&pcxz(K30uz_J?csl^w5GIPhOF0NnWh!ItS?weLS~`N!X3 z`!+SPvhYm>_gCLCaTkMrcn7GyCzHqe0?b^|p8}Wl3W#rwPoQJl`qN^%(|OUo7|+8Q zMt^)pp%SPVaBws-;sJ_yt6rieZ?vJs$*(q4k>;j|Vwgy*2?LW%wj!i96d}IXQ?E-x zW8@<-LCGQI5-%IP@_AZzXwa&>{%F6IRU(LzS}p+qlAeoK)AH+OCyc zq)~7R<1AF$=g)&}y8U~xHG`|TYf*N&8cv5JZ$YKW%3*O_!J~6Z1x@Y_OZ4?^xmYYF zlL}T#tS${SBnyQ04&tj52E!XXT`+*LYofq^qJV&-#vuQAZ<_EI1MXUe@3#=)^eIUp z7VyP@PgoYx3xk=y>=>8nXOFCJZ4Ilml~c*1h}J7YNR{>L-Caxd zll%P0F1%Wl78R2O;) zkRg6%CnEcnUJa8YAswbM{%Ly-)^9}+LsEbX6u4|vG?T04WY*&j>EEhH0n$7uwN^g2 z4}OH{YT(7rBDTfj#wQflZKop|%)yLRT(}IE*4mN$>KOER#SqMrZXDfKp|^MLvbMnK zuHr;JVdod-tT?pN!zcH#i>kAHEPUefmZFB~S$o~M6F+p9w({kP|K=~hbXmHmW? z_WL*-bsOs%Z;DbCyOj>bi4_UbOTizOLf_%t?iCx{!ULQ->}qCfXLMx~d% zOM(Pu0+qCF4NpDWVS&bJjj{Ml(P>@e3*PvO8%_9q1pQ)tJ=j^RYN)Rfz76g5my<( z%#8lRKOPkF;E~$j@7Vu8q`hNw-d(%y-PpG6G`4NqMq?X|ZQHiZ#ztd1X>2rUvaj}j z_FnIOuXm5}JbQiY_5YADI_5d&spEH`;mJh%8jHT$NSmhQzxMtrjOM~!!BYEC6>s-x z;u%**#XhIN&pQ|(qY|%k8<;8UdG}lU^`!A4C6O1B3=EJ_JrFmBldparUko?J!x3!} zHBWpi5JSTlQ?s|gvcsS+f&jpUAO0b>6TMgw_&sl81f&N4zSvIezmCUmap_;zV7AJ? zoXA@?nsL==3J_IP7FsCP74(Y2l7Pny0~Pb2ZUR?ZU~t>Fb~lr+8@(m_Bv^a_j?3n? z7*!gu_Njo9f12-Z@^bS1?cssj4;Ote%zy<5%@{gIiZe%mogCRDCutxlz?{0|&{;@S z&vTN}eR|fWs;b+oTaOY;dUy{Qgn3lW*?Q){))vO6*H#s@mDgv{P1eh5&UOI?ZN|-GG50tJ6PoZA zHkEfbV}lxInHkS(Gp;Gc_=~RySYminomHN{uz z_dc~pb3)l?(lOffw%lf_u#ybKh@ZJw$H_FAZ0hIB)Pr!$QmHvriHF1Sf8@t|IPT_N z!)6bDuk#7{(d6L3G)Y>7^_}gPX2=$s2X;D>;$y4q9;3%DgKo`EGy6BED&FyOifjw0 z`-%pV3O>$qW>p#!WXXxTaMjXXwV?zm1mYJ67ZKZ~*}yYwaE8hquz}~`G7HRaSs|ek zR+I*M6;D`>$De5`GM?aU(=$uT6dT}PH4;}uL(W%`u#Tp6Y%h>*OHHnOzZ=ZT(-bNP zmYJ;#_WLMW9nag%1jbPrC*?%ho_12&?jR@RJtk$x(iD|y-B+F@F3aBeYW?7Dc_Inn zSnT`Uut7e-v5GlXBX6(@;`}CXAiTpNVQgM^59;=1A;Y#U(u;Kec57YWo`7%-+~|}( z3}R5ZMj0s>F)}IHyFcmtx{t_+K;C)=VjUurZj=y*hgYgE7>pTeRq%rWKRC{q^e{t8 z)5X`{F=5^jhKzMkpyBjH_Wm8S3qYB2FPo zU;}vkKyChx{q|F_Mk~ol8VznJBh6S$iSjK?uii8GO`Y$rx%}^-3?Y^Xdm86Mo$m7e z0HLtPk0I(MclX>-7ks{*U19vo>uV$gg1c)d1h+)YK3=el0G@uR#LF6sA!xEuGspF{ zm=bhWCuQA9JLS!6>@m&9l8R(jpU8?uB}RGH?~2h%?PY3rmVg1mxuB$SV+w$T(Eyt* zheT>t4ZQzw2%AW!BIRLO`{jkWlR2%?xw@@n75oE#BTD|pN2n`MT!sRQDW2mIAt2^EdPLv#o ze(q%X^VN;3fM5Tt(4$euVbxu^dI6iptWMHbYm|gxFq~_?tX->ytOBiUbFXX#^w$Gv zfDlMGNwmh@cNGt?#T!p)-QMiG*9*lAG$)NtI(#^a6$_z!5}TQy(l?i?x}P=3T>NcN zKG(pPv<|?s?RB}-?AnTJ6-KhBd@1F-UB{@sU6$uHqXw(;N^oidKrEc7v{?yoms?1D zT&MYMF~O!xU*%ay`nw1{mO;$Z^&tN3k;}F3|}L$tr);m|h_j z9myuHHHuC-Pwi*O=_?7SMg=!SjKX7&4Y)w% z6IB$X3T|Xj#taw&uqj@7R(Lpg+IUplS0oMLJE^+DTOrA{Y;d&)&g7%cDao;_0t*rQ z%L6Yg8J*qUP6Y2q=v63oFO$p9pIgs8YU_}#QA6PA`-j_p6tY`QHnq1-dWC`C-z7LQ zzk&1{XD(zn%cQF5>JgdWJY*A+aLO(>y(Q50+cO_RvfNanorW)Mk?9$HVEBJOCu*tI ztTvO&`n|nQR9}td7UK|SWwrM@mEF0PaVJ@IZbR6>A@ERmaA1FC9J5-(sk961Kd z_$`KfSOQF8UMKI{@dmiJh`KjE@K6p*-CD;1T8UNY<%`&G%h2Y%DC1kPckbg8d_kp} zRMY7~-@MrRI0}7#UIsxrvjgT1U_1jg7_0oXzGK4h5Tn}XdbB}Zw8BTc2UxxKeh0a2 zWaWYUG*7BQ*U@2DPVRiy7iPtD^>W9vNB{_#r3hfhWq~7#AelQCaW4|-c*0$9=dA#M zrD*=Ws($G$dbvR|xQ=9wW(<7n0Kl1Pg#(5Q?RV0S$3=+x(H#0itp0Zsj^>Q_jeu!H zGIuYr+a=l_e=LXoh{(X}Q^kfx)Ekr0If?1jcF_hqSawJw^x1Ncsd+ zcim%4;^9}4L~og4S7+`dOcW)I`vA__>L1QoZ?yaCm$}I@vUFp6{xOlA+?tnCl(Ly? zpTAby8-U!%uw#e z;=+BNVKVbG{d}F{^&dlrnEVYlB0xHN1IRhp{vWQ@f2A9$+REP*5Z~cbOOgbNqoleC zEf@C41iSq9;4Ep9l?KtpMj(!wcn#8Y7$mcQ8_JpC-uK^3VSP>7&k@PD6s$+sY|Q-C zv)Q=1>HX{R2E~t&_Q?QI4A&ScK^+Biq?x0J!XAWuKka0Q)RwAkGf+4!VqXqexQ!;+ z%V8t+)<3`kj2XHC8lTBe5WqgUZa{zX*`*m}r1a2((Xmq&%*m%YX0b-@KLSwCs5-VX z`q|wtiWxFmRM9qWqM0n%YU4&wg=hBWo$KT155jy4syi+0G{hP$S$=g85Jz{Nt*)ll zXrg4miqm#W7o+F&2$eU?7c>H|Hq`7xY(S;7FCu2E;10(n#e7z?Mk0>k`UgkUrs^WfD2?RUmNFOm58keVv(QqTm^??}ZV zx@daA>Yp1($885H!@H=G4{RClUEVV)-Gekk7$a)L=N@wBTr?%SH5c8e%dY}dQLi=n zvm%I(u;@hL2OE&#nhv%G28*Q5 zDVSvF`buBM5wfrHst!mzDoe^L%M2ukpt6dd*6p><2j*E^XY~v@NMTGgHZ+;hE6xhg z&*K-E*Quw}(T^O-LT*4>4^%_OKmvUy5eK3_uz^A{SveE1^P3^7e~DNjSF={G!E0H4 z9v5(ErQX$0Mi?Px3UNwLDOJ3ai*5lT{mRUEUmH%ygRZNGfiKK;2f^Sea*g8E6^!L! zfSC}j0>2)^^bzdB*a%_K+4W@CNBPOL@E3sKjw=6L^Pn~9SV~86qqeSfF_r9c0k@1K zN7zaTCkJYn_G+HfYd4I^$_xI*rgS#CDT`sv-hxv(ANQR|-Z02pZsH=8xhU6Wj@8*! zkz|KQ;1-z4B-$7iV{9KeTR$%LO|~24HNd387$5f<;juDsk2!?SRpfO9CSS3YW+ui6=y& zB>o-#?~B%k-p6$FfI3hE5O^a0e$Y7@8ao5zmm(JC7S2xpZJkDO!uGoWDsN)Z@0t)K zN!%l7uZ4 z*;syg-@jA;1o36DE*uBmma9!w7_0T7`EaKukbK~d^2p-Ug8BA2NZfe$P!boqMoFGL zab-f7UOtox4Egc_HkPSeRXxTe#npvHHfS7^?Wg%0+>>#QnD5Au6>}BbR=G7T6BeV2 zxhSTq)^S?kqy($w75$6OkCS|W?QAh}KMPba=aHd|L}4uney%-9H9v&(3v;uLX+jXM+3kU&lNCkv46xQ(w_c+FJ8KI|yBd zengo>vC-jwbE*&2h46wEFACsS?*Awbuv5LhoBgN`=;}8@GSvZv@!R z;;wl7E)J`KoIa3slI+vF{H(*R_vijFHYfp%jq!a1jTZo8BOp1zA$V&MxIKhxGc!n) zYJ!Umx=HYudQ~%;sa_!J%<01yDSvYZzFX}p@ZZl&n>qz{BOw1h1u!!7WmtM1Og z5pr+q#sH+=b)NIt&?4PbGj6E77x_So0`Bs$SR|X@(XMm0E^s% z09-HA^|Y^C*j6R>8LOP58TT}=RuhZmxsvuVRbW@d;XafOhoql?UGy5f+S()`Jk1M7_>zCpK$Z=aH}CZerw}U7uK< z@73hf)%@**aouyFK~EwkY+{HJ*!uGSQTbos$J}!4E(L$Ncmr?zU z<=}8b`T0yd6?2~@?j94-z%{mloTng{nf@6LX7fSm`EM}@iWlNmU= zVYmQac*y=c68_?nbf}Ee%_tStLZLCfKSoT;?8E40dLqO+!LdZPQ-Vq48;Cy!&7^LF zOe*Wfg*dBP)AO1vAqD51okujh^ex)=A-e`AXAOL5xh7#!fuTgw0M8E1ei(NWKWe#7 z@e`3ot&1$H&V-v467vEqf~>vg)GvE>>)gp?8F!(jybxr+m|ETFBw5bn!_Q5_sd?YO zQjXpA!@~A6T=z1bj6~a@+Et8URw*;HD>QP)=pvpIc3k&Yyv?{T(<$ zm(_1_)%mZ8^kL#A-09H-^%98quj9<$z5ykC-AgHg@)f*XrwE!E_SO%L^tU5O;X<%; zpM?UXuv`SpkNFP!l<%_bjl_f75uCkXb}(5^fSiC zhogLotlzsSp72n=T@3@|nPXe$Ub>ewVq1|fKPA$yLfiPHyqSfbeF4~BwWuBxr|bCC zsKR5AratW`x{)rQrjseiMB2WoKdfGypZvKYN3ak`FXxQ6Fuz&7Ljrs_<1lSvgFId) zImsEN&sP9{LZzE=tZwCA!N*kcIxM8iA+pn!r#EBz8UdhMkY{U1vee!4uYbQ97pv{7 zA_0A~9>DNG=zn-M{_iQmAA`b?kJ1HOs)_0XrS`Cn6E$ZHK~YdvCF{RnY~kmJ8mZ^S ztGWPU@9!xB!Z14uf0BcodWC>A1Iy}k*2J6H^kmlE-SV;>U{>6OnRY6MU@P55BAA#bon{7@B7A%D&~S{V+=~zDgjHIt+augCl^E%C znPyOg`j%n40C$GBjFV&KI1qbJ9nE8$?Mll4yX39|KQ;~ZW?FhQh%^wTWo>oh?xJp& z=1I~}NG`0u{y0hz3r5KWpP~AZs_Z?*V6yUv{q-wqif)t6h}#|otZv0hDjgUbUPJHR zbJizvgk`wzf0(`SpY>b^4GtL0IqO<@FGto=>WxR!`e_Gbq4gy!&?GbO@I&snLiZ-gJ@q;NO_ZiROuap+BQwD3sn zXVi7fdxCVMlS1t!6&ioTyEy0?d}f)HQST<d4w7--iD*3OF^5%CLpl(+@fhkP8l z$>1rm4_RI@J%#bXF5&eVy|r~ZUs~EvC#k{oc(2RBVX(wzvSko-=zYNE7VlL`zQbbJ z$D@WwW7>`fV3I^mVCH8R7Ny1oJj?n3zxuy>TN3EnJ@)Yt3Nz=%Pv@?SlhgYMvISqA zYzbeI3~F|nqA-ogIMrSSI-w*BHDE6Q>uLtPC4yUYel{m}I!f=9xN z5}Xa+(YwTo2dZblNI0Iz{_Hd_w>&r$8L_QfBf~i)8txrSoP&N5Y-Klz?__q|h;V6j z@$WV4RtGL*iyda?cgbyEDq?xcknRtnyRdwwIl~p(NtP{nRYU~ssqIN6+X;VzvWEbT zwsf`CV?Bv@Px+rbJUi60&!igT1WeZ1$quG#$(lSX6F!VfpPN~n)U75T`V=lEWL^qz zzVtV@YvP~C%WSk57^fTF$v0!Nm7uDl7sYU7#U&+-e`CAUXp0O9Cm%q$T}gL8f4g6q z!{=^4egpjLDUBQ=@PRlcn7Se?$k0^lHQ9~Sn~SlT8IL(FRH>b(z=1|SkV7Ju88i9_ z2#+*+jYpc&<*Vz!qqtPhTuSa*qeas0jed;3tct;Wtg%7-B^h=(w9n_g4JwlrF5+1v8JO+bH#k+JNcaYwf6(lwa+P>4@hbyKNHh_N<_S!#7$^ISww zwM6RWjg+;Sb#V!nSN1|NU^FP+ctw~>wzRQWC?o^Ml6*$XQ%Ov1ioT*`xYsM%kfd>3 zevuN-oW2-~d zS{0>fWmfU2;hHqbSyedFHr>RcWaW-sGnzYxh{GfW%?!!*A?t6X!swZYW1CKhUAm!? zG&GF+J%`IPrpZ}~3TCT93oG1WZYd2pS`~MfRTegf8)`!|8g=tio|Xfq?<>?^lbB#M zYSszpvKgv2<6DDQ7pfh}Xgo)k9!Y#1;4Yt5_f(Z z^A~juT&H;x5-(k-vPr`My|K_OJrdDtrX81yx@g__g&%LnH7_2e{etxH&G*YU$jfa zzPul+5iH-6exfBf0j9m1fP|x~8+rOgE7Y~O@3Q$JI(!93lzKg)1n(EvQlM@|Pqr6g z)WWZIKUp)GZHYS}#aLgRc>q&{u+1)g4JE|(d&3k&5o`|+A}QJHTSUrwBH2l8DS%Q$Kx`)kaFFeV+exS`j;D;og@c;alAC!M*Am>;@p~<@@?)1i{&npm!mHt{OrR zW9n8ev)=sRfcI?0H)0`H>I17Y5j^8azrlB$S&3kVS{Hoo8Y1GG7N0IN-YP?4i%=1R z`zij?`1O2ZD|p|1bZjd$RFi%hOLUNPd5R;@_UB_5&biRxwE4j_p3qw>kU5w+*tGEPp6aV#BTOdsg1Z#HRS!zU-RB-)ql-pl{U(b2#T96Igs1)*HUXpW(H4 zBKxM$Lt%yw&%9IapFbEON&%0vuC8XUdK{&%u3pUO>-U0C=4XWj0Jwl5s!7oUmOIlJ1GeB03ZYa6FTr8rnaDI3jb07nw&--_7@GZF0B&ZOj10+cZPaWpCb;g? zzpNM8=hQ;Aed)a`u#&ncs|aI}$foIJq$j19FiPtM*GrCWqgj+g!Wcpt5(9IxG#6P4 zd&o>!Y5Yl<>vE?i#$s~RGzPE`{8$7HZ$A<*&c!I9U134B*ja9QbDO$>d2Us4Y&fbZC z#gZ%H?TR~F}D6fbANr`dNbnOhSG27Se# ze99RANW~v$-xlUX!Dftr)s=5!$s_sh-@*T0#+~!x9|!}20|XEpGXL}7_*-gHtB)SX_+2o$ie9 z^Ow?vYud}EcDsoWcjcSO9F}YjC}Dr46_>!cPIOM&vs8OFW&Y%S;q6r%iQ^q6P=#(N zjDhiwg1N)47G3TQVxoJg%t4qZ8{i5T+u$62vz7K8k8wtn;Bofue7o?D&o25LKpM&F zdHE3()H#-;yXg_CA=QyX>V{ub8m*}HzEJKKhv2l0DfDJlVMdI=h+A^thgs~glkA~; z#1T(?JQ}QUI7QAD_c)BmrU!(rF3+Ts49q7%t~>TKY@-=YISDgDo0f%)a5r>6P~kZy z%?>8UsPRP-fbe(gB4g*&W)}^J$W#dyn@jszP`Bf^5mUOKX#Us&2wh0KyGr4<6Zux0+gT0}suT`lWaW|8^DEqG$&l z{hv3vWVI?12%rdK0yyIS2QB>n%T4}Q*P&VkFhvtUeFvD(R4eA`-Oz#Bh@v2&)^Fu0 z2*QM!VtO03Txdo9C`l}mc@gEKVTS*?^L!M=KYn9f;GSy~|;XI|wPpx*@Z}U^~Q^GRU~07U=+|3FpSTVH`FU z?kU*@`?D(P+tljDT~O&RUtr3y>9zwq3y(pV+=N+nQ12WfECzIpcC&k6sy=k3YO8dB z^bGZU#dPW@$pm6LB`RjgI@i)E+`46QRf_se04B|L(*@P;(o(y=lZoQ9*yx192yzA+ zcW)CmVS{FfFsHaDU+OzkYbLQ!y8$eeV2!_jzl`}B^ZjN<74>9z!f~f_ujD0|HSaF7 z#*bejrYTr^ZWFGuOWsoIq}8x~r0coyeE zm9fzWq<;z1Gu)SvYO*7tDMOBO&l=2o^5kpwg&}8%S=TPNtHtY2M#kquv0HfR z?lIkTW^GkvjQDn$mD3uWrCatzaeR2`?z?SeyelUMM>Oh~uSobQ z-u*B#htQg0fm_spLjqOb*RCH$cz#}*}2CHdH?6rey3I-Vt!&+r+5kLcfD&1>+(>9&8j3McY znDWtohOK?@Oue!nIFcJ#v33c@vQ9d!S!Q(4&0PP6`FNhP6Jw{*-D3l*Jv?joYI5RG z$W?c7{H@W|-Jo4g7<7no99*~oFzUOM*>oJN^yk^!`)7vzdLmiSVRW#)9Rrf$8LOXPJJGldj?1RG26H{jB^%P5@`laFCo zYlEs(Zoul;4JvS32n~fr7@6W+_A!etCd|*^3D8bx&ngV#p}Db|*vk(w4J4wF=Y5+k zb5d8SvZUPc4}obLz1~YYH5$FT!l&9VqbL8d4Vm6L8pxvg)(SE3GoAo?^Gw-%A&xaH z%;zFal!;a*>{`Ya(~O(AtWAzE#2;4G%|qKA_GgfJgZk`Bq7n`MP^>?}yNMAt{*|O; zXnmT7ztmTH&V&VLtS<&>CAF-iUm#?@0?}L%$M?xo=AIDxGqaQm?{iPiRz>5*k7#N! zFPI$@BWJ&-Iv(^AN%B}@P#w}EMBa2EC^jNlW-C}DsKylT&G8Qw96R7UE+?5r?Pw#pv6S6(FQwe2daCs9 ztxNk6AF)-Z8FCu`LgI_pEYg_ypQThDLaE-{L}(DFFg-bjoL!ulMKdLoJKO5>&o*b6 zr)AhH$jEoIO1Nt82%LILd4>|1<%kU~do1pXZtjx-KQQOe6&QulVaN_Jb)`1NBaiJy z=@Q!!n`^w;$g*@*W61O;wOYx=o5KNtH?n@$IgWA2^9r#!Y%h%v0`!-EQ{17OYr!un zDK09-iY+T10<_$uYxtoafTJCGOt5C^NewlJVH9kX1$p8x!HT?Om0EW_y9zowwcEYT zoQ$nhzePl;YZP1jNU=dX#yA>ekFO&q33LgmpWu&?guW zqzD?WL{BM;e3+nke=KLdtB;r9M!I8`CX;=0#5+tr80_LS;~+{~+x`OJeJi~gDFy7Bq%0T=xP-N*Pw`T!?;s6Mg zf8U!}?4P&$zXC+{&&1|ku6%O~vCJ>8EG)96ppy_<%~mL1=&$%#wT*Qdb8TJSOnAh2 zsRHPr7<$s53!|Jm6zVZ#b_|)Bk0-siCpnqTzy5j$Xi`~Ph}$AeFv}^&LKS6p6)|HA z74kwD@djXXB+{Y@LrRfzB-0WZ=yy3mF!!_pBB-eHc7O<~2&<^7#H&R)^*SKRMvu-u zbPoelsHY$C{uJ#`q$E_Rvit&3w=!+)W1UdFGf8g7yUmNMB)jaU!nNOAU!0^Kf+bgO z2f0vCmYt$5e^0q~(tZm`xUenP4N3D^qUo5XfnR2g#lRwdSIhBINil5CG5g_N8vg^d z{+)gKy1*7YW%o1lJt>$vgE0nG8$BRwTvU^K3ejW)Gg~WTrW->TLK;>7giV=8hz(LV zF;lEDk~Hj{Nab_WI90V#5>1H`4JB*q2^*8b8pEE(a70k5LzPjq;rJ6toezO^FVxYJ zZfq)=n;m!RjJ2(Gt<>mXeGFX4+!Ls_^|yH}4D;jpy<1X~efMD5koDtSY20PTz0|oQ zvT+3~ux8DWH8pVIuV<`GquG6r<3|;$Gcc2h($e~I$~lG_?O)C%@AQFpO^h&8=tKMJ ziX!V#OUYgtZmFVZ4Gy#fZNH7;#rW<_Lb8(UOxDGYF?hK4-R2l;6bGw>`t_uceJ#PU zoL-6`o|!Yz&g&K3HP*fKl%<3vDZsjmhM!)W<}b5L)D_@9^zlV`1%=V&s$GoDU*4^; z!M_FkUq>LxyYWEk07q0vW_(cu)MB=QmE@FNJr zCHe`q*Pe@dPbxSFv_XN@2Xdd7B@p+HUk^U_X$-X3J^H|aGJq&yAb<29B&wui0gNHQ z*yleZGyctf=Wk@jzd-G&C8+jZ@O#LVLJ^byGT&+YjcErAdQQu$|BrR|za%4FKHPUl ze^2(>4(oz=Zc*)4`#sU<1GY)mw0BAPp5Bv%@z>)lP++O)7^VAzG{Uu$ z;8oGcmp@$ z2(WVcXk5r%^+e7U?KwDU(V=upyG%{*Lo?R~;7}@Ho@DS8gw@HeH;_4za6G^HKv67@ z6xgr)tdG&dzF0qdSsp9(crp-SFSV(HYtlrA>sVf|blph{vPe4@$O3)JocolqCp?iR zIKGZ4*xBLDhR7@&ii#DNVqi4#&z}ayKeld8Ho&fb%yDVe84NV>%bWXmfynIB*eedG zMgZTk-cC^*8&Gu5l=bop8^5AD{YEn~s1w!9ZB{VRXpnYFaYkyS)ajUJI;)M!znATE ztzrXw8JmBj8Syud{)uM1kD+#N0jvc1{YPlVzfQ&9x+7DmtAN1`?nv)GhvpvUG3Dob zzZB#?$-H$$=-?(ePU$|`F9{*`_n7P7O#-{mE^W1*z=()$`al980Q{UkARQ&3@InN% zJs=_gL}&7nZ7bRw*=~iH_ONyOa`N~o-PnBi>o1>Ic)$HRCU>w}SK??PjA=u;fv&b5 z@^2nU=pq`ZhLS-r#I%vu9gs9w_d9TKc9!muc@rk=X0jv2X5mODFa80hwWm#D(pECH z>NKKavf}I&%@KO^r!J-E*AS`|xy{wlYm|bX^VD|{n_vSbPB@Fijj3Pizg?M>XiS-r z0ajo7z4an=%hisoY7En-zif2*fK`gnOf0a8bP$%By|4t3a37L!b;~dQq#Krx>pr; zwxW}ovyb1|L%;7G06<@4nQ#R z*G(Q*c9IV(XXcYFH`pPYn9C-vCZe5kMDcSVl}5gTM68rzRKs-+nssH<@ALAK>wSSs zZEOS15Je(`JEZmOmxdi0O&9{wK{HehVg)$vEQz{{2Sq?G(heJ#G5Sje#OpQ%)OJP} z4tYCdC+qkUE5VK))dv~O91SxObZ~dw3A`AiRyaw-TMKy;xf>+6Cj#8MJ35^khoMt6 z(4cN3z8@DX4~t3GYqh`eFEZ9D=A@q61-G>i+61m`MxldsA?;AhRf_ij7J#a=7A_@+ zZDKXU&ARaS6_UQ}SygA7Ay2)$+sb1~${#IFgNB>^;)wU5R4k_dAdous#uQ`!7^CO& znj34a<}0cT{YVwhbZb4vh$Dz2?k%W>>m~Au+}@95iN$+^z6GkK;48T7$-9i~qO(}Q zgI$&lKJ^WQczLSQM@KO1HQ)UXzhfYPBf3U2H(?RjBju$P@=6(WHblfTSsQ!JulTDj zln0rx^rc$`lCwz2caP}lB^adWnOtWK{khO`8=mUzd)SpC5Bjs~wNmKZl_0@yM0>92 zUwiCdg)XWjZ*s-6au2>2t$GLmpp3pq4v+bk$AZmwK1y%uNXJAxWDdSszdzvp`Cx2$ zEJyX88P*uHk9=&{+=%K$SSJhq zz`XInr^xiyR{-!D`9%Si-Q((23DDbBsJ`5L+!4z0oDN(~&N)!C$ab7R+ zxsUz1@vpux&ogoM+$Hu)UhfSU=8OZiSnpMt(sITh{C_XIuCZ9`7XTCOa^(L6*7)Z# z{40aZ*069xQN{EvS&&&Pp(*q8^Al8#4{At87Loo!v{sTr*ignHN%zBmN!g5?Y{+N( z$!Ghp(J=<%*UnAm@pBxo-Z2}R`pvyP z^E%nKD`NSZdpC~V&J@GeY5%&r_)w?rNxv8Mmimo90CnPB^a+~SV!%MHqG*+^QPsOj zAba69#^N*ei8K0fdcc%&iK@((J1yTBvWi2c7>khX(fP8fY{KxOfOldia;d6GSo4hr zmc5wakeQZ)ABQhW1sT#R7XhDDNJ}QW)Dq4~%}YYnhjAMoCajOV3rQ-C1}q$BZC&lZ zT8qBJ#`1 z!N)d_Csd`55ot0kT^{#_@T7yFJ`YzYAKM5ka<6kw2xR~76N@*fWWeT2#v*S;^HBkG z?8SRt;yXbdbI$GUs2hCaCYI9+cawIjePdZ=)2a7emzPaNUsm&CSd<|)LD}8s&Dq=8 z&^e}}Pd$DP15)5)`(cN)|tFCRr|2;$+fFhi(jE(VInY5|Lz% z2(L2!Ar>DrpsH^qjgwhAUMv$4X}{T#{c!L@{3ontUH46NeKELu+HM7X1M4F{dYiZU zP~DmJtW219k+F8a7?wz~6AF0vN>K!vS+SSpV&cXIAErD9tr5~Zk+!dOgswQhn`pIX zf%e+4QX+h$LXdk9Pv%l|x_6J!D)f@)A*I!{&R(6K3=TXEQ=~prMRdVMjByU@_tCn7 zqZ62_;VTq}MXInBxB-{?r4)eI?;0hJoqk<$$&g)hSlbo{f>@>Jz_1NRVrSoN41trZ z^|7OG08_g2=kpABBv+f2I^N=4tx?wY_$8v&W*rO{S;=REo+6wMr!ZS*szw3s_ODXx z8YN28jAub9G;=a;OH~>kY~_*u9R2$n1CV?J$IvZ_7!J#kZO5WnUP!e^dp#Hq{gFE` z-sO9hkUhifA}-4k{haFkocjLVU%0DqTjgctO_fK;OGZ?^ar)h!bGA9#E9SadV)=GTKx#xnC5G#C2U4jKw**wWdUUTvg1>>TFXZFz{_I;wr`aThzp@VT8VZPwGm& znW0jqVTjBHmJYi_o?~zN@iOohI8E2X-(W-{o1qrCw5owqT>aMb-s1=t$392sxJPE1 zSq$bX!wlV3IIMM4(Or|InZpkEq{`NC9uRtBKRb+$ zbS3WcK6*F~sBO|&rhR4K)C#dZjcp<(TAS>x-3T7CF>vVN&+HYtYr3&*|F*%PzU&14 z09|A^m<^KUC!^dx#j)*J#&8HwaL{-yR>J6Kt0&kXoT&y>?p-mn>c zxVOMC2Ea4YFT_Wnr)`AS4pjO=nt4FVJ6%b=kkWZ@;s&DQ^g9WC)aYP(DYx=FlK%35 z(f*9RN6-yze!%ewcQE`l|N7V9TlSx!Ts4M^KPnY!2t}BC^PNsYtRUgadr3C@duLtH zHhcX(+~)4??ZOZ-iP7j0U3Wxb5o<=M@8^aOL%^XzDchfRQ8oxpemU}$HHw6`#@OPV`_a=4A{Gg-Ka{gp@pI(EJ<-|gq|6I zWU}Ei@Q_S(haYXxPw^JEtAlRYO?9{D=wx8RPUBDo)6s+_8G5Ka+1Qf`Y02*E09d8@ z^L+AOWX?oM3(v`fo4Z{EaG3Q{kEw$3vvn8VB`Q%!9yV&sCyO`HXQ--3cney z-|~t#0qEl5BtUUxksK!^{hgepw~a$GT$$Y;SaSkLTreeyv~?PfdD4E0tbMiButjo{i+{r3k#V3XX)Wtrm3o0#cO=ZXJ`PM z`yXYV#g=6c1zK)W@LOdHE{iRei)7N3s%bx_ktOJ~$UtEaofE5ff=T(S8E-b zF*dAWE>|3ULEJ5VP_VSitVhz6*KvMy65G{++VGA)QaTE7XxS**OYe5Vt`W&K!- zPh8byjw+tmo$5J@To+=G%fu*hQk^SN+J_BHr!1$2ewa5Qc!)11Kr`$nYgK?+Y*SV$29iebo4-{yV z#66_mj4)?tHBg^&)jZxT!+!@@f@lMnq$^5m)qEG>znP?eoJ{YQm3U3rzW*}c5S0KIC)r6%koppA~RK4sQfplqbj@j0E3Incn-Pzs}z8+0(aWhtiTUo zc{M|!shOW)wHgYlr1{??za7t6~*f`=(`cPNKTfTUB9a9rYYo zRuG8=Oo|F1tl&f;v4WodhL2#1|L8I6!LhT;jSq`YO_c`03`5FOK?=!R89Fwk^TPu7et@%xHih!7- z*0h(8&BB3nPUNENYXBf9QA9nPpVn2GsSpQmd#Gy=TgJQGoE-; z&nKu9^)UdC`)(3tai@38r?wH*akN_Eu3ET4B^5^? zhN)ID6OQj*O89fd_>-Cd#`Ld(B7|gOJMFJfiV++jkWf$dW2}~(3`9A zY&4>Gxxp7+cm18Lc<#u2X#kUy+ASxJyO(sZRxFERx1sL^1fUM~WZyd%KAcuRnEoa7 zrZxCNT?Twi_4{}FKfix>JO(1-BXD>}G}GGZwE}qDHy|=T#y31&k+fgsA@-o${KC|K zG~34c?Qw4iK$4Do^Y=d}?qwo>b0g_tuQz;7Zv$)XHo@h^$OGFla;5?pUx~^Cswy6D zY|?h5=Te+^dWw9`0bhVRIO>guj*-ueC{CXJ08EF(B!`blUU~}U&0M)oxZM3PYHMtp z=$94B3M|yq9&+>P=Er2DrbhqSr!5?zG1LF14rX{KG4unp=)V98E6#s=CFgIK;lGM2 z6+nAl5cR!e;Zi9@yIT=VMAw<7Bhpck*0L!g4K<32@mb`NshrHq!nIYyH+}}-Z4a@Z z8O}fMZl+#gKqQfP!O842?bhRz{&I6Sq5kQ+`$8m;%xGH{g$G$|rGlxXm#w!*ko7cpPrVG~GJ$qm_WxzISl~?) zFqC`!>Njr{!uQ=l?WJ>@^0wfD?M>`0E?*pFWL0WMfh}+`WJX;(XJ~-+yQ2k#K8#lW zR4TTSqQpinxa-8eZ;1GL&G-Pl;goZ2qX+F@@tZ(`kiJ=-(ZqA_sUs0tX!WRDq)27gJ{EoI1?Z@W2eC* zU`4F)$NWHQkHuG7q!2R1MEYDywqK7L^s1n55$flEm8yqHG_r7Zt$SW52!ds}t-V&od;2z5ne0#Pt@C_nN-7f0g3E*nagh`R! zPX-%L8^w+92{hj}rtlR%Kv+u5T#ETdhMXZ??=Vp+= zal<|DGX(gaf(~4O4XTr!q+`knYSCQm(CI*QwwW8p=F3WXDHnIQ&*vzv(Ewki&Tn<$ zr5=F>-YH4tOFPChRnbfJK+B1w#oHfao7Vj=&dxHb%69MeA_@YFlxK)Oqij&tMl?EUWTIcJQ$Up_DfANY3N*Y%G%=PyL&mOp2;j4Cd& zrVune^T2XAAf}g92w+bSyrX-yzi>Q%Y{(H$Uj6adBKaDC*~2C8mc>>=*IqrxSFMtX zd)qG3?)3P2?sgeVb;Vcg@Ea_>9~rq~mvUH>lt<~Xt#Q-=<|e(dR-Z(w-S|AYP`OeM zMGb~-R?p%lLh<`_SDlAH66#;3vO;o!0k2#{YXS5hUxt3<=rd)7r&xDVi6kL=I{&Fw#MqQ zLX%Ju@`P9<%%`rLrKc{X4j2SHKES@Ssk%KOTs{^@oA-xwm4G>%?%xC|*-kuVC`ub1H&LmZkOk*P16 z{pmfz(BhhFyfYO2MPuYtatbuy)hcBNTT{@ZaY^fSWQ%>xnzX^HJm;R@rv6KA(Ya8k zpEIK#LBeauQ7(>rIBy;*cJ-$;4NglbcwIR+Sk8TRj_bU}DCyj7jHO(ePUK$oumZ0R z%NtP++}@-89`>5UcTh3W^ysVN65LcuL%V6R7hUKEnM$MsFVf@*PFEM%IgFpuE!B#{K9dU#X30$FeN8jgZSI(MzSpp z0Ct*n$ZsT7u8HZfH3Z&wZeej7R3bzaHcl{TyvzV#r(DBquo#rxbd{@T=!Bh8Br$zTQUlqJ+CG{l%X!bJjwN=U~UHn}mGcBT}uJ`Y1l2$(> z$={i|SY$T<0Q>0#sa7H&E(Q^Zi}BOB$OGbHP97DNx4Xz;m|vZ81?n%ffrV`Z{DwXa zF%jHh99WRgIqd9pW=lOtnLPpQbLf~48*$-umVhMsWo!NgT2w2J4=(5`!g~B4EOr-U z`5-Q;`(1Y=n8o3WIN4P{&b#=Rz;LFks>?KE{_s?1^<6*j6IKc+>A9yoo|1 z2q)|Q!e8rfku12f+t;8wX}mGSTCY=9&{Y)(qBjTN^1li8W$rV1SM@1pbe?K!8Bgre z=HHz9nBvUr_%$w*(ex(ZAKX%HptfYIEe)Etyq?0`A^@YwGytLCM!e|FbU*Xrw zpTQFrYn;oc32^6fzwz}7!+dXsvLe0XwIFZ_a={O~Esv?>(dKh8{e>}c**#0Kd{~2p z`#=W02I|>)j+eGo7D`7-CxJ|1siAAkW8gWEz-%BH)LQ+{?D3)1U-uiD-tErvGik=P zyFaGrHuw{8g+Req3KV?o|MlhfSFM-yk6O>LF>zDfK^00EYbpE)Qy4u0tB9ELB{T($ zAIYM7(eGL>@9v-8*?`2;VMYd8J81a^3&xer;o;QlU$;QsycPZBC!$7^rq_iXpO z*ad4%A-61+U&iB-nU_B3^T#ri8L4-Q!nuG9V+|HLJ!%V9y&wrEp~BiM;qB`{YVs}Y zlSs)0Qe&?gwFX-;%TW6jadGPGdu=3xh$;4Gvm=L}dSE4vq(!!isFr7Y4Mt8ep1LcV zg_KbF-q1V>{pu}?$@9qpwq)bgX@{BEVef-K zYgN-duq_0YseG2l?pL#I*RO?#EV05Z;+(0Sgw785r2A4V#``r9 zqUyob>eVF$>P(hyl^ZX0ia3f`vxv!zgnLzDPgS|)artt36;!(TPJHdHmM^p!v-R}! zbrMf>dlBeaLCL{sLmn2BY^`f|`q@EV_37&7 zLyOOm%gm|z<$^cypY?a|6IyT>*Wurs(t_er5hvS4=OVN*$fUZdmKEAvGF zX|#K6b8kW9q>?+{0N4ms3HLhis5_WU?DeEZH|f>;EYWTuVg8K99U&Q1sn{S9mOyC` z;pHujk`cQY%lnN#6c)Yja@iJvk}w=73IFp~U)s*m!P)iy8V)KS+W<-90+okp<>v1D zt`CH6<`tR7l%YgruO@l06R&bie)N4jFCURwreg~0eH?sC3xBgDB-6%J-cTA?^OD6o>PPQ24Gtb-6B=gtl4`wkC%St77udTc}CU z!1Y?Ivk$4S`tNQ;T0t|#lY}u=<9la{;9Uf;bE%(*4_DDpZICkZwuT%3Rd`nh~JH_={%r?4L9vGw4BW?HQ_>xQ21}{K!I{fqFOT z1H)FGUOMvF3u819Dd6W7pvEB2gJSCa@Ioq->rN?jWnSNe%fl{>GF0ZChiAplKfAT| zm@(k-Y{=o6Lf76`@wV^L+^m@?UB1r|)^2KERfbkkcgDXOBGpAR5)aZ4*F1c~r7!!# z`FSOqYueocFgI*TT?cjTzK=AkwDFc6vvVxhr8jN1=S@?h$Eb5wr{nVqu}62aYtXE* z^%xwq!)V@(X6~jc=SOW}1rKaDhHKd~?ax0?Dl5qEpEfqi*}zTSjr^Wj%Vn~8-WhI> zN2(UfWOS_wUiYCew`ACD5RGCiU`xMI)1%wjYH8S505|J*s8gv49$%r8Xo;Keq%dwb zImCU%1Et5`$>TMo5~mtju}Qq2MGmjTG457T(tYm0T6Wk!aXy*?nPy}#--E3#Kg@y{ zskJy2=2aRPT?^9R&t_2~$7SmC_6I zAD@+m?jGWQnU-?UE2Fj3uAJHAQ*(WX_tU*0v1h;dkWKHo!^9{{k1XfdF5?&*WUkU_ zs`uzsCYkzqVBDp{gZwQ1&Y?Hy)8U%kbehhecpQCXXm zX1wVF&@(f%i{EnG+K{mB{QO89RB~L5h0%sXj8Qm~Yb{!A=Nv5|`+ogt#eXO>M6g;&9&W}J@U)mL%L^T>>OAw8 zgx=r3!@k8~V7P)l)lrp*VDI5DOqsmIUPEXdc2?=lK%G+%is2jBIJ68@xv zl{%HytRXmAw_f3-xl0H=?&3zhYEUXS@$CL^Q5v;5{+6s)klh-;SE$5YLFzPHJcFnU zP*~If{LFiPU>rC-3T?gJns>!SI{JZ|#>rpgNs@u_TarOFJ$k5oH;cNhGEP2P_yj@X z`U`@j%;zC>x+0O0-I-c)d0e)j8GXkHqzeKF%_-{@1)4kc?n@kgolU;7izG4tVss;w zbnH?mNb8%Re03Ol%wvu1PbqQQ_EGLr-(Lt#4q$+2_Ev&ofLs4nJP7uoIQ((R>0tQ8 zM@q0h;*NXtw=6>~4v=MlQVSbKRAkOlu9nab6mj)l=DMA5Dz6+rd&EGq??Kl;KQcI3 zqc`7K5WZ}Ya>fmLeEIL&6e{}k$EUoCZ@?}2pBrBPxFP@g^WQt`a+MW_DQ1+1Hh}sD zjkk2gg3a9U+$!#s6u;67v|#BZ+KVcyHAJ4`X)~DvYIn&C11P3D&o}&Mk|c~)`IvR^ zb;h!S*~jh2quXaO*#;d@o}srKW$W4)m=&|t@9{Y8rwvV}dhPIZKyEb4zw$VBfyLQm z#Oownm_n+2saDikZA1^C+-$1m608X zxy9U_jxX)dlp=TwM|8lBU|et5Na~GG2&_at6{r$(po%9ahr3>YLk7C~^%hRW!_obZ zP$Cz+MWnQ*^&gB!^Ns`=qC*nt0A~pX30Ko>=OILvxopGB8-N=+%nG4FaZL4QJn!h| z0@;WfwaDPcrQRoqonsJ%CVtDDa`6$zRT*n*23eiyJMX>C8VN8m{ZYuZ37Vcyln;t?0Ln!>E} zWv~%GRz3Xj=4QfwoxcP+lp8=bF8sfJbN@O~|4@$qCTRFG{%DE%Hiz<3>;*k9e#5&^ zQYrio1FnXymg7u$i;S9+AM+VZ??{E{!i0seJD!B&g@uXG0I1X|e*$*9qEY&*-(%ILD#HcRp8X;F3KSKGQ+ z$WJuO6W26l;L;sX`-GR#^fu_a(ofG(s!Eola>`W^?;+|9Vc%97Yz`Et)JGsnlowZf zY>eA0UgRm<;`yw5+jd9gJ*_IpV5*Vd3KmEARLonBJQk^oCnt7hMq~A|f569Qf z|7QNMS*RFs>?6mtV&+TUhad@Jr@w!DE!YIQAVg*P_iuaWPPz0)nZM% zuk8t6FWfeCxeY99GN9Me4VB_Ry*1Gk&QjJ8U=*yc@8PIu&7}OH1sYQ_#O7~ZHJ19U z^R*ON{L=Offv0H57sZYMz<3s19jOIIsF;p?Yd;*V2UR)HwFr2-Om_eLA%Wdlt?LvhECeytz@Qr{&`NXbJd zkeXEtUX0_!Z><;fE8tgP9nKm!@epT2A5{_pu_b#_!m}iX=G0+_8&V^x@EB6}ITSa# zddiP%ON1$iy#cfQikWuanT1%B%=Qwy$n}iNSC;e8dr1V}f}r;dz!PYx$eFRp;w*+c zSmG-7>T~hiL^ z4=2H(SWqx4zVfcf%Q_oCaA2HIz1e|D|5=hk7DfV^8b!s$Lj7+3 zj(CKsyB6yru3siQE^-x5*+(ki-A?7~6M|!hteYA@aO8$;5c3x4d2k}{QKaUt-%9Dr z<@x^+e00?!sqxh3#{zx+e{MRGwl}eLGd26O(a%@@D?Te7$XwN(1S=0}V1y&U5$hrq zg%C5+B+-g*#g?G;)z`}ZmI1+B8vJ_kioEFzu#YOph`bSbuCwqf-Rsu;BC5mh@%-gi z!UYb<*W}=IO#5lYUb|XIb(P&Jp(quAFy@v)CU`;^b9?n#Y-^jgY7&{1!d3??#%t*+Z`6lgx%d0dPZMUZkLk?XKhU>!uiKvuf%= z6d|dCb^HI@=(B+{|L;aWve)5X8~slCtTbp$cUwpwt>~FU5_W?H`df@VXeVA009}j- z+sX-$Wr8ug1h4lM?%bH}-J&||k6MN9-LUTSbv}F(j91?I43@&4F;6nMwIKaOGK+O% zR;7@1;b|*zMw)1J6Q2XI&K^HN-1|wN^F86(h#;oU+v4ECOuv@8>nxzBo-Pii@6?+b`$IX_88GA93Y4&lK%+1EpI?uE zoSOe%r_TX!i~pt52Q|3qXk|-S0<^NEXhhDw=7J-9zBz@DaO5bjC&~5SbtC8#lRv!p zfr!k6QhA+=;sHR52lUc80cdf6!l*~~%J$Jg>(I*M-6_?(DPTo}gy|h8RzWmdRb&`u zu(G)-K$z^MxoVUYvd>?3dLoFt53Gm~UlLI_Nsl{B_-GCNVwWv^vCU?}vq)2-tu@6} ztj&<>Riag4oj6#aJpy?Cf7IYn$d72ZXwi&o=~N~bZOWsOTO2$W1#N&L7}aIG_R6fi z5|SYOuTu9ZT#65H8a5RO`F9;hXEb&rH`8*S^snm$GOMM$Lq2Y~;J+|-o zlv7q9GF-TuH17&Qg!kUBO~9|}Ib>iXF~&K}L_ z-Bos)Ej7U&sUr^Nwow8L%aqyXX8KbCi_LFi2emQX%;iShXj)m^s=g5-dfh2j8*AWa zj^670OmO?9aLOU_?GXLwjVuYWo-j!;NmYvlaw1P~*W8bsen1WegRH|3+5EPVlh}z~ zhF-uT>R6mFSVPg_E~7o@ptNMt$3M`0m{IjAYi@o!nG^_dd27l1F^*G`VxZs}mUBmZ zZ)7f6vUGXxo^@p2_mrYvN@0f1-@%6C`uR?^LrtwsxnL>J0x0gy>yB5b-@j$~>I1u? zf;CPbZ#x_H)>LS7N!BB8G+UeAL%)oPg|w^nEnsCda{c2IY^uA^@CX6hLfWtNh64>d zwVTt&9P+UcIFKRAox_VSwsd$fI{WjDpq9JIZ!2&7g#+)RD;V#BH{O;-GECB6RM9yO zIdGsgw0zZ$(=I)=EEUU}w!=4O!T8>z;+dxBGcR!oD(&G(kOHeT>bud0Y#&9bZ@lo_3;HigRivqrb$ ze+DE%=Z!4K<Q}t)&Z2)KfNecL0EZP?ne<_?YzPuHHtWBgKY7$j{xhws*IF-TYrn zvXaxNu8<2ILzL%}*joAm#Ba8FPmobp?T6P&0v_#z%vr`N{0^3%C1iB1{wbzVX?KWv z!WNGL_oM9p`fmLDh5fV1*8`e-bOHUTw1)Rltb#Bf5UFD^!@fc@fnq-~t18(^rBmu> ze&1uIa8GI)zo+{V90S|UCIs)4DQ?Z7^j;l*V0ISZ8pdSqXLq#w!8#Io*l2#+q{Y`Q zHo?%~nX&$%x!pAC^dYBW#u_hi`Smn-i{k7Cg6 zBoUPpaq!?BHBRpX_er0YQ0^PjyTH|8B*`$<0<9}NkbWA_*NwW6UIL`C9-2Dt1<>0qwAIh= zT|i8aL(KJtj@OX$RRa_;synv<;aW0fnYgS zyN@_O&F{yh1}PGCE?Vp-}COQ#&5?t^i5(_ zz11`{P@-Lh%|Nc}b4=TU*ZScW&8zZ>5H(z0@zCmfC%QF41beGw^LggT`giV^F>hyj z2M@=n1NdS5*hWz4!kvdH$JZ6DSEh*kaHe_v2kFOE`gv|G(2H;Y9sd9R zvHkl%{oRzP>OINN1XN@i86tw8!-u|VvP4~anPj*rD*OJ8GP^eWl~}`~G{bz1xrgk6 z!Nxzr6Jl7GcSY0|NWW1o^0{m;yBrN?@Co_*U&9+B;jzfAs-w$f9Jt~)I#GqI;Pcnno#zpW&Q^-a#BhyxqpOllKk}H-65S zM`cC^so}gmjWqg%|BfLq!ph!R7E&G*8OdRa(>vB-j3W(_(nNNjM5A{9JPohyLZuy& z$$Wm_UWpY9ZGQz?=pklnIJ{~ZivZz0ss&A=U#)FAZsB~5Ka+mC~0_%N-{uZd3h7e_r$|m|EYNi?5cgBXcoziAbo!_a$?%2>eo0R(BM; zG({8~L~czTS8F4_X(>z^66eSjtng1lrpdDpZF^q))V$upVt7crk?Js`cQl;{t@o^p?5oIykXN$?NUz1L{LF*F()k;JpsNrt-|2@B@tnZA z$cjHa{ncV~VkpXmUz0cFFTi|V!;tvi#HMKRCYsR%rWVAOn2&2#OlV#lPCpIKX{b?+ zK{Xv-%?a|tiFp$sh~tH7O($YkuefTjxn6;5Uy(G}leBFki-u`RALvhFBB^*kQf78t zK%Egp#hPUtW^{0HGXT8IN*9mqeV{MKuFK7pb|DL{nO)b-XGtz;MyI}U zu=jpPSL(AH@=mtspQ%yBdGe?OKeL1K#g!Cn)eLqo^*P3fruk4&aVTpf&4=p0UeI3a zroYQFp#znn@O6627LB@f z07>O8iilwOT}XRvmxk*YTA^e6p?>Bl?T!8PWf9Evi(EdX0-dUeWs-?&*X-VP&_@<2 zXd^uPK{^phG%{?8F_x$H+>=r$&`x=s-tY(tqFZ2}7-`b@3PMVdmk6jcWip70 znBN8sW2<`?-ZA{;&xv)#PQKY@#S44VXTq^{N%$bmkGYbEWFB_-R=7>SVP^M^L-)^m zAwqOYTp(3jC_+f&LVy#1TZVoM+Q+i;O(H1KMbbyl!M2EtC-?wi!w)$Bs(4(g8?wgC z8Z_iGCBSKjhm2p=Wn_6@3g7hw=SiRWCPVJclRlF~7Zz`>4oKte+FAvBm3brOnLEl#kxBfkpF+zx0Ne8-t`g-zi4}=2pxqn~MGOFZy_;i;SFwWx)bF zoXVlIMCF*RkFM;Kd&B*Ai&?evByKIrfLC z4-}An3AA~AdK2-klBQ*>RTb13F-552*5 z&S1RMxH1)*9f^5nk7j)a3>Qe1-V$w6gf~Z_#!{OsmkiiHhG>*`%Rg*!`Gu%+?|{l# zdzsl;(!FxD24|#hoD3(M^0IqzllBFDpF35WEO&~VTyB$@Dt#Q4TmcVM!s=RW4XbN% zRJd#uChNSwdRPt?V(X_$AB-VJ_TBHY9LFtCBG`motmngO@`Tiup52PE_Ex7}`_mdQ`RnLfHJHXR~c4`G>o2 z_1mwz`+i-obViqWBK}g@nmnO6gspAUT`gEWmasu@_0Ac~|80S_F5W7aC>ZvqP`j!(?+Du%=ty zHTv#UEodTTM*iJ+H!Nr+tR44etbA)l+l~Zw>zPr%WtX7~*Dq=ONw)aIhtRe!zXL0D zCtuTZ9*D%2!<}$FS!$v$xBtK-xi!aXXaqrccC-WUzw_{7TsMashaP#|f6`dfaG zd_6`TisfV$kehY8#rJXaujOZFF8&QmR?js5yp5M`NPLeNA(tZ?LOm7*B%V1{lZu|XvSi82RsX;isd4wI01vUtd+1leehTD7?f2hOj=Ilz;XVYIk^=O-7d*O1Yo z5kts&UbM!ncVRbZ_(}Ql>L%Ler(qW}!NP#XedgCSI=5B0`>B#^}K!m0~=2S715p|K;=^Qv6qi#J0h;FIsQ0dqV zV97~zB2tZc@Mz<(cssV(PJv4dB+Wr9DwyTb9WsemayP<6=*Hp( zhu0P4{i6=|rCVi#>fUqgD~kwRaTTIgjFl>{uZpUV(3Fxdh$>GAXOVHEorjF}BMQwX2#ToTCQVG@apl__YJ&3d4TYE~QZennVA1b2GM>GE;o*;N zJj0TQP9CJ5HlONuYrZw|7t2JvFw9NY-KnQ%nsTqne8dflORo+ms~c{N)gV1?jEbKS zp+hP`$}#DhHIv*Q^;(>Bc!y;3fzAo-RF1jqBIb$(8LdJ>cnr-ICmDu{mMB8E7c?4~ zWK`+`&(j~JntL>AAjswIE!8&US1iUYPiA!Cm8e)SJx`D zy9CS>t|{kStTs#P!O%w}z|0QoZEajl#gL;Rf6@P34{}ij7n5^e2@h)AidFphX?x8P zhE)O&+2e=LT&Et^A_!_1f7lhte-B?X^8+co|1Q4j(iJ;JQS(O`I2GrJNFy`-Q#V)g zwG30fDXI@XMe_YBxFcS)NyFJJ-}(4p>nQMkU46Gd{kFS#5EJEZvw3ePbVlFR^=M6K z$L(kY`&90=!>OL~cowbli<4aAUeA01%DtOxrGPW2sN3V}lcd-;&$=M(_-lC>eE#_cNa=ji+%wkV-!x0+aoc%``DdO?JBCeP`q0pF6 zj^A)Qd+%Gdm2`41Tx$ATSWOYV}%^Gakdm-d4QI5U3xqlvS-8qYXobO&6JHYoS)? zW?jbeMX59yr(SodY`WAtw~PxCKIHJd$UoRFsd$JH#Wcb_nCp-(6*GOQC@Hm8YDi7r zxt!RHVYbA@ZLE&rQe=MsMz%q?RQ5ZIcrk3aB=1t5canDL zP2hIQj5VI%m$sQ8Ja#O1d8xpxV(_=XbKGT0X7aEpqM}pg2&?@m^Q3y={)!Z1$1~|@ zu*WO=gLf-@ei2?bzpj<>Uer_{`eUJmtuRO%`10bW;gq(op2C^e&A?Eb{M`1Ef+y3A zvykrKd#&`@OM-6L%7PL<@F5fX`9hF_K>$hr1WLWzED^ciwKWZPMFU@=lUGdip**GI zWt`BxKGuie%L^;f$~g|d*B<%@I6D3+Xge%JNyUKX7ZugJ2AYjeXVyRu=5jJLH zWEv*axtx}wZj1IOaOwdw72!A={kR2; z#{+pWk^>SIr3isK;ib|ZOzaXa3$3EQ) z!%4HLtEVQ3#>NeASzjRA9t*itPgZ}SqE9K+Oz#ReO<05e_Mvo`ZXvl3cX>@cGs(8v z5)B=lYWiizME91E`D7j6i-nAy;@J zTq`Xw-)6lZ%HJV%)IDm%X2+3q*H|CA|skY=v5Hf)}5N)LcxBe`RJ$gM` zmCr``?iOyl@T9K0`ICFHsE`!*lfwom^#o}ia)ZvOqh&LI)T*Hz542GzRlpj02w~_6 zh<6l(11vc*Px8t%N2E{IK-uRKgZ`-1d99UU@BNsif;SXrKpqJVBwO+2UK}QMcF0`` z#?;EUZ+~xh-q3(sc~<<>?|o$q{7MG;gInh%zXNsvCF7d7Q0f~4_=%@7x3zPrtF0-%{#e&eazT&*MM0tg*`}4g;j_gpuY50wJ41L6>P&-| zxi05e8vzSY4m8!3+9nZfjfPoj~Sic{*3x7=g@)o1D-~CxM$DU{@dsA z@4274oy%)AbboueX0Q2n6eVHQ9LARF8oHU!_2b&g)^t|11tL&M&C(SdO-z|ffSpU! z{|VC!-Nj{or4+rryhKh-^LlaEHcP-`%xiSsWsJus`~H5`tkR3Syd`iQs7Xd9BVhRPq(m=RiKR=)>r#cX3FmN&{N5Q zfWeejI3kj&)Xre$q74jc6zj@Q5)qg~NIwshVYctL7ZsaS7sj6J)&OA*q-T28`YhWf z3AO_J{oPs>S!k|P4#}mjnC(U>(phLd_d#p^*`#|C)#nG6KDpYJWqK=`TTNy^I2&jN zv(akiubX)|aJi4Ln<9Kb76yVOptisS>3*^UPh3`vJL2v1DA@0xL8F%FL+wP}q{-!R z49bOD6yWAZi@0dnXoq5lXznELc9Rq#R}@6gPUH^Y4N^N^Zl;~+lqhY7Z0#9V$ox2j5j-SnZu4zg z$Po|{`(kPp)cNW7kz21&&1X{Dm{v3asqkH-wvXs~da*BzL!qa_x|f`dFRXbu7JGZT zU;uJ*FYEFw_XlKl{h;!R9G8er*{e|gZRUs=ns}a;N<+{d*BRfOid=Fp;p$vwh+zk* zEL{Mx3h%?Kd9=sZ%`E)F4Dl zc%B03eL8br=WQSUm|>~=&^bbYV)wr@8v!+qvzhsygU(E4U`P4}B|}!Z6_LhDg?dE| zaG}F@ii_~01O+M6l8{~k(XNDJqZCeNE8-Tgkbs^iA9^NH@SMwYX=pTMyWP=RzO<#x zUw{m{9coUpHqxfaejOZ@ZienOgx_dqJKr>PLjRWr314vSn@o6`Y;-|&4XX?--jr)#I1aO#bqSX`pIbZO;Z>|6BHu}EzKzc>BAu)khJj4VQW7LUXKh2yy+!k!Z)~;G|E-_D)APiJ> zan0AOV4z-Vqv({t@;-Hc&h^?eBxiBWW1FFGngJLC6ojz4^HlCqEX}QH=WF&mFFCW< zYSLOJm8m;9BP~(yEx5I7Y^Ad`RI6+x^Yx-+H@JxH45VNhEYO&HdC8Aq7MYSUh})wh z3{lM1F<6wXX58Z}jw9@Q&!ZOy`ob;tv1WWRFa}@5>$?|Ci15~yAMa@kH~w5G(cvuj zUDsYxy)Ic-2{J`Y&9P}Pc3dHSuLD|)zhl5_XeLgzvT-qg&xI83koK3)=$O@(uz%v` zs3v6EzRVOCwmS1Z3u2QtF$wxn4WJ=>W2 zebZ!EIW^~!ILfG$Qgn#dW$LXOY7~1P9*>;~%X-YJQ!AEBQNZ?5_PfZn7DJU2FR%PpEJ3pM(izkNpOfX_&+d%u`~Meq4B;4|uyHM8Gg z9AoiyQU%f_mS}h-%l2Qg6}HxSh}W`0tVa7w_St-Yu7G-s;0e|X%vxTvf7#7(^R8H8 zU>OSIS#mu5Nhs>PT;u80@`(?r5brf&)Gxz#uR}uBdP9tU#D?bW z?3-NkROA*OoWfy@18j7VlA<92toL4^dY*DAP6|P0{*3LTI=kk!wTiLPzopKs=!H@05qs7xVsxDQ8q#qaq;6#dgv%HnQr2~fbJ%JKVj#9lbuNn#*WPuwF zj`btdXft{FJ7K@V!h)^4vWYX?yFD?_N~4vEHTJ6h`4>hT($sE;`M6}v&N@TVnY zpqyIf0C-OSJCo5L7vo=l{;5B*vjM0Z{smq<2^kFqzw))~XNo?)$_mVmq{e1Q1gl%p z_|y4(=nJmdfRg;m`t zKZw6Vy$WoDX`g6hwA3k&fEN@Vf83yI9Q2bSr->n?+E=uyF)`kW4qck`bthZl@{H3g zhQKP3vto3mV zN}7wQVQ#pY$i9$nU{&JQE?C5EN$*(m23*CN`*myz(I}rzUY3pw);wS?!H$8Km6Dsy z+n!0*WG$8RqmkW=tis)V?FCch3nyn4K!a3ar4mv`oiUg@m57I|v~ipsjW2U|gK=VE zHew_|Ae${rRQ<*vc4(FF=kaxv9r|7 zR`cQY8acb*UMh6KJ1BpSmyCulvDj|&ZNEga4$&U}Y>HN{?oQ!nH2j72@8ih9eDG`? zFkMIcuUtm|&m;8@1=8OESc&#Jm7m-jPLhii)EykW)!B?EKz)ux)g{M$A!R|YxPUId4<39Rfk6z3@*@V?&igjcn z6NoE{#SX`YMkwXkkK)y1!?qDPtQ{s}P5#urbKF!e0eC zvfl?w^PRT2{J^}@)}p@&Tqx%bhK^Wlrwxohk?O_IVm9qB$8A!33n?)xH7-#TE%z3$ z)aUv|AA&}2HoRU82#H?uo1}oM#G3F>jyPX^N!xaj{pHT-e0^}U*Bc)sjx%-|NOGMs z%27CW;FO@VhD1R>ped1TJ@-IsMm|AhL?N|~ub7vkhFBg4o?%A>6DqwP`FGs?oD9WnsBs5s=K+PZ`YAfx^YOG9QGkltPywRup@p z5)1@zo;Z}s0hwEVjkX_IcPU}Q0vfO@#zE858M#>Et;l(!I53i?g5Ql%l7lZ1iD(1tc4fok1jGXxIbAYM*P5T(L3VVA~Bdf{EXdlT~Kd5lH^tvZZf47J2XGU zE*vzGK%;`^I>kl26_~X+%G{-<3oWJJ7u9l5s6qnklz^fHGD@MBkQyU>ahiSyx_BLC zx`R#dn?oVOXMm#MPDmD?*iMSuiQFBH^7vxH3kXIKK|A*jVU}SHVj-78`uw3Ytv5*u zB#`$j{>(``Vf~M2kN{@ypYgya@!wg5{{55q`&&r7eS#VFbv#*w`bw{!0ScsZT5ni* zYV=K|zm`sSVGxtz9v^m(mx~?!*-71>gs=nHPGeX{FX-VhKaX$lw$}1xXU?Z)9t#Nu zKru(>qw_j3gza0!%i!iV#dVLctC}V>O-Hjpk{zjn-7SGExOFs2a)=qQb^3nh8SC+T z>*NEPtT9r%|HNn%PjVVL3*Fv>QaMAHVU+g+mSU+0d&Z_>R<~~hjI}48*4)c`*w2zD z)3#8Trcuj)IB4H9VN;-wa9CwjDv256XVbT-uNGDii1|>!P-GEkW}w^zwyQjCls9%B zbsp4jz6s5d$Jjq@b5Kdq3$E##b=OUR-3RZ+QtF+1Jda@d*pqj80=3XkZPTC9$=*fo zRU}SmEsxBxnxoEE4~<;k^$h3o^i5}Eq?Y2a$pj^-okZRUw6Z30DP+1cYFdP)c zQfEeF$fsxC%j_u$D!s{vI!_iMGkU`~qpJ5#!%f0D_Th~1Aag5^_ z|B;M68it$}=mnp%k6+wv^5t6WyBVBs*+&YHl#6+ob_c5&9^GZJClIsJ<8hKuiT~l1 zC5oTa?X_yBW>tmCH#uQV=c^U8dxYyk)ADspJ- ztc7TlRF?OTj1XABd)^U1Pp|=o+rQ5OkSa8CxkK`@ih2j- z(~v9AU-ggT6@+a~YcO!+#XFh6ucVRr9|*GI92^Xm|BDiLJ!Y=+Cc#{-(z-T?qb%v5 zF)W3J1714E&oHU@vTq9oFU(&xUzDt2Xpt?A$O5ZTpJj+F%4QbBCN|Oj#a&d#=IyjRe1o4F7XJS*ei(P@uls%Pj%Tk-0#pU!Dx|#>&;7k#LthdgI zUviI%14)I|dV4Y;Ot(IQhO3#p2j0pP1ketMNSrJ8r}G_Sh4Z>-86nDNeYAdu(|OhX z8Xvnkj1!S%jn3{#A#iQxJ@Pl$8rtxJm;Mzij51$pvxT49PW(l#a?>rEMXo~jW4hGFU zvOKj9XVg|YCSN8xwdeGnLX8Pd?IB(=6Pe0{M;VlX00qs&)+fnP5_ z``jNy7%e_~I>6bE{f`Q;yOTMcwhBx-X zxm5X+6nBzjD_i*=59EJ*Cw~m&>My)FuN4^YxOZLu8pzEts3_3E2ZdGWJ`pobsKoUf zh@i7JSvyYVYdD8vEZ?KtqfFuO(r{_~0$K>Fn~0nG;r$|=Hs3ExIvA$kBqgOq{B@4h z&ZG?U(@PqX0CA4sryn&$-Q5+<+l=#yE`jg>b-d%V$elGtylZ4Sup2a|%=R5{ki@mq zlAW4~Noc#83xnw#ahzhIqJc?^4k{)yu0pvyLaoM^1F7*2D6}Gjq^~xE#qo;8bdzbM z?=&leMKDM9NfwF}V276TAl{rD=K1%v1Xrrt+Yj1pbB?gb*D{%G7M5Pf^YL__SAx@I z#3p|7jGISPoEI^CyZ5mOdy1-%eRgJ8c1J}(`8Iw-u0anj>61=r8T|^scK|pd#GUJm zIl%j{D8yRQO7mTZ;y5{zM=fZ_07p!=xooBo(G z44<{#UpAOI>8fU--PZb5mYV9-UTqmaxUX za?4^=MFIIlejM?5;P9~cVy`frAq`A(eWY@rh-LEIU@*7`TdDQv{V`bj$MdPNkg4t# z%H+6q4@Vb8jr4ZMXGx{^1#}geDUD5mT`B298?Hz3cVv`UMc?Be{XW?&F(tL=eCgG` z)vC;CO^3F6co$V|QU{otBoF*GKkZxD$W9fIuf0jKUL}Kd6NQ4IryUVlB9C;veoKru zz_rWu{``~~NCd?ZQF$l%=_?adSj9uGbF8o-n`0m*ZLdd3F&GK=k{<@~{I%3!B!;`+>2SQf7z;mbU3q5u$4ZT(%f89T2`6`( z-7kHM6Swi{5?%+O?5AjA@;M-y3xBAcF7(wiP5|FxU(c&qmxp)|&&hG0E`b%X4r(nJ5SYQ`*be77|ql{ zJLnGOcX}6ia$rS#irX%m0OapD2w2etF#hI!w2?b1`rWD`?bNTDd)ul2p`S7#VB%hM zmOXw*edo!!&IO?aF>=zE);$&mjOcNknlYSjVb4;Kb`COOQwz36bat11|NUrR8VbJ~ zz-FUaG)nTU25`X)_%FENyPNbyM-k{Y{4;laQrGH})J3IGH_WrED2A1{*6y*lB>tz5 zfhUqBm>#6)s~>5xglQp-yz4R5L!EvZji-!@RDt6|iEe{E%XdBBu`wBv1#HUo_R+2( zZ`dZhxsw;rXlLf%F8p{AJH^%G$qK<48>}?4n{kgO%ggFL9BIW%BU9h96~{eU@~_kM_=fymXfa%ttNOC{9b3 zF8{|W%G_XX>|x&AlFqLXH$`M$9?TVq2bmtmr5b2-AEvo<#)K2j6?R*Le~n9wyS<;W z>#OuE4XvTXuw%Y1cDFE1X`otZcFIGxIDJ^l0+;lm(N2C1e{MRu!8cCd85w|#M=xRu zLc8OOA;4lbP1VlcghE^ThBZSoi&Lg+(*<|M5T>RZ;y}fyN5Ms5U5y_u3zhi8m_Cm^oKnhWd4!c4*Hn;AsOt(wb?n3O) zr^0<}uw<^E3=#nbRr+ms%5J3;kX`god6v`a$Aa_em6m;p9aLTKgC=xjR8(V0J{u#* z9RyBB3wvpr86_Q!Ia$;H00F3LrNFAvxAsx#q~zl(o$}(P+!`Ab(>MkP5N& zUZ^`#UH?K<(&q##X7O-X9Yr5HSb1%WdfDIr;)`kpZj%H(b&st>@_QQT&6}iL-Jb}f zP)(ZR;9hgKH0lMRD+YcJ5{+dEA{2=Q721i!#yA5;9kRJP1ceI)iC&`ovkJ8^-*hn* zM&m0;DGB<^$x@^5#4pE5kxI|6d&I%C}v)^o_j@Z|C*HJ>IGuN zPbRS!hq}9PPP?4H+?GzwtleLZlkCc}PiEXAMzq+wcb%j6`1W&XX&d9y>-3`6V9TPr ztPnm@r(o#jTH~@B?U3CG5`FNH%jodX`H;Z&dGyztiU^VMAq*nh1jMKTQOzi+RVW6i zJ`W$KUp>3Lg6OC;-quwxi$6Zhy?1^j5&_31Oc8kcBmOJCTrB$&5QH9pApG~~2olD& z{~I*iiyTBvm7HimpfLuEJ)uCwK>pP50a4^N5Ezf7vK3JX+L)gsDLY&;GWWgv*NM`4 zDT;_nGdL9#ZG4F8Eti`U3kKuZOg4NipGeAY08f3A*tTskwDl7=k;)xZyQZ2X`5E0G zUiz8U9tLy2`WefiQ9KTm6u#N8@=M@s{!$(xigo-f^A`m0*G>20M3F{SeR!=_~7n_>dhqOQH7rS;UCS$-~!vW&~PS<-B1pPyhC|{vY4VAF}Yj4wn%AkriLk3Uw$ck*=XK%{mfuPTx>dbqvBaa~#z0{`BDt z%ozFQ4>Sz$r$ghk0%KAGz#n-Sx`r(+)*6evi@Uegd11o2o-S>bw^^>dwnBEm(CF@# zB8ocbAs#BI_)u0J1oZKR5K;wIP<84fDSmbm@SCQ&TpvbV7F#n1S%he2RI5qX!;e^z zaK=`r*-O$M^gzy1_%HHWM^o9@A5e z&+bZP(>VuST16Zct7KPA3LCy$15Dvw?4h3-)d(#O*_`2>O?^X;NV2lImD= z(VcS=Hv)Cpey)xxQ+^@S>B-dts(4{s zv*KYB$Rv_?ugRm-w(19I^3m1F{@RL$pglE7_nD$RLXB;O%?&{8Ehp zh?bj^^WN(oM*00nBbi@@zHz_qjRh!w5}T)^--49j2Ul?KO}(G)m2B$;sn^e2 z$d+p*op2T?*6pXRlc@Y}j2si!^#gDkd*R?Sj%Vuy9~}ZmpebF(sdn*>q|Q>|m69im z_s`++A6aoLQ}}z?CmC8Um>TA?(2~cOL6{p;p%zYcw!Q@1hF=$xsP@YS_d32qy13B! z1qpOUw`^g$^{g2E%J!EE-1^{uGuZ&f9mW-k3Tu4n4VymiIl_dfBk5<4#PXR=@F(h8 z5wswZm~m*Am@Zfhd`=i^nBwKWwjn`VKSD&fNpQzJ4;ejIMTuSxLthFk#CH8pka%sH9TZNli+@B%UdG0=b z>oI5|Ta9>C*l>l%pOQRXwo~&nIr{dTf8#^Jm0x7gKCf<4}Yk0Vx*t=!~q z+|gfOt-V8>ypp-cn2xyZ>*e2MS`z;p*{jeu>b~inX%&c?;YYminz!isD6+FH@Qx>3 zH_H+#j>Cu4?f0Ul1&a|e(|UvKNwn5hEclsW`vEmQp3U%u?xsY)^Qy=JPnL6qwA&Nc z7O%%T=z`J2ko_{{H*=V`*x@*Ky)BGA!;8e4rw~}}w7sOrUoM}%iw8dwY`ei0m@c>N zO!e4oM$m7(Dg=(2lzusgukm)fjjsA*uT-08vY+oHT6)RfwTc|%bh1+W17Y@X+3wv` zwt$2OJur8k-$&~!I?JzBSQv{$d(LbUH_di43h!4kevH7^e>_i8-|V#}*p%`+PbzBm zb0yVDpJN#%8%9}Il4}q!wnGcOUR#N}vxmC1_}qXi=hW@VbI{8^G*%mu4s2?e5TE`y z=44!jEqKX_7XXi=;Q#Dle0e4RxuwaI`^#ckV51j>Hy5}gLnSkRMJj^X@Bsc~cq*<1rx{1&8O>^K!;9?&!(x%E{0%9xEDwn6I9v8qSMz!TC8eu8$1@ed zlnQJOD!tfc-y39nLtd_b&FH4`oZ6^s*BFrDrD$hB9SiZYdP{z$)Jy`smRIsD(6^Do zP=uHTfd4YZmx>sp^&V1pX?9b@S!<0}fl17tNz&9Vu)6sEbIZ?=JSS!`fvBT1x~v%1 zr=XJZNj*a&9b)?(CSx3Kv@^X7!^&Y6(Y+#F1JG65mcci!AbqoRhS-N0p2q<8K$u;N zv%YVKfopfo)6Ar(u{m|cLSKpMbX1pY=+Bo4JbTs6T#VM^0~Q)KI&Z8XsWHq!!nWJj zW9`l$!vd-_?fw}IA~i&xw9_x2nOIC2Rqi`2Fcl#??c$hp%&x;h*#%CTdhk!7d-KEM zi9+)-40^+jO~zb;KuSEyJA=yyqUcU&3UX62OBV0Rv-s>4noF)j+?PDga$h{+uRL=O z)b6i;`9WNxE`{lG!uG}{p32t43esW< zrVkZ9ZN{RdBUsZ%Nv0>)R_P4&`wHr@8^6NbL>pX}nix}0XhPPY7a`|9nH$0T?&L~5 zGL})7W-dv)cPFh@oG26y{HW?18|>q3(hrYS4Y!z$Q(?Jv6-e};*o$@w7H`%7Keg_y z@pTuC))INjmDwq!VKeWf-98}H&v2l%<$qqs6-dz_)4Sb?In&V}QYDW_ZWgg$SMoBbd}^8@Kb3?=i^ zo2z2kX_Q!W&%EB$K8a;A6~PFWHhN=>&(srwA%+76;hZ=wBOk<>OcT<$q|v%_)h|b~ z(`Zu`&*h^s{MfNBl(iB+I5S5oMQkd_$k#^86{lpUhh_!_g%Y6y3mcI&=B_WRK*64m zmg=AOX zZn7SMTJ1x@jEI}@la2PQ=QmuJG98%_5q`XcP7;0Z3apU{0$0XZD|iF#{Se1aJ@60V zI`!_td%|&`pdCec-@&Z0CSM~x!j2ci+`mQf;c+40B7oP1rth?18nekC!?xhZ37aS1 z(@u^#_59}^v~uU`bqFxgHvkho+yCgn{_pcVI_%5(b3a>kT>Vp|_!*djk7!3CvahsW z6KA3L^~52~KMR2JO_6Hena3O@vD>y|d6AbGjD_GBFAha3R3)~TGFcdA zWk>d;SxBsx`MF}*3B+WICq~mzYlDD+-WC|>`+pDg$Be*0k9F7K4g9~SH;4Fq-bnNQxV(}x{j+rQGIwx>T?$<68VV=OOtTCcx;SL=J#(b+I}{eUlZ z&VD4R>e&rgO!=J7glDwM0`oNjmaS7eoxnhia?*@!K8(IfP7yBUq*SN=kSHthj8akU%K@&bPLN^%DgK>97^PPeJ=2zQT883DsCg^l2O<&5&B#muw6gz zu%fMD5_FfIopa#b*H;^LotPg5?GsWqvCVs{k2p%N<`5ZJhbyLDA1X~V3^^)O!^7n} zLBg)ZVV2jN2Dej&71@L;Nv%kF-ra05;iKfSpiRop5WEJqny;=AzPqhMtCzp+SSAomj}Y0WeNPaVz(bJMuB3+;<^Fb@yL{X;n2PQb z>V_UlLpV=W*KW4K;?m-`472n){12}5ad&^Ty(st$ln(=nopk6GO+DAs2P)qjEu~4b&rS`z2biQojQm5-3dff*7&;<$h=`~JwAk_OFK4@ zYGWS$J7$Oxk#iJD7AnPtHHVZFa9)L@XBP>(JRK#%k!xt*$273r+xep| z-8&9QAzf!nWL|vamhr_9Bk-OvlZcdWL^ zizQbD4Pnk~mumVKFbwqf`9m=_kj{e>=4q#ODRDT;P{_luG`*5c~Eo2ec0NOyAkVz#d?V6If<*h6@pd$*mJ8uSIFjL^O;;nGTr*YXl5h(oLey8eNt*vpZ=KX{jos% zFF7OwV5a~4KmSnvnCmrP);$59C@=Sy5y1T=8W27oKvy;OhovT0Hi1PW)9Id{cQ;T+_WCSx%tG`JU6dt)5J@E5@h`1C+m!@qR z0_s=gBgV(nS!A@8M((dEY(m&YA?;wV+kaL)t?dHo&aL>=JJ7XQ! z8`=SQcMm5XU+YNzQM4|G=C3a8b7u(2OUvO-BZY!3yK^JDpv!1|Yf{6PalU6-H~d-| z8Z{u4*>#lsT+q`OudtkrJU$q;Rdj>rk_nb9|BIL|wEW$~nGK)|-hTdxt}P5M;HQq% ziq?UemD=;ZglRiUH_^N_rRIJXQHs)EUE^|hx4_BiR{#wt;hME2PGoOt?JcuYdK60m zP!rUR0ZOR6rl7veK}`_!zEicP z{AmU-%@5-lEhJA{Z2y>x3WdUhUr0V%LqaqIawY1vhDAV4&{+d%vV$~G6NCfQ1lg)y zmjE?E=fAHmQD16;u=r@r4Z1RG(>?UZw-OL}UjM>{xkgo2zs2d-EPTnIbK5~^+^B~6 zmFBjTl>qpyz-nH}XXPREC4Elw z1xTNB74Wwne3bs3J|_Xv=Wg;ZB|#Y>K>EBIz`g-Dmq7YF@t^5)cH(a7?$nj6*Cuu& zMQK}OA%BhXN}O#Ux;;^C(=)9t?L4G`t4pcBYJ%KrftsLa(IIE#}bKzSFawQNIeMZIYGe383+Q#G#?KGgfWCrJ0@ z=+c<{!C}ZT8Cz)Q2U;@Y`p2wha=g+aCM&Ezn z4KO8e4)l~-L(Cgjplc+3`m|loaoQ4S#agx@_xyywOEdlh z{Qh@Q(CX$N!f+U!T38AYh6lit_#fOz{PDZ_w>XTIkp}uwdY>Hu1b0;js(x^wik@y4DlD&&XqK}*h0+Mckt*`DmR-OQc< zR%Xen@q1CV5N!g!YZtJP2Ba=oFji|y(1P4pMainvd%1?<55*q}R?~gB-e68Cg@0@= z8g|#bg*|2@W43@On>9>?zgO?5kaui}?`T@Q{}8It%L3u(mcyqJU@80ApWu3^YC(!q zSvRq7ds)V0+FaJ8XxZV%!BRMRv!um5Q?yY-Q#!GU`QFg9ddPx8{ba46boM1~Yp(*A z*T|RbA{S)^-jbqva`}@amr=`mUx?itXf#MgR8)DcA0I((m_j8-k+s}-m7?PAEg!w+(nXzC}3;XyvxDWVG0^|$!Gat z)XPby`aJ97%_C|!{;t0w_0h5p$;rGxp+8JiBn+OONR<$?c}9I16;FV~m5M$!`_kW< z`{({o+D*9r&tlp1kut+q;a^q^q`ksbZ}wzi;l@mAs(;W+xOO@oaaWF{@uSe9&sDV93d%Zl%Pq)&sNB7g8dE_vSk+YtA#3qYw2hMm#LX))% zs{P(?k|^dJA8Yc=y10;GVLvMOYbApw-UriVNfcAL5lNVBI0JQ$dOvw2QFb3bNl#m~ z1#S{W)b6Wnrf=QmK!NT*NlOyF)e--xhIisE*wnD6je{rfOH&`yg6e}e4d3Y28N6O7 z3!a6y>(35z3`b17nDr+K>*s>?R)s}c{^x}CCmZq9Z3y2ResbdhFa}*^%~*G=^u9p! zNw#S!U)K`J53<-3&e+9lo;_cV4)MlY&8AQ$L(`9G%lE9zE^#O?EmKtVu<#zA!Hv4S z;W)b~(wNWfweT{$17JsFQ6tMEEtejlugjjXrj_u&G~M7)YQn%wRmc*Kj4zQh;uu9P z<)#Wy9T>&Wp{F67S7R%rlB#z2J2xw|MiMp%)lcL9bHsf=Ofy>uykh_1vgUvNLjDkS zzi)VYpHaXl-*tujOVq{J&A`?wFN3G>Lj-@Tb%=qlV44eS5>Hun4)1m4^})|_*%j|Ai=XeGppjfaP_#TVvPAKT8^RpQf`BKMx8`V01w+r&)O$&BB=xe$Tn-^A*%N(E9k60^-;V+n-@+Za~y~A?{pd zn$dhPO*GN^=W~lb+sl4t^6=FFor{_Z=(uRDLEe}>VTBbB%Vn;@;R*rhd|b+veU!h< z$D#AnK}pE6tW@0e_651ZyG9@4?pOKK#Tg%n8zhl-=Q>J^&(5()bSc5-f#7j10=u~% zk6n1kLAdYh*0Bng{R|yBru#kITd;IK}J%3T)l1d@@U~M^X5r?QkJIn=;6!>qymSGYw~PUVZ+<1 zHYM&LsF?@Ba~7<9*VJXjIHviWeC+T|P^}fCyQvPrQWq$F48MnoF>a7<>Ut@CG;(VG zar!9g&N*dixEorbA3GeqHhzpc+JBnK-BLs|dV1tJi6l&Zsm4k@*~I6Yg0qs1b#xR& zKNBCCZOAE&$v_$3opx8X)|iT?COtN(OCa$cndR_JL0`f{m;;%Lkt`JycI(LM>ri-D zG7~a=I&cc7y-jvTwlG{I2f?2x9jMxxegTBBg5UJ$;3$3BhZrSDEwM{?uewH5v@JyV>;b2{hD-c#ss%YF8TEsn$vVSGxAJwzDkLPDWM7_S|M|=94aH<*Ji&2 zp!Tt8ky2jF${_MO0|Cj95CHkcd-nj;@YIg4nlK($wmj#x@4k!N$Rce*pq-oJJ5!JW z8FN-0!6DleL?M+nEa zIraiz(^CE;6=-*KRy%q~MSb=da`w4znY+UU(lQ*lzjd4A^hk^BLje7bD8Lg6dD+?I z{NC9}7pDEny}e7kAXWo1=4Iaio>1OjJfV|9_g{IZafv4i$)sVevp~jNk7pa_gF-9* z*!{QDVUaaQoz_WtdJfXE$y6kK?^dL2;$@plgTHt}-2GI;`5*dg$9Pq5JbA);;1`hY z4w25Q8?bD4`0vcrH9A``=tuFA4db@S&&vPi3Eljl?R%Pf)ryaF+ylmQok9D{+Mk4E zOn4Mh#0IJ0`H%UQp(P7k0uXeAz*G1iIDP-iGx#qtxAOOKcg1XcP99nu1>t^HX&mRb zZ=b?~SeOz~!+v*tm!+uK@Fq9;)_DF`*|%q`bsZ^M?z_wArn$MayP=`u#i!f5ElMwl z5|XH%TJU^1qVfVdUmTdBd@GcC@hhRy%(SRT4QJVJQwum z%vBy=*$u_rJ8sZ;#Vithwf(3iR&!UWW9KeM9eD!|Cc?z~R#9{`&<~VBi>9Mf@-C6A zTaa3@MvNNcRUM_qF-QI>>v!WxiK4Zm`}l9QdC{e===HN^YtXDyj<=Y0&g9uE0;QmkT9NFCZ02MwK7=0gl;Ic1&M-2he7PgFHT~4H@WA7^M=tmJW7>I z*S5u=lm0PuNdER{FV=_nC+@PkzKVN%3t#lFb$UBSeq)4w4uNAt{0GVNud;B<*;Jq9 zY}%f`MXV!*YnNH+)gs-S*DH`CTK7FLcSl+TRq&R$Hj}%7+}8YbYd#-OcA2c$9PZe( z(-B9sjaw!p@8IXO(xign#^21Dqd;Vu)m;3f5B)`WdI$))rTm8wMbPo|UP;l89aq9g zCbFR&={GyL(8-j9B{*kNA}g2#Q4NC9V9ZUqd+2N2B(=j=A1!Y>mOn}{X3!-!S$R20 z-GzRJUx{24-WR}U5L{ss{U9931ynfbtk=XF_-1Yg<^Amz9KDfjPJ zH%PpEp>oDAR^9*EsawKaDG3dIaq2#Cp`OVm`pNqTD8@M1$(92|skoT%L(Mawxxr~i zn4oNuUzm@dKmPcNn}=ui=62ymTJzQWOod+bvWABJbroC%wfZ$sh$>Ao{1MyQ*KJeA z%e%zhk82pl$S`FLn)w?)XbIc;AhB?B7f<#RNx4Hpp5~P4N*twc$pK&xh_4s67E95^ zkODvG1sEisrd@9zJ~tR9-*x?@Ni)mg@~N>{9RLQ2e$>9_5`#95ZHZ`z`rD`*$(Hzb zApjV434&BT-=~Vqlb{qgB3S9BTwQc@tjS7Ow>$kJ4k0icxenWPf%@5hxVlV&K}|G+L#TkH9`&7c@DL(lH=^uh2-Sg5Vm;rUwAHg>Jw6TzG0 zeM5yW)uc+68kE5mgwwZGLIr{?*sY#N02tKx7atPpr1CN@@e_hL@doly8uDB_MK^Wl zd)cpDEhmJyUfk;7|&lzBveZLQvHUe>y|GG%jI{I_m+f3uanNMeiy~w zLAtI=9!oQ1;k7+$JM0?81c9AY=R{k#3J0Gln0F z%DL{?o>o=5p(l*cao$-LvCHaXc!!zTc+2r3oXzxS%B3qP>6OMfI8fygB8l4m+MX{X zo!g|3@Qsi*yYgyAI_0ilQ+D|n&)A5I&fTv*BgRS1k11kJv*qS@J!tqFBh7i-%xB5_ z0Ye3Aua7>mI!&)ZbZrQNPJmEN%Qz<=X^3Qw89G8lU6qpxC?E|>)!rRs`J7VuQ#$J; z*f?pK*`+n9Uov@qxz1^5K3e9~YzIq#!u0FnS2COzn{II&(v@&CNT9p1N%MaSw0keVWFVu8FpB5WJYP``dmHCIU;bpw_gY;c;p(TcsK=rlG2W-&M>oC%@B(f2a5DH{O z%RP}C_=JKq1}(LkTMpiKM~;6d6sVS4^%)#!A99-&#)G2>5IK`nu7bR6n6H%PsHWvbb4pMwU2fhC-_poX&yinWT**?A6NnUQdFwteVAqVOifC5H{ z+LKJw^sqY*k&E1MASn&lbltygI^hO}$?+orSp@s~{( z^OsErU?S}SOr+6J1zME!$w%IRgBP1ldUlI=@fXnNo&LMe+cWjAKJQDZ$KcCRgjFb{ zHI2n~$>%3hkD-Yl;E=n^?|?q<+qQoWw}?hh`{IDA+W;QKf1jTA$7A>}VfVWy?=P3` zoJl5;FdKa-wJyacP!2_nC=oski~crv(Sg-A_pP{U-*u2%DG{W*wwvL407Lr1z-Jcd zEK%3vF2JN4?f=`Pi#;U@qgRvEW)ZknfwXN%?{tF%V3Gc+AIB;(R~@iFHspLL&&*sc z^C5gO>B=Y{iiUkZfx{ltlbJ5Ua<>iAy?0pf(Qe(olk~0se#M80`(o0)$&q3Vu#6V= zC%BrbQnjFT8=;G(ZO$1hn#~+LQyD}ncf^&uOIJpIS#v zB)YQZs@Cnk3ojlk9}%-3AZou?=qS;G!sJ8N<`J6N`AL-TYxf&2J+dARzxi;P1#bB< z1pc+%jv1j+4Rz1&l|@=I-N4bf!~!z*=Pz?U-8SS^u<;69J+NJid$@o_Cua@gt`Tiw zCy}G%V_gCcf|-K^gx%zChfa?y4Z%LP%B}2BC24K$j?lHSP+3+ATc##48&{TTuhd?m zRCxTpD5K<&l6Qi5j}i+73;kT!;UH_pCMB-Z%j-;699~xvNvJEi7pK#(Z|fJ>1~qI3 z?vyumuLl7XJfkeamB=U4^k@7l^C$4#OxujIY_`{FLYyJ^UEgTIMwd|z7R~$GO!c+O zr3@6f3y!{bB2bD7Ir@v$cagQQlNpT601*W(e4#JVTx2m8vu*+*gpf#M1Dl4HgiMVq02|HGmiTmCpU z2I#skfUe{Jw>N8&+D?K_Kr5H6vBQ7s<@*2Eum+Ug77&md)uHelpY)n1U?+hp^`td^#0U^Q)^hcE_7z+6qxz620F)H@dw!JgArjVeX zPdg;Yzb4QZm20+jQ?^#aLnIsEk34I28<-2g8;OpBa>)BJ&D9qDcXZ%x-Y**dB!+k> z1bd=|a4YuG^n0>|co58SuHnU8d?7-zAd>^JyT^l5<$< zQR=C_BQ|wDAlua;Vz*yOTuZ|80ONh_w07QpIuxP9Mp;;? zcd~8pUBJLbPrPa6&OyobjQ9EJ4&#-Ccba$8sWESE7Tqh;in4adHjDF9ETEGK)%oZ4 z8Xl0#;@QzAeIsC{=}imhg?6uQymFN?Vd^lX#6f9Pvx1@t?CI;odAcx$ocQ8>gW)eY z`n79{YHnJx_F*jXILR`OS8wX{OzmU7E>n45W~=j!Xz|tmbXlTeG)##{XuhDM1wTpb z5gMKZ+`A*X3z3eQZ!+28BPgJ+Xq;Xs4R&fSU@gr14a&xhnm-GmR{8>MII{@q=SY@xLYQ-NYGNa8%(D6@mdK&lhb77IHcla2$H-grRKIkWvtZ} z^eWm?y*WGYFirH4E9TGbzH2w}bwZXGHF{_kahm#PD#aL^40P9N@bDmbpGbX}+{bgj@b8z6~d=#`p26_Q)bZ)hPI;-6?^TEyWevjib0gqNrV9F)Utr zSR4CF*}wg5!PT)1Z+b7Ico4RWze@vUkL|AuiXe^ngd4-b>fOj3)O(A)_~YTV4?Cn{ zxB0HFZY6POMb32>exDqss}ie?zRc?1Y8Cq8;lIs#h?K242=7sR2y>T^zs1%RLcQgH zYx-3E1ya&m3?1~Eawv6)08aNbFo5E%E0DfByf{Sw(su^v+Z_X)U{uJ;yUqO#a!hZv zakkv^ot_NIj=`q<>6S+l znUJ~>;t`WVe22Za#yWS`@D)!yJi|}KE0|Om+`ewE9q#tyJNDrBu540F#qQB^rb-NW z&fg@MHaf@=or6f8uJv}xKihhE&d5nm&|dUQ5e6AN(noPq$>e1`;ftNS(INQKfj?NH z-doGzyjD9nQ^j+6XcB09bB89o`F3~DyN%$Hak)znTNhvBb=iHbP?rj$atM>Dq>yPI zVQv2E`yR6|=o&r=XY&zFOO(pNwgv=8yf{K5dXcTH)L=`2UZ6EDwf2MJ+tFgp%cyey zKKv`gyIzC&1c>ZjMko4Ru?~ySB#a--@gIvAXRxEGomNh5Stf z&wr`nvg}P=@u`OxasFP7*@y~AH=7-p?-#cG4{3=PL~2NEZ7&^N05<&1x5c}n#qXMd znj!3(ZxmL!h=IRn)dld8$6VBoBhY8vi5E>)E#^;4kvJhyFAiSpaNEsh>l^;t$HbFg zY;&samILnHeNgl(ugEVR-^~gKSt>%Wgx!s3b?h- zE~K8mi?q~Ql!S{R;#0WKccdO_{%Fkxr*j{~Xu5uS{_|a=dP+730<>N(aI5#}|LI-) zOYr6WFPMf{Uw(HPh~GsqT^Ivh7-)ap?D0k&E#=2A=6r8jKf}0tX-$IKuq1hs>6z0A z_JZOww@Cw>ywRbNk>eM-99Uv!j0U_GSI8iHw31B&EOkiG`?56`^gNzeYk>|u+IuUx z4r+)-Fo6zKK=5Gzf-m^D;Im*P6JLbq_DmtbwWtU0a+>C*COL2#SwzLiP>?niE;t?(TAvvp^ z+Ek&Lv#)<7#bMGM6oKU;W~0!!{#9>ODWy!=oYQ`-{H#$jUTxU)SH7~z0G~DQ)_21? z+%?cW$;vv#@hVLhm3~3*+}_fmT~Zp}^i|8@B~fUwYeTt~%8Niu3{60`{J3p?c;<8T z0W}=2q+H%KZmT=a5Y|9`$cMsVc`a%;x}bCqYmjj(iab&247z5iazk3G+c-7o#@dI1 z^vGBH3;K_W?+bJqGpzoi`Qt>(jk=CIJI~zdLI{ng_{Xj-k5jSKPwMhUVDp<`G@DTYUC@WGz5-XR@w zp8HSHxGW!fwFrZ#G9qbG=LPdK-Go^DEq9mrj^AvCu!}uoMQ2)(hek=PAw!Cyi{NDX z>17f`L!ka?1L_4gvQ7L?z}<@v~6>1eZGA_Yp0pFFIj60!(o{L7Q6Z1 zE#?|@bGlCnflOYb*jsg;?KP2xzcP7Y(bk9P-m1C2FPS{ev-K|^>vSPQ9Zi2{LcN}f z3C=CU#gOmsUDV}DyDFwUNvos!vLic^YqWlvWawTq;`VDB8cNxe76ZNX<9}!J0-@*$ zhSOo4-G=P-9>|r+(;3V(s5XiZKW*8ZRzY{Og~T2LhtGv)v+(d&tpoOCh=g)h?#s#2 z67gZKFPw&&r|Iyu3)SB_*L6Q^GiYZNm=F((>9QTZv)D3kOij8qNofP%B8QlsCx8SnH z2w`_Luv{O$peSE9z+Lc(Ey>Q>`Pzqw^Gw`f>Scd{XeHFD(Q^?(U`#4rUKnu<`FNG1 z$W6?Wa(O8gks@z&tu<0It?nj(S?VAzxyz=|OlVIBb+Oryh|msg)Zi z+HN*DxdA%5gTZMo+IMmw-}_j(b@DEv+|*>Qs0gPa z%B}@0Y1x8l2Jw1kwyufWLR+C3N~npeXKrzJb@D5>zAOaZxo|DLW+|0WmR)Ct7^Jn003;T5@)q{d=16Usqlk!X=z8dv_xjO_K*~O zf_+l&x{41sV9hs<#>I`n>s&yrqi6wJ^@8OZMrO^_4NGSAfa&nHqyP*P#DFm-LnB!3--g1l*JW3?)Nt<0OHnJ{ z53n%jP?uL7E0GUaCu@XZ*00K6DYd9<@RhQc2qxF&chw?isW1Y-hWUR18& z02}6|S29q&E&M*^SmDvEUMW26Ow+pb&4O)GEQ|X^D(UsT<=SL#v+~-^XdpKB){Opz z2)%ZJv@*M9v&!j}N7IReXD4ex1)}-LXd^&qxiKuc@v z;vGA|lhhAq>@w)ol_<`TEP$iPBY*6saLh&aqg*((+?&EG{pIgfkqq%E9Mj`C3;b^R zf841zEVDdY^o4cz>HPR9Jg~juYO_K>@Zj;|#y$10w3T(MRcF&TuskC6&Li+3=Lajb z--)2xPKC~GS_1^Wb3dC4!6&%p?p>Q73&J7Gp$5@{w`?LdjHjbaj~UYZrl7}2w{6Tj zK{Xw>W7!WG#shE-LVaAedg)O>d24xrR)Fl;0M_GV8{c*UdIc8paWCf0c{^XA12Y3Shru9=uVmX8TdDOpZ!ao>9D% zL42NcPX_Dw`l&~GXr~{(NtQ8kHeDpm&CNZYT?{I{Vsx5_AdoPyW*0seLsZJrqmS!i zRvXP`@?x+MNj&a-Wg*r;%omp_ny3ww3$8nJefz6i&>YfOl=UO;Pi+xlPRS9vuNS_c zd{+Al>e=}+U8^OyT8=O^_cX;J#!Vb9mFWe_^t~E>*Ob&6S@!W^hm`OcmKp~me_S7- zH76p>HSHdWz4CWkv+xj0RWr9uzNv>kdq2~0fl@)rAcegm%P4NmYVOt<8w9+P1CT(x z+L9#%iDp%IW<$pLBC9G86tNdynbBW-VK?X(^vo459m+?g&9h8tIG7*{^{6k#SZVgW zNXBqLGBR$PUpuWyVOlF8uqv8f?VpEC8zNIMY=1)IJlQvI5-%H40d1wM_YqO`If2g~ z|2QKh-C!E|@r#WwF6O#}jtVxLy>WI-16y^GXwnJUvdg~l0`3`4Itx<$;q8rvB`>q! zAf=zIPV9srIapo|LSBGuv?Gt~ua>J3i0qI3Ka@d*6RmSDs6RDyTT@pfdG&NKvzw-5 zOj|9^yzVP519Z6rk9CD(U1Z4MbFy*w(-2k8ecwze<$cT)b;e&2vVJun#NN*V>UgOZ z98RzwMaC$NRxZx@s<2{ykC)cr1{%*HnPg-U(Uh@ciU}c(Z38@h_i~Ur*9pM zW@3PTqF99QA^)XYur+dCU?oMp;-)Wh3uVGz&b1FUceF466ydR{&)v(3zITsT02!6W zA10byt&^@F%vc~c5}Jv>%4?nWpMz0Vr6$QJpcp>`2IIe983!1Q|0I+A>ku&QA4sn^ zewNVP{;2P0Nd3Un0Nys%{{i8kGXs;$BqCz;|FQShL4B@ilW-tNkU(&UpuycWxVr{- zcL}b6A8x^e1$RkscXto&?he8BA?KW(_neu1Yi9QQs&;GVUy3TKsO!1!zPtPC&H>ut zYHW;`p0}8&eDE&5?5y~OhqBVL$oCjIXnnIA5=mG!i#?%sh{JF2=+6qa9bkrmOi04X zo9LtwtQi!+B2_qQ-pHZbU{60N%oht7#A3ZCegwG#D?h+a#!q;Q4rj*nAnpjvVl2K6 zm19i%#C^4hyLs>11E-{se!{^rAvA`IYGf z2Vlj8YP-Ny2D9U#%4;vPW30m_#tSctW17p&@eN&DZ7~W*Wnn}3{m{9xc4DNl5cPMQ z#^s1{2rd%q>azM++as8JO@}Y%Qcj^7d&!-iZrZQjsW-8Fe)?7+9J@N^9pOt${ewQM zc>DwLJjB)`1$+J~vn$vv_UzT7tnTpxU4F}BPL9s|GP%n5}=bhCbMO`aVHkJP8S&?^dM6Cj_q6a`O{_`8ke?Ke#El~6w z|ASe~$f1C#L$CRW{CP6FGN5>~BugniEW7gPCDY(ZHws_IU%5px8EWTVsR&E6Yp&%Z zbGpavWxgkHABu7XTR7`$LFBWSaz4tC(>G43fpjiER`g;5Y4DFu6Q`J1;>J*!GmFuK{EPDc#@NR zQgOEAi`Eg9?MtPeeF3M2sB11JkO&#B<>qac!<(DZ*D=;tLTx%f(>13jzbh-N+6C@d zhBGwr7-z@rm88-*H_TS^oK~YB?$#Px$)?I`Tqa_n-C$oQlB!fBiD;>iovhpCG|Ya= zJH3$425INgS~~(h`j2b7I{1!WAnUy&>ImD9nL%{54Fk~XA2PmJ%*w)K zJLL8q2!G;4=zu^q53I1m6;Sn~WQ5@W2b?ky> zF-#!iRvG*p?KO&IF`ceITcfY+cJ(CpdHa(Yra$3|ch+d+{Oqe0^~mM#qw9-!Kk<6Y zqTYJHmqomP-IsofPdkozcLHlWR>XomSszg)mNjiyt3sq?0ozTV`|$k)yD?(MYhiDx zRUw7xrTFnIy*=5(MUyzvj>Icw_`Fqk?d48y?T6w(532XH>rFzhT=_wbdxSmr?O>n1 z*W$Bbykw5%-}#RSc`Sp@eQgNhIpL07M(ygpVRGUyTxH0w(?4p}RSgd` zk6c2!6>P%uL0?x9^RyMdR6jh4E-I4?nMbH3oiDA%Vzn3v`N>P?BTb2)&>C}p;}#2^ zUi|r7?Aij02n3K~7(g!m^X99+I~V_ulK=1snwJ60qHs2Bkeex$Ti{o4aO7fSsb3Y; zMDETO6m-Thy92#`fw4` zKxtEkSD@$V@^yQgH%Nal**ltz%N7VD}v+ zCI0F+zju_m3?20N^GKFVAggNKRc%ZdRYW$Gfw=MhfhkhR3d%G;*23k@*LlI7d>zvB zH5&{7ulVgnq5a0egn}K`gB|4dj|CJo`ip)~dfX%B@R_aZa#QnKJj)Izgc%b$OsTAo znvMB3Md29Kvy0evm5Et+_RM`_*tyedKqmMR)l*5WtNaeU0z-^mG2kaehGZ$@RJB}> zdN2ve2t1Nfq`6x_2NP_zZD-IXy3SDicvGi@31tMQ^o6G40Jvu=M&+4r%Mo>nM5bHMT_?~PO+INwH49vi1-}l z%m_F42~}LK7D7af%=Tpyi9`0KoB*R7K_BkfUwvZ(TQfWVh74_H{eQ3w{drFqsmqm8 zwlgi_OejB0uf%&$wwAzw<;=ZWJweatM8?PUqo!W9|Tp|vA1N<~K$i24#y_l8mlc?X|tG62CjKU0T2-l+dsyre$9&cNcH1xWh( z>VOjLX$EIat$zM($lkW6i%b)A)iTGh@I?_^>+@CTSS+wNLVMKi@GZa{;fU$rGx(zt z*i!;{vvMo2H&O%sm^sEhM*x2$nd47^6CA7OwDjoYLQRBR=xS^VwJnzH^RCj-QHKI7*{-sNr!p@l4EJ8QnGbDHlv$U6t4H^0$&C7oa7XNRNp`~m7BSZg3hW?KX{r|cQy^bkt z{%>%K|KMEw?>R-`s6aYOh!{TxQYdet>mQTE*QQ6MYL7(TKo;zy?)^|FUqAc2B-IMP zT(YLg$B)}g6%`eC>)Q!sFLF<^F_PY)1oe-&53T( zoZ0^JwfeW#sIqg@p{sa}+zI$YJo|BpO(C{hwq`e2JRm(5;O8hRC1`Ag|9rOu5R2WSX|08a1cJ&v$S9(dUTtYSzjM}sKY6*jQnP{Cp~MZD_bA)m(F>|)ZzQJmLA1?{)ESlrulhU>9I4|j9APZN4b#q6f}annXwzG zh|1nJO`g6xVvG#&dYO*8)##AbsygKF*f$~*F`;&7tELLeG`PR=Qa`L>%0}PyGUR9@ z!*-OL2C6rFQn_DwbE&+GX{xaFu0|f$=exX2MMMVQO2+ZQiSlAar*N`l@ziN?$a7!y zur6W8j(p56)_z_Yd3_Ro=Wl)00;&)lRv%Ce41pvZv&~n#XxVSQVhGxriFL#dv$luu zf4Cd=p26(?)>mx;^i_kFcs6+7HzsCXq!Yrx0)5qe&wbT~zLj7S&ylbn-k<)ZAjbQ< z%!_|Rg*LPPJLddvwBjGxG0&#OzgMAMe^a5=W&ar!TAc+@p+DguOk0qz=Qde$)UJQ+ z15{|2&n|QDJkKh$iz_aqUr}ewDf`)3>p%>@fN!FESvIGVUM%UE)WJS|Xn+KkN`2ma z*d3CpV2eRf6;}MuV@`?75ckFk2^`blXrh>p2XbmwwmiUmM`jI&jEi?MG0rIWFM-CL`+OIHit zZyykj>VEhSjNYqqff|@3WHGWm?HCEMvcf~}PBbl7eLq=&cobUG$yc5fT5Di$Tvwh{ zTGQFSh~9l_<57}G%#0Spj5j&dfzBf$$=JgH8QaQK?w%&bmmZ0ePHe+(P7gEenlvGd zAj9(T(#?ia}JIEGIQhVE7RnQ_Yv}0nM ztR2etmjyeSFGwE$h6??UCgy*M7m@#4+hQ_#FBNfL!Cg1}$lwXe4NNOs0yN0P3$^2e zcsQv$8`}ULV+^sz+{189!(8ao?e$2@3ti*`-decyD*^1YhjLg8?BdXU(DQBzg#f=l z4boAt9O|kAuyCyV=E&kC07?gWXZzq3)|sdOwTLb&TUt%3R;o(Dx1I~PE=q=et;J#` znkMb>ee2mSpfaHBi$?&C$`A|Uk4&pc$}o2(h;g`&SR5~1V=AiDb2?LK)W4q$cch>; zYJHn7N;7kC&K(-;aGn3E63v+_hG{%?@B$E_?RH@tRSVYjbHX*f((&aMGd)!4Tq63M z=i~N!C~FpdNR>2hAb!U0LBVM;ks(3O(XN$koZ*@oby+|Mzs)4lb5 zrb!%Dk!gau)TJg~u+Q{U%yJbXhs z07PgUx7pGii`wYQCU84%Hf(FiyM2p+MTDAiqUD$CT4^hmM}?ug#p#R%P>6PH>W0dJ zSd#`u;Cw054IK|I_#@Q9=1E3-tEHGDha*KKZXdLk(rHFA1tS!8>Wu6slDqha!!b^! zudh1QECwcl?GzZ_LD=oV59Rs$j2`7bL?R;tYwUt2p>Uu#r}7>NkltEziD11ik$n zPh%ICSf#)D7Tq?ECjam)3V(M!1$>JQgBs;^J$p;jF_Z)I`hagyF=ZXjD+Y(O>)E$B zbz3VB_!d(E-(vr7zQwn&fAKAf{wu!4Jr8=wm-MgJY#`hK-y+nrZxNyXzTwj!zQsMi z|LI#q{LQ!6u08?y7R{xFo_&jCtGL}#zxx(LpM8tK;_+L+wYZVTt?R6}&a0pFt58uxQ5ESvsw?KOAK z$D^1vIEHQKRkwlrh76#;FZ4MS_KWv#o5yzy%hz__+3uE>HZX_^bhj;}Qecsyfp7L58b}SsHRn8nC0%Q>5!Cdk-}WaEshT3*mqG7JZExuU0F-Vm1B7 z{>m*LrUUPcz3=bO&{|Q^-5GpNsY|!Sv zW2wpPYkiYH#Qv1)rh$oR+Uc-@aVE(}W`A7Hl5QVwu;t1T1uOTpQVO{lV7N^R|`o z8C3#QmMF}yJ;ZIVA{lcfyaUKvjLCQ6tA>~HwhS?(dae$3U<75w)t&+4`EB9h>1D3P ziLM|U?w7u)dt==*BMtZvXo?Zfid}m;g_=t|t!|zLlf60=vt%0_FrfHdn1n#DYxEzQtM5+_#>;`4$C_UUvS;w+Q>YZ&BzU`xcWp^!^PM z+RXa@SQR?#KPvS9Pb##u9goGop+f)Nto$#5;`4sX|3xaaBh!CW=>MqD|52g;Uss`X z_&iBL|GEnO*K_d?75Yyw@s|p{qkMtDFAPDVZbeUlsi=Q~Ru@=>TNk)>)Oz+`7n=X8 z3cdU{6}nx4?I(R&*ClQr4#$H3=Pn_H8e1;7DrnM$X!_Z3{DnAMSwAxVgkQX3-0^w& z0k(W6G0Zhqc8FdVf9*h2gfmWxUL&@@)1oQnG}%mYnuUEw2 zolYbhR_>I7C_#@!t=q(8ax`Am!sV1zWc#TaeI{`j)}=R6P7SY1y@Ez1S zxugYV&;@2hEG1^@e^Oq}1KPxck}w(wWgo z)>z0a7?UY?8sSk(=Q5!Wn6uk$Y(8Ywt`u^n>Xb*0uy2)z5Hm9=U5_<2~s1< zbe_UvZ5Jmw6YvT2La-f1@HK|=VbNV^nxq3r;{$+Ik&N%tgAia<6rE|{DUa+O9mL3n z!?=p35Yvg4UWKl|j=F<5WsDg229c0!!Wxh$)`Gk~LyrF>Cqy#!F$C-S%PusXg2^ut zS_-f#^8eF2TrzrAMuz;3j`n8yPL4*R_BKwoe`6K@=pVJifwxj5-{eBAkp^3}7vg`5 zN-hwxAXq4YJ2T8`XLKyG&ywif1@lJC7KphqPJJ&C?C-DgWj4w4&UkC+njpOe{D)wJ zuaoA-^3@fIm&%$|TVDWzQT@02(Y%Y%bp!lxe^ns0uy(MK9q*kslAADV?+)RncB>+T zi*Z;)$3jqo`lbPBY6++yeefU1Sgta}1LZt&nTfP_0;|vpzIsKTu(R)wISvknZ#DM| zeRb82x)dN>v0*)XJNy}k(n4J9JDn`o&3=U!a!aC+SCrXvxX26XTk4Z?q1TykJns2s zjH%W|bb49Bux&}*wtCsy&OeLL(=CMz3n~0S)O=d#I*gb_j@E)NunRqp@DYWcD_fKj1?fG@B6VuC? zc;VM1U+b9FN{`xn6Ag{umoI94Rcg}xy;^bHEC9VaQJX5+RfI;BtshPCx4fI%PmEIu zW=Uu!+#?KU%8`qX2j)hf-*T8>a2UU}P_wL4A7(NM-;(y)mJ#U(qN(dbOn$_3&8n}h z7HfUof^ve7rjsh11xsEz;Gc!5r<$~L&Cw)lkao_uRw&9YI|KS9gloLC4Z2^;wO4}4 zjNkobu zeJzH#oVD1*tnnh;*_4p<;w6{DvSvS&)?7S@Omk`60osJ{rWqz-_)3KK2P(c6B@lX3 zOn2UtHRaTEcAdT|QreQsx^QTDCv}^PaeRC=v{w2hvHK^XgL&=1bvjP*S~>WoTJ%a@ zhq-e#hU_UyKNL$i(d7**rmVDW3y)_pt?Wt1`EKL`s#_^m{HpXR!*H0@$;`q$vS10# zsGkW}B#c66d{+ubOg-&7;#S1cY8Ig)u7t{Ap`tF_ql%Y+!j+#IAM=9bDz7Q5D=IUp zA|^PU_hv5?MM~#OBncwRVBMf{nsz}XDWrZ1sSXJ}bO#6~nwkU~#7h)a+Lj?$d_Go6 zDEsS55nD@Vn?d0t8C>qxwjUyUDL~T{8o?`VN(P(ZYHpSDX?#_+X>>Sdei1u;ol6Z( zItp~rNN>f|fc;I^zA@t<2qj(yqWr8Oi03TB(lu6hWNQnRh9p6AQN|(DDHnai(|Wq-tKwq>sHV&F+oJQWcIv-NG~@+-I7cvkr4>2n(_ z$6IG;Z)n#Lh})OHg;U@1G>e`8=qPK=*0CTdc8Z%Jx>R2uQx6s^p}^f{K#T1fU~emH z@~ChRNZ{O3jCrge9L7TYl}-iv8w;ApdAe@@uc@z2^U=$;tKo>DQE5}6bivacZcrJTi8wBZfxIO|^ zyTL8<2>oYo4o^`dbS{7s&jGjMKkxYe2iNHDNKr`(AQVw~6wBx1H;XbA_#w0^(H0>) zBh^tQAsL>5;wT0X2yNcy#oVBw;PpQf4f*Q1rcYmdOo3SPl1) zxJ&EXl0D^RyK79hhbA(UL~1T;t%+o}OT3x6cr)9@t4i2IYR{NAkY@!B-hwr+xIYiY zIbUdLF*!AqDtpxE&A>#NIwL9i2N5lN9}NHO^M-r&gc8p~mi0QG$R+h5;NbK{-3*Zs zhCR()#0;>xLknsa!R zyq40ib4(aT4iIvIsg>Y8s11fIu1c{y&`ChT)S8V1GsX}}k+!$r4Dm#AEo zK^z}ODmuqba35L!O?pzK?lMDS1m4%}A>JSEox2+-ZWG%GZ)7FYqk~p)KHrIX`e3%s z?6S$Ai=hMvu!79sAC?fKuho964yJNvQ=gx_r;_n`@8|BV)K#n~MlSZs z(ro7Z>UL-_nTO-y9_>B!A$I9XVSojC>5N?W>xzZSa=lg7j`g=|;%nqQ_BZ~}2CEx( z8*sEJ@50_i$K1)J!J}{n)vceZ!RwgCNn@(qiQdyV6Vr-XkC-}Q#X}t%a-y4I(sSSP z>215BGAQNoFbe5A=TN=x`+D}HHt>w@3 zmV@MJlwx$9tFhTtVwA&ymmIVvv$e!>KPQ{~PF$|@6o1etR#iD2wet;oROj85@O z27Ib_34yed-k372Ui1>_UJleb^;)}TCwcWZsp3#n*UAJ_n+2fDzWE7qlZ`;W?gecFiO-kxwwOWf+{EXa<2D~`z3=eT~ZbU)9rmR>g&I~cdB;+*Cl2VzUr9lDS)Qftk zZVLI6uQS;l1Jk&q+$p$-R*yo&uCz(r-moQ^ev&)b!Jn9J@crEIsW+z2_e6k~!+to2 zJEXno2ZVYK4wD6I{T#+>hM1p}dA7+elX`o9xc+-bv$fQGKOm5NVu=0$=d~uG z<)duB|1C8W8*1V4k?Xs0Hvb$7Cy!{FS8$$Yoa$H{%+Pt?4$Q}5VA_(#rS9q;*%>YH zI~vR|SR=N3x0dOVJ8z}g_*pa*jlo>y+2by~OPKJp1`!!?AeC-PEmkmkxdN|e6QAIJ z266oK698M5_ZTtp59Lmn1*dbE%t6}2$}$Zzm(AQFlPi3;0wPeyM zc!0@4Z1G)|@{v?)ty=KrNw@jhU)@$jbo5oBls-48NbMf-&&Liv(oL@paPz_fH}5}R zmHc0h9bk_BxO9Kz&3PSxEZAT_-9n)tRqbq5;-SQ`N!!}#GtwJ(uDr8vSR9O=|7Zq> z)zUj6p+Ab)4Wy5dukT`mTHor%TrD^pd!}utIE)+~^DTS7AYXGu{;(j&5KZLH6d=B! zz!2ANwIFZj{Dw0ZZ9!81%{AHv8n>LBZV;Vh-`6HP+|@YJYtL0Gm)@^RE2)Q{AR`I1hv_UdhLnM0e)D3u4SufCL4<9@5Q z(rDM%j?Yd~8d|*C%N&PIy}+&!Ua#7=t_i1U?m*)n*Ujvum;5Y3VumY*P18UV9%1Bo z4_a1cLpbF$%F=@(g^XkwT!RrLoD-5tMw&2=>|4HksfY8}ZC<6K?OIh|yix!HM7_k? zSce=a422(hkFZ-T)IOh6xEtWH8EcDmDPSKvyXjpj43e5whO*k2!u(0;Nu9rJX;?^3 zz69OhCf1+iJjqYF2Wr*RdjNH5aF^xIjsp8g>U{6_3Du9)+z?9$WL+!W5*=!w3kHLO zqVzbgN6cwX)MXqPmZ76~S-a>LQ2CwJoLmK6;MeO=T1|sjP#%z%%QpvXTj|kR`Ag>M z&}O*Wf6_X`nzhu9Sf`2kWR8tgMC$dTG*dZu!a8HGN`E=lD4MA2FJ1hIw+cb>p>e10 z9p-}sGv^(lTTe%|=nojm(iO^Ci;XxW!5h?Op9cX>lzGwn4*VbQNKCh=pcoUbqI=1g zzjmLX^zmf#I*XT1u<@fiZtG(b;}8ck&r+|EBzM>n1tVdHk9)*>ynlfE^VlZwKeCnq zN8cL8zfuGCU&i(?@8?5B9AVs^798+*Z#q5!6#!K#lkcmbt0@I&;sceKAtA8~)Qw`O zSLy3QouOYd4e$Io4WLUI!-%kXK$&FYZM5|`B-pHVciueerS)gFGXyP@Iya;*n-Ew# zpI`HN-^1vFs}L-;&o_w?%|s@vO_vju9tWM2zA7Rr4lbu{rvci)8sD{x5J1^!blhR{ zzTIJ)T_l~bEBIgtp~`5$F+jUtDH1v_Ri;V>DIzV(R#+9HO}FEew{Zfj{LxKNQZ1I3 zEY896+b>a`&b{R5FdS%@0QC2!mh&8rbzBP9OWrg&Hpexqd8AMP(pEe?l*&%{uTl!AHp;AlIZ+3vxitY zY2RY>(HA&mtoSq*%3>BV`++x2DG^!B3xwpjYtEHOWDb`aMRn6}4X?jKUUOtTK5*fU z>A>EZ_7xx2do*H|RCh~YdVG!)bAcZZpjRK2j=02^HeymNqM_N=!cW%_!HPv?U(Pvd8 zrDm9A;ZV#Xa% za`R4>o4C!`-AxIw@Pt0);yfF2%o9QG;fPko)Fa#98)!t-2F5cjX73;hNP$!cj{r`D zb;MlRg^?^U30&~$Vy%YW?@Pveyzx%7dqeg!HxT{A}~m=(Y&Ae=zZhWg3T7J|rSLpNDHcp;VB z>*U@pbdsY;jP)Jw8*X*uqei3p;-k{z8MR^LeG1^|Jgs$(jUA6#lswQA1 zMFbWn`}0*{)dyNw7vfgs6ywMQt08k12lNB6ZsJHAtD#zFKVlUP6z{o(;QSJf<0>~+ zvui`^BlxlD;^k^18}p*^NFWr#iC0Sh#iuvk#5EM$!r9AGdYz-EhBOIPNyP`H;Fyyf7gv-=epYd$y|SeV)~IgBWN zT9tUtPAie3BgZw6A@l3!I!ezkXLp8e$x+f_6rcydk#FljaB4Wle4Cfzu_EzYvUcI* zQA-|YAUeG#%rkrM!TrPGJY9e{*10ES8S9Nq0q}G#({JVl+&I`eK(P}A#r=NbF>@Ja zDvIi9eS*~2GDy?l8r%oz!FkaEW06EdbQ=iqT<|ByohMu5Kqe22XjuY6zR-OzXWA&) zz%%5dYalV!_g7+UOA@f@x2@W?ga3rKn~vz~9rViC0F141+s4ff=ELuAXCj%WzZ`|^ zH5;G`;0C`2ZgAFr0}1|id&m9$WS*F|)I+v6?o}O4wr5*Pr=0*ZguTh-QK7pE|0xy-9kJ#9o#&W_jw` zacHz8MCBx~F%DW{{-E{WfYqX65^Y zz1_7|WO89cQ#767j4E3^X>o7w8l+%9vKQJa8ylA@y2(2|Wf24mc)@Lgj4*9YL}b1$ zF$Y z6ka>p<0LFX4e2F_SDp^CrQW{!JYj$T0xS3MjJIXj??r65JrcfPUWeBFkM;d}W%So< z%OA^zulnbVhpKBgX@syAKQS(Pq+VQv+UId8h0rg&CwPNo@sf9`^J`=c{l>Z#{2jZW zyh5jKVANTj9Xil`djq7=iscFfzG~rmaTi2h;=xbiwE1Q%_5$tO8?U!sKArD^2Asnl zv;5zOP#+pLyk;dHNS6h6~dm@h9*g3IkBVKcAfZj0hZT z^$d)D)s!>*_AQhs{ugKW$4#7W%qac_X+s~E_rkA~@|g?Z5L3xcce1sUDT1lq1)P+* zfI}d=FGmV!<{4N)A&-j?&2sdJZvVvR3gl~fcu^i44r{%V>r48whLT+W17gkV1qNLP z?sIVbo_M8~p^>$0s4Cb{r7QB5x2xpk3NsSxUQ%#`HMsa8iAtIKJun^m&gm`NA6v70 z7pGZiKmkiVkRcWv2e*X;`Bq19S_m0y`g>+^@kcO??e2v!}p6aQvqntaAoe`x8-5n)bK_SV- z2NX;;4PVT}os)7XK74hYVwGBvT7P9X{E^pW4-{D1fqe54h1g2`4L7>%zC8Sow0Bk1mq{%WMGuzsfujMa0)TW)m#W%n> ziD3P!;@;mz>MuBR8R!p1?P-aDsP<=uG%u>E(r?37n5R+55h&O+3D5odo}xs(K^#<` zc#u2$+MjLY6gT|=Yb} zTM%kOlrO$mhw~`VWr<)ZzFsF}t#$1jB4dlJb8R0|UGNwhVq4(e+?r>HI+gOxeJg6) z|J5Bwy+8zpvEU%0x~PD3h`f-h4)04%Ue9;qs(f=anilCPx4PJ@FM0)TbqWgm997n6 z)YJ0QlSU;{G+V+I^+vKNom)fTG2Agzuj@6bwoRS12IABP40yVbFQnUfA!$g+I(%=q0xkA?gNCF zz|ox&s%k2*Xm*q{`y+eg%Ytqa1oe8BU`yf;SXl}cvuBDWxazc-6{+4bMS?PT7y=TJ!eS!+3P{2~)E+Q1$Gi9MtfS zmB1S=pt#!*m7x!QuOFn1JuwMf)f5#h2^s$IV|=cJ!z$P&L-!-ssfx({eU*|drZkwO zf`_k4A#>SmY-%xI8fvXZQp3(Pg&TjxtPvW##7QxeYup`*$J4Um8oB=xSAE93^Xy)3 zH|vkw>Y7_3DoOPv)}lLz;4r<>JrD5;>V8h+_H4IF#dYD1FCU7wc0W5DB0x4;pC}Ug z(x9SQzN3do)g=;QhU9|r2>k44500TrVv9w_hGw1Spt#w+*1eV6J!B0I_d{}pmzOlr zE8xR-!RERxL!%VKRRjxizly+`xsWoa`x{87nQ=BU<73tQVnwvgJrQp8AY^h#z>r>np>E#!jjc=n{mqy)c%H;*|<%Z?l zh-ksR3lG6dQSDHr1uxvZS~2@0=~^_Jktp#|+SjFh)0OQ*G-JH*TfrY|`4h=?O=me- z^4@#BRzKvk)1L^$&Rj5iUO=@y4QEAaeKBc6P`R=~M!JGwf1nckNlJutAFu;A{icn> z*xmIVmhmSa|NWquQz-YVZ(QfnvLpfd#5^Zl`ci?7Lb4a{18*EfQsgn3mw=S`n;`WA`3)Q#Ab`%YjKnjp%NgTXm`2e+t8h3>xpk?8rbW9+bMbRjS8FO zY9McOFwg%i25ig1MW@w6YnU266_&ms(|!xbev3EbUdrb~mo(UUZOR8~H@en?kp3jT zD5jo(vvaU5m<42dZ*mj#P+G`DEqRV}QTr{g3=gta?%;Wv0yUPf86YZb{iyCT~?io05X$mw~eg<+0Hxc$OW@-R?c> z$`;$7mXi1G0cZGroJ8{k?E3Ae;)$o$Zv!_eJnO|aK5bqgxTn9wI|>q@n@j_MH3jNl ziR}6FO)YI?rEg?UB5dts_4}QzeD~}je~jlnQb&*%LIn@0HrI$7W>XRDM`uWm>k)wdgAQq2v6hHG4%6n7d}Du`+~ z_XdD6WgOQc?Ew|dkyT}zhz6ovK`ACp#{dIc2Wj?FJ&htDX!L^7ubWuBu_hJD-|qux z$3nj7RUjcX5|)Z$7eGxp#c1I0=kGd7;)__#PdZcmENwXYoY8%WTn3ZSC^Tl!3_tuQ?- z{J8Qw;iG^H?C5LO*ZQ$Mfj);3EBlh|RYQ3F6^DxOFHk$sCfJ9;dtqj6!$2$RE#Nmnn$#ZI?V<%rI2FMTu zb>C8NlBZvQP16N?> zf@X#}{0dg7=w_hl3%1d_zi|FOG02#_z=yLAy!8J0ApL*%;rt1ff*`9~ zr-`N|tELO{;ml{$QDUZ2Y0LmXfT&F&JwQtce3?|k(6ZgY`gb$D$@zAe8j0#<3-!i<)cA5JyfWHac03l2t4b<^N3esl0U59po>CPV}3?!;YY`?R1JA(uIJuxinNBUKDI6Eb}!}Z zN%*2;Lp7$OO~29mz=P$l$(dbiHM}!}bFOs1AK^UuT1yA20;=?m7#}qC^dS@4bxVS6 zAr~Ss2b+|}vJPU>xen!L6JbXvmIp;QwIP|tv7a{Eun#rN7JeKhDr`NsS zK}sLcQ?8@azY3>VGf+!wZO&qa50yqz@xTh<&ma83Ymk~^ z3F%$uF2O1+g<}X7C&<9Qr4vI&xg14p==2Y!BK#;6o zmthBqFGWkQiBUH{0q%0jsVK*iGz5QWR$}17VseAY$P&->)_zT7`U}lAO=PlSh|=s{ zZRu6)(s#DR0sIS6E7M>L-BBPeaarwCDs%U*#hgl9Cq-@ukNA**zJEAo?ErkogD zMGNU=sN9kS;?8q@olLr_v6YKf>26lBi#qXE6=TV#A6kRhvCJg}%#%x{!gz>zV{-aE zg8Ip@=HN;%UebQTvMviz>4!5AD~zJoRkMym2kPj%WoJ*tYV81^xotft+1JLYDs$$tE+;M^HfprY5kXM zXVNy!Eep*KLA)3j;C0TPhy?8r`l;Z|l(lf{BmR)F>*Oh>@M}d*iA3X_NC6ld-uC3> z?(><4_w2cRT*}lKWZk)E*l9a1uoBI~IaC;~hw;chpzjf|X-p}P6$p-w>kx~&WF4FJ z5m=3*cE~)A2}xl%jS34g8KNDQj;)@s0jpmn;*A{Y45d{Qgu_cq^01bQ4OACq1Q^2} z18Kb{Av;dILz4Au`Ch4F1>+I3C>KG2VIui_gVZH|ktNSk4HmX##-((hR8xK?esTIL zK7*}c-6H!+Qzr&8wWSu5GhXNoLMW|{+?}I|w+5zX|DmUBmU-)F&V>qs6UUKTgIv1t z^$V-+yAjTC*0-$P%boJ)r~b!t7W#ezkjnLf(hgN@Ds4_GniPibHOMfu=+xU!?#t{R zO9Hf)p@mZV0fUdJS*1LdBB7$>p~@!CoFdoBvR1!{O^G)V-L78#Q!C7@NZAp->??rpVi_LC9UT>gQo*rLzgP(M!uwqa?fwB zsw7yP0h^T7?0Yo>b0-@UHA?-ESJa~Ls!jp$f(;u1v_3qwi7IrfkUM%Ez+ZFB<8A`v zumc-=FS!T#+Z4cN%8S=T@Y&>PR?w}t83MT|9nn}o9I}lT4km9gCllHagLK3B=g+v2 znDOvIM20Ro$#?fOY`904VX4E-<(VQw7oXDF?iS`yx<{Qjfk-gD2G1VMk70U0UiYoo z8zeUnk;Kv;(ie6kVZ-m{F6Sf)Ph53gy-zzjix7NgG*MGKvE@s1eVVc6e3i2s$&3lB z)EbW=vQY8rMk$@;8{5xs5M^2>c?7e~7{i+Nd$K{8@lR+Wgm*ul7yHD&&diZ$RGP$O z)%TV3B8tG%8H?v)PspWs3=lxX|ETPFT4B2gQPL8`b5>rMi0be}qXIg(z>Daa_ePb` zEU^34W^9oXFuy!ypo7N8XrsS}|J47oRKl=NODGnY(?X2ND&v8*!^e9rLX*@IG&>_J z|F&Zd^=jL`O>Q?hf7d-4Q-m>W_q_BK<^_f7YI!2e=kdZch@RHS7HpUY8D}RFT_O^d zjPZSv7G@T81Z>PLv+GwB>R{&tZF|sSIVZ3C-8scp;ln?e8DfW2PLsWlwT<7xt(vJz z6w14n^U4_!LqX(vFLK+}fy~|YO_lU&?k(NN9c5WJ(yRoOF-i7FI0LRrr$K{JYOAE5 z?+p2H?Mg{fnABS1zIoblYYY2sF_xfeit;8ChofqCx6A%{OvxfSY?Xj9RRf*`GXI-n zD(+}x^>?%S%MLaXk6?vS5=1~wWIko39FG_W5hl;j`2`j+s(WVkFx#>M;I>ufy>pt$ zc`?%;gvrP{x#me}U?qHpjEz4YacnO&IUn8sc=-9c6*t~q%plhXr?$_IDiYZm!xq~4 z95Y~8ek-3o%NM&KeKR!Nd#wo9@ip# zP;Mc_8lJY4Ep?7HlT1W744d(gWOqXPvBxzlb!RM@^cWJ5@%~BivR%vt9ZY904_Ql) zPj0hh-?EZ;{avyeG<29|$ms{hX1oAKPj=Pe!DJqOt+a1DbgkksoUs zU2&hg3`1RK+(SAmnxrf|dh((I7X-rH!c0q@Wa()HK~mduPtyB}Vw2egtWKFdAPb(3 zRCJss>TN}q^X{?f; z+9VCpM3Ww4QDC3E#LD2?_lW!WcgfkI>}==Zjn-VOa$dMUG`oa_=;5avy}vZvY2C7g za=aX!K~|^)@8ToT2g8Qo%%0Tj1pN6Je_;pkrHe4tgF8-Jmy+ zG`p&P@Zv?zm=Tb~h~Qt#^=_?AVGgCJC??*&{`35TuG?D>0MwHPpdN+)FXs0jyl*vR zQRLq|A~YSKhrA+!<%iU$qUpCsvJuXn^b5@)e+zT!n-XvE;rrs}#ekEFMiN~T?DbF> zI^H{zFo$X!a5dyNA7hwIXic_~XE`d|y_-E=()%R60(bfG3M~?qJN`nP_)D}k$!Wf3 z8YQOUsg(5uWp|FSNE?J;gSMKQcJH9{CVD(vQqsbGkrZoBt0QR3a>`!Qx-N8K;SCsU zCnnK2FJJP|M$T7X!i}>`iXhraQ>7YeJrn68_I5qYe$~V8-7~Ic%BC7<738&>rst(r zYMUul@_ndy|AV!+ii&gH)^$k&!3viY?(Xgug1dX+?(Pt*aJS$=6P)1g?jGFT32xz3 z#v1eNHOFbYwKLb=H+50hUzfl4w?FUCJqq_gKGL%$Nyz7Ju&sl$(n5?<-P*wf{G=4CZ|#Vj($sP1lb??op#(q4L3|jm7{1*OEM{4>TC=bHpAYS21fQi0!OY znI%n9SQZN8D7`rh72ydo;zt%k*KgjVqswjkxb`rHOZAlQ<{G^G^1(c9L>J>K0*+%j zV$!sRZ4o}^PqHv93W5V>+&Dz7>Gzyk=vQ7EXPbU}p;`X;=sy(4+oS>G3BJZbHw6k= zr$Ii3i>IOYdQ)rs1iqWsZdVNdpi=E2vIC_~4dO|*3Pi&$e(8BtdJCAww=2@Z?p4zj zMzq)&vW!sQT1LJ|ouqk6ztt-^TuF5&35MhF&LnS;Wc|o0UVBKUX@!Thj^=TWvsT1$ zQtY>ZTt1bKgD#04J!n?3oo9{L#mneN=;WB{AT6*8SQm?_PVk4JnETllG#N@ZaM!vm zz=2_Ly&Tw(sQINKkrD5Jpf~PZS-Dt+ru4#`T7u+75K8LCw*=Vl`|1OBN>Xt8aHM=d z_f{rAPkV{9ivX8KMkLk}LCOqvO2Gh~oey>6LkQkwprA196s8)e(B3_*y`RIxQ2@US zY3T;_v~YE->KW^f6g=MX@6k7ZZ=YuisUC}v>Y?_3G5Y@PBe`4+5`d78_x_0Qnk0M zp-q`rzWbSJ&f_OP^>YN@HHLpgR~jvXYg*j;v%fg;)4xC5?WG>P^_Om!Wn zQI-qy>59Smw?Xw=+|_E;!TVCNkiBU6{j{0nH8Ftc#!0jl8%&Ye{6pPxuta|}c~yNC zRZeL&L42T|R+&57a7k|DKs72x<4V#H(O7L^nkf5c8rGb7Km#Fsj%IT@_{f`u-c9@Dtx(e6+J?NfrnHmLE~-Va)s*Ph|h z8^AkCc4#n9GTigGqfxq(8@MK#oI7ZeYnJyPAt%+xhH&Ivak5e9s%$J0e2V5*-AZXw z$A}gDnfF!A*l9;RV_=Y^=vn!3l%eq(*jM@qVknTlIcW6o$g-3nJ$weFwe9vf#^!oJ z3jt7KaSMlS8)#s$`n)>ViJ>Vh9@pW(-2pA>5vTDpdK&S=laI4dE5>yOU%tz9?C`dq z+(#(7iOC6&KYor`K`IR;hg}TX0QUaYTXe?=J=TU<@KnP_iRT;*n%ORG2f7NQ<1piY zTSX_WeJj2mwA+9dzJZu$FNNC09UU(GfJ9|6>m@9^K|Ur$dpDDdmX+;&V=720?zX_W zHATQzHZgwp*_F}+E3D5=>%mXGgBhlz{)G5Kn6J{d71v0b__U{LLM1-=FF-^Z%(XJRjUxY$4Sp3=RrP?*HEV{(Eq$ zuA?%e2q`QO$PQWo=&~YOyOkVn?KnhvL~J>)o)pAKwHr3aZkVu4f#9fh`}Q~u^`zfgcHv8y5EmH`85`eyX@jlxRu(u0Hbt=W7Efz@Ul}J3 zHk6_8HYe9FPO0wmc~Iv}HK(qtE#Wew&$q;tvmZu;ibA)Ci>>{Xd-kwoG?@-?h@UcH z-pS8r&K^;ASniijK9cs28gJ#5t0bn+`M0K8WN| zQC+D^4~&sZ5TGG?afIH;wI82$CWnok>SBGpLk5-wH^zf+`SOm*1FYDL*mvYHG}Ra3Q|H3!^xYH7UU z!)SGFdRGrQCD6p$52?c9HykYM5$M_Q3Ni<-fA80}@dP8;s)1`>-?^tNHRNd~8cUNw zF+flHL0O;+TcKtrdDmm->!D@jaYuUSgd$49shtAjd+s) z1?*H`N|QDL-9Eb+zRrSRQAA_akyP1AapFwE*WB`P?BGOhFH_qsjSi1+2eR&Y$Z8p zCk~rgkgp|DvgxC)7u#MCDa}%Ph^%_o5_UUj#npC)x++tfb4@*Y{_l0GZecxU6H>Rv zAazUp|3X~g_Z};v{U0#)V8C=kbT}*YUq(xIi(=Kq^Tv3nm3Geji*m_>vw0 z$qSfo3+!nO42N5~(CsP+q=8|=9A&1)%S*x-=N7eDtqx9PZ8}CsC22ehPY6scNZ13L z^Qpnq07&$6c0hIXz(=-vl}XPuJfdI_O&U)ZgT@59#+FWj2qgi`X4}{)e9!XUp5USj zRVb_X^XFsA283p&1TVWRkixILrAbcF3}1D+X8Pe6=0>Vt05tt1EJ6y^TFCkZyig*> zD-3$Yv-TKgj#Qt@Ft?DB*6&KnqT2Q-vIrmZO?$+iNSn5uUvmesV z&Zf*)Xa3N`4`QK@(-^xe$?}+sD6B44bJFe`YpH{(bw)jM)KOgw0b*BuH=qGyrr?PC zy!*I%qvWojv|1wbnBGzoKU6fY&N*mB0fyWj;;vMe|DX{aY^TwTG$g3RInxIv0PVI? za=Kv{(gHz4hu>%p##9Ur%IqnEmf&2!nJ{Y4l|ff>$amp^7p?EjHCybik1pRcmx1t( zO#CS;1KInbz_lc)s_F_iZ)P!|)ZTti&h$d~3Yt%>V0%*2@oCx+7Wy1UC%jhxy%##$hZhytF)3D+jMSF zKO{MS%u>q-S?s*~(O=%W@|p&&vx-TsmN8vMPkBC-(=|l>c#ZKXN<25K9n_S6jSw8D z%D5$bjeIt5L39bYlca5Wa(RmN{_Mvae2MzbTNR;`OUvo0&4tF-k(3V0Kd_F=^-8s8GDU5t>X zn+~2y$F0rQZl0Pn9)INQ(${Xbwc1kh-Gj@|j4ag#sZ)h)6r5$Vu=H<)Kd_WsKLvQ_ zNlL#&6()WKl3u~o*d({XEJ+S;C@wK3aAY&+7}Zb~+h4ZQ#5=i-(S*rr(T2-`&=`MU z{8H7U%r%e~L%0IaeO#>F{PK{~6N%2j2g(O4zu4K|SqVOpLa5Y*L7E@BK1e$gp8Vl-fu z!9X)|OTQHtu+Kzg)<7PE(*<_K!XO zZ#K!w#td(__UnOO7AeoB^Lt{O%m7Lz==YQe9qW6;DZ7D&!u9G9$Y99d&jz!Zt|2Qr@4A*?FJaF6|BcQ59V9 zbFa2Z7Cr=9?(=;N$CH4gN+Jq#+2G0x4f74L8AE$SNrV=}=rv9tm_()G2}Gq3jLvqz zY^y!WhsGd(>iLzy!hms)^6zD**^oYY5E3zRkci>=pGC}nMM~DcK8a@Sm`2J21M^53 zmmZY7}Qn;um`4s5`sWXDWb=ha7el|T}Y6ePQi}6gJ{ipUC z^F3Mr*N5NlI@#wj4n!$qY!Xg-$crwhV+N$YPi}pYH+-)^K1vzatpe|io-O6UxCsLh zjk*qOg4U*ebDq%ma0&wLpeugHRSA#3Zx~r2^NAtB<^@cBRoVt@i~TIM@{;2cbSk&g zF|FWhS0|mAZ=en$_EjTnr8{>dTbM8R?FN`u_X)fR|D<0nwlb95d0_DDNsF{xv;`-5 zbJ8_+TN83!f7Sq^8-DM7_eei;`EHfvUcF`-Uirno{8Frkm4MBoZ!!^0d#Y83#KC{c z<$kaI{+gl927WQ2CM*y7{EcahhH@KVr37 zc`xUBgAeMbYfZTj??+F;DeA^2T|x?XQwV<*Lr{09B3iH`M!`~D#n(9Cpuw+ zPq3hg@j3|ytjpE7Ewe`P=s^p_ZkAvh#WOnjQSe@+tZdYvI2z05o5*()q~nKz?*qot;rk}CZl1sHXV4J zW$c@CD7;j0Ho|009e3<7qJ0JQ5;$v_f1^K>6#-m-sBb$OO?E#`KX#xR>^tBHl(n~D zdJ*p%owUY}jJQGid?FXcamw(^@_?GQm9O?`0&hT1yO$-vyS8+aH#RKH@Cb2%>G~U) z#KD6D+$}uI(nEyB<1m_$7t5ni<-blb z@xHm?$u0+GNCb0loqtqcMbV!O8~^SJ6601 zdH@jgTv{tSVTZay`@)0<%8dA8j0TS0Q=Mp&4RM;Zdohc$qB=wb7ur#Wqz<$zdauM% zPajaeiM?$?;1GmYkB|Tyo13uZRyC@E3YBZ_u6h+SAFuipVa9^q4--gkz#WB7V=0t<;515_^kq z8a*~)K-8>n*!mEB^b-4pkCalePj^VO$h{^?S2$~a1d~mwK}1smuQ5!fHr5)L1j|y9 zxv^{tUg?fF+y941gAvJhtR5m7MTQ_gg#Ux=`rn?*)PSM>RM4cTJ)!@) zP14aW$Ewn7hsG1m6?;CThm_omMqFjSytE9@F6}Bdh4U zBjC8i8Y#L<;OxVy=0iZOY27+Btz(n6m#dy5H!h`}I29(LPW3gpho)^+Lv_+aqt2^N z9Qmr8b<&{HMzK`FBo|vHcYJSmkxF{tJW$kWm{Iv9JJay8?^HRPkL#vY%3Zxic|&_h zm)09>+hmMnb~3RDv#L8sAWDu~QR3Fj%h^zPevn?QgSQm151bdz zS6)@UZpLE{HbP3xwJuWL2oOa$XSR{9ZumY@)T0V6AH$`z$4u1a`lN5ZRfV}`N=-O8 zxdql-nXzNo$L*^+eNkT_Q_FBTmyb+$$X`;qQukcWkKgwyR?_bNN+U!}!MYOv%}S}q ztaLG@3A7{MlfTV;O=!YW_VYq#Hm;6XNlbN0w_~EVE<|_I`?bOnK6T0M%z|IE5IG#X z&Yw}U$(`v#ZJypVwq=05M_<+RYHkPiL8U*3yUr{r<9g(l-g0omk8)Cw#OaqIWsg|5 zP)m@Thsd2r{N|aXugUBI}7)SeUrx3Opsct`Tc#zVOS3)Z$Hw=Ma9&H zS*W_DxOaw8luC_PS51}x_`229(R_GTFLfs9^1YWAb8xt5cSPGM=6zYm)U6nz9_ok) z!udBxJTF{NOl9h#DOg&M!+V|??r>K$&QA-NU8sgK!F&*QaMJV_D6H&W%pQwvxqPfP zuLZ4P`^!KH364I4Q=%jw;lg@n3aPt93}LUqGpVaQU4mQ$3IN5 zO-C=P?#Kwb%+O|_ndgmdFCNdC`=#nsMMxUNnDdOLYFwj-c_Hyxb;S!MS8mMer?a+= zRKF;SyWCi#b5xIp3WmSpI!|#ikC5$k?exiz?s|A$u~vu8FyWkP;rVYO=_4PY2#OcU z@As2Z8Ja>C<=^bJY9HLa{b8PP;BWDkmM*9ggr)_w3uxRXv1(t!wci<*E0y$>)PeKs z(Brl7si=#Bsy*OPX6h2%nk2p_ZA6hA3LTS;JH)jM(7eMzQzVk#WY;4q^jCU`iuIxY zG(Oq(3EC4B!tT2h{?#Gu&xH~nlu+sIXBL))i75?fM5xU)B4f!i!4d_Iy#IB3h6=+-VhanfM8kLUgr(4R*xn`r@Cn$eyM$yPVYAuk294ZfBpzzW}Q(LzrpxI zkn1jlzGhK!ZEz?U87v)bl>!&Gl(6Y5aC!w22;o%>HY4`!7&7-*oI6Ycc|{KK*A z)~%>`;Qa62zPP0y1-n9&XxASTgRkxw5LAa(t_j?G6|)aHAK;PE3XjJ-Im8wbF!iIF zD`A_hskdSRTX0oZRI0|S*bslb70u^eRjeu|35CUF+#v0_dW{E&-g*>5cmEM0Y~7&N zix86c9-RvS>*ZI`uBmc{l>{V(Whc2_1x3NhG#e9vFg?l=_Y@M3MhCF;SfLFeBVQE` z!TGxV*)FBeme0WZp)s`h^YwHp2jFoS67{t>jD8@kT*!N{=aRt3DD}=~@2V{lBNiW# zX9j{^2XMctMVV26xa~<8J+`HKaqGCeu!|Q~5YrPHe79k!WWWDL72J3vvy~-!otV-I zbqO#!qMD2JL@TrBVN%{zpo_%<*=A@9wqT6_(M~)tQL}${vK>7}BQBRmqLjOWBuiN; zpPSL};U9t-6@&nUF33|Qf_xl({6BoEf6o(C|1!_}T|Wzg%;RVg!onOZ=saNI-b4Ef z=LQrouuwqf4Bj>uQ~Ye%JB#?Id0x39>dhuAUklqh7vJ5OAH;+f@iUGI>6g#A{U%8# zFVuv@IO4Psp^#qyE*n8+39-q~cYS%G!HX-#urTPp(# zxr1I8*gx4h;1{h|{`ZE8Jok14(e=fSA!c8WUbUIg{RZIt>o=&n!qo@=&uOMmJ?SK& zB85J46B-IvYH5|65mt2iZQoH|Y^&{%Kfp8XyknECk8I!I!76RdJc>gVs@a{;a!#xB zl;Q@64mpSaMk|bUvFZZN=_VqAMT+A-swm?uKOo(x{dx;|tNIo6IiE|ED$xffx8Z(r zqV!QVNIRXR@ZKI7mDTE%FQ!!OShL;T;lfSL1Obb`hPIRNU|o-c1FydtLJ@moG^D%5 z`QQW;amluHv@Qd4#enY2(knRkhDYxfxOy=HFkIRM-+PCmp89-Zc07g74gLkc z3Dr*O6m{S&$r2;wRV~;nQ2i!~Ox_Ksr+P&1C5m=ERg!Z+HAuDf4}{&4*L>LjX)d?4 z``_epg&9aLKU*8FCpF$ej0oc`%=ic+C;J)b3Jx}@>W%MJ}qG%#3XoeSRdz^aGscPK5ICK%-lS}2DHe3d>N3Vr)kXUAxQew80pO;Yp4}a z^mUY(qR%jK86rbotut9=f2tVxdL~J;QZgo>FnOD-etglO+t6fl?3zy|>tCbmyiz~z zy~2#D?8{1Oh+&BUYt^X+YV<@hKmmx2!SWEfjrUmS9 z*JL;&^<(eLik;I>gxe{@X%^mq!v=5W9hy*r|H|dE8TV%PwJK;J_fxM4NG_NAlgs0P zDZl$6`?6|CE~h}Nb%Nw_6nX^J`lds^vp7TVyyYZPe9~c#%y#PtTRKG_&a-yhgNnSs zCj`RpgGORqv_13Wy$CMJM=o+*%@L%8#f^cb0Hz5t9B}uLG<-1LZ7+8p9?6NIXB=vz z|E<9Sx3k1#jt^sKH1Qj>+{#yPFaXiGQy&@;+*E&28gt#(iK1zRY!9C*f;WRS&=kdg zs9soe&vG%7K}Na$%Av5qJdI|pco2=yj;W@NO$#ityn}|OHZU&CeL$(O@$ zSnk7H-I!_$eD#(Bx0!zZnG6SAW`z4EUAiG*n3Darm|k;V_ukKRw^w*Nefl;5Wp>FO z+ zgxrceuRs3#ria{53oUWFvQS&!ZSJ78VwoQNJ*<_vs?Xj4wjnd46?tF-U(}`_5Pkx# zfp%Bh^3-#;IPeLVaD${LY+tfNj%&a+QbGy!PP8izEb%puO2Ix7%s)<}DKE|QgN3or zM$7CQW{o!uK-AG#HgyEtWOxe4XGHC0yz*gM&QHl9}sf_?&=?^CvOK| zIQtyxN%C&1POiLG%71jj8&rR~2q)Cj4~GTh{}8aU6)J!1Vk%=o5Rh!idUDaBccFS!Em&VXtdOId7>Ci*RopAcpgap|Kz_b9iKYExz?iRl| zHRx+uFy@x^p1^{}&aYz8>o#5}?@0DBA7TIBqa@RwyJWMN?ZnQXPg*#K#Jq}V-eP=W zk!BG?=ZV-pAX|JpUc?5>n_?b|RYCqP^pC657vnF@zK~b#19{c|2`KD;4H*8O-a;<^ zXBANe+`H;qk}9#VFwuS-kS>vuzKy*95nxa)Jc=Hquv70{lX7i5gG~?7)>E(?1YM5x z5}9V&nZD72n=Z&ogS_N4`SG?6KmR9WgSSl82i*)XJv`M7&cH4L7;WVI#?lQCECMjm zQ795QYQ%$hI~Sk_?t*%MQ@0=fb?1T^GdBwUy=S;iJkiOpM{k_o=4HC6Eo?1UT5x?T z7;rjer^gIPefes3!P~HgNajYM;=sgCi`nFp#To$^ZrxqTCSYK$#p+)}uieprU(%}= z_|bftPO7)2> z8}2f2^wy(NV+7TgluOkd z7-RL8GqN)GhM-OORepTl2Z)-ZeC*@6{x+5~D4ot_G-JVOk8hiuOZDL0vk4m0WNQe< z%F6h5qO+pq5=_VcR_?{$F<`>rZ)wb64wxzg;fH8qkJne$_HMC<*_*nc@q=debAk3C+Ap zdT&tLvF?zi5e~WTr>>e-JV_wJH}+NG4yjdJH>ZOvvR5tkhl~#ZpAPu=jMBX4c8DkH zGv^LKJmOM)S|ZruW9{b)%4xEAxLgasZ70&8i7bd ztcwa;K+G5*DH+dGP}1voYLi%gvTAYq`9UKSDgfFYf-swhC&wiJU-)E51JMq(An`56 zHq+g)tFMo@q|s!|^n-?8Ee_!T`~<6h#*c|_{Mm3Fl8KTI$q%eqlzwOrVw}See6rv7 zr)t!E!C0~JNqqdPpZt=IxUd2v)20i+cD093JFI37d$WL+EUX=7F6HPJZ+{3m`7qwV z0#JayNgo}|v!V1cZC-eQpJzvW$s@iD69wodKOM|_ew>CYz+}WSR;aEQxzd2|f8D7_ zbd(k@rmx+-cjR%$u+)cy!gm2&dZq1gu!V!5657k?7a?IF7qahr{ zLh+*|)a(l)Mew5`EUVv{X*IY2QB%lj37Y^iMyi?ejnQU|aH-Nw9b#+YJ*7o?6$%m_ zRKQl|=W(~D`Gh&95aElf94toux@NBb@+|Af#l$a_qFRfqJv zI0!oVcwC~&J!s;4`{U=O)jQ26X$U&G4&4!aCZD$WG3bPI7vE^{Q_X1oflYkQ&+l9G ziwNTkTgSVIG=X$3I2#~&ndnf z|K8T3iTmE&^PZ_WC1jp@f&u|1-)yq2oQR=6_^otXAy{vD=>$)RX?`#i4VFVY3#+2& z{y=JTXNam_bfJcz&vu>hJQZ=+*sQe!(5Tt=99f&YE&;7KUgYBX0vKdnu%P=GL&T0q$m-JZSx+G zyU=TTpi_d?bRO5O2NsaJMRr{@iW{z~%~aZRWEmn5y>_KUklDloD~p1Wxq5dh+{^`t zKJ*|X>s)54+IL^^5m*nQLY{v%>=IIh=YqTE6C9f5gY)ZGl5&^d7+@9F#E(MrK z;b=M6k5AM*7_yN|a!GajW+4xLIz3c#^@Kp6GGe%;bIs?Ok?wer?A&}J&1zey`nkpQ zcC>Ge!PgO%PTsj?e8}HmYgoLz=s!b-sbE)w51!-87NOlClzmQd-3^v2q1obZ`Y@#} z0RadgUe9rMd1HxSJ+#|T%%2uMYzDxYqS0E8cF7tOA_8VEGsNk& zc=@SWT3s3g%0tfN353Fa--jG!s*z`W&j^%He)sq@OcnpEnyHSG3jsdWIcfg^KB2hVj@@5ChgQ~8 z{;sHVR@QO;je1u*eKxeR6rNYE zBh!Z9o-Ape-Fn^AX~Fxw^kX=eXa~n{w6_=}?8RGsYi-PC6Gx|PekJN6KC`*Len_+! zts+R6z$Xz3#e3r}7&kGyOR>^Iay6RkDQ=mK`kD^GJ>~ypz6Ks;LfY^q*|ekIQaOL9 z{-9xD^w#&<<}-P!!z0nZk5XrJu!j{O-QN%-75)d^-+xPke|LXL_J6))`g8akR>g5_ z@>s<_F*Nho4nV`0$(lHJnHY?Qb!il=o|#F#(%X_OQ~j!ge9DAeW`z?Cdz>LS4-#7> z-d?YGkDv40-CqBGzPZ8s{8oKia!VY*24BsE@ujaExQE^t&BwAr5EKYOL~j9meBrg= zdEimVcW^q1JDl*(k{MR-nwU08f>fuD1CCvB#DnZI*hba#Dhm&7+kR(T6D+efp51Fl z^XshVg`ta{Xs!NPw2w0fJJ;ocgNuNUZGw6Eg@g!k z`CLq`)H=^n>vy?ia0y5>x=AnOV>qq*F>=hF)B)UwtGYig8GhSy=uXVS#@C{7ZL zPMTyKOo}Q!p!f*4yW^!YCxm$BO601<-pev-4r^u|V9r~vY$w^>t1k)|!bb6`RMW6` zh$TrBNCwI)J&sn@*)Pwhdl-JfChC~CPKh|q`r1B}{f0pO?m-R%L6KuvYzx@`XVWgI z|1%4GAF2*Mn_Dcawr#nRsHlfAL4t*PDr+tU^PJJGn-M3#`vE#dM-Q-I{HGw&#OHM(HPGkGCZaG z>|1Ny7=wpxr`@O~iqkN*9TQ@Ucn3rd45JFqzn zo{Euot7d+SVkB4K!hyY*{)=gh@rP;b1z{S~K$yng3~2m^t7@o4cVpEkVI@3?`-@^@ z4A1bQWdxXKA8BU-xRIkb_O|F1Mn7P?*{lrEieA|l0_)8&6|f3K9XUxX%WIKfTQ~^~ zCO$@P@@SpN)4Ta=o!~~UuDCPNyD@3WItO+6(G*UKp~W+ojY)U>nh+C?tYBgvHOQhl zg)Gm@34>W>^_i1&PF0pV!khVJsBb*{^r*a8X0)v!U7Tdj`&kC?KMdOB0Um+ckh4+F^cHKyoHaUOkq zAkxdXy@=%GPY-Oju~3P0bFPz_JbJ;RVtHA2Q;RsB8I{AG7vi7M$D3pS7fL6IQ+ zDqV#d7is2foS`LokvZw~cF51vsM45|TD~UhoV0v-qi5~zkx>42u0kFjF zvfu3jE+5CEw0)o4YIWhLFc5&SM!xWU$ms*GiIPHFW2WtUv0(C?Q{ljBjj4A82^tb*38B%Xku?SzR5#gG&vke?Xb;;euNq4T4ei(xG{c=OFI}gQ78>&@ zSTX0sbHY*#6+OTPJ|WI#{9uSxZ=J)VNUwXKm5qzfY|wZ z;2vklUK2;BKPUC_P#9f z;X0l{<`l87xia)4`&-=3H~1z$Ll=eY{RSlj(Mk6;wMYZ`X+{0c$nId0Maf@#8KjV& zt5zCh;9g1ho~UDj+x5!kN%;3fLwEa)4pJeuxPMrmM5%mqAD=Z?_NgukI(f+4u|+## zAT}9IS79p;ge1SsMm;elV8#`Ovic^^|5)svJ=d-@>4bG)ISam5+wjpnqX+-Sgn0Ej z?XxsF$D;c4?L7nJXWRTIhNJri^^N-9DBu1Tpt?K7>h_O*$nL#zZU45@ZnR_1vJORa z+S`)3Stzz1Z^fKQ4_1>Xf~OByS()Q*PNqEC<=hF#a?_3G}Wc+>As;=cj)OaN3bbdYP8)(&Mnz#sh5sc z3?Lu1vm%rIj@4yJN0F#bKCN05oU(jyP_Q4~4tHC?6-B0xknCl+65E=4jx=L89HZ$W zK?6E8K$S5)k^s8~&Q0qvvi*clUcv8emvsv!`a$8KF#4M^rv4F!Q%@-NS6vM9r&_uM z=2Bi-+v6UD;5mOs;-u^lTJ{Nen1&xCcP!o{?@p1>fLZvcOXj9pM1@=0$+iNLZ=2A} z=u>0J2+txLy8F|Ec+YqnL!UTxVQVZFEYLxj@u5MujA)>o8CSR~9DOGAl6~8UCsyX* zWEzMK4FO!FfTi{y54@gArR(HQ$~) z&-S4m(d0u&@bYm11-+Lk@b&f`-?ccmzrknMptwZIk5pk@}DC$dv{m-Db_3V zx~u!C5V@2XlW~j<;Ya-c(X<^3tTs|Y8n#i$4YSz)y!!s@W&OP{`Ikf(LSj#T8xi;c zQ@1wkEYPD1FAN5n0fqtfI^?9DjBychaW(xHL?Mik|1X7b%d&ETSf1RH{rISRJCFHZ z=HZ0Ce#aYNj~6;dV_Ii9=H@BpnE@+=*0R#`0!`?$K~h96OEncBfleqhDD}lu5))tl z3TePhl4*(4-MMJbb0v{^fOyQBV%^alXX#~?VBCS_yiup5K0kTQq0TCe_os~lLxQPg zX>X%~pw0@D1$MlGnZ&QH$U(@scp&8q_M`E;^XvM6ZV^UE2 zL3fPe@~a7M{icFa(@rLl&W@RCUT?MQr&iH;6{=_&1V|WV9AP16`#h{vA zh4o-4zO;K!1}eXv>ei)VhGFAkE!i zTm@Cx1@fzy7KIzn`VfnnMwH50hj$U;f(WsjjUxgBJ|iF4Tjd^Ea!ic0tY;yZPiG7eVpX|CC&@f?Yp$>1@qcAi1#$I zWBNnzZMJa^+If6CFetAh(4a-A z(Pa_(lYl;?%g042E3tn(Ge10(k-zt4Zcn?HfLN5tG^gZ zYJBq8NuAi!ZdT1ox1EjJy^U8n!K6J>*35JPH4Vjos71#wb#6NZ7z-TAE1A`WY z`@}mKynhSLHY~DzE#DICxXeSM#(nWW0WSHXdECZmZrW*q1`bo2cr%jkGSl~!k<8Gq zCx!FPe`K`_F1}uO_HP5YCS~3gAKMRRI3Z)b1Co!B;O?UZJxBY!c?yYbWLD_aTvtq2G%kGJ- zDU!ec;XhI#M7ur+>1T)`mFGX8m%G~jZ`VG5nI4f~rWSoZB6dXFLJteZOcO1U7WhkO zzZN|&&+;0f68Rm{9#Z#~CB`Yop=w*2nctpfq;akL`?Nt#eyoX*Td8(j?$4qfZnPd1 zz(cWN2ZBOa6jU@0b4LdF@!`1?wuBwhnw3~%R{0&ST;irhyY>7NTs)~+!8dCxLYtt` z-N|Dhn6pRvHE~p&H1gwnYw3}y)z;t>bKZoW+cSMZ4PGl^pjDeB0xbqy+eFY8)|+eu zPoGX#lP#_4qz;pXX6fzHvQkQ?3r3Va?#Lt?Jd+WJ=c#w1b(NI7n5%=R72^`iY?64f z1U6lU7SE;7Jv}hJ8ZZat-06X}>PuZ1jmY(vv;D}Tkx92j(%#O60{OM6uxm_(ZJvCL zWAN|y+aN|qJEW$XI!Vu{_>png$}Q8>LB0jG6BxMTUIatb-aU$TXM~g4va_3sN!cJ> z(8O=a(pd40bhX#%pIIapDp%@9s-{@U?2C=~p#1Lcu>Kk2 z-{%41dhBfZkUqB_V)F4HB*K5ajepDmR<-|L_t3?GQ3|zn=pYs!$qcsTaCNoN-z^ZZ zsPpER{wcd1RM726TzT1s<_ol>pDTR%QY}sO*5x8rcZx%r=LOFID0N5TVG&v~8 z|oHx^~WQC0Zg<#65zg&{OPK1!k$0HlI(^ zJLjW^CNW!T#Y$NMC_K{{T`YdYTL$5Yfg(BZIKZ1`$fE5bt0BlX4^l^Y&1W9l1?MY6 z4`kRKGVq~~E}I_gLCav_507m-=iLewnAdrFQ$HT7mObFb#UncK*6T4@Bvym>nQmc1vTA*DCP*mWN8GelO64S9 zVFRmjPIJ;KM*D|&X|Y4;r|)yz@+z_qu9u{sya_+vO;C|`AX{v~olP*eir?c}0e~It zZS)5HxTo|*dd^*3<@-TXTAARu4{C!A{5zH%PM7V@rLX3N9ki)_*!cTs`u& z_b;1avlJnk`582bs|N@2_PXL9R}Wc;Q5No3^}h@;+i)FkbFKEJ>aLuXpS{ucX>jk< z_Z$AG>2-Vm_5`D`2mJ4yjEQV}`GXB~OWh?QaNM0_6U76}ydcIbaMDGqJ zhy93EZSy}b@r5nCms)K?lRw`% z|I3)qdp~3R#(k>?9n~Q2*l>FJAzH2(g47XZ=*V;&6A)Po@ksJ$c4&Ztg3;ttYbf0z zC4+lGATH@i7cN0@w)N3q-7I+PWbWKc_|!FA^Pp<RI?;^ z8>ERFY9lo6G5cayIBVNe6s8B|8J)}|AZuT?sg|`6HA;{xEaCeAyShzw!e=xtA`w1) z<(0HzyHLBrcx^cj@zDA3uCVi)Oh;6ZK`{+t7K4qs5auFZSO$u3=Y&s5sA@~)i|%Hk zw*u1V@?M%_hm_l>lIqTQgE=UyLMLDNuBU;KBA`o)%!H8SKvrm}2~02(m_T&a(R_Ks zB7cs5^ZK5h z#xz7E)C z$u3bc86(~w9aQmKdiY4S0sm`gOW})8GgNwqhb|eyV&D8*;(37F7IZKD?hV`+i54)W z68ufK9YhaL(n})ue-Vf?hf$(&U;8P7O2EL!eV&cFXpl#VzzkkVmzlWX%g?W7Qppk%lLC%6iPVP;0j^_7m!&!YW-_D3Kr?Hfu9h5u^L|ys>qSsAg0w^wP(C%~z zvNErN86b0|6S040cT@AW^*^9-=5%snid^H3N%WS_av~Xd6Z3v@>XWTTi*q@Z=ZbO0 zq-8QggUpjSJ-UNp>3xDS+1hQ`A5nvje{LLdw>G_t`DRM1p}{u~gk7%R7r zBpSc>!YXKG;a}r*wiD@to1FXZQcu z_^~C17$Jgo!Kwc9Y8Mk${k+aRamhWu*^8K&WzCL2zme*t3OAPo6xeBv>}1SQ)Rk81 z90!b)K}@tA3Y&qoR5c{O=qBr!F4FE8T4Bku-aye=D{xT|9pSI>GXbld8Um6iK|>1g0g+=6S%ZjNav3iBq>L=sUP4 zh=WjnXza3QX|7hFJHwk|V>qWpIVEbMZ@XpoPfdJ!9>ewosfRFnhrPb(kt2iJZBcBh zj4;QJ=Z4qW2!VlT9t5Ow{#0xWKtAXA9$;Y$__d_pVdH3@ZJOY!UZyZ8U^$;=sZeOp zqBw1)IgkyG#HUqc>)LUvaf;5zb{dm^A>C1Vf54O5zbuihoX3vAN^0>_R+jD_y$`))qo4-uvYU}XSI;44`OyUOd^wKggz5LP7M*vPY%@% z{c2H<*2Z5U^Qd08B$>CYX4s8;O0n)3rkC=o{X|t5n)-5B0G!TgmJFm?QZ=KY@Q#ZZ zaPd0zaNXKW9ZeIyB{X6ZF>@^$MOUede&thXSu&*Is`f8VOkF(CV9Un$vh@VqNsQM~ zauZ4>+m==mzD9d zj>NIYg5jx|%N~m)YJ^=sKM^NJta}(e$Z4dlFTUoX0Mpo-EPus$`Uo;HH%K7-T1EI! zOo@?qS|5%^M_xO!?Dp%7L-KQJT6HopUex>*bIOOgt)cZBXJuX0=6m$k!8NWBm>?R) z7&_GVv6E5>ls;2VIGv>su6W9LN5N+`Z)^_QaM!3doHJm^qBa2e=poUdq<%~yJxnd= zJsZa<4TobreM!&BC?>b{dP2_|o1=!Pg_^dy?Xgnfu6fCft>oMRH$=iGX;Ziiv7kat z8poLKQ7{^D4P120LejPFWdWO6fk6TFhQk4hsVaS;Dz*~L=f{!3LMdM=KRg2L>; zHj`u2>4}upI#+`ID}Br3v+;>yZaaOggZzJFu?=fObbU#uy_&jVgi<}+SAym2SYBUk z_uvV74oky&^1G6<3r98ya<>E3gf$HnsM*O!E}BaUniK6Y4c$cS5m!d0UK41%nL@sW zkA+V$69yj>44_BKI|cfwAkdCOjINny_+~sbyt^0mRnKxQK)vvWx;Om6frK0uv5{P^ z|LM%8#ws1r19$zAY*eV#UH$-56FLI{NX^)>>0t6k_u4!izD1a)i?Foue4Rc@kpl*< z#lw%{${%wSICuyKwWV06Wxb&}Vn8%!lrV)4h~`+-d~ZX1_2_g)Z~Ohf|58n~VK1Hf2!&DKz0|>{SD!idN zXrxb)osMB-y}RA^N%R}|DXb7(J*GMyDo(%?N4v%ZS{EYiM`d=5Gq1EM*!>zYg5{vDTUJnET& zkTBy_xKZkz`~TWOe>?u@_Gw6kfRZf_cmy*3=f~gQn(d$2<+-`n!DKiGStTF(8M3S|ilK*K@xA1PygUKDk_4`B11moW_P{c&ue2SD6wAz8 z=NF{Qi*-T6Q7f?~Y((m&l`Z=_k%|kQLKp!JRfkG8aPe8yQmIiU7+)wOC_OD zdz4cttH~GGfJ5oxUFWaHdZ4Up(8L7kf2tBVo#Id{td{90P41X|HUk= zV`pbz`~To^95B=;0kUriTjU;FFx(dBbB0lC2=cGo_aCNTrb>(^i zcyRBb>Ch;VBV;eNoURynNJp&;3ItWGd>Sd=VN|BapHGapx>Q1%V-WUevtU*ROvoyT zbXPBY&oK1La!7!d8{QV4JbcyzhnI2QlAi$Y%!%-vvrB?64*}q`0!i*j7k3GV{c9@a zvK;#J8gb_e4*9mMZi>FTQ39e4pT4geKh1vNbI-8-8r0PfVM!@*(e9?LH`hT~Oke$? z7^q_;d9EPB_Jvq3YF3opx?*>Y>15uRo`cA&&y z^HA%K3_$3W;iGD~_LQe)2idY2gY?%O)t&~>ZU}Z|;#p^2u2dwpWJhlAmP1d$>lyIr zla{_gC0!84;+PPy7BvHXXpF0+yaWNZWaGFAA}VRHDs%;PipTl1b;U&7VC$}{%RjE5 znF8$smB6!18pz}D{oCi+pH=gRsMBync%!bP^Fl539&<*r+2?pkNA+yiypS|~LN7Esq=rT@}MTGr2#Nbc4f+pl_S#R1{2 zli{sX&zC!db`@pLJIu@F0Q{-oWMyG(8Fj0`Gd~D1Jc{6QyiN-^MS(k6-x{ndJx;GO z`1-DKvx`*LDI0tGJ~XO4A-Xt?@vF+T#WmGj`C;2P@LHbAG`3jL<^pz^WPgEj*}lO- zQmx?_o_W~@a2FFx%&*l;bKmJeI&_T0sg@IUT^-Y)NJbT>(M6Yf-bMU%Sedn@zHkxH zk3=A@%oV@B<&lWSHq>}5oqca-DCe1DCa_FlJXC6t;78Q#QgFlA*9S4g#=tiwPT1!j z`tgL$T;$^dv-O;hIUsigU0~%S=}Y?;pR}M0_`9S`>FAv2W!i?KWz9hb9^J(zcjxy- z4qE~uk8G9FUn^OwnvW-a+OK61+7ozAJ0cJVwFj$e%3QzC_=>5IeQ!!ktVDY-vw;!R z2)eP~4NEV=Q#A==c3M~%3E>WraHQFh{w#Hz?zJxR0qYpU&)L&!l{J3qLQzC5!#yMM zy8G%Tvcn~>PH;B1woD7-B9xr1x5QbDoos_~1~!4(%gPu#amOHe*Dih+&4VT1_EGQ@ zHI+i~IxBKcV_`7M1ns2G(0t|^t@Y8WSC`tabO>NluVmsegX-_IXi?H8j77Tl!Cz2|8L*yren{;E!y5|PMDn{woC@10R~9FfQTJWpXR zYdY2q&eVZ_LxrB8Sk=pP)N^63DEBLO%=A4Cfa{9y=~HHMZ6(jRs?_S_-kIp5=Z8m7 z+8cH@wlkECvHTFA$kVU`wR9>0cq_)|BNf%6f2s@eQytla=*iJSDO}SIkkRwS_+6iMN~zUko3TeHUn>%hQ9cDSZ<-=*JjWK?TVoDrW>Mso zF8}BtvR(wYT4zIccATY3d=>`&RT0>jJN&ybr@&5}bJqm7dwbT}&069R$9F35##uY_ zA3sGQriZeGZ&Y{Rf2gU#9K;{xl0SaRTxd`WS`A=H_ad_4Dgu7L4)5(bN1nq;<2Un1&KL;N7x+9t=0HyLancJ1 z#p+l6hvk}fNOPUVpRA!ANJ2}!Cs-fIWyj3gxdFcHw4sM9&ls91T@)Iwdz#oHqicI@ z|GeQ=03{yvan|`h@I^WbJQl_N*GJ+%j>tdZo4-;=HK&qly(|peV8CD$aVX)vzQjm5K`H_LOHE(zCRxZ#*P|As!GUbAPHSuU$^Wo>Fqx3mRYU7 z=V)(1kF&{z0#`az?qCeVV6-l_UD~Sekyg5Rt{n`K&eUJC@};FyfH|p^r91A%8`AGR z8#c4IU%2i0<_kWFO=yGTH~2(?*8M_qCZs~0{SEKQd)*J#KTtkTUoog#7RI=pApkX;c z)ZD_)sRW;ZA8um4fq6}}W zY6h%J{g(6AV#OKg5yH;AQjF-```r)6v?;j_yvR-|*`rAL_PiCeg`9y&$=^!!(hP4| z;#+$-BtzxS?({8+mtI0H`ViJeAg$5F>J$2?w=WH*`^~~%@1g(iwr}67BXCW*Q#<4LnlfhXj|&3rtZ2|^uOv91vVIFk zda;M{YQGSvEi>R|C-f#e0(Z>0onJvYoVUcn_pz4Sr_nCXI&M$*XE1H_BGQlzKu86{ zK(a~5W?V=hgXLyeNE4?tE$O-@6lXm(F7>*XFNn`ol7Hrz2H1A)Ayk|3CC(QwUs6?a z8~UrK4}g=i3@TKj!8ENY=hWm=zZGk9K5OQ2@*GyTU^GOj?KGJ7V!6N63CCXjABg7OFHoIaHc>cyo5)A`)i-_^++KCt!{%5t zL8xx3Ry10iwL8rjKkBVMs!{kkD#Sww%AS|H1%HB&XBveLU>&=~I2k02;{ui5?tv36 zfth)@j5`lbV6sEsSfvyeF)XTuLwxqNfG>xe33qNknE+B8PB%f{TU}o`EGu|vXFOg! zGhOfl1Ggv}&MVk|t>z8Z`ncX}3K7C!n9I8KC}+WtuEL$ppZT`z61FG2tM$SXvkFDgDvu!g8p&BL zp|=s5@-+y*DN~Xq0qinRUJ=RDaCIcF; z-;#j$AZ9bmt#sHw@jmu`B!hL_9d}8>$p8U?!mM_rxMKq`C18# zx}^NgT3Sc*;zi&c6k0DWuXGYWUdo9D*)p=*3uq3Rtq1wz%QNHYuukB z0Mg`Ip??#<6dysVL-jmH=h6*L%ixhLzDr4fgh(Yve~#u>Jk--r+Za~9l&=Ci(K~oX zw+Udh+3F*~0&_fsPP3FOa}Y5oll}ErQfVZA6V(2g zU8(eGb23cZT2qYFPDM2bW~d5a<&6MmNU+dAi*}@!>z+2QJ9{ZC_zN1~Vze9Z($CMC z_A|!C_QnjhPql@9#2K4$Ngo_(QQyK9(R%E-$NA)z*WRkJ)B$jgq_w4Y)7)TV$ckL|Gk2tVJq{=>HNXk;Y@0n!JzA&jcb$22|Yn7i7LWir|1^Jb!ICXY9 zz=N$7fFywkfEbCplo!OB#k8w4wf#IcGgYB?oSxahnpxhTXf`;_S5=sDEKn_r36`h- zI+HIyWZIHHn;PZw2}weu2x$nwC4ob06&qnsWtCu;t4J#A%10h|KB&DiS#yzRh;d}~ zs=GvXQjr(e{85&q)|{=>@L=ACW3ggDRgp!vNLI6?5n#ZUx|*VU9{I5}t(RzAZpQp) zLow(a({So2{m=5L;w~Y7=p6(|0+d6x?O#aakcgnp_+|Ye>D}eigxTUv3DjdSOmK8M zAs~bxQc3gF5-T~S57wNktUsp1M#51)9cPnAngKbBN^?asDlWA`1-9L8n3R4LUkVWU z6oQN7hSmNm$r|{YCMPH+uNOloub-4#{o8ZSL2QS`Y?^-4CE(7QMV3~?J8RGC>|e#( zE%DvAZaMn2iolueYxEVSk=&LYD-I;A;!({7oKH*QiXvBgYMs7Apj>E`lsctSQrC1b zKxwN)L06l~X?!Pb1#LT?X1Gw**b(}eozqb7?_1?OL=hx9_=s?K(ni`L0@dR9Y0BE@ ztin);+2*CO>1dx!Ea^n`2G{GV(nQv^wU`yQ2e9~c#;LonT%uWf#ypkEIaxP|IlMw3 z4PaEB-EN5v)`4T4jnE3>YH|lQ2qiyh4LQsJ$giWPr*V_Pcf}LFVzKtnX|5U z=i6RlX$i49G(ybI!6t$=dVcQLe!p2_#At25apm8euB0vA$yqG>%cf+F)k^zw@zeMK zCxm#7J4bJFBI9T1Vz%j@T9H@DdRh?8m3%<+P&<=lgAW(Tu8s)(qLMA2C|3{=LaL|2 ze-LSkdWqWAIVk&QM>kEKbkI*0E3*IWiH|z(_R-8iyJcsI5lFgob~P#x{_e4Qyias6 zu(V=AFj>saU%4qzc(wV;CzAG=C<7bp$FsUG*Amg#hgRkDGLe9F<{wpU?*>|aD8sz? z-bp#(f}zmdxP)4*;rw7Yg(&MZyZhyzynV<;0B!Sm`4xj8f=~0C)DzI^Dy3*8f9NHj z6jJ~_+qOfd${9k23`J~ zTLIzf-DVZE*hW(#VXaA8h3r0xuhJT4vY3Z$NX7h zziEE4flcSp3>41Ar|4an6(4d>q*)z#GC%G>QZ!7jXCgf6VgJf175 zpR>B8Hm)Bz5QV8>K%@|@Pvb{t20Dl!5-!C^>%Q}O>bCJ!s;EDO*6M`!k>3_vbKwLG zWXvJMKr_ynnKX}tGV>lT#8K66n%Q5NuVet@>4p&PtVEK6V1+CuK%^tV~c&N#EXa#oIuWb-|kyM8>g=%Stp^6liE1KS;Du7YTkt zLysdY?pN+X=Obk!04xXSIQFmIK7E@nY^%~JQmVzW;*Kh(+GIMR(O+;coihXbd>L!4 z)XQm3GmM>H8#2X$0P41-h*~~7Q=`+aib&ICmr!JA^D~!o>ed&IW;j%LzM=&1sK^3y zAo4K=32=?@9x$WH*hwS}QOvJx@J^Apd~zlhR~apbUhXkfsx2@dZ37OjOLskd%4IE4 zvPd2Ceg8|90HaA@Mq6=1GbsnaZ5@J!jV%1tGkM)xhpE`KMeDWj@VVz9iw0mPztrc* zNAPWeF&LBdo*>N!C2}766JnDT}?{@|Dren5F$U&PV{C6f3W;R(a3Z2TO=?!0(_GGQ#7>sBc`u~ilo93e#K zN?P^yD{5{&;8rtQCF_>wA4wA=2nnJ8Is77Ppkpp%Yh`c!Kd3&8zu*^2Dv9^&K=>s< zECYg+4!(fwy56BSkldA7b+PAJiSs=Og%u3&Sq3zd6+8w`waN2+H0$!$Y{Y18L>ZQXs9|52Tev zDrJvo%{BAR6>7`g48VPLV+2HNKiSUxrj=WM0%s=A{a>ggja*GLn3yolJ9Ug-iom*_ z(Ylog_i|aVeBNl~4?tS^Y`mAL3(MpX*P^ zIY-ew6APS<;H1VuOb3_Z!Y*W}5ofr5OpA7Ytpluy9MQoUNA6Ez6cjs}>4TQYySlF< zl`t!wwc$h*^ECLwQz|%G;6&$0Ect6>0$le{_r2Lt+Pllt`B?7!$LHX~?r-pmdZ2Pn zlY*gQ1;0b6Epi2gUhW(G5`_&ks6hw9FH#%VZ}7{T^!pe1<*hYnAk(S!X8ir1!7u+T zk3ZC(niUX!0j%1jBoOqneuK)*je&0$$z1%BA%q^qVDiBdgcWX7qwMDZ;JWmeM%~F* zZ|?R_@F>DKxWK>nv0p%Qpa`hGY2h))*sVWI(wq$aRH_i9n08qEGqEQsSK&gnhuq07JKro=y^gA0vcV33 z%X*BMZ=*F@eec$guzOOOR+q0&N}gMSRN@z9#a8Q>muTn1+BaUJu*@hBN1`wY83^O= zI5aS>GN}=cKBE6U`9VRW%Fb0o?LuQp(`qn3{y@S7_uJhJ51NZ18Q5n~StlPaG1)r3 za-wXGyzG%AWUHXaX5Ap%(QXma=79{WuDU8{rrVm>9(6ew#g&V;(1O8LDii;wo`ZKI zzj7<3p(n(s*BR+fUEt!pZXxIJpGrdUTDo=nMFovFxExH|%{f1wfGM zw{BqEEGQj2Tk)iaVh64(Gg?e>3(+TkRmlbawfY4iC28inrvrQtY*3UHZ6LgCc17`PvRD#ds13NQeBL}e8KQJ+U1<7yR~hVWS9t_WMD>}5*}=)!WcIUK zC3TJbe$}gg6dQK$xW7k08?GG?g@FK~FlxwOc}!j<$}xn?vBxL8(j%V$gT|40^8!k1 z*%>p^(+3PSy1-TCni6=%60TmZp#5^HldfmG<2=ff_l1NkMiDS4pS~C|h_5EbcySfH z|FrfFcJi9%0cGSfXum(+7ECOmX@rnMzto4V)^c0lw=u~g7Uo1+fO8VJc*Ixxw^e1r zQK@_&r;I_n`=!vqL-u%yvd0qzxT-9%;ie9xWL830{iSOz6BZhTf?i31_TjyUD{Vh# zdTqB#5^Ms10P|SByKC;5mTv3V27l_Q2#|)kHydW=FLaZdc*sAK5L<8Sag&nkS}@w6 zNP~`oylQ};JdewM4R8kHFwrs+bY8pJ1jP8S;xn%&1hqzYRf1eqK2INs@K59k(hGp2 z63>|gquOD5(M#XE0mNfzbPdqARb~CwWw4hf!Fq&U8{B$N+JNr~xn`f25Ag@kj$Z$0 zk=Xe$@hAh^BSXO0!hau!`M(F^KV;lL;t9QLOvEUp%beQyEd=0Yq$^g+y)!_kvo`M9 zbB;56MWT~FQoP`%&!7ppTf2Sl#on$bX8j~xIOPEF*ge`=ta?1Y@%_EOW(_$cl0%!= z9*PJ&?11jx?Z7S4HA@h==X!tdkVla#J=NZj5O6v}gJF>$9}Pxp6V=LL#`Mxc{NcCI zvNzaI0KN%r6WZ{S$Y1O7Fg|5pB<+thDi{Ke_X!tfLJ3{)s59GopGb$2Y&CqGRGDrI z@%xIIDOyx!lQn0c_t+vYQfT5210!yRZ_RD&FZ(rqVa`mQT1fDX-9!nTuo?|t_e+Z} z>Xo*&uS5#)PUb7B9Zr~AF%oJhI?k%JheqNca!OPpYqA^q1xA%RmL1tu=_Dded9JaU zg>w9KD6wI;Cy{qmBQhzYtQjbsS;0!1WBpZg!rt&f2E5ZQpI8S$b|?oy^55Up(1um#2Oi*TN$b07fez119%qvLa;)86Ft6NE5apg> zykM?VqG@;%B~#lUMaF7o={J(#7VR+zLr%i$s#lBwg_SAXC4pz0385@ytzeu6g@jw}6J7lbdj}z#Bd;-!i^)#;Lwy zrfBntEAm{t<9l<2_0#KIkax>GO5U=-X;!s}hi0`UnuCNEMVk&%dekXZ00hnKX5;~? zgi2Y;UR-Ma*^m-pEBeI@vevd+jfx_EYh&(k=7wQv$Fl?i#%DbdmgMCP%KK82xr+u^ zUoWQU`tNs@d#DOKqNt-MH~^|F>|^j}Qk zEbl%#(X{hzZ9Aa~eZ=~7mT-pM7x+$UL;lB48^H|pHI)u-|4Wdn_dC9?Ac7#xBzM`~ z++G z{%3|gvIhDFh9;H<|Bhi#1mZspdk_g^6%K$djPOb~mesW#Pvnw6zIn5AL(v}k66FXB zYl}6dB{Bo~?z_kEF|GGU*(x3OOXb#6oh48~^%i05$hDM9dMsyrSbbrWeE#7L+`wO> zU)ma-gSRmzTjH+14R_wR?$o&~YA`QE|3N8yTm-=ND641Ja>P*PB9k~JAa;d4F@zuf z4o2ve&vRXyM9K-(0pmN8Yar}a`OFg^LT>GWoMsK*{xZXbFW0)JaGI*nJqO1&8_mtM zN`D&N5yhmPf-SJu!9D0kD+xlV2G(H3LUr9Pyn;cxlL5ube%bw@omOT-r zgFODaH1Gem>{-k71MB)8HJ>Vc^b$4C2;Y>rt0{b>8I`aD=JPBont6$bXQ-SU>#>~* zosO)bVVux`PO`imsWQrgY*_xJ zBkQet7kaAN7CFKgn`uKG;8T#cYIeX#b9hOC#u$DM+)0v$#~*hhK4kHLH$><^v+VhA zh4Y8@{nMFImE1IAfl|@T4~o(%t`X?WXd%m0{Zpys68{cvI$4pL zL-R3{gX=H$`(xBqKPyM_@aR+8>hRI1_{;t6Slhc4|7D-UyGjh3y_R~fo{w?e*Le_H zfxp9Uitv`;btHVt1e8yCxGjmTiM^~)T_|6SJ8adv25kZ7R{@sswG7$D`gIM8q+9e$ z<(MNBh?lB_*$OEse9TaQ+TrhRQ`L9Hsgx-7+mbZhMn{;m4|Zgl6ex7f)u#GDCYYGg zuN37%Okl2>(kLsi*rzd-@xn}S0CB)O1ac9aK81^fkX5yck8cQLHm-If zPTZ^rtwOWVW9FQdw<>I8oL*_bb`{_26QH>}Bb3jPQrKu=p*eAPBx55v5A{|aF`>N< zW|2`v^P4}#iD_NjwV`xz^IY<7wW(5Ce02r6*o=%?d5}ST8ki+w5^k@!%U3{-JeXQq zY3SEx&5`=yP)uq@Mm0jfiz-%^q(&H%gK?LXBHRc=9|pI@GvFj#|577_b-Irp{HOL^ z>-$KiFrSmMn{X=qniP$3WD_}KQ-g|T4TEy5gOYgrT#KVb($&7KuBEKHnru8xrQ--l zgu5_@SQSl*^Wyaj%&zDzwmO?9$#E6Ek^W@XuH010r1*7Bpi_@V`g$JZaSwnv#4YmhTBCFH!p0mM~ygEd(uk22;&-XAjtOdeMlw35;jXld~z{R~D zjb%#PW#l3nK2@6)&GSaJ64F_ocwpX5)y#wZn^TVut|uCAem3WGmN)Z; z>lG-bO=0`?zE73~&z-SpG@1N#^)ZDU{kXBx@_r-aVV`}IZk!ha==H)PGRM5H#lXFd zy9yQYT^<=4cdRg?(Vt^S2{vLQx?G>}Y|3<%iuB2_`_>`_(yb|fmb7`3#~&z5_e8tr z{RKn2?i^=EAxS+bH=eLo;#q#at>_&GRDD)p56@54irQet8_i}Rw|V*YCUHYq9)S|q z-*nfKlncRz3mhnYHG$7B{`!7Fs%y^OF_00em;MJMbSm_l5qji5UL^NZgIf)LV}zoB zjF8)x->Z9L#=y86qTDmvZpRdKKziWN-4c)yivDfUc=~41cr=htl-L=IGmzWPt#Iwh z8nyt#?YkxS*e|ti+MWu#C8q$iD*PGYY&yn~%Mc!@CD{R+JE3rA7se%UP=|iD8DULq zc<$%;nuLNvBQ=NBI42bKo#o|UmZaVq0aH#NvyXu<)Bnt(=f9nae?Rz>68g*F__sxm zDlar56e7ghM@Tuy>u+$vACUxt@~0J%=4z^PN{^QNSH3-z{da$!li|^3W~;fXw%4aS z$TdhTg>v6R1Lb;|9y-f~dJV5oBn)61iBLZFXtrd%556voYT2I z#;Q zfTJ%%cvC;uIuk>1NCh_yDg zOZ|mv+vX${F1*hSnVhLD>+T-a$pS>Z8>DpWyy)KT6OyKxxk|mCZNV@qbg=TnAHjqd z`71l0fLui}+<#)w^LH8jUy=6rgTL-qCCZO)W5$=bN%J4lE7itoYT}FmL?sp#{bJ~v z6Yt`rb4r4e^)ov3nNKW@^ZRZe&pq#|ZZM^;!Nc2}!#rd9*sG#%!I+Uoy{sGzPnaD~ z98X6nJYO&0LghC5V2^ai!XHz86D5x}-MK4M`+07=_IR{-#j$L^_X+yrELN5!wlJ4`b2g}r3C`sR5-D=t*9X%-B%*|hY^T@kFUoqys3DzZ; zlvRMw=$y_>?l+chkJ|{8&FQml{!oani)K=j6eVE6-DJhXXWrxlWeRmm`C4x7rx zI=eih8MM5H65o*deYR?t%Iy5hu*+;MB#*%O;5U`=gHn?*??!+?q4EgJw+n$!FY3jR zB0~=fk>Y_7)dwb&9p%~D*=8T&lDmLmvdS%(bK0c_aEEAMLu87fBzxcWi}#aFRQeY7 zu2^|ztsSDHhVo?kha%K(OV^X)^h|WvdyYB8l=S8fNfeKH>l6+reT`xZ6P%5SIfCVk zoC=Er_vFU6^KsKloo6!*i!>zf2nT4m5iJ&n380yZfLj_01bb#8szrE?-f+%)4bIHw zj5dp|lns;%s+5d+EE=pEreFnwTeM1Z$1Pb)_>3f<>)95#JQ^XJ>La7TS8*t7%Dx&$ z7U!J`!0Tt6o;S%%7@YJFSz7E?UOucJhoVv&7EM@^OxOFeSOil=3-P^HfYot`tn^Gm zxe5GYnOmxv2WiMPEcT_3E){kRY$t>3@4e3(isICgrQB0Y^h$f4Dliuuo3FBS4nQ|? zF}m*Fw{2AHCroT8Agr36N~D1@45Bo+>yqAoQEiOzb(WTQLj}4sBwU2der7-P7d!NC z*jU%4Q&;3rAA_f`|9A$;rEsqDE`1XkbaT`VZ`nrJaWH2#)1XRyenB&oIEy^E=#s1z zW{up9lCDoDSwFgoV#xN1sbnMhU2BgcVs19|%=;_7Z#}o8h8#IoQzPRT^-*+(1MYE^ zNc_!_rMrova;sVFo3D2GB;4fkPZ>BaFm+O(%xUAfW-4Kqc-JW?7csnSm%y~#FwV)W4~zcRu2i~@$om`LlB zn={v7q*{E1X9&BBby|>2c@K7OCrA$|zO8(08O~PwF+hRu+OEjJIa1^@$*4Hea7WoU zE&`)!yD=c!@g0`YFe^OF^&?4m61jVXmc`G;K9g^2XkPeEqH9wuR+7TvO&@Xq&En?#zY=>;i6cG&OlkY!cah4368r0gqtbOf~q~yln6BuoHW9K<^f*J zInM-|u`GnvstaShSdx$4XzK?;6{gx12DGK<09u*;Wvp zpfNxY<`JDR)Ie6FHW%yh&!|oy-PA^1!B3%PZP4fE*&vAToIAYF7{9xW-HaN&^ zcr1D#%(mUQG`1-C&26W4u4j#dx1qC zw27zxE2Xj)DdOc2wbBmZaK97mL!jjA54KuXE=%V;;Y?pvG-{eL8fy#8*(s zq)ZJ=Z%YhI6;F+Y4WfdF4tk0c`m6k( znAwE3r|kGV(7Ns8lu-G~Wp%%4O+n5N3lt}p(9{b*vSeQR!ZK%efgAj123<= zibhozX>!-=%4gWgG;V%0v>*XVT98!ePjOQTUtkD6~r2~$H%P#JI)f0+D-oi zdW5o2S>ayYy!zqM_oGQGURq0KIKScpKp%!Xa)IxGo*%qbVD+O&M)VgS0=@cBho~0g zOh8(J)ie*C*rH<;(1z*xj|DLuL!8cOpk~zu_G<2V3Brq3F?|h~S+P z2XNB4axW8bSUpag;Pfr-r%fJQYQ`@<9UMdfyMKvfwb{(uG zq+0_cG`FtBd#So6&q{{-@WT1P%v1q7P2Yo9hwUkZmQ&l@EU)AVP~*TW5IrKnc(KoL zaB~=?aiw4z!X!98m~A5fN~%oUVo!^B1;>V@#l@R6x|SGOU-rB*S>^p;dpykHEmN2e z^e(4*zk;h-zol{vSi1t(!~_n4vq?qFa=$M59cp9TnlBkS35q(&5jLlbItfCS!8B`$ zI_=i%PGYsMHAl$q6(;nfD(+A=!-NSWOzDm>jA~<(9$&@)>e71YMsHCMQd9XRC-^xv z^{=k>s@=f#N>)(cd&pUb0UerF8H~Gt4owqyse~62K!>IuK)*`at?05yD^4H|X?ccr zJ%>H+bcY446$r^tE=@}{v0NCzND-|;Je);Au3R#X3~WqHq1&qysddGwG^@0XJ6H!> z2LBmG)McRI_wJ2cM}PND{Qtjh{^$d#DPbre_Pr9T%i>6QEtpya*Jy*9viB6q8_Q7j zWRc2S=9<<-Z!y3S(d!t3tdG=Oeb{5(6Oz`d=BjtQ;cHkjGQ^=DVEwW{D>kb;wx#~^ z=y=m`eE*ov{qoWJ!wglmP67DmGiUgrW#taj&$H!J!+bhSzRm>0D4lMk!%CeT$U9~_ zt^0!5X#|eGcPB?nty3xS(sbYn`k9Nc{tdP0t$hEi(8=W2tZVUDX5)25{iV4|rNMO7@z z4u0XqUKtgqXsXXy@IApoEfyce<(uN@?BPy>zHO)peKG>*X%E4QF*1qvD5P=5Vlp~LTR;k;V z%viS|`rCG9Sl9^`j+T=u6=z#JMPka#8_hNW{R!(a9WP2TQ|4^gMM_19PY>MZPR0uuMSZDyIq4N_E0$FF zAv3$T)JdK_EeXj(e!ABWdKAn?#lmAR*utissC?89I4`4F!KIT^89uQdq4+#j?E_jJ zg6a5??OMi?Wm^qT)2CV{=&e1uW_8#0gzn}>w6E8oqFNpYa3JEQ?!b0z> zpSz@fc9D>#Ry<@xKS8?Tg1=Y^hOXap#%{-$7TpuiS}r=oPnB79H);~!Qx(qt9Dhc{ zNj=rJ$F(N{3mWBEKmixkTo~27E|PYQ0Uos>AzjIKUN_w=QgG)Aw?gj3zIL3W=!0m7 z%a%nH7aS%O;66cOqwFC+;>JtH4X4u@ zB?hOfC0p}KG~G;EaA)i52w#WcbeiwH9c2cmsU_RPF0h;JeVZfyB;yN=0GV57qzy$I zON>bSltZ{=yWa=Q19pyD@dOsuX{%Mp5 zSH|eG2UMeuz+hVb|L>FbAF5R0uV~sh-ZDyXKfy0==Ad{k#4lvZ{2A4dci}kLF2^#{Zjf2>z^<;XP zVZ>ps;B{l`lLxXAOWWyONO??Rnc8+%Cf^GcyVMK;$Uxol`G+2D7ugm!Wop2-ALbD1 zN;gDVVoZT^8Uv19v077-s-K1$l**ZC8XPMW@1!cVXMb6*Sm~Nlua_PlX%95XH~rvj zDuwp(KiL$+3ddbhjPnJ!*F6B8uZSR%Npam;vaQ`R+SGR6OUOY9DdO?`pc;Q4Jl&xO z+9E{XLjn~t(2Ymw(7H{l^e;Rs)qyf{^l64+=*Q^>=TgEngKVy?#^;x56bo8jIw=<) zBEBT0mhmav1eQ{zmfgg!8kRK$#McHI!B7II#h9g@hF~1lhSsh1+n}n3%FEh8po9YD zISWZtCMIqDq|K3wnK5a{KGA(<5pkZvz=}u}*9ivi*ND-Ua6&*Ib`oQ-T+Sv0e%(jj zV7@r&iTTQpR-FxF2r-19R`8x0*H+U+K=3#zVLC69Pa3L;D&v=ZO7L&@pGILqi3Aee z#m)RFPUhBfo)Wf1=oPNOy-b5g?n^iP_Z2I$_7vel4*1D}H$R@T&SzFCC^5nhO>sPG z?D4Hqp=l^Ns8PTReft0x^{a62E$ESK6S6^ReP5-@=e=;g<{sVzQb>DK>y(O9IZe7( zl~L8ILE-VQY%9AlNk~e+gZ!}77`k70=AY8J`o4wW*dI6J4LNZ!6GCEGPe1-Fy`h~I zlw}aVWK-LWmwrYK(cMCca>64%KZQO9^EZ45oK#(6^k+O|7W{Z0e2zjCa=_>B8JbOe z?H!1H?sCwLr4K&q0tR-ShfT8Vy4y>sNysVK&IpU|`0#GzGpt3Rsb=3f{l7;y8V}+7 zH$ivZ63|`u^MCQ5nki8HD2E*gD)^*{FNe$n0wR17 zAyO*j%g(X@j&?;%vVnpezY9vT2!fU!KERNI3QA_PT%0@Vxm~upd>%jO5}Z&~>5dI5 z;VzX??6#>{FE2OQMeLX%Uy#@(;&XY92gKQ4a$G{BgrN=Y4v%<|e}#l0)j#b(6))@i zgpkA|`xz51jj7^p^4{W9L=$nNigHm;^{_kXP^>`j`#F#w<0m7eg?yA=Gi&i0xj&xs zDx7+$>qyE8GKy9 ztv2R=!$_GvhW1UPud6f6fL$d-W#L#GB;`G@vj(341{5F;1u|vC)Ty-s0yc0?x2vKs zg+e-<$+g@0JDsDJtWQB@#m-o6(sKcMx0(`pa3AA99VPQRk0wO9Le)7(X+3;OtGkR* zmb{2YseF1A&8tI>SW@#p)C5bPu0otyW`9N1zBD^zS#t=6M2yd^D z5EnPqZN0b{uu6_NgHHiXtVTx~M&@q$;D_Sv{S3Trec!G$eh@h& zH+&m8T_1&Mr8cUU-GO&$XzhP-(^wienqYM8Vkp&zvh-($G9ovvHjN&m!mxjkw$f0L zo={i8Qlqly6mPaxHdsfHU2j1AI?bxJV3zxBoA`sqrrOdycJJfRgW zW`0%n)|9>F(cwq0Ft){2hZH`5l>l7(C3Slm2EfbcMuj-xv$-<3F7NFiB9S5efFIN~ zV(=69zbIN8YYJHnE0GgzK^OWfYQ`iY?MQAJQ_% zx3@f!sSuRwT&!oCcUhK_M^G9^E6sST&+VPv0ng#+4`5bS_qc~SE4)o&^~*g~VwI1L zkiF_Esb zE?g@||E=TEjNrjBG}HJ_9%YXcFnb<1-c0l`MZYXB-PXlo`hkZDE6UOVSzkVTRIIBJIp59=Repi3v*+bZxM#LL~ z88No*;jV1GSp)iw>*o`WcJ);!$sGo9chm!=U zbQk_Nh)w-#B*wFMwC>F2;)CZRseAGVIh7Cm>4Tf_{33hxPs1^KJbN;Mmn-QVzE2AM zJna_QN$JJ+F~zna@+(PC4M=an$MhcG?}&R(QhPIAubQ7ZA^^@O`cv+ydn_`~e*`x^ z=q_O%gAUgZAW=Z!f3-i#8~y9R{c{AmWi!Ws{JLI*U_TeShKW`ZGo_vmVqpLOrdhak=qu+Wusj!AA}?QlLg~}6JGFe)u)vrqBgeEVfayKL=t zOxO3JP(!^LU-IZ%BzOT)f;K>p1jpETVxTtNSUCr_sNkW9wM|No`4CuH^K6pDaSX8z zNys{qnP{7XMMp&M=CJM@$kbEfvg;cn$`e;~o9O#7XF+fI5eqH&(xJ4#yGPbBL)4MV ziw4H@>_T8@gi^?cQxkVCP_cG3W=Ql=p*7Eq zkx7urC3th&|05nC-}X zC=DxeIH$Aiji}j+Q)Tpew9*z$HNs_vX`L@$g*@1+WcmEZ;agk1_TfFK zo@5>H-_SSy$3pt2C{OY~KKsWUR1L;qP8nG{h{YZiiX8GogFqf@CD^=7F9!5985toY zIi5_bMyyp_=&C&xWl!Fn*VdgEmOECed@gP0TH0%g%pGr~(THe80Rvc0!&BFWSG&zp z{QdrxWXk*8kFRAR>^rnb9UH#)GGHBWXKvdskoWKSuD^>$oil>Clf^gF(8XWwr9d6A z_kzBIymi*560@>(W$!ji%0|^mXb;;eBF+on>31ix)U6i0YaHB5rTIRqs*DRGX&`T} zh`7&m7)Vp<&JpbbFvC`Hgqvm|!nGr1PEHQtG!m+*qzR*i*+<>U%%0`s#~ULnbo2{v z@(jm!QP04zzU zVS!1Q!?)z#V|pi5V(G{%F>j@QnfTCVFTd$l5$OX@7v6Jd6mSGBL(kSU6|L*In&}4n zQ;L}(;r0{wdB&j=Y+n_Uu=ky}^rRuVVR4%JxPBgu+(PS>U~f2UVwrxe0bKHI7exCs z>@eA0oLDOmXOEb2;ap5&ph?VfRFFi5P#B0TPm*LWUzR6UG#n;v7E>T4gV)Q6Jz~2U zJFAg|GBDk$h0-;6XpjI~v*Crd;;KDcnjb|c)nVxqC^aM&wCO)7-uSDSFTNzDKc7UEN-E6pQo*xN0~W%KIGXKb9Q zz5PD(JB;R9%=AK9T+woE!tbnAaF%ZRtvb7H@rbLQ<%W~GHL1o6;R9J!a3+%dn)QMM zO`tfnejS&7nTK7ZwZZ8(hr$+ILywsGMu;pU?d{b0Owlod?D2JRA6?=Os zosOG1jwczisHR!nWmD=T=T`m)XZ~Ysmsb9lf%)F)I$=Wu+7QdEr}{G~aA}GVM*d{8 ztrGoVy9Tnkv&H5QEa-tB;9IKI{fwhV{7W*@?6n5Xi+-j#(T3wU7o=E*Nk3B8gDIDn z95JahvksND^X^=?SYuf^Xx*5*S+K?UZL}bL?V%fCFqAGNw#C$m6eAL-etJY3x|F)x z7!N%fRbd0NTUf_nXke4SKpuXv8A_z^%`y-#2K(|xMQP+bng0ImxT6j^ZAGzh2KMe-0_3@-eFLyB;5 z+>)I5gyCHO{dO>CN-;EuyqA;S6KWsgpbuKm7(CAtoG|%RmJX$E_9K-6g>Hh|jz`O< zUSWDoe*$n-v%2YPl(}n^u?D_UTzj&DGlIwgVlb}&UZUrNpqydfT%xbw+=J5IChu?p@v-m>ti z?%+&R-Scp8wA^ZDqUTe0AEoRC;d?NTC)ja$lvi}!t2cAa_iZNGMTqa;>14+r8z{e< z0GDF+>qvXYj5bXAAvsN8VYay+wsBu)q~^zw6w(J8q}2vHl2YOgDxH zN>Yn^c~lz0bgBaSG6sD26^JJGqi7DBlGlo#HErCgJ*KTK#ivwr??upT>!YW1cr&tN zp-5Phe&&D|?=#0wL>ehoK((zi>@x49YZQr|KR6Xh6MkO>G=9!{7qvYgv>xb#RmTbW z?oizmFWBu}XeC3=?uU7%j`Y2y??llNdN4bUcqzS1(Mvryf$yWo#C^clhZ&)*@Klg} zAP!YfeK0OmP~OO9LqZA2ytyyd#J4^_%K%+aeOM2dkbP(`mQZ{?9xkDEN8D@mZwWj` z^`DWwlC`9rV@C7#p9MkhC`Wr0oP}87L4^_oodj}o42JSU3k7m>o)W!SFZVIZJnI3G z5?+;oXQZ#%z%$|(Zy>>^*Uvx#k{3cC0okh_a7*NIEzBqIUKFH!U87#0^?ya?7k@;* zFai<;p!CW`!(PPneGD{<2F#Yn{@@UK=I;4~x6kqU87-DLbI&#Y+NEa$?~L%Z^ZeaT z03HF+Yu`EaPCgz1@yqTx_z-#68#>R#1;90V*I}N1st*oNCoqMhYy1&{=N$IiyK0~l zxVi6(nj2$`fyOt2mF`Mf=z`N!(EcTV0HM6TxNj0LZFESc|bJ+5$GHA0}5 z@mSBf^btDV^YzOlviF*$YN;SixGwlhw*$KTX=L24sCNNwc*-(2JVak?gHd`0^V8s#XMH>dniMt}ca4r?R)6mvk5He8la7gj_P zo-gjiSzhvX_LxqUFK$ZWZ=n%XHe5ulf~60g;W#y(#@Ws3K{xjoh(2~m6IQDwyFZFW zoHWXAT?(j-LuD_%KB@b`g=Aft5KP*ij*wnY9t3Y;7?zCg>x?(L=er|aH;KiBXSVIM zf>D4^V_!$=2nMidh7jUgvUB#SuH5`;n_(Hh)3jMpPQs0@RxvfkEpNylo>toLL75|E z#WGu{$w=NT`$gORv-$laVLet=tC<72EaD;fIzOaOX*L@7U2@)1$%68I2r(2%v2^(k zi@yo{$FgN~`c~HPFD|V+=SkA-qn%3m=5b_NcI>gDS}R)Eu(s3A!YLH{1I^9=#gqp zh$0UdTo5Y9U~>L7pc(l2j!|j3^F(ij)qLFmTk(w%K4sYRKG1U_?EQ@|MX5wPG?wNW z^i8At2bR&ZIY~wy-wwG~69OUfq%I4q3*o-fFd5n}gTD-wM;bG#gg7b44&no)*v-ga zAcaMzv+!b=H3#1z1X`ESR)=!NV-G@~;1$}zFov1{nU}vhni#YnxHf~`qQK00e&+Ge z!wRdo#u&l&{?r(7O&%)wMAeD*H_s(<2j?%I%PSbuNr1b!@!>sRJQi9h|G$fZE8f6~ zNzl862P6vq=Y-V%ag9`Tvo-qX+&fF|ZCW}Xx639}6!5Mn$hjoYJ%x>YE>Inn?Y+sT1Z=V*Ds z-b1L30A=@LDuNN7XzWZ%?mn3#_&QM%^X1LAv3+$>q)?YeTxx*StZaJMKN0tFAjG}N zh{Q##p2u&*eO`7+&lOR;!J5Sy5faT10jR0i!(E@q4O^pkA_#_H8Hvu?V>x(e`dNiE zIKx3KS8|%!jRyjd9~HvAjqhA@q#v`xczF8N>CWfZsm8_&(Y4RvDZS%>nK^?iePVo3 z1tD{AquY;^ov=vzc)L6u$UD^xfdZDYD-vb9*TlTlRsL_4D<#Ba0NxG$_KMfxgJ$K^ zty|V9CZ5M?!s$RTEazAwF6zCb?=*Z+NEn&L6rXemw_2V+^4}eESv7yI^BHe)7b&?_8|X?{R8h-;bXrACoa7ivi;tT-nmH9(cRcRzSS_o69@?cOd02 zAf|RXiet93C4v-T4EPxKyOW5hw+z~XXdO*YD{$(|^1)~RQ;U1eK2VET1iw}d-cn6n z=8m~Ji&e@MsOqXNL$ewk4q&YsZH*}j(HTEOEi;*iD=eh56Rp8kUuC9YF(u&{PRM7m z4?UB@M%&e(HGY1X9!DuV@{*X?Dn~<;^2NjC*S0v+obw_@1+J089xSSP)07eRCN;B= z$p{7ayeVVSCQ~-Hdr!^fBUNGTrL^mf{E0?%3`(+-X>fL{MDi03PM5AL4T|a3_YIi3 zv?e|qOjopmdtwE6cc#&~b5fx$GV!N&13Q)O=6GxW{w9~lOIYQT;qv%fC&N-MLpWu# zwL&OA+yOFQ#)QoPLdwLRcoPeqJIpc|m6o{OAI8RINhudav zZ!8qL?1YC}SZ&NeVc()hzALl)@Y}ex4#l5peLpyZ32w{RyJomQlSeq^>;8mKX{s|- z4-TmWXn>lE&R#QWm!^%lv3(E~)mFOGu2#hKp35(U0d@FOIbq88cO|Dkz>H+JvGK!VvGf$c z6#{8d@FQfA^HRUFRDc^ZjM?Uw^3BHU@RHJ+G`TJo8f5DOon=(vtIv)d#`0#vI?3mA z#$+=R!VQ^$U3J6Q@PN9D+ls~BVy!M-Y ze-_1&)5ndvpSY@qC@u0A6jkxWQ!Jbylp|)RqyIq*1Vwe{03Hi1OrDiywHMy!qwL!q zpzgz&n{Zyc{#9Z`K0nDT|6Ce+C9GNI@wTagI~Lam0W_q{6$6mi+m45=}80hi29v)IBMA;MLWp&EAbE``p?9}V94kAk?;I!H$JqW!~>Sl z<%rf^u^sjHB>3e>Sx2A;sbTgy<5#K)17L_kjnJVZ249xJRNQkRBo6@fwBKs|;?!qv z0AhTuG34|nZVxZ|jHOO zCC{F^&Yt*Qe=V`sf6ZS>GK_g9-4gX~KbtsXx7o}vVBLv(i)+19@4WOtqT;Y4?c73b@ABt0KsscbK%^#L*(w|(7o}3a=z>o!i+IxT8g`9 z^+okgv4ln+K}adjMPV+}_B%)Tv-R8rOb~Ot&{A#zHGJQQGe!ua`E)*3 zghv!w!Hia|W-F8>a!;39g8rFR~^?RCVsq{%A@=X%}9iF4VxgpS2JlzrnSy#bNLwT(7n{ zspIX@BZj*B=21}IfsVA3nGrLdal&Lf)Sig!#9zBiff2*Yn<9Qyg8kmR)m)+%NJCj} zN)xZ0!;dq<yB_WRaQXOm|8&NRRM{LF-87DUBPV$*p7?nYu zq|$!&AWsZ)By2B{*epK5*N#<$$;!jsteDfloo*?rm)@2+t^!B1v@4WkQ>I;(5;r*| z))GKg)X|ZQiF@sUi4PV%ZiSZy>5+)FF0WPJ+9~QrSyqA&Y7S|?b%w>Pn<1PMgul|e*4(t^iFgqiZqe{@_LpyI zoHTB2b%Wu6>0cq0k|hN}|zMs8Cyu z<}lt7v~x_hj9;4_>}VdED3hzeu#v=d;2$oitYpM)YGhS!E}QafC18sJeSc+W>@pKa z36rMQZI|*og+lwxttdbfZN$Z5;Vy!>0MFIz9mN0nmk5G$xk{xB+M3};qMrPyk*35i zn(nH+13NM6zSw0MA9s=O=B#;|KMNa`BihDbijkaF8YEkPN&c`(;zuyN;LC(iIm|ZU zz?Ame+P1N%Gp!NoeCem~_;UI!Yy{ z7dMsU?KbdKVsE8kVqB=Bls9twA~)qQ?m58RpI4x~&@(nt7k9y~|+QITlF9Y96&BSgg6=NV7h-Vm?Rv4|ZAsAmXgQHPPlXpn6%A z2-q72SVzP*H|vyrmtMNPmBiexHlz8dm531dOZ2DIlW?Lv3o;d1SRI1Hyn3v8#jCLU zFbxJ=n}Q*Eoew7#vVObT^f%8!io^%JVn^_T$Ct5oU)pekmAv+QN4n^pRK98zHF7ga zdR#hgg4w4#AaT27MR?JXI{ck&tD?n6CyS^lNjjo2{gaCDrhRsTis>H{%@`6zM(!%6 z({YUvG-e4!M%%^So3=$ao-nij|lV(jyOc{7@xb8k)@OH_E zjY9K{LRD*p1y6}RHVpaDp0gb!xqAcnS8$(2-Oer8!svT>(ZIy^ZFdpQANbkn<3=tq z(orHi^o;k^&j|Z<3Rp%M|q5zSdGsb(UXEf&Kdn;#nOA4?wSuTjM>X7_F3 zy*`N{3qXn?g!1pNe#CxMFgm1i3gQe&Us!XHsltNOZ@(@^jJ_3utLXQu%y0J=>`f5P zq>sR}5?%*My~Y^6a+n7vv6cgT;S;Rxp)O+ws(H8~O?2#q)bMHh(JE z61uxvqJ%fd;u78gfT2 znz=s*BHh&bQC+Y)-c>wV(r%DKPm^$H~C^!B|c2z-L!@4rBQAn=9a^iI7e@Qbnc z3|%}N+TO+E|9ty(mg@!GGkw=&yB?1qc*^dXhsU2=p4{{On%TLq=VULeuFv8Y)N0=} zmX00lWXmIo>74*L?VXV5^SAXZ0NW9K8sS9~YqRT)OKek5h^Lp!)U;cbO2UW%KKdKw&j-nJ8ds2vW~3fnku{)Gw>{6g2L z<0nKx;ubsa=%HX6gS8&s3MQ6Ul~6qkk;78|26`DXlFB6KZT+F&Q%?}|Oys9KnnUN- zPxnDh`nyj4pYCu!XUBDIH^nF&#D(jgSZxkjR5 zEYRIC<)G@!8}e!TCH(S&ToK>9f7V6+0|pI7B#xJc@E+{q!FmCxZ{?^2Yle%BBET$) zsS4A}QpPTSI98~|;PK&)5QYQYJmGI?feYj<68w)v*FTob|Ch2rO^85`fgWLHH3KdgqNMvOA)V@=m#`3T3V^ykyB&$x~9-g}_ z%e7N=YJL5auytz!{Dm5~DC`Dc4oLkpV5Pmu&;+MgpOh?NjR99q`WvNCr#ICVnZ*j5 zA+mz5?3ZKwR0oe0!)$Cy4=@VhqAg_h7z7id$5z(XaTzO0vcW5lz}a&4#CWfkKOUP} zZP@xXZ^s~*H_T_O$cm7G*~+Vj=6o;+$X%3rp{OX+M-I;&!lTZI9nt={(I~YmX!)i~ z^0lF?&sBb|PLD=q-(rU9q`d*EMb1)_-gp*nnts8MVst{Ct%X~uo7H;H^#Q$H(fEL~ zVz5SIce<`;{i>4cTf(U;bFmGr$ulR<$+B)ra|-%K5+>gCjR$P%anh3*%% z<8=-Yy|yDGzgl^g8_U96gRQLNxhP!5R$+6pDcqI!25r^sKG8awQ=97QFO~v3IjQx^ zdR9J<{v1Urh^5d@{cF^=o0GZRdg^?^hZ#eZ&`~Na`A}x=vPhK8OsBnFKdBLd_-OTq zDEx@<81To6{|-kcz7#vlQlDR@7}4U%i+wV^Ys&eGX?;1+cKTcm^-hnZHmV|66SXt9 zh#lubS|6Dkq&hBRfH-1bK?7`xP+2J;W(5gISYU8Ue?QBqBORvPdMXLfFVtd2{x9Bya`a^`mcIjt5>lexlt;2018gpJwZ_OX!&?B34UHm)$v6IDXtiCSV7`4^?n0=U6w1!zu4=Vyuh1-ga`kF z^$_0XMfTPOkO;FxYP#OqKXYii``=H|J1m&8-*%!N(6%W4|94CLdx!kfM5JW_nn>}o z>sZ7uEH-#6mMcfKg>6&a8-D3A%|kvGlDv>MW*2HRav?jGVR=#c6+wUmtoIQ__6c!y zVUMLikl2MEAJ5|4&*pYH^?Z3aWcF=u(dxsYQ36 z!p`#)FFC${VnPM?kfa2-2*r^w5%M^z^L|9qWJHIz9g;f`&qHMo4bJ1fUALS4%2brW z?OOICN0Mar(>O%-*DpRenwt-#IWa_E2itq$-1Z9{3ih$&T6kIfl*LWt4n@8`fs|ak zSSlGq+AI%p%V+7Fxl0CFKesOwT$Q|C5i3ZkrdF_92luh(mT}M-XzUdVYcu)FDH)$} zc1F(*xS@baHMScfXzZ5j{j_k=QD~-Wrf6JnUv%^RFa+=THT`Qc2M>b<5!S8F1RjHH z_{e*{&O+!peUet8CLS`rv!(D*zc!Mx{W-5m$01xaV6>cm7q7rWobd*X`xH$#3Q!rM zUPX^34H9bg$#mSsr+W69Q~r{q(~bCAVaaJ(Z1n(k@DcVJWq_zF_d56vn%u48JhHbr z(#gEn{X0#1-D-VBFZ>aAva8j;>S=MkLsfbhLCXGh#kzOQ zf6yU7g;Z0dQQk-f#-!%<53%Y-96+}e)10>)(ygG9`PU-6?_@eBHT+6qq0W+>x!5$FMv!j+ke^+6Ic zxb#W$7!a=`VI_e*oBijkek2b-c|x_UugVjdVV>fbX)JX~--=Rpud`7}4tH1+u2Ub5 z8Uo->RRI-}@WpNfQZ@wGQY4EwH|Kgi@vrxTLD$ zT8XN{EC7#ch`%v)r)A|uxsplkl3_@VS7zzp%o|Q@D7$fMvogw>cUE2Hf|XSTbqL$;3KFw}t)4LV%ST zH3uH$4n3_?F8`qhTFP{Dk!^EB*Ly1%LTAYc9KmghL&ar@wg{2JBzP&fk$vOiAD7bD zz|LRd;)XApB$QI(^J1OgV9EZCc{k~w-=Bq5wp ze}{+B@TP-c#j&CbVua`N$S97VVp`qu9Jpkr;!yBvsDCgWkaj4`4a^?j$W8mfSH%Bf2OZ9?M-@Yh{x!^|ET%auLyf%!HqIn)&(5d5Y)P ztEr=xWq6`(OhxQk=M?)6MTvDi+jQ+P7bilPW{j}%=+Tw}_rSgFtMiHR-WG$JoBv|Q||=BE`Nn_X1;k~h8{0Y8^E|jaW$~Gx2Ji}x4CHNq$Z82=*7r61{K&vfvSnXw26+o z9H+0RsndEXt3KY?!HK)wM#t#c=rmhh`s?ewi0}THdF;(Y*j%7*NLM)i-dMnPQf0?^ zjWQD>rIpg%+Tc0jB!HYHZV~%->eiH%*YLDiIxkLLlPDP*(!4!1%8IMHJV@N?b0zwy zw-@3h!BU<6#7Wtr>L@+TT+#;@>K`d~y62mr_0-N|V-(JeHesSvu#hgP=23^Hwr57) zdcyp}E(ZFZI+}G2zb=!eLfXs>%$f=CyPS1?`F8iZXdX@%cT%{KI>$*rm+P^V$tEFO zCZ|dqFi6=cA6X{}=O1Pu!dE^JM12MfHWvevn_NSz@t~_ed%W|Ht?y4q@-vIJ|DIeyT8TXd@*8c#{oXQ?Aq4)zAPzw zPmmHjsYcVLs%^Hs)W{H@fh+S^xK{_~D1s z%P|+z43?NEQgDz$oB1n(+EXbmS1XKqp;PEt%x+p^is4u4W-?jy=kbeb`SPRYb8Z*2 z7G4$V8&snGf<-kqj72rZUGA5+q7}EI%4-BD0VV}p{Q5}QDDW)X?Z#+sJcYn z)M(Qwyu{cr9{6bo-KcHErh@rxY{O;x*qOv867#ea9O@&cJzv)aBLlBjG@~4iz?EdnT+$9 z%0OJfZ-X;sz|;M}3VDwKu&wO=imU<7$+>;KP9hXR9CVkL6>HY-`C((rJ1^@juw$#< zN>gD$wkEn&y{-LcX~EVTH_h22pJMSHx=Lv_GF@IJkd)pkjBF3nCKV6aUK|p7l1r{? z!*p0a4Vox%zj2c!d%tUm%Rzn8MSf=o21L#ba%IaDa-{>hDf$pBhqk~>igvs^m2~Cr z2Y*27dx2pm=JWkU08Jb!e!2A_1=(77UF3C54{E0{l)Ka$s{mPa1Y|uW#uHtad_`jr z=Lq7EzIoE+*H3?@4}n6N{DlAM4IYoglL3gK=mTwxvOoML!69{z+)upcgP|$yiU1TU zebqa+?a$wPgO-KaN2%Y-0gJMIZx{C~<}>~U$3u?q2R#%yav!i{Xo4`+Z|-QLp%|As z!4@#(q11amA9=#hXF_B09*25&kqN%Oe)T0s<%79!zwCaWEp?CHUo8I;b{&bh{ z0<|3w>Js}BvP}%~yTuTCXCCvvcOmpf?ag2YU#pCa&t>c%ak zt08FDX7hl`AM-)s_Pmd5Qb;IMUKT??w56kp{4w$8FdHR%>TC{Lima-y?xgkgH|?pk z3vVOyq|uHpI&9_`=YqnAmR#0Rk=VxLh0+ygwqR(wg z%i4&PL_puTi}Q!e^25k7L;(Qxus;P%@S`F_8!+OUqQ!Q!Rd=iKt*bD?9~Q7IB$<9< z@IZXb<-Wwp$WE*Ak}QxM^!FF0VT8}hVTD+-# zsG8HvX_Lht0{o=kb5)&zZdPd}4wHaq)i03_rouMwEWl@+pKG4i;^-#<;kE?6^=@qGsS8rmakC%pkQec8`E>{=X;@?+Z2O_FQ;H81x9M{*zUqJ=(re7 zKq&H(>PF_=N+4hN@;3wuoEx2EY_1RZkCSvdth^dLT`S2hPHfa??MhquczYxww6b|c zOP_UeO5DtIE;vAZoLPZ`N8HPzRARsP@bN#8qpm_fKa24Dy$EojaSN=idDS4rid_LN z#*@Ir01t4W#%@u2g3=h|mmAC%NfJMNLHLBo9kw>H+x)0iCl7;s>v+IwSIC|c{jm7MM_5)mb}R4{KWcv_1<*$rl5nd-h_v|SoaQn^O)ofmP@`~ zZ%I2*JWUMRh)^{ver2F(05zPb9m9DIzl5f$Ye4XD0l8T26KOybsKsIz0~WgL@3JRlQc%E8EdFD2XuM3^mg_Ft`q_FXUkkC72Pr=)k(`9>%Kh%~ zUjAMbKs#^6f}I^dvpH;fmNJvgxH{%_Hg0<6Kf}WQcaJwZ3QQlc(i&Lc^2ZF|{*2&LZ18l1yj%Q$wvcUJTrhpOgqtCm6X z4o_M!sMXl+5YL_rnb;F>MWN>>8?uO6*?96*_iRl^xAQghG5{&{K_pE8z$`pS)Tsjd zlPdYZEvg0faM89<*P@?(j;l;h4lmK}1$~Q}Xb)Riil6@vLodhKXvcSui1OcodKLa$ zMt`WwXEvbF>QHwID2XNX2*!ntYY_Rt4C-oBH`2L5!>2a7BB+Vl2tGAoT^(x(v9{d^ zngqGy9U)=t?=Lb!!ix`KgoM~)p-azlq5GEAwF&KPR`FpHUYVI^d{g_U$L(YMZ?6|v zzPmN;w)pfeMA1_0bh>MVjFV>SKX-Y`ul|wk>9pE(mh-8gzOJWO_i-13 zbmm{AAvi{}X$UXrRcURFMYOG?ed-opDl*D)oIInaEA*HhClVdj@5Hv50w@_xcc!!8 zW&urX7O5R5iqB<)gS;3JWangk?n=q+(}WT2s{;d4#1u`f3mM!E5-O*O4K>toNpczW z;Td$i2%7XPf{}o0E_kt0_$D4LIBwUjc)PeGH*Is%CJFe?1)kujbUfPQX(N6$HI_L% zo9BiFIDiic?wS609v}V+Cq&*+9=Rz!8wh=uh~>3?dJgM)FIszvuBgWK4$dRdoGKLgQDNH-YehS z097m|j-Xm^z7Fny+AP5#vp%MEyY%hrX;|Kk)3((8{tCLmUywrflXb3Uqw^m_=AxKA z@J@Q(Q6K^&Z;dHIt=P;qxM!elxfSv-g_S%47Wog(}<(bsNd?vx!&6m03kk+m_5rum1 zl|Ifkk1A>)&-}%DDyXo-12RNP-WStU%3~UA<1KVRL^Kr3F%$NW{ zkboD5Z-Ap$>Z|aT5dLM{J5C{^TI9 zgZ1l0Wokb~`o>My67koi7{!COrXimp=G zc}sxUyxwSbw|VCKAg*tg{BtwPzQHufbnEo;i>kkB)69-Une36O{F75gu0FV;V(y*Wf(`ST3VQkjDh+Dv}< zNYkh`oR7-=YocS>krMGRnK1F0u+It@ZyviPljjyfyS0eJ)8;|ILcoIC`UmRu`4h!LQ-!0?2$zMQECULwj?;#- z1s+wt2M>Ly{h5#KvaT3bCX(A^V5WVS?J*fS_56CZOYTeVsyKjCr6SuOg|lck*KnHkg5?Q|1YIP`UR81*qJc*gw@p@T~vWS%RyF zDN$wJ#8qy!ixUM2_BHl>_cIlnxiaps}twun?6}T z9gKH^{xNz43pXF6Y>*usMv%ifatu=k1Iu5|ON4Xl^ZL}KO640p;*pj2z z#tP4Ijj{E6Vu}$+%%_u)odO6eC|Y1PG6aOz_IG-uj%^k4Om3#lU$`~Y${$fnN%SJv9J_3Y*0TVztQTbY?rBOG^$%D&4V>AJl$b?^@Io)iwn)GX`y3gR5Smm7!y*(vgl_K0^pJB(kbtxnmo5hDc? zy7!Cvj5cVLGYmWb4{L7~R(IBAdnW{ESd+#wL$-JRg>7A)At-66QUySqEV-CcqO zKRfkSo$jjB-}ChQb?;j)xS4DH=Nfa4@k^s_N^conS+#(!U2rJzlbWp4vK~BD8P8C= z7N6eU4}Q+Kbk-7lJc=R0kG^0QcCe9Q{7%29*ml%Vl2bcbiXedjThX7+e6e`Uiw0b? zP%3_f4kngZ7?GMhm?7zHV`@dR-cc`+9HnmXT1i+3fs&g)NCNA9xQv7Os`JnI^Xsru znDb|B7s2Q5nsQEA&`eQPzlw_!pprMPRQF|+hgP$OXsH=b+Y_GPNaNdEF}9^jK;y7G zgRD64QBHK*)se>9CT@JQPfU3f8wo&qpy}I@h)Tf*#;l|!?BFXPZPxOxNiGC2MNNxd6S2&$$w3aYP$k_`BPY*l1XM{$cxmpeQbbf|?V zoW_ighz+u8Y*vD~8;TLo?VFqv-@GZgtx1J>^j}%j?~t;QyosJ;z=`wBA|XZ^ImK!} zG4_E?%;FS6wX%{i9r~z}-l8LK8w3Rd#dxj43sJH@0u*=xzK9i_a$2lDbtm7WecV>e zDwM_knOsMs!}j-M zq(0AI(h+|U{saPi6NcMTcvJ19*l41|VmZaFu{fGcTxjo)dB0sfz>|PAXK)$RQMiy zxn`$wi1i?8h&8>^?dL;*<*2^MB7(UhgbxeVNPlSR4ac_oDJF-`k;p!95d|-f+h&uZ z7mSPDaL}Z;TEo6HQloZUQyun%DcOTsRLEeicE%pAk*mOIwVSn9*h=KE9;HPMNn8F3$~Z3aEE|uZ>#qtcZck8$LQ`%aaf&g z#e%{RKL#LFSrW4cU1`-`#bFj=P=x;VhqLN)GCOLl2noPzLZB zWB&+p*NZ3nVaM1y$*7yk_X|K+{J!^_MYCW#KjzCO;_>L|`zcj>!u68s51|9U(!2m` zz5p*%sgE#~c^_}2M>X-sMjmW_+#iY$?af``kPIL47b;0P&GHmg;3)f>aR$zkL762A zfgPv(dUpqZB>e@`y3)04ome6@%52i;?x_Hyt;)76F<9azOVx7FLtKP1+gj1*Vyxe0rn5;p-17tf;~R-^naHdVD>< zc=ov9I=kTC@Og(dXn{rpByA!jeIf#qiITWs^->LxxXnSrw}f9&Ei)1uN)8xe%VCjd z*!*m}XabC+T03$W<75o-Vb1~_mXV_FjCqaC*646w*@YH27#xA!;X4@4xmLT4&AQcN zcpO%8lQZeYR`PvtUoe|}Sc`eMVwafi0BfwLIT^QWu{wFdW_z4Q5rR0xQmRXHv|R1m z=xsDQl@huRKU*;xz3TVnOQ~X(N)0_?3sIxmFpHxMbtx;UYTt>OT$>Dkd~gKNOKd?G zeg~sh=T)kCNYkMmT!SYyjipRiO`=#Av5su* zU~xfi`$(*EN1Dx2A@k(1Eru6szbm(Wz)3F62@QoO| zz7+9eC06EnW0`y$O3{B;JQTLC5|RxGs2`Ar5GvoD;}){6Y0`PClfLy3xTS=!0&a=I z|IinF4hYNkPi^NO;}rE(%IMfF4(TRMUEeSxXQy{m_$@i@8J8xcx~#qxUBsFS;2zoN zR(}Rl%*~*T%wF5eFg(9f>HQd7;5~0wK4FrNS9-cwhaK9L1a8F1!w7ZRD< zDP)$YYrHRA#kg*?YAh7#h+p$OJIM8Hm)!^a#oY-VT`}*8GI`&C5?XqY|1@ z6OovF*ETrd5_S4R-zTBD4V@NABVQ&#Kn(mA!M0Hl5`{+GVRX)6o&siwcyv2ONauVW z(&azkP!Jb%i_xId@$cne|8?R2)y4cJwEmGeIM}IWaj{GQCW7`ma&~Vzht@^&|(_!$e_sWwqV$5}@I+0Nkmz zVEpT>5=r?N6BxURlA3z^$8X71zx}n`V0op#R);rZB>Czhzdx$Nbi~yh(P4a^44d&K)*zPT z$By`|NnT5^a;4UzLEfW8fS+k{EF%c3efXSPja|)dIKNL!y9!Twe!MkcQLU`*Uf)7w zpxO;LMcmT+!D1;jx$30`6oc&!!BE}B=;Td-ezW-%?+wBxHCsvBZ!1~1-_6i^nxt2s zb{=@bx={Er`G-BQ8LovunWy)eoHo=qG$6nHutV?w1R0Tcu3ndSHfhqL*vb=Mm7I9YK5c9>?UVRko^3ShuaFx8 z=1gMlOZrE-81NPtCTV8hl|!L3Pbt#E&8t;GRoDMBTGxqyN7YoPR27$kAK12JNgKV86Q zr(k?HLk8256Dl6E#V%QDG0- zAUBC{i&MwgH8QO43IewU0^LcB2C8Ow_Dom9n(@Bs^v)TmA9p4!i5n>l>B}5qv#(%A zzetNYEG|8Oe86h(;6k~W5?conL^sHYUqV?uXm+od7GkanyCtsz3=A^{)RwYG_BKV3 zL+vrBmzak5dauL~0k<6^&Qu7bLQU-a+lJS@171+Lc37HkH2rq2kXI@&+(?wD(I92j z?cG8*MT3Gw+4 zh?|C3;U_;PZD#q6?migN8l|-ocCX)l%6)wNV1c+{xJ66si-RHAhyGQ|*a#iIWr5lR zd6Zdo#4K(?r6vwXMbHQd4djUZhYxtD?OVscPd-yJ{zt9+Ls0#{MquRN zEs^5+`QPNT2DpZKSai*GO-2E75c$kFPTIh}HqC^?`fDU+#!iB(cYrte?LZP-)Pgrv z)a0qnuuZbBKr8`QkZIgn%EonCN_x`s^+l%7do2Goe{#?H2u|j9^#Mt+((SKmpoL9! zRASnm7U+B7MWih_WOk3Ks3#a+@lC1UE?|v1JhjH3-wjCkVyj1aK&apAR_#)Zal8e3 zF_utrrPBSn5+%FC&k74Q&kBJ`>0CT|)DENRM!}QI5MOSL0b!NOpY z9AWzw!)#WgDOMyW`U4Xu`#@cG;Tj^tp1W?qL6qb;i1#~+pfZxj;_+yx!{TfyHris` zyKF96mK3_-08&wTyG#yKD)*Z&V!AMXtEh$xYcL=cwLw3*4O{s+oA~h$6&1bLMkf(- ziU_2lw%1FuP^m82jyr0WQ%_#hRa2MN>uS|Wq9?6GR$!(P4**gTgcND~>E#v%AV2|PiIcm>@V=yCDEJ~1LCT+;V9tY6UNy-#`t_>Npi(96Dq|e+Zl}`$Oi1b zwg&+uj5=8zc;yi?jeuWcg>8}I(PCxjb+P=arjxPtggJ{HMD4W3NY|U5^IkT}YHH=| zJk(y6?$CYVBfqiuM@jE!PwDX_^4=C)yx;srU}dJvg_Lrl!HD-pe{m)}D#~8p(tKMi zBE48M^*Sgn!%XvqnZsong#FFbtT6>)f0y2bB+?OgKmdfk4Wt%x7F_W1+Z*}_gbSOu z3;j-#fmZ=Bs8`Wv(-tw1jQX(!EU8UX=yN$tNxwzCXm95vHT0eoMFXinY4g z_Rsm?rYQCoOYiJOUvARvu@5ak;4>CZso&r;W&VTT;InHd1`I)6Wn%uj=)&io_llk< ziDd}hx@RlofpVgr8v}t|jbW1My*va?>eh5YvLfMLW^mP;+ATB> zxoT$d^(>)a*h(e7p6hUzG$%mq{O*S@nOmyw6!{9AV{q1|C0mt{nzO!mz-RdQ#kYd* zrYwr=!2Xf{@88diFJEp#L7ieaNGtd^JTL#a6aUpIrpG`1F_H&$ik0y@DxUHXB78SA zUxSKx!I?BaOT!MtV?Bqg8Y)Gt=C12hKa0GUkwLz6|N2)rwJDq+aR9}_?{MnV)3MXn z*XtK3kUDTCN;pu{ltJoF8k8nqgEhH@VPl$omle!|LeVnq-->cBF-3NWLV?{y)cMnk zAW@q%)QxQG6R1^Gw?{f>%-c!FF~y>VGEm{L0N!Stz)!L@Z;5>k6wRoXrQOH=TEbg# ziRgT;wab``!PCO2JN^T=U_JP>=%}25&7#7P>uQv-XaSs(dniR^GJv|n_>jfQBf@9Z z)EJX);VRuNCR+-fb|$}z!oz3j>Opgj#l6WU`J;wILKcCh=Mu6%9DPq%SBb}JR6V`n zN;Fd-6krxDJyE!@K4(_gNwarudD=V(nVDca29yWGl5CtTo``J8Vqo2%F)fScC>O@A z3W|#vnK@>Gabza&XJ$it$<-`iGKNZ|N(g|!mJ<+b`|8kd1laOKd84lJ;PeK*j{#p} zdoFohUfsq>5#_07=WS%;_h@KGvl!}UX=!*$mXtdyM-r7_l!VKL4xeF6U>D{3y4?Nq z)jka~a3)hC8nAQhyCjLn?d{yL*q!|r9ikb3F0Dil1soRw`hD$VN+G$AF`RkQrULZl zJSUhm(m`$c%yAquP08A4uCfn9qD45QIs@8?qrhC#DzQ4~KhA0oYU5ARK;PRzox}w9Q;GHG(`NCI0!DqT}0(pwFlJpbFPk z{mf|MQMJ75gS+Tqsf}ovEy@3kOnsU*aV9Tc4;u*)`Sk zKTJ9oUv{N_r$^U;dPJfBzE)svZD(ct8;@da= zf*o8V{c3fUiV(Kzxcy{L1E^GN{eme&a&M-#3<<&m;s#?Fnxwxo5{Sv3^SCpMQz1DP z+7eBxFrzcCfh=Be#_AX8SC0QmkCs>frAPZj|B)VT=eCD~sQ^4CBki@ZtZ?D~k^MV9 zdinn|K01OQ6dw%-OdmA|#YY!OBdqWHVijh`;`gqyaJ?S+X3wjoAoP7UL$RU%e%$On z-V+%Sq;72XT1n7*7ry<6#fuVT@oL!8Ul<_eZJ7GvCKB3;+P}sh+FF3jalh6X+8TyV z3DKqB8K-!d6Dy82Z*q(H!h$?SbDY#-QYD*k=O%5arUzt})? z-IglTQ*`f$lJ13wLcUwEyJ*(2Ucg2_VnU{;B;FK10?b<9pCoynYR6=HaDUDg0~rPO zUWUK(A9MI;U8>1W&>VgaHbGcp*Huzt`?7&_s4C>+9-FO0B72T4uSGLtm=@w?`{aM0|gFt!y1xLnf>Ia(n%43de4s5l` zA1xBvRPEtDu7N-)v1Z$-4SV*ZX>}3fC^}-;v8XP-0bd;o`VZKp+|TJw9!To7ha?l! zr1~FfOqUaRmdl)dCfIMbL(h|YnCfJfe7SpL)}FDKM_YDgvI4DaggSF9Mb9tk%}cbUzDjW0Rz-;Zuq%U@utW z8#LBRi#1kfCm8lq=MB@eu3Jbo(&y3>Rpl(2TY_0s-Dh(L15WY_j8Q4tnLa3*L&}{m z9T!iiSz|WqZpvQs95UY6U>aAQglqD#@!6FHSErsZ6gF_D!C|l$3{z;Qo=vZLVO4Ml z%pRj_K+p95hy$utNiE|UC+ts>j84kD+>X3zXe}%sbAf_3v2<=ZH;zH3ukw1nmV(Ro zdj%4@E=}1UZC!STm7C?d!~V+sWrrfQSsw9Zx%&Xj9Su`wAE4a%c<5=sl>I=R^ab6S zgNs=pfs3tdjP#HXp?X$q>D#V9F~vXH8ee$+icXu?o=wCwl+tTNUCrfx>$-ZE-) z<&&C+XGjiS8U}RS7L{2h-l_z)14~UYmyJXHD9Zsn#pH-EL;zxi{iJE7+vvgwuW1-* z8gXgSdD1hNnn!5vOs;K7YV&gDR|NK)L(?Xmyz}!2B>ZQ5BDBWouUx8Xtuf3EX`lPC**V>k5gW zz>+e*^~0RhVK~Xr1_*Sr)z!gAjoPA1Iv3>6DZC(ds0ZLbmHLDuDXXBBBlFkg>PMf$Gy_SWuUUMP>MIPJqa=+F zY0ooRMl7T04-o03l4Q)cDAiqj+%r@8^#uBwF;XHqQ)OK*6fMpEs6_>oom z&v)lPho>^Os7y#+HtZU)ban81x%pFI)K-20Tarjnel#Mm%2X=-KU%A2%3aRP7JP5? z-eZ132xb9+>eodjLs5K*8g{Gsu1zw|DBpfP+~R%{bCU-t8zXjhxuMppPSr}jVLF(N zI;#dnG!GTI%%sXx*dOn5jIc&QQ*4^vP3QPna~=#03Kn3JcW&wId(dQ_K2%rx2Rfg(MaJ-M|a&ryZGqx%oS@UPV2S8lF~KtVYOVc=%Z}tFUu0o&Ccs&SKU*> zn#SdOD8#vXv1qjKC8BT z@eJQVLHJ*v?MQ?a_wW2L-EAlVxF5`avKl(NamVY>KQbF%VnR11#ifdBTH|Qae|AR^EbFy|(&n zA3lEhpyv2i@7Wd!yM!~2w<_4IOcCx+yZFy0E-b)&;}P^w$pwW;%l&WG*Po*wmEVI+ zEIy^GmBc{7_V*+?70a;ap`oEfje-#LNOVkxa7#9n^+pWi=NO|5KQ$x(kNTc0S7O+m zYxMQyfdW+$9wr?r7oJI6EHAfDE3WVEV&q&#Me>MSi1(B+j*{Fuq`NYVk0hV2rIl z&B;krIpb3+0cISO98qzlVjokS5oKnOxav6$)=Q;o)kp)Ej7rLrFtv;K6F?e|Cm8uq zVRy6Wl9q!5eIEYs98c(8UGhP!DQv>m-l;+iSj%T2RBPLQs|aD3DU+B`of5?-yp3Pa z@%i&Qh#m)+%K}u~GP5bO2@BE}d$@?9mRYA)QkIOu1#Im`iL2P$H+3pmLQ$qt6ndpt z?l!h1?&);Z-&LyFGN|3-x+$>fH8uN*;$7!-RJ!VdvB#Lp;bvTwPLzBw?gA%jnB$nr9Vm5=@2cWl{GM8Qm z_NdL5HF1K^%O5Xx`mw;Xtn%Vca|<{2Bl9nQ8vmekb9Jk+u8iE5)Dm4{J_1nf&SA$R zo7`lQ#j>{?@ocV9J@TI%8#R3kd$&cdeOH~S%7<6BRH;8SSc-LbrD?qZUGe0WYtngi zCIpT`Ea5j`9p%J2Uo%!|w|FbLXRj)IQcgX2a$KtPg()Na z03Qh6MlgVu=!1cp{%p+qS&lPQ7w1-?hB{Sg^B;PE@3YleBIuYYfaa>7|7XYSuY>i+ zOx625`Gg(Te+%w6MOCH_LhrLcAhoZN{#bCg+-^mC3aOXIvfmEo!|#LD{cF6B(3rOo z9c?ifIkoO!-Eq==qWPel-`o2ERv!!w+i6D=XQ5WOo^HU7G$Ks{OgK4%5* zHCwv2gtWE0E@w=Q)Inc`4~IR&>kvg@0r0UQ6Da6XqiG#WQ0Ho}rTU@^BMlJuA7nJ| zA^kwG&kxy54*Ai8tx45ka=4RNPqU8C6qmtv)}n=&$>@ZZr(UzGftIA*d>;CPzL4gb zO}9QIuG~$lgBs(+fn{-~q+__TITXrmh*4<$r277`0t-ioBxWqYjO~IdUL^{hZYA_d z5KGm;;ao+#tN$0pTN;#Pd3cC{W1~r1nGI~5dT;r=1$>V;&vVw0Oe3mv(KpvgM!HOm z2d1&K8hSRtxi7-jgbHzfnzbePL>AUyOIoj}!$qUT%!*7Od)2opXC)68)|REK0|n2a z!?M#_cr+9FY+y1Cvh1XpK9SsJgVN2T;b^!tbQ6lmF!|n)j!Ok`r&PT&wG*q~{}g?~ zK;yZ3tU`zl6_PA148nIxGy_g%`c4 zStX4i2E^?`mrIEYeA*%G?jTK)JI&r1|F{TZ3tz(wKR5H`{TwmPL;VFD`&dIrH28@A zSP%^61RWn9%pHvIDCHyy{2H=9>`6F%T|D*=ycEu-B*9xy@1hQR<^8)w{~sh( zC1a<**|Y4z`Z1KXhJ@XgP2zS)m8v`ak%-FR5 z0yWK8$1*t)t1AeH+^8cH;+5^ElmW@?A~I4n&$U&!3gf=&s;OBvT(#X123p$xkeU6G ziG8X@@-yIzoBJohC~WS7JR`z9k}r${4uF+gY=%{32>Z?@b$z*Fau2`k8JI8A_~ykz z=Yf67JTnJd$ZEa=s5Q}iUlzG(XA{h|BDdGW#xR9+)Re@|%_I0N^r>1M@;s*z>NX$! z5($nor57<86by=9=y7}ZS@USGv%Kti5fmk9;O^}<1o7cfc>prZE7)mg&&(^+#+)e! z&+IE2M(oarkS9cufg{(!0S3;gFZHe@p4`C+ENm>vgNn}X!t}Uu{+!~OOlT(&q}-V} z^}ndH^Py_fTsY-_mN$6WY!uM-#`)NQvtcnF$tG4wU%;}d0KF6K4G=UO54Qnd0vNLW zz*J$J%|A|QuRVa@bzDRAa}X*lzkJKLMJv9h+e5azvEChnEMe6poyej~vL`n!ZIZ;J z;0kS$HGF@9+Lllm9oUq6@&NO9VfDy!@Cpso3r~T-7yo_g)W164zt_}1G=p)FW`Gss zW5}~KV82F|5BkNk3&aXGW(%z3(eLK^%2NV4;kR<@EIp2`EG}AF)B3o4`w~9*2)==D zg6(~4A|mD_vIj*L|MlDc20nIbv#sMnVgIF-L~*^|)HLHh#g*UW`IbM^3t_XD8yLuxNabGQVZ$F>%gTxR@| zf?I;#OU2P?c1Yedo`~IGAKOh&lH>4Hl3J?VonFg`-iw;05FL|M>R{t#peRLWzwnq0 zx+P_=&VVO1#t@$Yp0&`~OMug}T3I^DouPHuoVFl{n6pEN#4obOWU2ngBxj-xTI$@P z3F&|pB6>w>6lJhp@orIJ4w0BXEZMSFX{op9nsVU{iS-?@HUFB28ry_s2z9kW!pWz= zSYE81J;@?gRF(ap?tPi8S#EwiYHDes?J`v*=jncyX0e2su<7K`d*b9S6jQ4UR?`xR zgQCPj)mpU)lEY#Vl=$PBI#*4OHc#|ViuG%PC1EVom3j0jW_>0seAQkUey%un=C*7z z>rXysR^>+T-Mak^z9Gk-lW0wdhNX$j+ zbGj?3a%poekj?^wG7J1%9+G3S5}%&D=+*t?MX?cYG=@$qR=Aq~9G!Jx{`xAui2)0n zh;ryJYiF>Kf=)+ihbsb+5020)zKJDGFv7dK)xF)l-@RoJ81w_2qB^lF%q>K}?8v>= zILBpUv>_@MuBF+Mbg{EpwBSQ|?~0z;1rF3e-}hVQ1ZxeJbMSo)L>J#k>otGVegA`~1TV70>Q197YF zp|ALX-{rO>e6N*$^Qj7>YoQW&G81`RVXpXtzN>sk=0qF?fv)rfCkT|!pX*k+KK8xg zID85-1)rE40sUd)Uw`<%+N>4)#<%NuQpm>K=qPxqikftDNLG>GOShr(p5vkQX=b zQ+G#{MVHR|Ed*)Oy^Kuz9lDAd!|&-Q1~m*jmp*^LcpKgrd+I?QY$&LM{WrE>|BxL1 ze(}l}TYoWjAQQ21w*HS^7UVhgPPFt`aG)X~QC5yGu~w)cDuO1FpTgssRwpC&WL&A~ zi8;Y*7^$HhI4f- zSV#s#^Jmq`N@TSbn~VSLH-NK^a-QUv(lb7R;$8x5AemzLjT;ReC2Wtm-nA3hNC(Zftv6oASqv-l7J9&7QCkW zn0?Ur${Z^mcSd7g5o7Y*DctButZJKJxkJdE(7H|5kcN5O@SA9RGdzb~oRQ|dI9%{4 z0SZ0Q7(bB>vYdILUl=h)aOY{Jg?*6^;V`1uYWa{?Rx^Yn>-^c3-Ve>t~L6&~=H}tZSrkFvQc(|s(75A~tNLU?_ zK!X8v!qn9xIN+()G+W?g)>%`Yv=~4zoiBr+!>DQ0lrKl#lK3fc&ud}nOkzi$TSC4) zIl|!9=k+ioW2plFQ=!pe0tGqaY9maMjU(;NGjVSkiVeDcGNvL%){+fpbVRoJOYvS~I>xq)`8BN2!7%ZChegylf^1}k zix`MK!)nJ z$O<$qMZ3M?+zemK=k4=~L1F5!o%ehMG;9x>z2@CQ1E5%U}d4xqDdV59PmXR$!eYQpl#m_Fu zEmF8hN4^lz?#maKBhR?Rs*}_yc!XGz8|<2Z=JXfQj<}JU_JoJfl&Vv*!+)@fbjaI; z#qjw@TtHoly8t9;YAXs7{Y3v4s`bxnT=`Fi_PnkZVl)j+Xt13b+*itN#Hu2J>~9!I zQqTiXHT1L?plqUZqP_nR`=Xd9)?r?0z`H$~Qqt2O?pBsk9v;tjKp@vEI$yxookOYE zwv0abWP5dq<)f&bc?rN~1CR%Xb;}0tKGv*1OA}x|WPvq*`Hh&Jw1j+%`EXVdmc!I> z5;X%D1klV#@)}&5xeO-eCgvz1doFkGp3<;eRSB!S{z+@_qr^qR?npyKQ{@57-3Xf` zHxR7XNM}&ed9A^MymY_Z?Q^(_G6mDe)e(w&+DJOs4d@i?WBs1l0#nSy57O-8Q^}y{ zF~=hY2M-}(D%@~l;vqIh#^fVuugDIqm{M5By4{D5Yj)ut@Ac$<0aPFLa+t#aS6ekY zG3c2n7!tHXtOsRCzWahAp-b@2fe^Yi!?ASSxHcNQv=;Uq6A|NV9m8zlhgd?91_8;* z#Hfx*A;mdkn!~G7>CHaJPT_`vLb`)w1z3+g?*w%a6q4@c+vz7URc5tPsnHyjP+4+u z3Y>WdP)p!G;&U;ocNFUC3Vj{~?Kg2Fe0+z0V3*-AJ#MWvh?j9})(ZiDy;UEnf($5B z&Y?>iRk5t7qZqldJG+%nD!KE!))WU88zyZhgAvs{~sgR?_iBKHq)t1>X5nJE9riI+U8V+q-HegdH)ZA@mGG+feF{YRXE8 zKgNH&s&f^#oQo5CaWh}d*!Lm=cT_3ellXtY?~p?QgWFOK+iT5P#~bCXq(tQCp8=)3Um%Ip8tcY*nzW1D{+xrWZjhM>7n*wA3jTg?Pi zRwh5DZdeJ!grL~t6Wvzo1?`K}R@#QQ1T54t!~xT{-<=Zx(<(vW-oR&U?0y`y8T9&m zd&cu^&@ELIZ&YKoFVt@Zd-XHOf8CVS4LGNrLPNtgvAU|BD9_NBUk{BWUUi17|FY6U zueEv|FnFn3+VJpxf!?O^MkkjZ=hdY8xQRa9)!k6<@Fmh1+Qy@0=}7bI#?+JUEU8G) z2^%#^WuPU2-GLpxurVLPc$vpO;xx_rom5+LD2PhKj`NQ0>_Ik!kM(U3hod$b!5=&j$!ZmAotQZkpctW`Fst zQssV2*m;%RE8%_>I!5IJ7arj1uw?8Jo>PCGYZ1h%htcO0jn_tq-htv3;JWK5LAW5o zQfB5uDnJU=vn>`E_>g!x8hIAh!H}+kzmE3NpFP_=vXZq1bO{$$8*c8bP{#Jx)+e!I z<)d24A9BQze$GzW?=+Oa~Y*# z9ast0NB+GbFA+btMWo?hgajB{4=7ptLUWMWi%cbGA|maCB5enD*lJ*WKir0LXK9>= zXOIWX^B%F+`|5>$bzZcrxtUD7Mf>eb;cA)aFK48;z28o07BfW_GK{K;bg6(O2&(^@j`T}ceE;Cch zhZ%c#qgER85Q=qG#n+en#A_9Np!1EJFlQdRA3^@XV6N)^UTB@A=^JQo^9AK67Ra#4 z`vwsr7t}=v?6TMH*%RO=98(iV$O$0{ToI>??Y4>DKxY;B=|=kYrg*q;6ey3o1mRW*Jq83wV+o7gp2#G}eH zV^nV9+CA%ZjNw0ShcVgda+BFY*GtswIS8ORI{RPR3*K_SlTw=1F80o!HmDCr?Oa_r_}kXF_oVR#slqSLloO zlk%D*7p&e|oIggbIv?d@)_$dTZAXZ1&?1mg6%v81g`J_anJkA(L{I(nqJ_soM`GO~cZN|MW1WLu^@0l=}ra{v_~4s$?55QNkJY5q-_!=(8GI zrO@0>RvVV)o)=X&0#} z+XP!(%_l#$2TK{1B5!;fCDU6X)g$L>5IZOT82m|_^lLincc-7Oo#1y6F=o98IGG9E z>m&lH_hzB&7eq*)|FQUO5;_6-V|G5EKETizkAYZG^n_=KpyRV8noM0s-n+^}rC&IW zS3t1Cgegc_Jkl$|TmgNz;1!rI5|bHis+~drb&fohQ^6spF_z~S*<}_i z3K?z*{gJe{0aN3F&xCjz-><~D&Lx_Z+`a`FO=hgU)Eum=#dW@Uzk)IPDWV9ueea4x z8@7Vw;+4_o3^aAi__qH311YR%++kO;A116WO|rgxqR1NBI+nkt1Kt+8)%jD8+GVJf zh%UUgtynjiP#IbR038D0}}N-AKV z(~kx`+T`qrGC(ByDvrji@hI{|!|t?Nletu0XzLzmlPy-#w!ehKiiv^OG7T#6L|Hg% zR2faWc*ro-AQ5_s6zt{$m=ktBhfMp?!gDlSJ4AGYTyy9G$bTx@uQkRD5JLuUCFrgo z?0Mw*6jS+RIl3olU=DI6b$<^9+YeznZ<@#(rZmz)qbs8N5|jP5{j;daHw`v1$MCy- zJQuFaEGI9}zMBcFrH5o`b%}93EiFf~&9Yp7;rOns7WH#^fVFbV&xQII0%Iy&d|HdE z=RIFh?5-;H1R*l&DH5!+ccO7jnzM5V26b>LXCDa_aAhgRrFjKSu|^1LRlz15*nc)- zygyRX0xXyx_ZTnjv28Kk7*B$WQowe)%2FTf`iY9L>ylf^mvq6*Auc%zXzh8~_lgn@ zWzMP>z8rqJ3bWsAAP!(*E>jNPAE_xoKF3_WQqwAF@-F!vpX;7z% zA$WGewU2q>4r!8#KiaIhlPj_ovmY`r zCgOK}d;BKa6qkg5|EMK(ao0|Qj*dU*==}G2wEx8b?5`uE1M0=l_&_*XJx>*RB;`I4 zt!bT0xN53+!N5E-X_#)xnzcyhVV6cw^1xG=rz(p7C#((WXN3WtR{83>6 zpf6sbh2i?MV83NGfpL-uopr4?y&&LV*XmL;g(p7KI2as3Xwh<>t5XwW-3rtp^D%QF1l60Wf+Cns%jm=g0LuZfNGhwV0~|?_;wm>6?1oTLp(- zM0&R??}bm&G?&oo$UP>f-Mf({#D|N1$aM7J8|qyHR&v156g*Ji+`1X%`XmL)@K9+< zM9kw8fLiu1IPnNn5^a4s0r_MO>L$quBrrCV-&V}Kn`IVu*!tJjsSMz$DDoVKQ-LZ1C{dED{lx1nF=4?+d0Z&~OL*$dDOVBB&plEK=|;(qa^<=;W+LJW z3Dfv_;n?l+`q?Y(9BjGxyq3X9Ao|P!YGnuOEB^WN{wKZJvQVTK&%yTN$b?2q=aucm zq=+e8AX$4``%MI_&NMCoOxP9Mw^OVEFOPIj6pC`#3ySgATMD}{NCoL__VE$c2~x6o z#uw~U%15Pap_?|IcTd646osW=W;&0HWL8%`u-#`Q&!mju%N;ndPErcbc^Do~{ z$$D=1C4LF}8!0Jo8`lWMU;&49L;7C-;Y_5px*YuNVwDCpf&cCTf{2@)mARq0lbD08 zv)x|{2!AuOS}RfQ)n+%bLIjK=Lv$0@K~pmaDJO7Nq+8b{oYl{}FujGM5=C!LL@ z`^KZdz?8GrUf-R0wmrP=T&unFIApDkEM;f6(zeWrJQ-N6vL6*q+j7UcqH|0jXy)D9 zQg1TGgYctFq1|D181163H4sH)a)p9Kc{0WsmfvTnr%?p{c!lBL)9s6kSzsA%0Z93~ zN_@g-24I&-KmgAsu=j};n6aH*4?Jyd=Hwaa?u|*FNe}`)?S2*(FRc_Lz_+KD;f1i= zGX$1jn|me@7Lj0|CuNH}7ROc?oTuRV+;&aj6$u7y3#10%Iu>{ueOhYT(T772deZxW zWiv_DQ6kRJcNLIVKZ9`I<6ITt!R~_9lGn*Gz44UaX}Wwl()Co{$x+CXQ~>3FO(PLd zaU2|OV66J$Y)8`beV2EE#ow!}Zqg8E=_?It3cq2It4oxb2gUIfNp4|~X_5=){Be2A zOH})~JdpB@4|*A7WChfMjI5rh$pe_1S->!~hh58Et$Tjo_6wiSFXLjY1fE?z9ACiT z>6F8zoEmA2;75%XU}~vGVO44CL`)-|^F;BJhUe{!acor?$N)Ao)>o8&zgoqZ)x&=q zS&Kl9gnzdy`FpwiO}!sa`qRt$!56ykGG}gnJ`|lz-Z-p$Sx_qgjfOoM7ER%)L873_ zsTS8YiM@TsvF)}eY6`@({pA2++9K{Pul9bnEV2H5Z=J- z5M1~_4Muz-i^lDORgD`8n*?!Yi2sO(vkJD83XnnWKr<*M6#7LIQW^IPXwbDCl|;WV zTTWuy6q_=%G|^C?cC(GJP-0x$e7&e4())b44Hjm>c+@y|esIF~LH zEFL-@AvqCOZHxHHU6)(27L()ohK6%4kjpz~xXzo>n@fX2GuZLd5LXyfBKli z(|7C8EI17fM#*g=n%lm_6h!!@6!t+|20A&Iv-Dve%jNajVXO^}8-=D_nn4)}P7Okq z^;=pEG#&)>2o*_M0WR1#k>QfvfJk0L)7EB1sg{9T6j#l3t{{UVf?;_Z@!2JtHMpND zB2weGP>L&>!w^EtiIFbNbF(Z#rUt(%V3H;xML%((5o9u0khhkV&n!(JcNjh#Op22( zY$)MM@~rSHc^~!?PKyt9{7q83LcCl&G?jg{cD#$ptGJJKiR+ipGyv~d&{US7qwkmDM^to>F(~3kOt{4>F#b(KuWs1yStGF>F)0Cu6=`ZzI#pg8sE3q z+J7I01ApA(eh#kdI?nT3-H%H4ERkxwW}voepsCQ@xpCK=EAKdwn#IUBXtk^P@Tyi( z&MX+`L3Y8%^dfK5iSZ+Z#-q+hX<=8SkKmpVBAw=!B=eJn4vaD5!FpWBs56s6A<1i+ zQUQfvHpT7HsiY?T2rXK`u%`ReVtOZa^hwJAFW2Dvf5l z_3eH}`=LFM2v{L=`ph>>|D+QYksFiiJpHL?V(<;EEI#=uWKv%DDcv=I6xIfM&U z{%zQ5LaCnpF@2R~39<*vCQxYW-P{Be+AdzEt(oYu+ff+2=UwZPx#u+5%0&KvZR-&O zkvqbk;SeoA+mQ&GJL}AUa37BRB--yB-qkd6;|^5Xav<5hO*PqqA0Kp=y^o4LLuT?n zV+TIJHSTBslAn|_G57$etef}vgRG67Xybs&D%;P-o4?o+GTsa-du`KyrK?JM(Tq0H zY@L0hOKj92Q6aeA`0nV=eQ{w!`YwwmO;=Aq~NNL|lv?kpR}h^ZbM3;P3u{yLy?VSs9(4(|WVv%L#3I@Fi*t)u4 zj>O1B$i(vz(mJoc-T$($)2h0_TlVt4gO!y8j#rQ9VZS%A7{(U4dWetB)!%rTYIL*I z9zv*o;}TxV^n(`I%`;XjM&Z##r$AnkF_|!xHL13!ySMMAuWiZ0Vj0lG)a+(;9zYz_ zYqyzY(b}sv@2hN!X`V7J;JhuSS$i$-%YdSo(YC9tt&o|kA#eaOklONw*_S||y%F$D z1C@2i1jD@Ng01F2)rVpD4|7{5g_>kEwC0qfN~zZHap)z$-RVBOssVFyw(dkW4?9-w zg8l`|nByqiC8!<{Y(pisTveO~7o6Vt-bY)#@?(X4O;!`VLoEgaRT7*dm^}LxNhG-M z#F-&H(ZxKnn4DkcN1~0;Oh2Y9Q!>zS#JM2<+a-&0eeqLqA$i}rwhskAhHK^(v(O_# zxfwd?CRepRm9Nf8t}sr0bp1yVv!uH1b^6M*{9gB}LS~LkDGZ!FWi(SKzWOnDwbK>= zJ!}zK(Lo<{%XPf3(Oldhd2$w|>uS$Xu*+^fv|*tv$^gXf)N={#48XVxs1uW`ccGLk z^%fAkK8fT3uC7^Prn`rM6q68<(S9`8Et-A8xQJ$gsGsneSD`oK-z7#_MNxYY2&7oN zOwm6acjwaO4uj3SKlS{B`%X_SVE%jV1H@EYV@nHpXDj{xFYXHkY1{Doy8KQR3gEtv ze{o+ERuQ(<6ACFWUTYGrPpmx%IWZ!ls~R%**5nR_O{E%WUg0qRmD%|(nHxFjudN|@6_69|Bh}GwyT;Kai)%*$`MLm;@NDF_- z=@@F?{R$@Ek|+K07&N*W0V!8IPftC)L5=`RnYckTRzPL4R5Klp18Y5pIloq-`YUCH zQ-d46wpD~h-=Cpp%Obp#CI2<|{p;iM@3{{Nvf2-uM=RWt7p-WDS@RVKz<1p!91$AoHy;qY0RH=%@WH6V9f^TOg9mQJGJ#H z>#$R!5$t`7ljr%G^DC-FvNTo;c1#(v)TUKm6>Y`da_4T()|0J@Gsh$ZYsXe(Vuj)NtCev|AB|r;SEtH!Rd2Z58-O z$FIR$+?W88J@H$t8$2 z%(ax?4+jQ2ZY{1R$2NK$_xUd0WUvU1yf((}=Youh8S)^S|aI2At z@0+CG*q1!?jD3z1bZ}Q31J*7!0QNNi*jHAFrqSo|E3`kJq=r#{!J3V`=e_4oQjllt zQ*(6)qjeR&5fxo92C&cSga4c12mt$d$^8+eA1J$7L{^b;0{%DlA*NCB6Z<>Iic%4@ zmkv94?l|Qx)t>rjXxi<}=En9s%we{R-x=!i$aC0UgWcI;nb-=2naQ|mJ2@vbVD#BJ z51=fvi<=F@8h8G1U)Zy5%AS6&ahp{SGqoo-;I9bem)v(krUhS-_(3nih6ar7O4eqm z6e-f=Y4kcRQsTB>kB$_6a9F?J%^j6`f+x1; z>HiGb{?1c(JBQF5xpHc(gvq6GbY-d4Lon#UD;ei^3^V|JJhxz)XR1HIiwyEm3Ton^ zYXW>!f2@IZW@@38EEBn3j%i;}Oduw*cQhFicEp{IU3KZF`oA**%dzf~`#N=B_}z`0 zmqtc~%A2c%zj+N`>N*NE^O}T81=LObV2;!$CFHu<%ht;hcY-63m3!NJR{3pGF#6qa zt~L5o^ej7m=g`N*rR>)x4xb8uloIimNatjE&KA5*Ph{)lbZbio4<#T3dQd3QJ$Lqo zyUMl&*^_#e3r=#?jqf=e`u$5dG)C3g7vvOwww91U$)hFWsUVO3P*8>OUwIh9~)WinyJm>%9mppNSlST@qd>!Gu zz>;lY`f}vs?P?90;xzQ(LMIxPgpPN}SHuP?=kbpdq1fTOIqClz`u^pe_-~-Eywy$T ztDmZ!?d;nV<3Xd(+O2v<68^19nF|&MqPWr3p$AAes(`T6c0Jeubc8tC%cZ^JkGPz- zJz{UMJ?d?_dg&FBKW6$tWgr*Z7upox%2k|I8ro_@U9(#2!9P6;%>3iJ> z0u$IgL+Ux3qGR@U<+Af=**(n!SzF1zjS>g!h`R(|<1q=LD~AVEOXaq>5$YV%vntJ= zg`cPDd~%LK+yY(Pxv&Zpg+e|PFUZF&cL09yx%3731O(f{gYJ|K$b^3*AEEj%{BPuw zD=8^4FBEaYdq%!~2v9oQuY#OTSpz;%0PrEnV{A$t1_zzhzQf)SiTr8GEr*3I7|0IY z9%WE)Y&I8kw9IBqCY-Wk5IY+NFDWX*x(H)&`R`Yy=NHmupA~mWA5A+r+dc_E5g-rzzVy ztjX}8V#GL_5K$Kx{-t+HqR?p8{`>l;yCS??8&aP?g!YlXrMtAi-3JY4I>T7Iv3(=5 znMEr?e2l&0uE+BhkMUeG9Q@RqEL3tCI{Wcjg#wm>Ns=X`&GMgv8!xHawP)Uw2j+YN z|KXxnR^Qgn##qJ4oYM#=9xwG+p`C*DCc>SGU*mA^$>rF&gUD)>Xk2)rEDNtG)p7Rs8=E-%O+v zb@_Y`Ta4<3RM%JSCfEL@Q@j-ubUP}I1nn%x^wY2&{r+VMQ@Z`?Px!7M)Bi?3yv2!P zd4j~uFgkY};>Z`|6L?0xUa=ED?JX(*`9J~WLldOxs-CJAJX8yAarvBkb>7jj%B$K| zGJ6e{Dw_R9C%mt%?OP8b1RwnL3yqXfhOpWSp(<$led!X~=8+A=V`;r-Z~){RKaTP( z!GJJ-q%&+t)=o&&=3$I;%;&6^q3_oyp8Ayq!fK{e^D8P`lX9E6W_vWSJk8RNq%&(0${#4`v4-Q$QrZeaxI$U-E0{$nZBeTdFKXo)gnkw$KtW!4Cihpz`C74 zL})LKN6KXk!bM3*tI?6yuu<(>zY2QetI4pB?f$K8niG2rE_{fY^&L_n^=otpR8tc8 z&rI_=wY068XXa%EcOWo7TC-sRTIk^H;EZZRBzdnVAw?ZwD^ix?O;hX>}>0 zy>Bj~qX&HElce;9N|)TTB=cmBR0*Zq9YLa57+lW%7V!2}I1Wizf|>_z;03Vl1L?4z z#8WNc2OtS1y-N;n$MP&`x4!xRFfN6P5pq4;W`kX-;Tt=^P=OikY!A%VwEJ}ntsgab zL@+lbnNjrXQDbg&_JDpCNE=DIV3V?!l6-Ia5G%txpFMAvq?A9;#HFcseNwx;klZ^a z-)V+HTwvq`q>Z#<9Ck4d?LNXTaVKD~!=@bt=&LO%sBZMHqnbNdDp5U;HIwDsJ3@cW zu#^~x`|jDeluh?WN_pp}8_if<7LaJ2j@^?R9~oOG7}Z9!X`quMe>Ne@rUN;R-TOk| z6H!arA57QKrrfp<1!%Rz+P}#A+dpZ)R`E51&B)G_Dd|&$ah*TUZIq|l=9BC`ZsVI& zH#bURcS-xkY;nw<0r@iLt8H&8)OBs#ggR^_EH?8EO0Qo!?p8k{FBS{&$TQh=@!Vw} z2~JO02@Z9sN5bd0rsO5FXt=N`lu2^_CVf@%H;<;XH~Fp{1epH`!H%+8F|&LQ#zB8RQW?U9g(AqC`8 zLL`(V6XcI&ron5G{g%(=(iI4syz&G0!SQuk6i+hV&X_>C^jDx<`qtW;{hb2iP;T6t%+ndj zvxeGfn@5`Gq!Dq1RbE;9$3?lbw_=^P2#Z(7DNJXYif6xwf&UY)Z08;RLJ0I?r2M^* zw`25stg8-`S;keu%o5*GM2os}gXf@;gCLhs=UGX<&^~<6`oSkR!~ukAtmU!qKZn*- za~s~ZU-+C*8vBXvKS5vc9@n<={D4^4y(!Z!Yoq z%OV`YI>D#MH~)Mkh89Y}JOdvhFy;GCcV&OP693vPM;<)S`MOd#t*|r9=$6ny(owO~ zspVv>O}+-gkO*WDLVO6DJ2Z$s*Efclc_jD%gxY^VZ;87W2IhSFxs=}CBnNetLr3$j zr{}@>*ucsh8FLdw9k-Rtf{ct@S=vgjl>iid z94(pjYkqsXv^TT`JsGowpvSO2dT_mYE1lBSx9HZnc^BHC;Jw(du4yBw$$hLwfp3zBlWLEoT!yTe?t6JZ-!X;IH5 zckfuu4ULjD7Keb3?4GsB16~!4piB2Sr#9pM0l(CGE?sG6YT@eJLk6lYQ>a=L(3;zy zrC3636YT>RE*bTgZte=L+$epuLv%=&!>#zLsDf4%R2g62P~hnJXkT7q=CK9Zo>)UD z_JRp@Gu?L6BZjoo(ZJ}k&6{GB^qXr7!uFAZzD-R|)FD)jOLM_=U;11SeV!ylMQvdG zhDs8;Dmd>#Wfnm&E*DoZ%TTvmmt&KmKjtysJapJp0TmJK=E)b`h8p1_-ads@@TW8t z9ON2#xD=^^?wEaYFGPE0rC7#RSv>B&fV&0VgreN;jQQ@@0}nSyxl` zJ%$pZsXbG{ZiD#}lBT>UW4)?;y+qeGwOEdTCN)N4H+TSAo{}K+smeXrCFl*m39i7= zx{Qv=RgYOJIrsw!iY24hnx1HL0U|9OLA+S?GB(d6a zB(YeVRZZq~K3>ziZrkUwx93P=76-F^2Cg(?*E3_+4><>M`B5~k=j)fw;XH;+Cq}*WKpd=inCi#%tqXSdXe0Qxz$&}MoPdYS4B+f&6W~VqS3`5 z>`e`I6q&%5=bkVOs#z>f^iE-D325Lo;(K|kID!;6A2-`4!s)w5L-{2)-h&m4=w`&{ ziQZ@Rv<3ydJ)_VCqJDxXg+de{k(lGgIhcZ_N72e2VTn@H2&Y!EX5)_=8E6h`@Ol96 z4$=Ojrob0h@#W$8lj)w_aNi~CL@LoBTQchNSJcE`BKTR;!1?7c|B|#Fl+}^}!2^#>GqioopInE+Qf#BovfC3{CAa$O-K`#)i55V(tjG;vc1v zmIn)QTdtd>j1ei1br0BItd-rJP)aTc{M|m#Xaf=cEzQq5IMs>tvUc3}KCZ&!V-olR zck~W5=tafjw|p(4C7Tl66B0>?i335K)UFy6`SHzs6RKJ2nejWhLRqScrh-+Qk?${4 z)APVR0%^1gM#;af7b@sfy*c$2MXRO|G@&)^WM~*;6)s?zV2+7~jArD&G|6gIwukGp z%T^WRNvyFeYD}Mj7{VY@q{0=o(kaOVTTmEqP|h+VX~{D;HBn)ln)nKg_FPQG9txKQ zyGgBDAt?6ZZsI?=gMuF+7DCxLW;Pgn{pg!z@Pok|E?k|_i8g1A4EzWIdG8wA+*?%R z;#9Vo8FFUUxK-m*uIJS!;d5JU+>QR-=)SH5lc-5$sBe;|-}rI7@IQ@*2@UwvMdvD} zI|OFvAi+*XK#IYg2Q%q(O3AIE$an8i+h52o9@V%SE4FDLaMZCTer|yB39jVcD;ZK6 z+BWIU&xJ9Qw6wOTYdZK`i?CH>3+Ko=imA~!*TH#_ywqHb>G?43o-KRK(|Yj$?U0!e zT>juGNQp%}ps)6ci?B87(k{J`tF`+{l660O*me;Z=Ye1i^lw8aG#^6X$`cpt6zgjd zifl+k%vR_RSd+P0Su8zpA*Nn8Yn4`;B^fk5*y2&y#J8M5^N6fKS0V=tqeRN0gHW6mljb<{J`R!Munw|25dBcV!h5@WpYh7GgT~zThkI|ICRl5HSIcZPt2cLtr>r2XSG)ITa zQ+Qege9e4HXoq;t5evG3Oo80{&~9D3C-5b%WVx=v6U5pJWkw4hGY{dodUSr#27b4i zt~fRpwqi<^#NUZR*Qun}%Hkw%bH{0gTS3P$m=d1GE%BHaNQMkO+t(!c%0(=&cpmy4 zNF)yTTr19e`rL$cWTL%9FOZY^pCkX}r(V_oF zltmIVNqA#WXS;^p5SPLcCxUZ{v}4JiJ*7CMBbb#$gUX zU_1u(AaDIJN;^*wr%|*>Db^Mevjg-u%uQa%g)8KQCX20A**tQVc z-nV$B)EFxet#LP9@tTA^r2PrxpM*CKhhX~zd|m3pyn4m*Uwmc$#=0U!Q@J@IWNz`F z;kZ!CB<7=|jrmL@nb8rI_{jX?ur!%n&as(9?$R@h9O=>PVqXKa#)r%eI7C0#ofa`Z z$RsUlKxqf{l1apR+1l3udtAq(;`1X<&j+|vFxnqT*Q$cd0=4mca98s4Lx886pKDm= zD-4a36V}NJJ&D34b1dIl1N*tBXqv^b54-)WHfNa=B1?w}aQw8SKKD7=jun8 zn8t4yty4mMdJFA;*DiOOEQVxaj5FZ+)ZM)_F008fDxwu7|_n+_HozlOjl;Fu?XymzCXj2p8xQW%CH>xtZpK^!ls@{K0 zl!peV91qLixqj44f~5F~j_)LS7obvtH8C&@fB_hKay|n@kFb5oqigY2lACVf+qbq2U3>SlGT1 z@{ieN=G)l7cJB%^p^=;uYu|@RNg0i%xktlx?j5I8n~o1coHTk|4)hzwz_zhgP2eO2 zR*c$FZZ~+k18fpD@T#wPEO*wNLIG~o59WKWW(`MGIi&vN`Afc(h#Gfnei=N3NvA@-c!Tqlrpq^F9+R#{na|o`^h7HH!!(i4!_ZmXGQ} zf-;hCB`eXzBCFA}sSmS(17@9JvaSWHL+U}VHB#_{_sOk#vCyD?`hANYWYc2?SzPE=pn@v2&iHNOV)7gwv~I+Lc34p&!`#Sn3)Bz0sYb^Korn zJ}WIoHy!wfXTfynp8{`+`ix814tXZu_y~x+nRvLZgGZ8PRt;zKU8A{59AwdA*^jP$ zWdL!xYXyWS*kdPDTd|xB!pHvXc$4k8j&AW@dtCNBKp?moxQai*uofSVS?Zu$Xkmkc zg;}~o{P5Ge1D^0nB{9MY2Um1Fy;l5Md3B>l%Wsv$T49w`MjfHPLw3CdwNs-T&Oc?9 z(VsQr+IT*k?b{IXpwNkJEwwd{mdHIrfYwiJe|;)3b;J{C8GOC#fPDsEJdfNmGR%VX#^o?wnDm- z8|tT9w{cY+X}E=4$r`KwgrGsx^zzD+zx^W=Lg`_1dkCO#5#Y7L`(M0L{>*>=$9<)- zoY9R18I9!Y6&nGti*O+S`R_gZ>aWEglPtCWxUYl&?kg)R&Nlz&zVgm!s?19gYs!2+ zHzOcnvtEBK_y=k`ANm=SJ#b&?*4AET6-e|JEG7?&IAWR_q(quwaUEFWxUV1{htQsy@ZX?>?pyRLELFX^mm0y;iyiojB1dNM{suah0&C$#hs357eP+-%D zk@Ix)%j0~r5*F+n$Ff;*hE7JYJimV6Ybv{FTdVr;YmKu(tvsQh7cT*53UQ2>iQ95F zaM&Vzy1(1fdPVnI5x1}{rYY3h>_Z{nCog-Crh#^B92TdZGl0@GaH^fI1HK>dpnJPQ zyA}Op1-q5J)a$fUH!%tNDPcfmIzt?#m|NXFt~x_TXTp)MS&VK{lscK1{*CpQ{JnK{lr(UfpMuFow_x$>@S;nEu5~a8Pjv2L64A8Re4NdVP*D^9}4lRZQmU z+@do(zE7Q}BVaV|qY`-?eP-XX{L(MKJEvEGGl?E=G~F}E5_lxmrm zO~3Tf3mYW+XIe&k4JOezwY>_fvTNx&Xi|s=M}YjY8ps`-v!+;%#Ad!DYxzN|$VI9! zt<%L}BiW9TMQ5SBh8rz9bxpU#HXFN;w>n5j2NdUQuNn6iM24V2&CR$O$hRLK zL4@RhOUm8ml;SR|{9x9A-AmO;+#$C5IIGeWw2)8y%Xg^q92}_Zp14jn3UYypDg!GH zBbz3=E}Vl_jFW1@31XbH4c}KaXgH?J1{RAkQ<`__y$_3$?L^S5F(&M1^yBOO}Z^1mA*xRjR`Go7WC;JV$>qOsMyH zh~ZV~#P@5`<*v~+(tEC+;J}66zYDL)ukMO&8o0BwouG7EkzQ^<-UpH7d(8wMK#mSl z$YVcxPtFDk??iS|+Wl>?od+J?na+tU=kwcseNAsK?NYNW3UH6S|g#z?yv!NE&t8E~5u-D?_X!1DQ`U zCO@f`ZQh?`8Yb3iZB7p2lo>p*M>kO_W@$a*ik-UAL4ndi-dlpXSPNi5sPCPqLDV;n zwi@z!d9 zio_im*7AtC$?;!XbX;+;z_uVU9@oVLWf+21{!|O15o&a=+#UcH?ccEY!t;K9(75ts zhWdeV$$z>du)bvl6os65xz*FqE@R@KoqIW}nj|l`BmqSsos@=lAy2P&mN0)Bh}2@m z+mFNHAt@ziTT^`Uhey9M3m- zmckx*2lUaAPZ5j~^7pC5Sd#6xJr~h?vGd3LO=6T&xnbQP0-j026TWkHPSn0s`JKUd zE9o^7O(?V4K~tt46+oDh?H5$L6`6YCD%a{&PG9`?>Z$9T_Q)B*K4YgJMsaDvC_Fpi zmJ#lyqsP~?(Wa-VfNP^-qu@zd>Qsl18UxR!c{>^1*CaB>R1Jp#e;leE-8LRhSM@;0 z>@}>KJ^5CS^Ao`u5H;;YpbJp}E9XyGW=>>=WnOJX8dO{0vsVyhV!Sc2YYWtbZ1U+h zpm#N{PMSSxcU@Aai77{xfr;7OpSwm{8WT}{;vcSe5vBLgE&VQ+Kvyu56fFx zN$5N1oAKEJ>vBLHdtmrciPl%m)~`ftSlpTk+_A{djKP4HiJ5e$en z;`}iR37;9U{vszVsC)}{V(<|EA<^H3OKNAQbq5|RsLI8Z=xJ>T*vxl7)j`bWwtrQ5 zhQu2Py1=1UA@D8o(_W<>)+2Wi*CThnivi*BL(iY1to$I%R8f8~b|o=!aE0MOlG`UL zQ)Su;$>(EC?)+Mj>aXGz*A6%Q<;xHY(Vl-yDK?;@D#`##bOR_+@c;UK_qZ5<9^Og18=I=cwafZs%8{gl%E)>Jnj(4i zc7~)p#nHEhMU9%Xz%iyCj4W`B*>435$6yyw794U%WjPuOj&@Wye2gbIdr$;iYIB2MYPubObE1ew@ll?*KcbLw_^M^@9Ys z#bi;epe|FkZ{e1*y6EDn8|&?wFLqS#0w~dixK`5w3WL!|F-W8g7R9;w6U&Jr_Xfoj z%)Etphna8dH(uX2aH1SDnVcTg@wqwdnrJ3!;wmkSbHhEc0!58hc5i);;^}tuq^NGh zpV}#%i#|tH>CfV;s_9BthG1A^x|kZaFMO&tS86U2bgkE@s4gJME^_D(f|}3b-XtlR z<|=7u{CRv`JDRlL%4l~xJuWW9=V+V}NMcYsmHem>V|e|zbKa#5&CLosW|d>?J+_u` z{;r-gt;kM ziZ%^gN2Au#^k43_=zQhwIG4q?57$RP_d<+w2UP^i*-yMy>IfXSsK+*#9Uo+T45`cB zGiIXX95a_RU4-kf+wCOm2C30X5qHPqGi;wiJ#!+2AIKskaE`f;QB$N+WDuPC%!%w} zMHpAX)-I-|t0f7XnpMnO@TA(OBFY4by2 zaBRkD-{WE@a{&fd7o*A4hFMl3q}0vTP}_ogOW-pDP8 z)*jfFB8g)_JDeT!>b}6l;F`&nVdnJ@zcVlzvBV{L&b~CYmpe@l@q>BFPD|lLTD}N2 zEk)pSM?zq7d%%_Fa2TqNhLhf~aQttof+ zE35%Q3pel7J!MkZ#}bGWBW#|^)45Kn^@4BI1L4L_1q_@@?32rpa@LGwJqTO~(PHq& zy!xjK>-YVoXyH=W1RuW5eBngv$=N+cJY@Z!W6TfFjQCt8Cv^{$$-Vix2KK7rfn--f>JWR$6U^-fs{A`?~`;#H`!1St=cPwr|)W zjN7Svl0AEdv2lRHVW-wJ%6b(>am%_zE3?1^i&Qk@tysT48J)3sLZq!4-HR+>KHEDc(q^X(8wXp0BpH?bgUSPrO#-E3!88>(bqYz^`g&launXNx2n!P>ofVh+!FmN2KM0pHq zQR0jIT>-w1gg=5l1l*TBfG<#YIG)}}A;-WJPTUl11FxR1NK&9nmr6`IybKmvpJFp? zT9c}J3K8b*w@^;i(gp=G%!EC)0z^eUu1*R8nsbxtQ09d4$^HFCCut~C23Rg#bj~{s zef19ML?JBk%rsW2rYPUVXo&WoM~*Jq2WPT9sVP$X-aT!e^-2clijPy(6Ci!WBN)&- zWM#pl<1*gCqotA2!J{kC5K`kN<9hP*y~+{V<#NQ1blXpRerX}~;1|fp}6)|rmddwB(AVDYWHNCJl zF#G{jRV)!+w``s-?gE}H)>qGb2K_2Q}G*7%1KODZENVaPiM@bY>Sbmx%B~ ziJ^SxyhLH|XRl;Z+eYxTQR`Cvxw#+_dKh~q$p6ga{+kH|ET0?aoc?v||BpH2Umo}0 zK2NT5@OXlkhI~Rws5Q~;>#8Ezt+nWf!>Tc> z#L)Z*HDs%_6V}Iw^TS6iTa>J}e}QcPu?BX50e4egq>fWMj`q{XQ8{_Ujb$bz*u6*k z4=b8&8$Ej%nN8^ajI9&YN{o{opam5iNMx}v4Bhs%* zHp0+JU~9Yu3fQewHgS~xmJ|bC0~?GoIVVVb1TnU*m8AHay|a=^mv2zC9w4F z1j^z9-)sIAYFXq*P4y2bD~t%yg31Wm3f{~JlY-ak-akBGR|1Kef%Js-FP*s5%EdWq zf`eAvjL8*A<=ILXt0YqabH0D}+;2(|SLp^>fWR~c zk};N%s<~2w+{#daHr8(IlhCh)+}N9Z!|7M1m;eQPd z%S~X%P;4;PQM(IINi0y9QYPyvZ=fzfZ=>GjGXO5 z@Hh*qEniG^R+bgM_S=tw#+E^EW}zK z#$ioP$ixOlvnR_#SqlFVb2~#L7E@Q;iM`7}lO+9kuXEG(%%HCC_*Z>vQq$eyz8${H zZEPM?hR!s-&P9g+x5cGjQX;=J-|Yz_Udh(NbNhe#Sp9`o?KG01o1uf}C}j%U?QqrQwtl$Y3i>|C zJaf=kuv`VeNFRo)^6HI~c+y7OYUNZ6h5)3yfTdLz(K0rdb4h#D;+ULp-GO%)b~hb< zslhBrA76U{oy6vsL@y%ucR=Kxzd{B?ZqDy)Q&r3-Qv=xbvp^?t29Col&`InFW^6i% zJ6G;mrLdFpB65@bEpkV*fT-^6s6i||E~Gs>J!p5J3k%m+{(nK_4z$D#&_%4O^a7E7 zle+=q^*?u*!Sm<+#9xc#6gZ;5$UDQKpLUvSj899jj z5^Qa2DuFp``Xru(b$@Haf9@nUgTF7Ftx%w+Ua^X0FC>~ z6L=G1I1rrfxUc8XBiR@V+}LSowmp#OBrh^cQ4Tb8gydL#AKj)v=SBiF?mnF38iW;` z`3~X7vyg|{FV6LsV-jas z%grwo85?!%_Zs$8d~VZXW}G|36%mI~gwkceah}`P!n33kql+?lZumS}({-roCj(sZ zT(V+TQkLbrjE^jEhb4QcVc$=EepNRYm}XnBR^}hE96%t*@_nc03u0@P>{F+OfgTx? zEScSO+<-ai`8Ktv^$XWg+KEuzj*Rv6=>+e32YZflU4X2Asy}<-JVj<#Kj+idLsa&_ zlq1!*2CRDRQPJ$({aWVcQRIXbxEzI*hIuMZ#lCf~S~vwTQr)+Lz6644LNd7rWaA_< z6F;RvOAdV;bGveToW6#8J7Y-ktw;z;gwF-6S991bCU4n_U$9J3Oq}kX&ZYyZ_)u97 z-706Ma9fp#G8bt|(ik`ZpE6xAzGY)tN?n4mf_d+C{pBlv4s+xg(dW^@-n*A5b+MG( zz%m*}a1zLII70q{ZC|}9;)E-cMsiON4M!v=HzyV(Blk+Pi;SEuKoX1BPCSu z?XCS4OuzlK^$e1f>Wc511~q)uA7i!8(c(gqhq1(U_ynncWnd~!1gzo6xF>z!W1=}6 z>!Yv%K++HZ$@+QQevRh*Ir|Zp&gljY74gQey0&w)#29e=aY9Gh13(}$Cvnw2dG>_3 zfJx+k{&$q1nZ7yDS^RIE@R!R`a}5#lwv8`rVAfDY|A0uLKOypqx3^;aOq~0j!RA2C zQA+bGHr|F{N%acrg{~hQ`L)LV)L4#YmFOHYZ590rF59Q{Awq4`qeRH+1{R6INHvfP z1Xz0Kp*A%oUCnGrz1jq___n^xPmw9sv@15-_HZ)a0Y8Z5EUahEuQk4$ale`t&$TXi zqx7#`HKecaUkJ$qAS9DJfRM2-2>I-UH;EwS-it`CFPHjtu!ThJqpy3dTxS5gYAH!O zqF^0?+A_Ko-LuxN=x^q1utlB-8+{5See|#-vWE-Kl)kcZul}*34jy+ z$IDX5M4j;236}=OkOKelpWJ^xDu3YPUpYX(hmf+rH`P^Yg%j14pVOoX$;m8bM`k4% z;KW%QtR2(xTvpf@opywe33FMS)twqI1)SXs9K{_XFc!m|*54;fz61doI2e+6KAm-^ zyrOA6Z2zvjEr@vIG2f{JExvji28kP3O4SwsS@2R(+eS)YcCP*IO7@z`N7C0L@WY_W zZ+fKWjIQ}jkEs7AJ=V*-(BoFad?KT>kJ=)UfXyTgf)1XgvYT~|?DAl~CSBgTrsA*p z+*omip;Btc(`(W1XAUx~Q}*5O>e{@?IhPp{Ims9W92I~Vpvuqz%e@9521rpw?c{ws zMa}YrRF!4jYawNpG>qF#6G0rK%wvppLVw;Zh{I2@1Ep2Y?d#N`;eZdm9mhuNGlcOA z7#=QR12I6eHqGFOb2EE=a>`AFQsNv_VV$?38-=^U!tfwdl+-{KL(>~VS+Z}$Lz8uf z8@o_1=t#-9K?lpSiXN1WoU}J+5L!T@YFzxmX|`*@jV_4Vk#0p6eh4?wYh_Qs$<6{9 z^(*+}$ws>~nEGy#!b9r8+?Za%irTPiI#gN*p0#ZqyLx&sre2)7% zO9@9~u4`k*@qfMD8`{c!PP)aAjcLx5jLFAsV%1 zUUto(heEoC(o%B~uk-qRJ7ITUwM2?p7+yecc!QQ7%)XISOa9pKi~M|hvgTa;1W*6# z3POx4Zm4SJwL^qKBXi07jg_~u<^wki*6<7m9*hR4pb<>wZ>Ru5q%v`79^Qi=@0cpZ2RFVU6>k?CEIDxC|(wGl;skpl9> z%-FZPtImzQQ<}5enwhGkZYHBGtRE9k@Z23`A>#eN_*!8aZr>t41a2C-ulM2G1ph)r zSO-V385B;2rT8v#BC1>tam`+38G@V~c+>p#EX@)gaKe?`w{xHAvHLH2lsrfbUyacj zELnr|w^alTZ<_9x93Y8<`yk{NR9l>GaR0M}=h-CT=6l|WLCd@(*R1P-*fT+Z9>t&O z(c?EgKF0$+(<4?)!eWafFy_=FH+YYyaI}O{W!ZwP8GO?mcopwflJCCJa}aC!MgB%J z<3eU7A-b(7_Q>7@-JQf@IXgunHRoUGQSX@^ALx1~hCj$%d9wI-!8Rb=^z)pK)uPxK z^4~~2(<6mW@(kk;*#Oe&ce&c z6K~P}`PIpSW`dgmz~e9gkDUMQ`|xjY{Hwb1r#;q&c{-gS7+ZZ?zktsKQ!CCW2@4JNCtnA(?N%-UcQHxCUcM5xVQ zDul%bfv;n1l7TY!^P20YP8Rv*vA|XBC^RkK<&h%maq;oBr3Vp9W6I$NW;*caC5imv zJa)6lTf7v?Q&-noP>w#9=(43^guVOJj-1YgJU}at)*&ON946BNU}J@pe3w3~4{>GL zM<~^?;dI1GBw_#?xl@$7Xi7qjZ{1|WI_`b=DJx*b(awV6o23yP`S4MQ%(LKe_6C+^Wf;2!1buryCC#;_J$d`5g;+?HQn9;4HNeK1CFowG)rBOF-cjnb z(h;bpy|){RUwh2BacEQTD z9fS{C1|R8|(O#C8kR1b@XkG%un_>{}c62DZZ>Fy`{}*X*8JE?fb@3_^(%mK9-6`E6 z-QC??QV*RX-QC@#v~+hj(ntvi+=ct>^Paum^Sk$)_xepf&u6W%=9uF@2FyQlFk)=T zMt%|pLk(h;HrEk>+e*0yvPO^J7m!=m2m*Wr(rL3MGdi7v+%@k5MBvurcts9LdYwCD z&p3%<$$|AF2v|QZ-YVo0PrNh0Nm>8v?5Chqz5DO49RFM={efQnf7w2o-;twXDhf2O zAPIJWQxj?I#TKIsG}OszFSgAA>)9_`;BQHrfoyr5+`9rnAt9R42XTU=jhR&S7SfS3JsCef?K4qm6)To*OLxI z(2MJi+rRkNMYUKF#L-yg7H>cqW7x)DCTj3p+@60l zPbvv->0BF81xVt+@NF0fr6g7nXW}{Hr@1GVf0oB?9G?a+<@|uk<*gz{Ok+sa2H9f9 ziD9a5elsf~zV(hhNGn2`pUKX8#ibfPB+e^f%at8LPtgJgC<{NsFeo>-5;MtggpGp9ZQ%>t3!L5$g@QK#RW(Y;wj3hOdI~ zm{c&|=D#%&09TGL5Xln&BI)znz=o$)2?ZdMr6WM{&Q@`ZIFYSfZ4n~_{>Lz@|a!DVWmKvZ^Tdw`@{p zP)E|Fq;!EzOf#o(jhE?}8ntb0o0!?YaF1qq=#K$tLhJ4xn->j)L)$Mjp?K`Kq~GJ5 z+}Rg1?)bi>EVk@q`91%F{c6I=*BmC_76+P)&{ChNCaug0v)2kTK~@z}M>miSazW_6x-vvhULT~)X8cHNE_@*pT4q_WyfXKe|m<7(`mHGd%! z(@ZOZSa%>qHO8<`YpKJy=ItjO!E5^xLXyuJRL;p`>pu#Wc3X0vo7CH#vv~w}>Ten= zE-1_t`1*WndtfxH%VGsHhqOBpSU4^d^CEQt_H`HQF`Ox*w0*^5{|~+#*LKYzySjk! zn9y*+6`oXNKszEN8M+N15U$v38@Y^8$B%|0f-@u}zdu^wFT3wvw(o6~iB(D;RSSTe zmkL*z++SDTU(@u^b!#p`-O!-zbC6K<)q+aOUfXWp(#t!f2B;V}|q z;sC?&!-`}5NO!A14t&P>-1?)FSkG041-3akB+ggt^xgTSJ7DujFVKlXwEwe18O}o? zI2|^YqNf}AW%FoE_^W-XNg75^;%8?#Y@8h?g9}0x#DoEW`mrR96gHpYj0QH3<&qcD z(0^Wl$L2B49wEnaAJ{yuD*nm{x+FV5*&lwW}GzxFrgK>pCF0P zXCdA`%0Er>?Rhr6KC4B3LH+cTQi6O!30ZTCPP`5J42jN*#Zt1+fli8<;LgnIX}qZB zeUGgSzt_iKtd-&`DH8lzpOWmqgr%6>j?_tACj2}>JNdx<1x9TD!0y{qE#fa5nPyau zbBFU^pWe~yXX<(VtmCKW3i)6DwGd*l{LAL?01%J=`HkcMekT5V{U`!Xw-nZxo!cJv zHAtVCv9LE=PoiygB(9UzhUjnA=PszL0>Iv}<@Sbaoa=VYY3!vh5-hn}6Nj%kqdVgd z16wJ1WP{+eDBDGFAR*{GYwMr-QR26L3rlznO0d{l(+Z2R2s2OjEab8B3Wx#Dm{=>lT7{sCw^-#^Rj9l9ZqZMUN{=ysfqmB21x+YqP-CpNYS}EJ#o%tD zc}AzI)7fyQzOv3vm!`@LYC22$>8TyKM`*uX%*~b-(K8`p&1?#^G)fDaJ0NM2 zyp?5aXf2oxbVS0>nWH8)B7jA~FyV!OV8KR}wBb-)wkd@O5&VWvx3EZy6CBkriVi() zOluTuzYlg-5U}>V=FVG%`k@#WuC~<8ibgdN`)cM}+ zdTMFAAlBf}+mb?Mj{)Z+^JulV!L}(G?Pn2xO49sZAt_-AWa|Q3Dp{g}Ri>+~Z;QnX zl!KpYD0@WOB5jQ(9>!6G5mi)JX+2F-9^kkd`WT-?_ehFndP}hw;lf53bGeoFBlw&UK|ZP zBuFZh5)VaXtJ$@2Q1!;PzOm~Ujoe3p0G{_SOh@1-QlzBS1v=wt`yMQIx68Nkdav+u zRk}=$xtq5(EFna->xNyRybx@edEtc!1}fQKg6oXPwiv;k8`Q2QtnjNNZguWxO2k{I zA1HW_hiYWDDiNk6ih~T=+=ld=7vdoNV6ZIb86u~)Lf;o`dbgiPJ@>Rd*TBzE>V8_PsQ!-l6`f$%p;nFu4X&lL} z(#%=B#eT|Z&RjoeWw+OGJ8d=Yd1BIeJ8Wh5d7hOIt91M`3i&+p&fT2QV}Tzv828mu zN+xzXs?9xbZrpH8LHr;p$gs{u#;r>XKeIof^^3Q8PuQeg`N@}zWiS)>tMR~We`dVa zXNdCYHbG$({VbPst#GV96>F3uUQwSV*!uZ1UvRJahsdomM9NjKn1-rea4Gd+Y_@y) z{cobyldZz)DTmg1nRzbS*>HO}qS`|b3n>Fpyu$38pp*T-p*g@6d9EA&4|ewdo}RyH z%756|F6p6woh=|GElu^3YoGmqz!!pN5sE4t4?@#a)L7$|G9LV#(2q|)B*TzAX5S^h z0dzCs(PLHKDZsVG<49lFZuL5bjO=`(JKAPWdTB5|w35N>ue;Adx>6&6klh<4$FX}z0VLr6yi(B#}!$@QX|_nlo( z?{Lkio29E8C?+p05=Hs0=M+0daTeEXrdjkm1jkS7n*^n=Pt)p3mkGSMid8L;Q<)d= zuu%e_@f`YZ*qw4Rox?224(quc5d@!gNd*gtWWCZF2zJUYQcI8A@>?5Y5nEZ~K!w_K zQ*}^gMD8m=(q3M9NY*esm@W;*YBQpZf7;m#f7sb4fStVt*x4B?w5P=v7UcxYMFDmT zPb{)!2(xT4iEn*5%U!*^E=YND$}Isqo3|0ZAE+{yE{xgTh3@p?f3dUYf7{vCkxnFK z$85LkKR?jarJgR1kpzsSn<$tK&1fgpLMe%#oo~htB9aZ?H0Dif_|d$lr}WCKB7~V^ zX@;T;BzA@kU2UCx2QLlR3S683s(j?zLvt2?%yaRNCC#ImL8zma98MB8()~X2 zabc$3?x9XPxnYE?ZU<7V`=0vBrE3h`6s>Cwjs0{L8`@lJw`H7X#iV(Ka{e4|bWJk!&=xwL*}QGzV#kn_ z!8PAvXxuP_Ul8O&8S9^T++Z(onf5O~K#XDT07-Y%-+v$28RHXb zM|bii#KhfOhkEHG7X;AcLwoBXj_bNaD-n0TK{2?0bdqNPJIRDQUDKnyUJjBVKitcX zZfddhFstTMitPhjBFzmtvG>s)Q09|q3i8a+^4+9KLeJK#&wZ>nrtT|qLU@}uxF%mA-$0^C z@L2d$^s-+F4CG4%^OvW(yC{}jCM>9I)t-LAX+Ph7eKA59+-&?ACr35Aq|tf*a@Fm2 zk^lMr@e%6d{z9ofzS~f>eN#C6O5H^^7;YLn!IFFL2bHb*3X~q;y8Fg=N;%%40$%8w6i1yj|7HG7!j`B3 zghThO4XVsVdwgxd9y9+JZBq4ajy+gSFw?EB%PUda9ZB;n(tEL9_mh zbQO_UX={rgoLSEzlDjgdOGB`8ER2`JK;<4Wd{IT;?w^f~H|lselMWs6Ga-$Wgp_r4 z?zb+$$nKxNQ)bK9C_wl)*J{^J*Ze>~W=UM&K!f=SeUyHKRT)nk2dQgXY=t_5kh6d` zJCc{^Sd35m$(i2JLU;VvjL0Wmg6}hG*1m!l(|Q{nc+H_ID?`7USXw|Z-*GBvSHxSC z$s>c))Sv&xK&3?W$8ZEbTYQ1(`p+xx|7DW?soMVKZ-0ElR3!Ya4;*-&Hgwa%fVu7# z6`2u@*r3nOew%9UuW!v(*t>z6vMP5N-@)1jOO^HQWeXm7G5W$oorXs*&=y+B_c9$D zyUSoPdzuCsFn!-JMp0Sbp1x3*4#X$8 z)g!@?RgRg316>$>4p}$(rK7Xz7oeeq*2{v$N2mM z)v$lZ3G{pR#-9jk_VR&Y79jK?8`74jz!lIon|7WB_GmFi!w@6)$17oec$Q=pd%d1F zBTO>n3PEc!6KOWi^|*cAEV)rqEt;BICA>e9xbCY&HYg>|$T zf7j9n<7+bLVw^|XBP>rLWQfyf^=)5S-MQfC4(?19n0B#^X^#&>!A@4h!hY%#66kza zxbc{86-lV+H<=e{SZRnL?qqzy9{jzD8e*>6_^J`V#qP7T!eHLSQBmq;7oOuU^6l_9 zzI$^u77J1MmPvwLlhL7u|AvYF&|n0;Nc7)FPmf3J_DtOxfr|P^NPWCZZ08MAoTggRU0N{*o+us-GzF<`TLhzK zicMcgE=m+-=xr2oQeOR6!oGb#qeD%@%T0L*+*G`2Q05mJgLtB*)8Nz&{n-jeeF;z- z{1~I+^{>`aHr8!?wY2C8r&0JBoKZZR4B8<$d=~-&CmpIp!w%XagECni8%Wa$uwwBQ z3|^zZO%|hW5 z8Pf(}N0{KUI>tS;1?{fT_sjT%lZru>R<=4m1$GXB%EAuK@B{qn3|W3<6j*y>XOBe; zSQrdD)l4HexhKZCgUGV{*@FS(94>dUi_?oUYPy245Wwf57i#xF5nA-Aa17f)W+_#p6Z=L4 zF+qCylBCT;-YLD=S z;P3}WuI?uoud;nyZY;o&+uo$8zFlP~?tBbg%0pDY7n8{b6~sG)oyvt->wi8bH$X7a z=Ja9GWIKTz5RIXA7&1`a_gjjFahsZLpW&%Mg5Ow5DX=GJV zchYV(VsE-`4q{%6O)cci-pP<6rURxOEV*QFGf@Ux2T-4~sqp$-L#{1Geeeq8cw3$@ z_AtGq3RBU& z;^V z0aZBDKq+_f^dc435hsz|2+iYC`YeTLPMKLI${;F7Iq6WvWptbN?x4ch>&oQ(_pHllR|H?Bi*Q&P-W&$-VV_7j3QQ9rYVmX!Iq@_2T6T=mN{ z;^}3`2gLXew-f&<*W1a2Gv7@GyIrMK1>~3p*O79jiR`{2_r*Pr)!nPTr;FyT6M{k5 zr@KM*JjXgDxv}$lw(auD@$=O(?6@AZ)>Ev)&FD$mB9N+iP1})Str5#hR8a@iTMk4O zYm0%XBJT7k+?~DvdPrhRqQ=UmfBE-_Au~&=4 zuWHT}>_^dhD=c;KkW;!lpAQ}wHFJ40Ng}qjo5`bKaK;fkeNfU~piv=)Fl+;47bP1D zu$y8WDy=QHM*9)G=|=B*h6!plJCbpEZt7W& zajpyt?3$2ra`?JJtZKhxJ_h6SnAqY z>3W*DRU|ZqV=Iv!GCSsY&=FgQsKVoy?HVn8aVtE=VL?RT{3P*GKoR`AfWoN3DF*HN z-Hvy}oZI8&Z5ZGUjesJ3@(=HD6&}d*&p*eWQJ&(RKPsQli1WkT-2>hbRtF(^Cq=>e z0MUBePuhC&ex^+_)PuoSbQg(v*Rf48i4~ES@l*j1lD1G!gQb4V;rDRuV*DPVztBv< zPDS2jl@Ccbi$!@juJe|##)Rs*cOeu^sxWd-f7za?a@p8t>&{3P?QeU(-{;{iIM2Cy zM7H?Ac}w`$=POv*?gKTj6Tbpv=zp;n|98*VKZIz3ijLB>06?enuP0Nd3z(DdEf!@J zynv0M3?iOYOi=EnAg9BoErk9AUigbR%f<}vy6a*T+b?0e1AeZw&wv!MZGUam>*jQ^ zBh7C8y$>W~^eh(0o+fl+<9DR0i#@;V*#bG^V;M#S{l1AM3$S<*}{jpIwX2~Q^&DI{WCFx3m3C!(B?IdVBQXOWWD|M z)j0rtdaaQ--!MrafTEG9hKCr*ghQ!zRn|+tZE!T2AeB+2kw%Uz86z}bT#fSestyGo z%3Zh-dSe;cFik318m~jo>dnxccW{(a`JkSbBF8AcQoqs;1T$#_&QR`Cf~bkcjHaZ` zV6N*Fn9 zkS)V|yYe_*MtZ)1R6@xCe$~_4WNC58Sn!TfX%9vvR0LWwA&V5|6Jj>9%(5Yvhx;7E-UY_T1UD36>D$80&FW>YjME#4{K0z1%5S-gU;(kAAhn z7PzwpPtg^OId|}Mg+dk%9}dY(MN|7w_oaG1=J*=())OL$a*z4FS+kI9>nH))gJl|@ z*i8fb19uLkviVHRr+xUlpVLQ3dT|o2J_0)`Z?@<>2QLX$2Qv{5WTgm^Pr5OCaYE-O z=RazT`@IoAlwh^5k2ZoQUH5-}$5D(ggxDY{WgLrQrv~0#z;G}0w!)5a=O?nq zAQUDy-Qf>|_~?;FL`tCDQzF0N)zD%8WhQ1DQ1DuuOb9Xj8&FZv96i#DJ7upMzJTd@ zW=@I%S@ywb!CcN|P1=PL>SRt2RN}0x$2ilLgSN)0w&g1lC#D9$yR^^E`jbbl{(}q-2C2y2@C^%reO*+*G3*7$^#w^_w+NPx-+6 z`IBp}px~6|cO3R=jUF3Tn|dsQ_+i`4+J|A2`Q~HO&WB|aw>gtkEVzb!MVJgVMt%m_ z!_FUwq5^6KzPVbE4+0i31FVJDoCyZ^K{+edC)4oE#XSSi1*dX^Gix8p-1-kw>QY6p z3DOP0%ew<){iLujujnT@Rg%pJ%uGMnz%X^2)r6uP2JtRQ*K;%iQKK_o!Mjm$IWibQW?_skTJ#8Pxc8u&qekX&>3hK=r#yhVb+Fw-Lm&VgI33 z=^18f@1C&waYQxk>dZ2XEk`CkrOH+Hos6%ot3j$JcC*#ON~}hCf*QNRaNoLBVWt6n zx_ShgrcGt1kfjSLqtOxkKpK}kYn|HE-9uv>t$4>#QA(Qz149ad={U?(38Ao}TvvT| z81!wYC_;na^X7rB2R65~=VGB)iLs~BmqIIu)e$RcxkbiHS*>fuRoF%-7zENU=$l-jg_L+Hgr=i$bzZ8|ErZ^eH#tATm9!g=V`pghUpls zVoM6!&-G=f-w*W*My3*lr^l}ir<+3s<)32F20z5^TdK{|t4`B7@(m1+j(KY=e)s}DrdCty*SySRRaI?o^&7nV8i7eqU{PX&vJh3i(iMQfr zvo(g9$@ft)f;Ik;-25F6@<$hp{y%<#+F zN0H=H$Qk4@otO8Vx3yV>`HrW1a|{NTsLk%u+fEQbmKjK8LU4Ay4(OhE*v3ZR`j}po za;=HXaUvM%1hoV0dBF92_<7-52;^`FneIpLnT4^% zu+7ShRcoRT+>N&)o=#ZiPU>;iQr`N_JmVP_!_Mw~8f)|y^<;^fp!}`+_MMvsO(j|n z1Rtdg$ugit*Pi61MHdYG!zkZHZUE1ld_xXTdK(MXvbb#{Er7s0XJyfE^}rd{z^9B(i6LSQXao;TFM)^t|oT-f5m@ z0E>UIm)%FsJl*@TVz?`fSF9g}Ic4S_0HynWijtv!<^*~2+=;M2F~Xnxs8tnd-?@`^;qsFqdm)hyF=!sc91It zD%H+}#t44jKy?a-KlAVKhHs&evDDR9`(%Z#?-|RH|F!Ivw<4f)pU@m{ zfPP)3-%8i%+Z}Y|e21TWX%s+973wEYynf;!$dj(Tv(|8fTPjQrzfqLv~r)fi>`UQ+JiDXjE4Lt)1BC(FC6 z1yNrVOz+bKhOA;h?D|2Bpz`cN7kG&Lvi{*l8C4lD$#u_!LOApB8R4y)AtdJN!*~l* zFjwo%Loh$vf-+CMqpjR91wg{Xv&IQ~-& ztaWuPXQS?}H~Up~>#tV^R$(w43gBSX%GA5ra5<=}Ypjj>`l)kDchcYiTMJB*vQsrj z72HgiDy5z{u8^6G*9F%m!M}*u1*|R4~}%r@uH<=jMl32$sndyzgBegIdbP7*I-&Z0@0$8G{O-GkoG~-oolw zXli0}F)oYqEzaeVpa$?5Of>!=7K>Yy!EPki*`&-QIePAqK%yAm!kTriONH2x-Bcuy zo3!Q?2-CA}grU6bQ|m%Zpi4Tj9`$+c(+%e%n)8vcn*SVolXe)zYQrX)n?r=p6fNq* zsKd+%)*-&B2KPYCuZ;0WUS?r}7?(X7_V;-|FBr}rnCy{Zo0A_Hc7HHams_>h+2ijj zrZ8d9>tFmW&q&-n4*k;1>;Zf}{pa@QzZ)o76B|Pl$Cp*7(_e?HLRrfWMG)-?w2ZMp zJ?B|6r-|+&c+#k9V;vQiD=SgVo88-6WRNmJHcY#ygZ3007ItA)%%DjaIsQbsof2GV zMYqH{(z7yl*XgvUz4v>#XpQKiI5Fy)gNAV`jbjI9X)8B9A(a?e(OA*23-jHT_T}Ww zn+IdPiEPxE4@{_n)f}78V6%wY$hhG*`3Rk7zkgP+xSU^cZnjRD71L7h63f~0r2FL7 z(m*%jJ7Dpa-e>yM8NY6w@xgbRLNFwa=oxkX&?N}&$0ija(Yn4w!b+h&r*2Jw`y4D; z`{u-`OkYE@(tc*eSl)2+vN_G99zxvoRc-Cn8+tlLTHH@glk5ojo{J8ps~=|`p+Uk< zAqj91&n!c+p8C=}?h*z}FfK4A)i$UfmUmP)Jl}v0jaPf;-^X4GJiY!jBfGbC{J2BNsRor)LINCx(# zg>8oP&0Ws{(|I5+6-rnhTdLy1Bcy6fEJL|Kp1fidIJzy)fWUi{j5(w{e8xxY^5#Hw zxc5lU5|~Uo=5oQ^O`L*t{K~y>a#N{=+V18nr(mO5`8D5)yBaj%^E3>b>2Ma7N4xBMHR) zRyeh3o2nY+dYSwH|5xGIJ5YqN08FtvFvb75&HDc_#sBc7R5Sn_CfbuNRfZy{qWB}t zR<@`!NQF!k4F=tCGMTuGg4xFIFjgZqh04P3S=iKE)5Yz5J<_qjbA#u7CM#eS%!b;vy$ z0-C|Ny_dMh{XleLndr*(%~F{cf0MGE6<^YLd1W~RkVcQ|V($5f{wh4vU5N#irS%Ld zG6)@8qusFC$2ZGZyK9!QKuMLDtU`4Hhspvozjp$+et71j_NKAACt~LHF6{x`uy*~C zhr^row_7?U$!*R^a7WK%uM3#=>XN$Bj9>K}<*Jj!HKKq~hP(=Y^}!ON;B~gP`ef&d zf@I)hennU?2V-Pmw8dqo)xz%80yY94g$Uegy;~R4{sGx3GhBfj7l_*N%VKV@^ww8K zN^*KaIEy)lv=8eAnjbUKZ|^?g=*HSIeV{lwuyAPEPj2&8X_7W9*dHrbu_})=Qo&1W z6;hMaGsH2xiWDmJILKX(RcG-mEuidSgL@?cg?NBe33UZ|p=?!)vQj~Q%D#waAG(bI z3Tuj4{zbE3cSTC_VE#}Ib%V_m?=8%_*cqd)cpvQ!4uot%dND(Z@N=HA6gE%= zS4eRD19WpqLUVEDCs0w>BW$mbWv5EA!0^eqAkGp0`UB#&*J=C!e7Ik~{cpey|KaFgvKUcgDb zbr)zSx&Q)7M^hx=%3yKv<7*jrd&?;ooG-mda2uqiUiKLKQ=C~u?Xg{=a77MOfyDGh z4h5KMOu3tyh@MQPIr*EdAO}#?tq;XHcCE?!zQJHa@P<$icp$sMeBL|l8T-H-w{R~u zf;Fx5{Qx3tWai^4@Xd6S@#X9N6-y7>sO8S;Qs@1}soHO`S=$P;7kfJNm|{H>y2j1M zXqnE=pFyf+rVS#(lo(|wGd6C)*_0W>!Ic?JF#G6P9ybxW@M1YKhN4h4qIp^s!BA6e zzYy2nL^HT!$zCSW;KKR1=1n%TT03Wb>Wua30@IUC%EwdsIjY>w<}$97jCm7a!$vaD zKph?W?ftwZ2The$lx63UV8?fd_fxYOo#9fYP9hCanc>&TygF$FHe3D=NK@j}zcAq;cP!+dw=R?SI$J`;ksPacrQH4s{CypiJ*I&)N` zrL~nO;~FdtnC%2i>PLCF*N^XNN!IkSPCAdJ^I{EteW^$2X|Z*eWBO>2Paje*2kt48 z{Y*MR=D$|@eHh$x!1_i_b*hA%pUt1X`_Y52ApF|F(ozzN0DJf&{B4f>4Cm(-uI*R(VtO(7J%zCmUv)M< zHLlywEW@Y+A@$Ot1G;`D-2sYdD} zpI^+#xH~x>8}WUx-3~cI7PWfa#pcG=~tE|Fl+sSwPfX0&KMqRMBx^y#GB0pDxR?53OLl`0{w1vy{gU`*0tygupeRK!jteAA0_`T)V=ZYRap5I^dMFzF>rO{6}o>#{YW7J_85dkg5AS*6^|zb z)iIW0pT{4svDBHh6D)H0F9f#Qz*6=t#TVQ6X@qCUFB_{#hC!`ycIl*y#i&V}#z0u>J z_w=O1O7$rbiKWP4eBh0wnmRlR9e`SqI2sT5y!E{ zJB9!Y=S@bM#IdAwb0_D9PlTI&PanB9=;jLylXjXgm`;Fe-zFLmaG1La=4w zC7yjO0czl9eac$(f}ZSVANvYD=nIv?#4X@P{=dO8vyt0pJDXU2?EJ@Dc>au zQ8WnqP4!#jsW;FG@*Hqj7E`?X2y}u3y>x;gn;qydkeE&8dj%T07;5xsV%tn=Q1DbJ zkfFVGu-(&RV9AHBoUr;=Qs2v*1T(oby^#92fu*s~|8-9Owl)4|AIN8}Kd zWP;tI|BV0oagd-YHCkFW3OQLa#*D5le+p(6Az70K7eY){e0CUJxB`79Rmu5WFr}2I z@Tqzz@sBbP>35yR=y8n6v$Bl}bePE zlE>v|e*0_cds0iorKot_(@b1PX`a;k=l2Oaclt1p25*0^Q(kS0v4b_wZ8x!Axx0mA zzP^Ju+;Kbj?*HZ86YN@#D2@@K?(0f`^BkzjQG-$PC+E4FD^l_cZ97=iRs-Q}%X~H3 z{)o_u7kgwn^m`vWZSYhCf6ykFcJI;A&+#(7AF+1e-_Y9u&~w#LETP9YC*RFigYO-r zr(S)by*)wgHY4e@>;C+;2~k=npo#Y&c|{#ABL?eXqSyiJxp76~ckRczzZ=Au#Y^o6 z-tT%3hn7oNpEiR2JzZhwtrAbK3Z%BrOyG(5gY9^1(jO;z@Qms_&b3?}9jxXn=BDe@*mDxA#^!{Wz+V#Sy6J6YQNAAM$?Rf32{U zhSq&c+{sY`pq`Th<=c(%_z1Hh)(oAQwodXy?Zo&7!Mt%uQ=oq-xjbWTPb6=?BhBI# z^L?F!mDPsz!g>a)L}r%9PbtdZV|r?%TF6mucN9D8Rg!pIdc`i>-O((vdXu?+u|;is zp8C}+kg^4A|M_2%f-eum7LjJe06-pE1M-mj|M)=sLmy_mRDl4SyTTb;twgO0A#@~{ zNmb`09!G^-m4F(3naK^*#o>JVMd?+WnnzK7pnaJz(vJLPYiFwo4l9^yJ)Xj{|FD+^ zbb-vD0XtzCL$+YuNHPZ!*&E<4H=C3xv)^V#l6XFf_f#rbA_w=DbS3GxL}dOb=zHqH zOUdbp_2WY~T3~%)n#y}~#@@0h7&9!IdqIt9n%28$E0=ku=F?!!FtN%`QS4#366UJT zo8wzHsjQ)09x&^sEpr#)vJlmUUP}h|o{1iEe%@aB{U_8+KjGyGI;&59<_@H4G6Ofq zha{lN^yC;!?}#lQ(dF$lw)u^&L|aZY$)sPJ`ajsT;2=qUDXo{ctdy0u-DlDp;jqBf z`E^>VAzE z>c2TFHjtLGV=2Kc7Q-BUaT4lr7fAIjlhg8I{qN|-mc~Df=PhC1_ua6G-wrKF8zrTo z;e79{KjE&pySpsU|1e#V4!dwVL#D)9Ekr6Ml3Oor2B35mS-^WR`t`K?3W7JI`3v0x{=4CvJ z7+u{tlp(MrdHekYg-*aSp>Bui3Y_;UgRisFE3uhB0^iDoS*^>Brc>OkI$i&YbMOl9 zdLjv3M;cKJ(1p-Rg9gn3IfbL)O!3X(Rta1(zOP?|p;>j-!Ei6a#I-BoF$oIVU4Z*u z_iGgF?= z_X7-g-3$E3ldWcM;cTL0Z(#JlWMPGp4iL;i6?8u+==|1BFoG?GJPQkR=t zwzM@wPL!9sWZqQjcu4ZyFPh9({@`bTeoI93I?Q-K)62W^tmg7@V87~BV~t85 z{7SvUaQ_K4?Fv(m4z3kDJC zrHp8dxuF__2CeZ>^$ORXT{ETw*VU3(Szq;p7sYg(M9)Wq=XID70XV2<+2NB*N|L@I zkvM}orfG48*&MvaRLpu++p^acWiCQgts2L$KHnZgV?D(ocn_WMQ-6Zf?#g4cj}1Ai zv=%XQxu-xGrh}v!;hdJu)0f`}Hxx1BhjvW7txP{V4AU^$?tFt80e9p_-CxaJ;H)CJ zgf5QyQXjX_`vwYevU<|kUCz}DwXH+X)vMo@;kIMl)eCb$wj;1>F-h?tH&OyCv9J&E zml5&=dTGWYbD&SYbJD=xN8KQ188@tQu{wEudwi*`BnVCSP|#cY@Es!84w0|kO!b*`{8bnG8+Wv1`n|IJ6caE$sm z2u#s`S0wjuCh2d&arEWfAjEH*QzIU0|IL)5rWDodbhK9ZT@uzDi%SS9TcJ;^@E@e+ zZ&(*+)?7N$<~rVyMr;2>r6xs?z=M$xKn4p63K9_7`s)7%s`uI7-OLU5te+(ebs0VG zM`Z`kW&8NZvG>m;zb|(PUzry0IRodHki}b3&6vszvn`{y#RqY*xLIhEG}?a61QA4^NH?F;yk8crFfd zU1jSZV5-U{F??X+w=e@rHyp*WwoqN8DRnHSx9X09;TY&}Qg~NelH(1NVDDOTt(Fp5 z6xG(&>ND7WNQ(`keGf=aJ;}pHut`eKX)sT~D`icSs=}U!=d)9%xew4{uK0XE!(GyC zF+c%5NzE-hpv*Pwg9?v{O&cbx)OIElJ5hga!7_dn*jJUDd;3WtAJl|B$G+P_5mnn< zmX#$x4`pJF#=3u+QOLfpU2tYvzSSyy2EhSy&16I_8_iFZw3*6lpoE)Jxs$#x z7M*m6*MK5?Yf3EKNiD5}>oO>>hJo%fa3tz;XT5YbF2>5T_kjn|E-Pqr6-POB3A65r z-+tR&b$k)RC$TYtTMc)3*}=1{W{q3ZrKzN%je31IH)FMWaaj>#T5a7x3O>nvAZ4cy zWgLfooXNXd>8S8#)0aDj7TbfxthxS7l!ZmxRtB+bn5Es#uGNSpxKUx6dG!-(Z;3yd z=fJ88)6`OZoXg3SET}iq%^ptYSK95`VXk-|fL+M| zr|*$?7g!F`2II@#>S-Iz`pU13Y#f-HkPC(=wUq#GmzW>k%WH2~gI;)yHmCA90# zmZY(*kre%cUExe+;;pX19}7N3uzBD7)C@Yr`#_3|Nr*+Dy?GjB)6#xSzef9`o^H+r zl(1#pxxv<~s8}9O4;&qM(d?EO`_YL&3iDG56|athDFC(4iVl{1H|(rsI>RaTRM<_t z?Ch-D*Z6q5IH^B1Z73>0d)|IcX6a&IMjA5sa8j>(K*#?NYi|`52e)hs2e&4;TOhcF z#@(IZ?(XjHPH+hB?(PtRySuwP!Ts;=?7i=n|K*%}ZohRu^%$#aRjpaG=F~=1ZoB)C zQ#kBJZks~9UJP|vneq^@{qSH4_K|*vYPP!44I-0zELPuPbNe)E^1$n6Wrc21d# zFWzp0^03)Z!b#{vy|S6T8w1VkvO!ywXOij{iOcsrKzvqZksErul-* zOSlTJHc2|aZS_-c>Ni&7KY4=s$uck9yuW1oVtYQq9Hwp|U-zj+QrJ{$QZxs6Wy z{^c)sHeN!C(_8vw*lsJk;&GE`@BrW&yqBOk6tnHrMS!%IfZ-1Ja2f0F(EAs|HhfbC z#IT)JX3&87E%>KiddpW3Bnj9@19E--#U5zh<}y`JAD_|F`JbxK+~04#ED4 z|8L6fKkv`~m=OP+ez3|8v|(O6l2a$~X`tOxCWy?oxHx8YLjFQlf`s?tYPwbF9b zGh82V#=`@!P;HzIeRsrxhd$i@GLy%(Cu;9nfNsuppia&hQmj*-Khrrm%!T~U9uCoM zd>}T=a6jnJH{pT9fqH=@kyT=s2wRF5Z2qI$qMUGF_e@x!1DniW{J{-5q41JGb6Xkp z^0RY+Q4`BI_`7I$_m0WgA*HOu=6QLHkUQUNy%O$7qXHseV#fjRx&#sl_{u8x95s)T z8!u8(lmutlq0>AiV!w+~O4Vyrn`4)*BVIZ^Zp-!#xy|yGR)*lL=#N|;7*_fd_Q5Nw zXe>iD#*Vj?(azs^_+fHP72{^_hK_n_7YOSr3O{N$xbP#QcX;9$-IxyQ(`Ttj#y?ri zn7r+iWRc)~B*gg>@wF(H%CIhxf3by^Z}pvN+9jmE-5aOQl|++=;IWzEo*CD82ET_x zIHQpyd-c2Xw*nNKSI0tb9F#Dj%|Qs(g3qUk(tXd}(2sL@piJtlZ_Oq*iyx#g_u5}D zP2_tA^WlS{H^jkm_>k<>4HBx8p+HcTuT+9F+~!vC{f`ydxYw{sbP&du3$TTW@%FfE6e`w#Ev5g2RA{?d<%3)Wh6|Bxy+sia3S0 z8L|h4>+i)Uc2e0kqpzvdk`g&m|DnDZ5`lsm1*FOQJXR>sEkw-Ukw7qEhrmalKds#_ zw$7uV?C1dk9kd(OsP+*=QgLCMF&88Yy$Uh+NC3d>MLL1q-is2PCc3qNejZsjzzx~p z`kZ?@TT@WyY~4w~YL?E8_Us1jN~TKZ#S^{lqiYL=0vKqlT0)_fpn2MJ_kGaEDAuA0 zSLlJnJp3?vHCV2uC)TUO_&HA$AGE<6kGiB6CJ7#5($+ApYq!30Z!*-8a!fO7)kx=E zTy^Ot9Ye06_2J)f#>`2l|58d+s??PbPfN@HdpPR7P!EaQ+PuA*8 zQQ=FPdZ1U#H;eQZi&#|Y2cv#9FQrg-P}W0+{%q+7fcZ zz&yskSQGKW*wMxC(p)G#u~L<@leB@M+CZ0=Yt&myyKx_6LL{1%7}b~)EY0&|?R3@zp9w}bqO4b=;_ z%nTI0?#_Bd?hp0cvHw2OR(ME--(P$Av>TL|W56qvTA$b|$RWDBWm$8k3Gfo#Gp@P9 zU*GMXgPw6(Y#WUgNE!&Do##bXv_(0GxW1(b`%$1cp|~E3EaE_g_dA})*9xmv^|#ew z_xa*N96oDpOL(P_i;O8k@!eqfAcijC9$*P^poLB1M^SFYL6l(f}^ow^!_r%2> zm=e6}m@q40-YIKZl=Z^SS`@^9ZZ+h-0RA7NdZ4x9t^$aK-X@7P1pk2YTLVAEFw|9s zUkws}l>3I=0vu-936eLr6vg%b;QjjmIC+r(TMYyn6o42Ms{c>3@ZUP*N+qek4Tit5 zg(KvmOXenmgJpbj9xX2s0TIop6mkSh!Py$@Rl>h|5-fivg&`&F`v9Yt`y9r^2T~p? zlAL3eQ(o@nH92@OaWOIV{dl@Y>w;gH2{WYnG1`*1Z2|4BHM+xTW5fU@BqSgdr!N`d z%5vcp9HI$GRi)!Xpa0wp8K{$_@JJR4;}44+ABWS6mp^l0+j?xb%-noptsjgR9C64d zEz^?3;8~@Jr3GDd?t)*h%H}EX^-J*RIPn|PIw;Xi*B)laSNHPmLca@TQNL*vU53Gr~W`F{7EbI(B4E%Z=xPs z6F94*j*nhdThKcZHw@0@uH|R0IB5xN$GtdC>GvkMVV}Hm*kLmsI`_54C1gk>-;$Uw z+eF!o(2AmL8V;EG^=OL_a`*KCWE)6Pr>oo@0rt{^-Ck_b%dm>BKb(+z6bvtS?I!dH z7)YVV3u&~J`20t#)^IEIVOg9!dNFiF@3Ppi11VCN z>AtvbX(PpBGdAgR(RQe@e?`D*K?s=G6AWV{sH7Bw*bK7&FN66X>;`R+i4Qst9#_&? ziS(|*%9O%NUVtJ$3BOQU0hpL_nC7610h{y_yrrl8dK_5{scD98ACplC9JiC3VF=Ou zvG(wjA7|#&0Fvju&N-N;Du&fJP88qilqb=BeFIbIe^?KCZJ_2C|8JjNtMt=vp()X z4fW>o`{$5xIULTm^-GTQ95ERxjsiTU-jD(1E_(m`p#YI}PVOoIZp7@X6yzrzEt|aN3tIEZU(3usMo#4v=y3v5@M$ z^3jLX)1ip2=MAR!n5K;VLdW*ayP_Gyk0)E!Zy~kJ#l@JYJN)?JOy>$XW>~MT%4G*D zod(J1T*#NPOfF;6tXYq|9863#a%PSG;nbcil+H~&&gS9!tZ$Z;au}8MV|mf|JJ5r7 za#r070iJxnU&yw%pu>`+gSQJ0!i$JA>KD}}x)=X_sMs0)vZC0Tra0;Gec#}xZ3>2= z@}2_KZ2h!nI^3_m3$}W`hTL3rp?$mBHM+4Rlb7NqVh^z+)V}-#-MZqJBnbqoflWV{ zmg`ZXO(#Xzugkq2u5cRFNlPDOHcy|63;c| zZ;$HHqs9^ursbq>a@#K}Q3SU)8-v}UnQ;k~pBbHTVdssj{@IuFE%NgFtK7h0g_aUD zYES$H2ak8wrsMI)?O}EG=BLPA33%_8G-2PgvqolUJD%`vW*dHKgAxojdnr-+U=_e9 z_D>-BF00VDZu6%p`Xe zSZ5=51iffkW$4h0a7VJ6{Y#z1OH2Lic|fI^BkZoz^#KH-8)P^-JuWmUt0#=TBv z6xz4t{{4s6_Osq#3ZEHUoqzy-7L6R@@7r;HLM$F=cdqvA8P5Xwl()k_*wQ51G z5qTs~vpWcZgM{&2FJ7NHn)pfspu_bkbXC7kn@&rc8vO?0TT<3YiUI@TNzLi6t>6GQ zmfFqGACax~ zcI=1G?!;8$z-)cWhrw9`^d%j4lNJH~gKWBxd&ZcP(E!^-x2~ylE>vv3ysJ*p8#U)l zQ-kiQuTE+eG_D&+?|GfW1Q6Cr55vzK z&HP0HDvC*J*zjppIbw;1>3JHNFG2kAM}ln2gl(f=!LIS%Kmy{aRt8womo8nr{CSy^ zW)n?kf+HikvER426u88FD}+3bbx9B+Q9vRBkX2uVT#&~TT_DdD;0YQ|NH=Mh5#k>m zVq(Sq{0C{frRf$m2^8jppl0pAFNXThnEpqY|0A|v{!4k~H%NJfZm>KI96XQE1LGHj z(jFPOa$kYo_wXIrJ;HPahnRy4zdu+{^&k=u%r0ooBR{a5)lq;f)Us#eV(QAv#m2?- z+sF6ivmPV@PQ#81u4^6XPudVWwkS{alA&Vz-#EQ)U$*t3$EQe-P(?{2C9w@Z1-`D_ zxXIZ?GVJ9Bi2-Kv^hJDXXtseu_iv(PJB4NX_8~?Mnq)w=TTp1n+611mECO4%gFV7c zs%j;XNZ#`Y%ck=-eDJ-GtT zL#(T>GIwupBlnd$B$-F23Lrh~47AbKL3|*dkM!2y=r;gG`Xy_7Qjc#s zN$M>BxR-EAtU&w*YIyCZcY(ugrhk`yHLRm64&ogV8_sN;4He^B#WW3@L?n z#Lw0ciI>#qSg8EYv2F-EWQC{-MzIQwJJ(jaXsY+xPA*;locCnSvgUpvt|`>KJTr4~ zo!IpCdWX;XAw!^QKMq2b*iK4zia2bRmm2Itw}{Yc%!(%-}2He+lM;2I|-b+sG#oA%nF3IZ@{nL)f z>OVXzKc{a<&=a^->P%C#^RHI{fV|#ec&YpM+7!O=(o^&C zbO2Pk&jEbWv39QX3Bx2KJ*`os0}P^pcEMP&TJDn972Mg|7D8DyU*7!{L{cXTT8VzC zQN>KNGD&ic=pnQ|=5a;7dY*L8H^q#*k{wBo!2yX4Y8sHrSh~B-t+TPHa5GNN{tQyS8r1Q?+K^D8U86Rp)(o ztU)Ple6FR7q+bx%NLLhB6o6R0bVzVGICIp$f4;eOBj|k5`Fdg1T$|p`$^w_C;43rX zn!R~=an?S%{`=AkZj1elz9TG|GfuP<4+~hW=dY`Ku#G{8>8`e;pBgH~U2$cX8ahvZ zyQ2(MP34xEvpQ2fsa_>UCr!Z~hc~h+BTm0EQc}&$lv~s_PD3!fQiREOPiuqloE(NVeW%NL>pUG;JKsL6L&(?BID>u43 zAt)7{>k}&eG98(KXD}zdC3EIz^{k~5OR2I#GWTGOq(o4gdgG1FRMzP{5U$OnERAqa z^$J=*KDHG~$eI4T;nGQk{)q(gaXB>6rWJm{mUIBk>JiNxv6^!Ek$`gL-!KMKt*pF0z@x@8Uq^$7cy?x)o#REV_ko74T8r z{g+eycMlcSm4Ga{Yadji3E!utM&+l|q6=VLK=TqcU!^L(c7B!)she+g6&-eUpp~s| zZjpQe;i~@5)2m1gPCiw&?A3-Z6D${%QwET>mur-qm93#C%fL2jvYJtfWzxk4+30{) z%C+eGNgHQ7uxU`95Fp@{pj*d=FP(kIHs+m$+#@-vb1E6Pa`AW|!g`?Wu^ z^{MKQ+>U+}Okk)p;l_6N9!NqTvI0O36tSaLcU_{^=E|W(UvM5b6r&m5vm&s8y;xs~ z#3U)qZps0_)kRESf_*5~_?nnQmv2ywPD?9u|G zPB(!gw(@&%kiA#n`Mv?xi30qjR{-B&F?5N~)@MnK7awHbp-vsZO)liK{q+Inrx58! zAKftPBTB1nDDu1W*aHeaqBoaXWv|;@=;x8B{wZ670WfA8{C+-iSCybgTf>Q%T{wS7 znG4#GjVKNnxz?N5wI@R2_x6+xxG51}!4$g-}dmNj+2 z8xZ8ov_FyWa7a)5UYv3Rmr>#Qk(Gq^BaRQ`@>Fp4<|%ryN*DBjdczZJdg?W}*J-d< z4cz=hb>kgf8H2hRiTtiP_P}fj@?e_Sa_7Sl%SN0Aw*@{wq`3NF^58U*qOoI<;~>1% zvwV1)TTNbx3G=oGzCuoft_{n9g!HlOJ|a_0o5$)EZqPsaLDY2Wb_daytHU9m4#Zbg z;TD3~maR?S?ij}u<3)Ox>QIS^tuDTQ$N8j)I}Tq#t>Yf3b^IT^kp6Ki$~o8?8aq1v zC1D2gF?9SFh`mzzZ=Uc%d@h+zzL~z*Q1EwHbrirGs2r~a6*3@Os%QeTz)K;#y>zh%wPdHo}fa@>D#uAfN;<91HJ2!b`W;&%4aO+LM>5VOia54Inmo1jKn|lLo zQ%$2P@^-7UN#2VMiw-V@+{(9J$$0O~55kOo*oI~gL6#1d$}L&POEGsa!glllCqe}V z-|(B^bNvjge^eR5PJVswtnn_xO_~A(EBOT4+K=ztYg8Vn`3eb|xX;cs{a9&I{X;2t zu!1&Ajk88a_TW!J#%vET%|sox9!+mjD@pv(Q)$gFwgC*|qJT15%ot1X_Z?yomWZ%< z0n}5ywUhu8>;|P*Zz-_baL@cVeoKPCIwz>@N0*w_)3}*SxJ5ULcyKAcIU5sUumx?; zk~pu`Sab+dNsx4&DQO9fr8p#L_$*>4mcnI-%7P!p84eLb3_?Bw6S`QmWVeV-3R6vn z@Edu|cRP{~$l+=pS;p;fZqw*dhzOWn5I8lbU-jE)w_s6 z7K_(0m70nP#KQ2oG4HnsV5!k~zoBFZ;H`Aq32ulVeR(m;T$i{n zGUyu}YXB029!emcWO%|JA1CUb;WB%Uo_f*SHpa~tIKrr!N-3f5RW2}#9;UbWG+iHP z2NAaDD*!;2#VJmz5ZDth>`?uA%YR8vLUdpF8*b*MOo{=Pt_At09|FP#sS(;6V}ri( z5OJFEcQWPaNx6GP4^=UVO8v4#=lZ1I{J8r}buf*{ZxM3D4PruKv>j5qw#4|@<8fVK zkfJ2iQQ8e&;0f?*+KtUhFDhMnDW63NCBw=ZXL6krs%Ytj_lY!!=<{Cw!{>}8O436V zlw!{y5aRp)yjT6t6#KVEq*6)yuU%T6-bKtMjlO63%0}vwfDsKApt&@f)XY+l8XD{~ zXZ!b~c;loqdidW1eSME*oo3z)yf68Yu9#`4v>J3T47v|lj)z&lTzy_&pAoxwxW9jm z{z+SGa8Tj*AuuTx*mnJim?q&^JE>Enl`IZ80)r$}F+bk*(*@6q)P%2s_;q5UhAz4%B~J$`ttc6OKQp1aHu%^WKb)lT?gs zTME@{AQcq%=}k_g#G`}C3))bU5B~soTY!fVy*tI zV0Mxto4G(SXaGOp^Z$8|@?)E8hv?`_h$3?l$u1u4R0$G6T(5cBtdf?gC@J(W5Mtpi z5a71N8-EQ!$U1PtDo7Xo7hoP*GQ)1c{oG!A#F5e8IwYgavja3&X)-!yQXrz}x*Y71 zpxst5(v2P%9h%7~R>oJ2lPHwPXQwwf{*QQdt!I_91-+~0Km%Ce|8>0n9aB)YcAOPO z_Mvy7Tc*Tb!xGOWF3fY5jB}$24k;q-A-2Ist3i;_WiWlR6EPmnSHwQVx^qlVl^F?@ z`R)7{M4pvc0A>{en1?w(x5zeqP-%Cae0P7Q@VjwK86?wMxOVs7`w8CJrA)90|A^|y zSw+;NnzDH1Oh~piRV&wpj`?%vsHN0MWH3IynOTX&D_=i2w*@n}Ds~1gPz|!yh@nj2 z3&|iz9;Y;SAcxML?Q^~~VmV-0vSykB#r88~?{~UL4^|?(2MT?p7ay@J{uRWT=MD)% z$Gv5>(kh^msE5a!zbz8iy_}0Nc-^I^&*HxPq8Bkxv7fB%yLE1VtR?fMN+x-rP9@u_ zIi!kl3aKm3&6m!>H^jKyGT?~r6Y}>`G(a$9{MJvh-dL=@%rDp#f6k70`s1)}l~54~ zaKx12MCj+=85Q~fE>B-dmOT@noEIO!zhzNG)G-=m)=0sjTk3o{!F!7iOY7K8D4c?2 zBT=PwmrPxwi@i(X+r~YCUa$+*&+5@Mce7;cC>*gwvyXS9yJw+-shUS`$VMtP^r3GGAmj$dsI|+C-ELMn&<1tkd+h=Jf|8o! z67Zqs;PIKD@=djC?_!Gj4Reo|l7U zhhp94O{9Uzr{>O}KRRJW&%mV?$6a0jjlNT0NPM+8927w|>>>%Geo|E@&jy$!e@Luqo7PoWA zv~fg`h<3B$Pd=?Dx!)cMltEcM)9R{sTXAta#oyGJKTW1jMXUnX!qGkt0E60rfI)kt zufRywUETp^ZZkn9LJRCghFs$OZ4?M>)EJ%^7@R@W00hJYz)GSr?3370K;LX%|)36faWI+@mhRRXkoq z4=F)*DYD2H{~c?ubh0k}ridM1=G==m?;p!9fmbP643c6#Drnwj{7&Sy`^~yottKE( zr@u&wL{iwZbOEimFYYP4O=!O*gp29~*7S2)_uIo)#YLU6!!M3XFcIxSnJS3xRt;NA zSp?D3V8*W`nFg8*_m68K>4)9%KV8L9C!g>H{AHK_t>$Kf_%pybcTVr zA%m5!uGhgU4i7ZufxA3u9GAz=Zfg&#vW`re9FaeAi-hZQwQzo zau*EW8yRAAX{^f~zlDyNv}ngVs#4JZ8Y{fCJC2w7wtuHh|0dfedzPwa;h<}R}~8jBDzTX*45CR+TO z6W|QI!EhZ3U5jwoDk7THsOq~i9O2YxbNbsOrIsv~R^zWPfc!>>wTj5qk|?KVN7 zldsSTu^zz-IL!P$&wK%I{F-(82vOA_RO10d z6e_qxUW>$%pC-G^QYh?OpqWav3^KVn-gywgH2G0OTTs>JKOb0sZC@ahQvOHza?U3qNO69GHCKdfyEjmM_Z^=(lkW2C(1fCqY*C% zgxw*v$ER+pPLXy9nj5zvPfvUtsNNR4sys4-$*d)CpT^-!-2Jd>GKW!wmm!~QJ#&0I z|KKqFct3pL12eiZ$Nm}?Y!7E|j5q*;^OF zg?j-Hxrh+F9NBf(gSJ~bJG;O_0zP@?cGQb{X!bymF0Bjm242rm5$u2Ck^mA}UMPje1n z_nu9v=JAR)s7?urPg+FUxK4{&^;K7#%^RCq$qlCD_o0e5poW^4lj+Ej)x!EG)e|qM zYmAw3Xkt6mQg-L19#pG+Gf-!2OKJr2HRy(g*hDB*fxmPf4M)g244cz2TGbU5qBCd6 zD${VgF(O5-fEOY)0j;ogLn3xK`M4KiH4!ZSkFB*NZhm*LyaGCUJC$M~*6e1DxHN4( zZf+^O9Y0l`k{MG)-sEei&V%z-kky_(q_Na|EUy%Mt)#?!mDp}r7wZz5D^>4;gaJU`A5O zoFLfG;wdLC&V-`(Rje=boJoXtsy-KI#56QrJ3L3I@#=TlbB__bQVQ=;C!^QtzAX81 zm-B(BPsEe?LgDkKrN?_O>gu8~p4OQCb}8e9MRcvm0p1DX{hjb$mE-PZGzZ^PtCn9~ z!vIL*C%;6q-{@zso?S#wzff1%vu@n=yrg_uTPCey3hjb%aDZ(B6-n&VRo4(D=^{3vWH4Aeay7M^P=tx(?Difi{AqygbsUMj_jUYTAQ32iIwT zD{@%vbRzJIl<0TXfj`i+WKC$^{ysk8o}GR2RFUHpdpUlMXnNGp5h;QE^ihAYM3!NM z<&Vg_PP&Z=$7>j6?cwzvl3~chkx!@`rhdSk zcEz$mzWM6)_rIt8LCWrACul(N1WJ9;|8d&?mF}d{`fjp@hRzO-|4jbE1Zi6|AaaN< z#cE1WqK_PWA~+QyD%70F7Y{RJ-Jh{4lFgw>@OKC68l`cIc$Ep1ue37a_>W+JsdB-A z_a!OVt9hDm`)uG;zum1Ke)~kYZ3CgKwcj#P+fzGY|0BO&&a)^Im)lhB_u}{u9m;1C zp15uH*>LoMke5B0<7uL@>0hzCAjAPC} zjxw~<40xJz(pn|nu?R6SiehqUsL_}|IhWSt&DmuH8G2fIBPI;dR1y@t;nnpr7-~lW zD(ldviLyO_#^-^N ze!63)ydy+C9?lMe&C=OmeL$n~o#5XiM6fheDi9PQ^8bqnF}L~uMTo+vObU!*tvSs{F*DD#Ll*b7)~M?KVek!LPKXA?CW@1A+`cmlDBahohrsD;&3eO zN|PNzJPp~=gT1Wbj}nj7snxQ)R~+y?aYh_06Sftf5!fYDvO_A!@%P)f%H}Uia65o&QKljv|phLmqg&uqUO0 z9wLP<)*Nj_hTLtmkg2z9rFSR0b>8Zx(NPW_Z2jyz(Kp019RinL>QUMM5FI>;u4@0`-thb^@@v6#s42i-kJ7o|+l9d-ihK-L1j)Y4mc#sE-1j$g z1}-@l7xx!{~x?Ql*)n`RSBly%HYhw#UMQc0gZWm`#(nYSj8sKOQ5qLNlud-N?^x z_!2)l$bT7$AI3!McIym{fJas;CzgtaFqq3gK_4@!bF{gm z*NC_I_52Iy@mHI6Q|RRo4mu{C|Ep}2k&*b@mHl6ucmHxfCuM;lUtgt{Tj-2mqt3anrcJ#mQ!|sz{Y~abTM;Kfvr4CMWUn!_XvkKZNf_Qm zh@oI)2K8r?Ic)I&qR5c&a+Ra=IKlBe55r7b0=>|Vq}y2hvJzl8-WaYpr{xs>*_E}X zoV09%<+f_o?hOolPpMS0aPPR{j_d{?zlax0e3JYK2av8^4iHp+Zt?_oa!QpH|9%Lzfn9iZ|SSnVme0pr^ps6J8<$ zEPjAtJzDQGLhU2hzvm?RH+PI=&|&|@9{BG|Q=9+2C;$6l|069|C42dic~%!hEgLl& zEi@Yqh&uEkQHapLp$GAg|G?^NmexKQF;R?fnw$J1arM_J_etc1sZov8wKFB8I!?$O z+?_u`b+J<8kOEEhHu$IchxwPg0{qEB#!~GFwl!^}fJStc!Mcjvu))(t!ld?l!c?nGf|V}-A%USWIh=y1Tu!+U>Bmn8Q=Pe4 z8J+~ciDisSm>xvhoG074e*lWGT|UUt^=}s2=v4_&QWmS)=4NICXMRuj0RWb7GjP-Q z4RmQ8bnQJe*3;;`y%V}Q<<}`w-@R}LKP>p~EZ1rxA*GE`sQ|>%hH0M~3G- z!L>!*MeU(2874A_nv%m$%1MCj8e!}(?=gT0FOdF$jEDD~gGs?a5z*V{)e`}y5z+g} zeh#B%CXHquph8@h)epPwUI$p|-75@t0P_6#{O{+z&iO*>3L0>UApcMJQGYvc8yk>~ zpOdlCKa;vr^+gd)75$wRj5SCE`6{@QTjWdEvyY#0Tyib4g@D(sK(bM=SzWgk$Mp+mVs0|RrP*WsHUbXlu# zW}lt7i!?>o8YrS_O0(gv8-)aPYTA9O0|N5pY0@~0a;j?i;_w#{aivps#!}4Hnt1!v z*RVTz&0UzIu9Q?s45%rOV>C=C35b{ydI!`ZX^h{(Yf$ij@$x`dtQ!S1c})RNnaSx# zqwm>-v&H9Obb;(NnMpszaj2M3_afPEtWmTC?tW}hQ4+E#UR;~?C~Qq;nF)+CCTIhD zo1_g+EUh%YmO)Xhhud-5Xp}w&lZn!a<48cOOx?ueCkdbD_J_NHR-zbrJg-km*CHy} za$@Igjh^UONaA8SeiD?CS}%`&xz^%EL#q2jJyb-=%44Fo`z%L|(>RbSA#F1bDd^Z2 zRv2ssHCq*sPxi|{lF#GmoiQ!WPGFKEL6mKjXcl1M4%EHEtxrTH#P)LnB|QBX9P%*^h*&* zRn94ySy{KBU@vKvg?P_Gte}PvOBu6PuQHVKw^)&0^k~YZCK5Q@qTtI@_S|i6FaBAK zYFw8KVQQA;s#8TpMQg>Em7v*Q?XH*8lSsE*=QLqYa$xBA@4vD7pQAs^q^X!v|7^(2 ze{Q2>D{aG-mAeskFyBXt)@JRcN}7Qtgww^5CZ(VNNM%qO{ft@R78KM_ZTGB#1GCcB zG8gK}m`Gc&s?gglEWyBGF)X4CpKh>5-R0k<-h}LS*5ia^7)|OO$E_EEqV^ zW-_irvel?%Xi7AFwM7%?VWja4S1!flGkhfRfYVcr)?{4#HH^7FvB}y|v@KBB()buy ztguFf|D$!HJ!+D3B6_-~w>F343VX!6(_L<|Shp(aD-p)haPxRH25t>PtZkH89um~J znX~tL5SBas-NEK|>(mDpOf_Sd=?27}r>WdlKT`<=-DEDcf2$|mYY@0&Wj%Khqc~Fx z>r^Rr@azE~MdR_YB3GFpqDA5RDM3ReSs3&R%hy;i^|6B09I2Kz1l8^8Up(|f?5-X7 zuEzdO#1mbI-E<}HuCa%RW9tO4V~t}oT0gzuu(|e+{HPOJFLp1$0yu{Jr-0gT&d@b}%3k{WM zNc@*u-kKYTxqpuT zy}0PEYxf`(@D#zNdwABd%f21rGn62Bn1!F2JWW%6-O@CzZMgf>y{6-GC6(&&IML8$ zbA9iE4*Vq~a*bSSlQH~qsONz;hiEC7&*V;NpMJ<08<% zQUM-hG$esp-apGme)rgAOnW9y+~Szfdr+D|tBzFal+4bAp_x~BM) zw8ex+J#8BZA+~4O6(N8}%TCQT=i;8#iI#f#C5?L_t((u#+_E~v7Q?hFR6Ro*i5V&Ioy|bGMb6K zEvwHfRw<#$jx`i8)q7v``pZ?k1|t?B9q?FfT|70osFPsFY`Bhib_kph@1a4Ch}DG0 zH}^+XbcCG?2;a>w%vLrwc9s`v#@Dw?)yVbi*;Ff#hjdPnp7T$kFxgiGx8LZ$@p0vh zYPUJtGVGifRWG)mn`P_hwg&351bcBdTi(Dp%lg_j6K))wf3_>Ap_|)9Ji7{ctFr}Y zgOF`(axzUAh$H-Gz*(;6tivxa^pO2T>AT-0!OsIaKlY{{_mgA%zmPScYm z)Z^LnPEYAV9XJEYGZ7&^1-_5gDq?$oIvvu<>uaZ5LX3Y;h*5*9?Jp{}f5E(sv)QMw zjO~qEBl1gs#q35b4_r|>PwP$Iw~I`SJ)2l@gFbxKF2XlT2`OuEtFCxkVw06AqWpM8MUvrbTZiwg$nh0vZ03p&+DmgMQHq9TeAv^y@*r7`IED4u*5}5`GTM`-65!2k}4LsI$ z#aPdI*w+aaMsW`|*WZS-EbqiP4PWF2E|M`Q7V5b~AriL7uRsiy?_ivsQ;!X_&M499N++{KktwXp zlj^Hz4DcAWqVZ5L9#C#hJbq!1Sj(#)% z?vK1@kP!KLUU2ERArO=8MS4TsWP6phX0K2}nCHY3i4a;YabZ~IdP=uBtKh~m{Zw#$ zA_@KDfwRTi6sRW@>;>DLj`V6VI7AleU=sQNbak4*t~Yx<+0~Q4#i$=a zHw2$eae7vy)y@z3+rphVU8g;V$a?77B+~^a@ zIl61&#1raZW6u^@+Ir0{%^(XFg)vf4B5nNhJFW%Z;^b@al*%3y&t%hWn_~|BNNA@UTX^{ zn7XOpeJ`5m${zSNh?3@cwO$^`lbVI4Q<6%PT5VNl44n2AUgHFJf+X$5*!hWvGbBCd z&%_jHUI*})YeBGha-j@l5c9p4O{z#-hBcBY4ypGXWl`PK zLBW&7>@UpvnLA_VP(t}&HkJd2ye)_c`nZXkiDZ4nWogjW24#+qBo5pY+i7^oi6UIX zWN@sSjlduM)NS7!?g4aJ#wI%Cd8(-5$|h}EA=M0ug3FsmOTT4amaWngy=7_noRjt- z=hY=?;i#xv zRBiV=Vr-a%Y{=)7V@HE$F{J`=QpnMK65@bQ3j?~)o2$}!nT%m79MIG7h{M79dWs+zHg%Z?AoB%zFmU1T}dGJ!ebMT(s9loZE^?<30T;;p)N_sNidXyUII0pqr)l+9g$A#kQInzeM+1obg< zwL4r>wVMw2u0ao;Sz&z0??e(6eD?2?T2IM9XDiS6XzM~@*$Tt^M<7+F5Wx$L>4#{I zuPOM4K-pWu?gvSMuj9UNyi*SFFI8I8z~&bA$A9sQ^+5!2)iN z=OzKGJ(SkQiJUlv=LMQr7X1@JW)k{WR70cVX2%_)(iyGnQ!@=r51)X}Xo^U{r!WbM zB5#S*)$GJphz{9-np@nN2De1!{#dWi<@+SGsb5K{WiEo@_Eb>G0w8C_7(!E9?E-}9 zSfz>fFj!5V8Gk2Il#}%jGv1J4bPVCA8%8Q4<LXP=Z>=jFIT=dQquU|(|EP8UJi>TJY=^OvCV(V{yDM8 zE=P%jA(@eFCD22K@5xp&-vW(?T^cDX7iMxM@bIYn=5`Cp;|g^ljL8he6ph=iEJF%O zLmElrxZ7u6fao(GA!Ov)r0mZ(2lW&;E9H%EIE|%=QL>M-n%%;FHVLrW$9jeLtJ3PU!L}oho1FIUTjmcl9R&)u&_< zILsq`ODD7mVt^=Gc3Fq()X55hcUB5#+Se*y^y{TgAa9I(i`oml-t5fBKlzsbG5?yW z=>1~BJ}c9x%iDC%Wl*KV9s7-Jga-Iu54c&sWm7(6lnkt-i?jcQt~GN z<5ZhXZjvcG(bSAO%rwA$gw>Qyjon&%1Gnb*A#1a8Gh_OFsH;!%x&Cg5b0Ln}beolW zfu9vd`HOefRyp6R-6S;|J>U+oQgM9&p@H~Ic_%5<@V0wOtmt# zUuR`I`gM+sc9N^MO7MlN2f6I z3-LyK0pN|1G+4c{#bK;y{afpz7_W`_qFLF&LiIG~Y2!dgxpWquJiGZddYMXz8K!3S zR|$?A^kOJ?qWjKqR)6&!(D?8&O|V&BAkzF!9U{8fAi7=0F;>X-;cto@ z4r;9c3F^Y8ZvIZh{CS%09&OmGqkTJVynU)s(Jd9nUTWS_ zK6l3OvoQ^j(NCE=sG*e^?$K@}!*Z&3+G(5u2lV83{&K^d2_DPEJUBppZ}B9#cIla{ ziWkr2;jyiTl^x!YH=is|o%%SMWVyrBIn0w5Xyfo5Jg2_@Dvk2dQ*F6%XaXVd6a4cy zr4nxZ?ES+C$I%?J+$SV8Kcq4QxeKwa8}XLN2g-YhGPm|-Pr_e0?-RU7VqJjhop_Y} zmZamI;`I3t(V~6*WNv8c46*V3o~1OxoOO{g!ZPz)lmE?%QuAmqf@H!YUCs1pgo`Z8 z_(Ce70v~loZW3%@yrk6T396y!*8u#NrN~98M0YG3GD841LxFen_s9`+AitgMF&H1e zH<#BdpRi28`eH#}qcOxm9uooYtxWquP;6n?6^Mo%if4jBE0j-`y&G575K8sRUoC`A z?FT2m{lGVL9hO*693u+^ggh%%*mAPxO7t>i+LOSNwfO1!TbCIXCno z>6*bk^OE~q>P){GcM*IAp^ zpvh#=OI;%e1V$#CxUngIXgRA8o4PVY*{&bLZ7q;>O$*OXryWw`# zdu4k?e$~=yMy_5`{Y|9Iue!u?5hGGoK&WOhJ2f-Kb#n5>)!60r^_B;u41gsLwm=dI zhepLDpI0E~^4FY_QXERh_7C1fIR*tl84!mPUP}U!?KKAYLJO=ND72}4TK}FpSlUnz z+w*{M#xXNk3HIGzxXzfq5ie;8yy)tJOtWUxv&3CP@si> zZ&ql@C(cN(xTiE=nXz+BS-$p-aO)A}dnCAv-8}$YPT8m3d&$mCHX9zEgF$W2(-ru{&kW45i_Y@Sq0uxyQt!yFCjkRZ(X7nO^dz+V0nw&aj8nRB+9M(+ro6(jhL20fMcmh$ zu0B#qTGcB$R{c`UdD7eJxfu63Mlelkp<7>b{BTjF;vVJaa<)_oR-QAz+;(O%Lbso^ zx%Hp*BCvjCN|`d@zzr_>3B!tM#PI#jx_8p6FP8}&>%2EwwO;z87NmjoTE6Q_=SUP_ zHhZp_rp5Z6$|>J(bizMn|2M--)vbL7{M2^wUp{e-0VL~#L9q3lCSJ*+hC_@QNsh`3T#-Ku&Y(+V|1FnoTfMJ8CO>w{ zi{0(z(N{_TB#eoVz~Bv^Xdb4Y5H;zpuu()&Ug9GfszjsRnA`yC!4bC56xQKmFUd|w zhM@l?XHI4x5IIvg)fQfTq-k3gBR^ABw_m&etn;T3! z(=&|jc83J4U{2={?u(d98s{r&Kc2>m{nX8sFN(qpD2S&S<1&Wi4)kq!Xz~in$ArG5 z57;I-eQU}rnbm-}aNqNfLtP^LFaf?sx7W?#IDMy+I2o^**;RokaQc-tLtp_*@Ebi? z7-){=cQoDrQw4FIbmxU=n-G}3Qmh>J-4henH-90nQvoEF;i_qdi$eGa8OXCAQ1^}< z)Z6E`SH^$93Pa)*V?89r`|wXEaQ-o2pbN(+=YNYv1;{`^lK(El=JC(Qy>DvGjjVZ3^z2Q{}aI+plog!H@a5y4;#1vgp?(bs5qzzm+TgAt`QtcA@= zM9rzasNhWlEz1rvllA7&Kx{VEpz~84!i&UJe04)9EnEW$hOD?84N(xCQ(&S}1l=7p z?f9ra5X7{o!rBHp9Qh#_V{L)b@&o}Jipb~ltwCA}BjhwEpA4#a_6&$idy%xP*|+U; zqAsQA@UX^YOQ#b-lq4V>oe?rd)O~1*^a0~Y7rn)6w3z0n1+S>>GpDhQi0#jYnBVi! zyV>Q`id@|Mdlg$0q#V*2#nhJTs1DCue2n6D*yh`pLPK>BADs}fnf;<2zpz@5sie98 zHZ_S62MA({R8czzsjSH=t1V19yAGQCDt9#V=4~I3Mr`7CqbdzfRhyQLZ&)!HLay!P zNR5V^&M_?S&_qpckOo<({~_ZHSEx3M#C`#FSQg7ur#Q%jhb#(?al&=NO*`ZaH%K$b zd6krZ$XUpJ04N<47nVRF;l?m5h?SV5-lO@2#4SEQQ^fcCgB)o5F*q~{I=QN%D z+MwhiZgOJX+x6*L>@|tjJ$XjU_#n9k^Mn&2%F7!soBkoSNt%5fs{KBQ24t33O`i## zC_Bb$L`o7-r8A+OUvz828%}F*e#(v68^*=ls;y7mGzuk0ep2t`jAesxT@Yiiska2 zo`LxMgFd#)?j?m)eu2 zu-j$T4fDj`G+tNsJv?m>bg_33?I^nF7KG}bTY*rJKOQD{a2Hdk1^9&{^piihg`E$S>sBETT4qjP@mH~%?(T>I8hmo}5>p%iQ z>fYGHVmtLLd^=3~FseDA#_iZD`Mi;5EIK}^`ME_`9^k^}#GwkMdXv;8%KCdVD6u)z zE(#Ug0nppYcU4Y*Qu*Ar0%E9~omAoZ56;mGJ0sgo0AUIZ znfiIQzOcn<`Wwrr#kzc&8!RxX&nJ%^^1=Fb{Q3>P`pBcJRf`-|6Rlf+@!Y)gBsR3y zQr;JOB6`huKQk?5-XLo}CCdbmM`nXxVO2h*IeX_H{y;D6unTQ$mJ(f^Zzenw=zJvQ ze->WdWG~nn7vIZta)&ilj!JE+q&I!-pTmQ^VWtchk?bnedw2(^R7xfVjz|lVm5{pIZ?f{2-p`SWca}O zfcB}rYQoygAXgz^Ui?miwIT*{re>ZpnpgX1rrG&fT}|(Py?;{plj8qFkwnypS2PlW z-j+$g9VSj?-BN#@p=71CYP;x17MKEVOoNo-3m2d^u$?(*Ki9Vq&p>47fTlY3WtJHx$IwvdYuwte8xufsgj6fsW zz|QIzlK*6@bfaZDDZik-@4$Xh>?)T@=Rzy&tWDkB_qYjk&kETv3~jDY1Y7a$+ZBi7>mBMMz%MZr=e2fg46@3$^@k)#F5tI}(BmPj_22p!NRXtjO$*u` z!^&mJGtbgR&C@MC#rD+1aj_2v{?*ES;dC;!G`p0C*xRMDmf~W88Z{P|8B-1w4sFoh zVORp)z0cnP5Re+`mCKr=o=IxPmDI0~6^8hy`WSg*%29OAAxhG_SF2euB7@1M&%j=e zyM?e^a@ngpAE=d4^+i)ywD&V3AR4{Z>A!t6Q(zu_Hxq}_5%V6BO&I)tTZNM3{#jcz zS3a7Nakzt%m)YL)8muMADwut^?X!CZKOQWtXk7fMJ{9!nr$OA=HjL?w%Zt-X<ws6k=jlaretW)qV2f>b9#ux~tq^b)M;`8^+_ z(*NXp#liJz?=8zFRycdbvOQrE&vu8VBk%*486_{k;gYMwiZ;S9hGPDUYyRL9cM5d$BVc+?ynp%49{lR$mC(i^km&o#Aq#{rmi8aPu)SiPgKNA%J@UFv zux?@dN*y^8v0A#G0F~$Y>@9`0z8sh>{}Y>$jAoBqg4=gK7Rp?aL3iI6_ODRA5c|xX zJc=lg@b)6ZVCwJ(AP3vsH8{yR1X|z#!pCZuYh^~FRl^a zfVVL-p9NbqA&($n&!^~pY#0BcO6wUQsfD%NMUtI=&X@gTQZBfT+1>wcRw0800#f`p zF~Z*7($>uGe@@H)@!Ee+%+;x9D%xs4M)FWWI3~fVo0^?XX@bdFb*oxT>yyRGfvrKC zmO|R0F*DiQ4INQsKlUIcK2BBfB=CAU=?B}q<6Bby!OpR`jtETLaZ$7q2}8L!r*Ao3 zbKQ8%-gsap3Vgl()c~SkybvMDeJTK+9Us;F%X#wqu#152bb0P1EYuf%cJdGGy=fmJ z1O3FR5WEOJoY&ly2%b1=SDB&epbSXv>CjS2|Ni$8AV^}47%~!qnbJhVNy&`oLS&A? zv{9}rlBcC@ube1`bSy)1?wBQBuG@OAS*~1`BmINm&UE ztK=5gGou3@UNh=oA?Ty?irl#}8S3iX)(j5ve9J8+=oULtG5&7-Q{s#5vf0O-pt{tu z`@an7f{WH=2ejhn$FZ@rpqrB2C<>-5Nivc?z5k+w(K!RI$C_0g`#ShsOp_sFFD>>J z*5={!)Bj_~6d|5#-TP~p}aF~#$$(-=g@Q<7yS<`LB#McV*FP$OMoijl(8 zKwfZwXW_0nL=Pyj=@bM)xl)6#h1Plfs!-aSYMDv>g+0uho_c;CWJz=JGI!e{xSQl) zE$r^y?cc&AQ=C!kZ03}pFl3u~M>|;%TXWEAwwN)D6KXnxj%~bhj2v3xmBmf3M)XES zJ$+Vn5fKB9eS*5ORh3|>JL0J6#BQGTD;kXYeee~NQRR_*dAvk5rItFJ&Tz`6yJ=>} zM9p-vrMJ$;iF1ClWjtzrJB3N*jLhj!JYWzVy`h@4snq@4l7x-nU zR5XD%Q^beKsX;ED>{;@jr@>)?{9}MUx={!VCLM5|R*pCu&Lfby7pyvGIEjBI+hXUQ zKFtQMe%|89^xb1Ur2Vw0?};MW$cyu?*c0|oofr5Gz$r2-vd$M%6GR*k#bN)`by(Sf zh8a)n!;6x0B?XO{oCH)I~xb$C`Gh2F{i#lGmILGhIX-&O2qM)!_# zdWrSkO{0V=&z1ov5d$YtMN)*3KS(YjJTvKS)_JzlwT?4&SKWbimV1QweP@thTN~N0 zd%Z)ktzdl(NvcgJj;5rZ!V82-BPr zcYt@ouBm(#N5ej5+k*R!4Wc58-iCy3Vq>uWVxxr-)u>Qg^fWW4S#A)dwbE=zrNW6N z!3(&ZD3Vwo*chzW45(~B8G$V-ZvB=tn5h@avBk>$G!0nj<{B-u%zUH_SaTb#Iy?H; z`O2f+ei?GTl6#>a-nFV_$Xi2$F}q5^JpPuI!N5+z)AX{wOy*k1Ym5^2m@LbvxPgZ_ z_ae7U?et`au4#3BOjU8*BD_Mj)2?)_S4vRVwTVj?k|2VD`y%)yXri&gM**T$+Ki%* zjdJ*-KYdlhXgLPE8+MDYu`=8#_+HQLO5sKUFUG9PWz{NK8hrh-4UrCGa);{eaDuhL zlH;dXyIF-u$AZ`$Rthtdckm?BR=+ZwTSB-Y77Y{JUSg;hlSv)5{fX=v)7GdK+=V+K z3}QFsaKyMhx20+QYhSgDAGtHzc)eMe>CpsSIn$ogO|FYycv9B;PMLhwc2KvA(_a2=81;ppu6`Gpo3o0jz_sKb3%jlBsIc$nO zl5n&DO}fP$k*wWnD2`;rC0mL7o$S$zW_scDO4^Aufow=KAZb!+>jA$;WRw?%oy*td0JjRCLGI^5(uvYnp&n+$ucVUL%ydSXVfVHi!|46zZtx#3U!2gtAFv6OG;?*GV-b zn z0X3=7;xiU&;G1#_I+`xoT1*;lN1-XTX{N*L$J9bTErCcsJ{V+yee}7n7(pTwUlM^d zD>DcG|3^|b182Jv|1s*KWRrn@h+e^ih0T*uLEr~SIkmn$I6#4rFB z>^r&BbjfC~h4i*Wm7lvx*Kim;O^toawUH?UxwKN?9U84LZsKk|Y1=vVuvfi0k@Gvq-my`zfaC<>C}($GO&0S=I{gStd-POee^IU;RY(#szQu zKjC}?`rR%o_>b5l^Sgy`oKY1%;QuFsgS6U<+5HU*{@<`5^KWiv{{;&Yj&?5g|GcFA zms{dLv4I288VVTZyNdwhi0BBKy|@@1C7)GrNJ^OwcvEAFT$6}x+^ivs{Qtu(u`4I5 zjU8W+wC;4X6XxXmCUCOzes?n43leTL86^bP^+QlGGoE!{FH@4>xISMn#ij`n#+C~3 zxYq)yqUY`)(VrOD33Cmtvp!}sPHj)}r0P||wrtk^OTDSVR=v5a z#y8cFgM1E^K|OLMv(K5(bO}K%rct6pCws9uvi$nKy2`Y-;=F#Z$DhU!%{ic7wZ72& z8zJ;2f3~AYgsO<^(Og+I7kb+vc2pG=QpI1M{{tbG%;aq{!50x0u-EIVz7eAJ(PX+z zgCoYfyGo-9PyRdqCXEs>?q`JlgL|o(!w0$wA}~!f;T&yei+;GF340r6=rbvc=)tC` z`TAaerg&<~-*x0LT%FS7ab#UE*S%*+zMX}T!_zIsldjed({zM0nR- z@N5X)$UlVi#}H}|M%@Q6*wJ_2`-wnsZ9EtTDG3#wqun(1nP94>q1rreLCb2(FyoBQ2pZ(H$=62bj$-5HG3>gM|Ij(4457>W}R4<<|L z(ks>x>*XgY_bwdmY2SxzGt6ltY~o_L=vTyEneK=?g9Y zm?bhX(_y<(b9BiY9e;Rvk+#JldSoF6?v9x2=oo3RZu+|Vt=If%U!1r z=y*w#fvziLXQkIUEVI)qFcw<~eU4e!wn*VHZwF3ghfGcN4lO_LLG#A00A9el5xnua zJ}|zo(HuEXJsqS6pbgc_r(H;{*}!hZ>1~M3><~So^k1V~;uoZGVISIHjIyiS+)4>Q zJtUE}sSLO{%R7DqS3fvQoYZ0oonPLRJnS}|Y1~T-Qvtn9t=UA`XKRA7b9KrMkV5mD zMdQ`H9I_8d?DHsY*xf=gb-WQF1}v%IsGe# zL+qp8nhysA6h{UGB=UcP68}xx6ay^XRhO}R6E^ z!?7vG!67JE9L$6RwK1D10e^m?yKN|6L`MElQd<0p-kh~ktiD;=xuNe41T_Ze!i4$oR@uZ%<)ko z4R`*a0yBa=JMM}z9%BJvER3LWoVR7x0^~Rn%#13#mkwNa(CdGGflB;-D2GcvhzA|b zcHfAYKBJWAMa@LT*Vv|^||h$ z&)d8?TM*vPMVR(cht*GmmSsGt*_`X}@R6z(RQH)|>Bqx>`qjL|!I4ahBDpu|vRD_5FxjxqY=vt*yozWsZWTVQAiBo>adt(x%Ft)W@EwJ0uIa;{ zZcu;$6$5KmH>7gFrl%ta>R5V(-$1~w;z=2v93>>4ye}@TW8Wry!JCqd?q@knU9gLLsW}!Q#`+fX_COyxW;37 zoF{NI7s52o9`2s)jCp+KIOkKo3K0oeYV-EsXPnLOJEavOyYqEUt~QKt>Y0yZGs)MN z+?+y*?Kn<^f~rcC>%*H%1l?S+q|HXk-{kA6;i0R%2C{mJX+lpimSLUs?43qU(c-Ru zj2#66P_rjInsv3t+^HyW!2O4EaFZ8teGPmbJqX`_C;W@9JDy$JExGUY z0K=^erf*0R{X4c@`z^cg;egTYXN!CE@<<4oqlcUk)y04^t>bt0VVE~OL6g2KicfX7 ztiolV?`-z1Z7O8fs2A47@f)&=`yS`f_6Bb1^2}$$8w%6iLI$^8Y~Aea?Bs5|e_LE_ zwLff`b8wttiec>`g7-NcCSMnW$e?K6{DBTE{v zpqM`Bh=tt*>A%*+?_C*R=p(g*b$~7}$G>`6BMHKEoV0or=gP@S8Rg56_(Z7fZJa)Q zXtw09mU#%<^mGrtf7WNwLax)VShnPCic3-6VLkQYG|2vA+9d|}(9J7NFpC5}2_u#7 z!75s`U3#f!ckCMJL~hS%M2c2! zIBfxPu2FO&^?54+juooA=w?Tz_!El*{*#sB5R}aHX+Yv1AzhaQS|)o_rH5C|3hG4P z?jQU#CRuF#b#{N3#*XACvYE(OSey7LCid~K+9Z&FGUbt(11mGB<<8g36AC zFs>bxJoYva8&;9rSb0Pt7#~e&xcZ@-^*8sK6IboSo;;}c5G+^3Q%222fH|?Qxx;a< zz9V@e;5`}jJH@S|X(G5nG#!}K>%^%Q3#W>tLk6QX-1>7taWKOcyg8nce15taFq(pH zzYoXS5Z4Fyg7UZuH}~g9J|^|tG)$8P)1LfA7)?f)r>D#l%@}8_>}#S+VTW{JHFLlE zBIk=nWv+T%6jw*G!9~2(4D8q|ZLB(yIDCL;pBZzkd7+e$js9x`u>-UGdmlDS#ZVr8=VyYoCpr@5}(i zph-N$?@SO_0rV8s7c_EJc-+v&;-C4iL&&B~kRI6?VV39R+EZ$mw#TRHTD(~a>*As( z08urA4juoPA@bx8xzLZpro538Y|~z`I0fBEK0z0%zf`G6ze^R3QH$%Kn7ZkkJqZPt zf!eav_^NFHr0u7y;kU-LEA!5yHi=@P&Dph`3+Lu?04(8ktY4f7Y*K=GQ#qy#n zoL~}DvlXW05Nl4Up9|2P(Jdw^#!!kdQ&CS!B&|87HnWf+6RB22N5Op2D9lw?-90)* z7j+>+))|)c%VK%Xn4dA>;!;r}k%}v`!FkFzK4V)_w^qxNnm0*B$U6Gf)!!@p)FgfF z8M`A%$e|R?k(8-Tn@GbBO~nqq9_w^iW6ULT0l5Bgz9tmABj)bLLUK*??nPDgcI1cU zbXH+ojoeh}w8oIQ6ktCK0i^qmI$ssW@(UZ_!10sLPn5w|3&M zGBYpV+i>&xc{)cdcWROW9_qM#xT;Aw>k%}h8MJxycVNOi1>t}lG?)j5$YVV8;6AHT zuK>J(c??cYnHhbe)$u9WttzrWOep%KAp$HlMwSU0+=#jVccJQ0f$))bdZti`H%!f@ zNd>Ggs7aa<%(oH@?oolZg&;9u_=^;g3L2Sdx+PpH1x!g)aTrWZn6Z(L%rMrH+uwHZ zQAuR{qL9)foPe7ZLtKN&MIByFMoG@XRya$h=QyEO zOIXKWtAA05c0{XwsPOO4;fy2G9IOMEws0TjAt9EbBFi07oZ91IYT_!2fo0J)2$rEU zN)&kZ={M_4L?UZ(W=$e`eEe~f;=j`69_T}WOgr*;br4O3={&Jab^x)ab>{W{vIK|E zT)v?%8g{zfA{jgjM97Z9Gn42Q+4)$O4SvAGr9}SPNb@H2nU13qemhs*mX7~=As$=d z;6MT|h!?uVgIvB(SK4r_2H5FT+o1~)lM8ZEUOLFolAJ8&`hiP5onG2df(LhE8tP;(>3VPg=_q6BWYr~Wo_OU?vqs?2U%#?;- z#l{DaL8Mp5_nw?m&qMyuoG;YRW~J49V9IGMeXwQQPOU;j+71%^gH#e87IBFzb8DW_ z-y5h8R-e>Ns?{(f*bc*P{_nHl_)RA&x#p?UqloAe|aZPFc?M_Zr72GYcOZIbfY zB`sTvyeMVlnUlU#M|Q!l-Jpjj(U2NVrs*Mu)O6PWObLrnYbKnj0P#40%{6P zej#wyZ~nNa|G4Mmc?-_>l8FDFHvTF=excD~vduxOiCCxLX|Ibru9XOAATJ(BINB?% zNYY0?1V}9wkya+{&LB?$rvP_(<4XK(xs1G=FfQ{1K`2tI*5VSc6mPy)oy_6WXfDC3 z_NY*E6t%Rv^`cJ8BlG~{N@<-ud;dkXcM1=4AM*wIKWP$ASu`itZxI{)J5>F@%bxz< zG>NjQ*+1<-sh0ncuD{zFVL6~Nzt6i_OsYc#gDDr&rB>6DHM2w0WvyUA+9ksNGV9+8 zj<9}){n z@4A&5$8+znIy-8@!au+VuQENySZyd?WB%Ky2FrIVZPEiCmY?<&2_YX{1{>c3u!4ko zTSGqzVF#@fCBX3<^Rp>)Rt#2rr|CJm3Ckz*$XP4jl3aT%^#sf|b||Vir>uWbR|Te2 zw#YziwQU0DV)rs*u|N)ZR+-5drfIkloJDiIbZVg^VZx!5Pfr%7U9KoO#man9WoKFo zBnqC+{K2c;f(^Y|3rmKp-VI~ow=%mLRTiSm@Wf6<`$u>u*pn8DaQ+Rk>`0SwYB{C7 zF{!ift!a^{X29o&I9YtVtCTB%hLS5Y0Rt`r}~qN%GajoPBV4Z4h1 zr+EJq)XRFDHilYyU_FbLa{EqNd28XlYn7A(Hmt4|Am5lrd(0Y(VoV!-lGOBli@lq7 z3ZfdhETo@OcbURF??=WWzjl=$Ogo*2$I0xaABCIw&We_8ZSs`2!>;#*qJjIb8YrtR z`b*io9cY`vJiBv*I_r0r$&0?UjyNYh4F1lx%%CVg!9|M~^dTa1dT9{g=1pJ*ms*Dv zOPPIcTcDpSL3$f|IAMC$+Pg|4gAPWIWID44y-xN~V0pO&`+UMlu)RVuqC0}9`-cR? z61ULyiEspQ-Jw}u+z?FiPejq>4!8tm^AOmCoTth~on|#!_DPgMI^g9@!sCkYO(C72 zylG>o2o3p{@u08OpxC^SOL^f-YdVkAgJ6C^KbtZ-G9coWi_*-tN_Kf3UD8mJTxd1M zQB-OBu_qZLY*Kj@ws6BP0OwMl{>NPYqj>zE{K)*VYmCgi8Hq$}8;n=fzutIt38#n^ zQqh9tC0O;H@CM2bU%}bBann*Rf^$NTde2jEy@Fyl^!nCe2@2Lj#_oVYRC320zVAa6 zfMgBO!q1=>wm@JU{Qy%Sb>k>C@4rUPSX(84i{oykh}zzYDe$MpkV)!W(tHO zSsUTIjJIp04-Btpk0w-)A{>DVqz-ft&4F^1e}cqT>m44xZ~)4y=#={|q}Z#~h+)?) zoe)YW)laG!nzTu%($RPa4(lIf=s=wvtkCsu(Vu&*>aPBnpy_%5*%4VL***`2HPvAh zJv$%#S3TLRITbnXyY0&Gn*{#fMYew+8mXF-=|3UcchMk@5K`6i20o)J92gWB1;{=q zA{7o*n&eRg_&`ER6f~r5{pGDf5aZFL2bjB2M6op(@XhzrjCw;MBJ6ieil6g2G>8?GII=BjDszS z{jq}U8U3`QG#=Q8Y<)Yq1-4XwWynoz$ekP;MnFx}$SXA)VtB9cHC?s)h|Mu?x6~O5 zCio@P8Aq4Jstmh%-~Q!cChYy|l^FpDsEy&@FTDCM&i}vv>gr5r9W^!lQNKU+T@<_= zXqbvh?8xzuh2h7cxAxgUm~%}dx4;U;dqQ1d25c#GEQ{&KO+V!~(>2ZH%zidmh^bgk zFQgx*v&m$%$i6Xenw$BaY)$^YYrDN3{`Om-JbZ}ry01rSRJp6^;KzywZXAcB*NTxy zRd><*`dSU&RK57HF4WCN3as6R!pjuJ#|muNFNOZZ!M3qz-iN^1X)=t0->l{|8+M@C zX*dW5xj?D)^7S#!0eSO|8{Jj~oZNeE>#0wkq|wtlsMG47%Fd`G={rVPRaY+0Yw4fd zww-V9h-)-&)|W-6olu3-(onjPD<~t?uW4rUW^kDF^6mhXuVrU6kkpQ7=>f{h3E6}F z*252JTv3TmYyDbX1`d{vv8T*MD=HUR#e`JVzX~jy2Zym%+J=MGY|}HNh))L@$Mi(?@9#SmV7SG(Rdn3;g>wQZlDqPs*O9Jn>yp-Io{SHa6c6sND z+V88Li8?9SuP826#VnCC*|?!JbLyq8^1*rNJ{geOah@3>qFu>9(S~o-UDZ=lrKnvC zEu{UJM5H3owfTG-HRf=WtM*4_UUbq1QDO~7rv}xJ>W~r& zpz3P8?<1$yy+wEF2JqGkUAXiMmAcVV7h?W%cq^otn%X?v(HHa9<^)-f)LBuc`Sh?E zGEd6Wfu3{?`FbI5O|GwaY-Z=p;aD7OFp0hU@(NDffmkKbOZ5t7UncXNBt4E@kt8-SB9DS>e z9?sK{E4epZccKzWexe76JBXb`n%^(NPvMXrV&nmu_L zh-J7#{}bDDEePZIHn$vGdl!S}#MEeBOTFfb22(6nSUjE#M#~DmUhu5K*f1)RD)EM$ zSL@I*IKQxvxSW_p29cMXlXD1A*DCDsiCliF28n0&;bFnrySD2ha(!~g_NLG46u&x$ zV&Z@~epEAW_yjkuwj&IImkanFwJYcyG~UKOfMS(=EKNmJ4zbfDY}>a`Xu2P}j6~;0Lx()_S<>SoDQZw)s{>)6VwO`<@bnq-W3S97cZWV-$rFU|t zMw;3Czc45HPuj#~H9-lts_*!#2Q~fG&4E?-J{&)5B0n&m=*4GPNewO71+!W%4Jm-k zyraCWy0|wqKfyJsoG+O=H-xTK7aa_wuB{zcyUMyqtW9;bOZ$w)@9B!^j3SKVcp+qd z6&>I_GNk4x@m@osK;ZTNOI88vXL~MT47(nBiszwKD(0R7s1!9cH}KOj_i*hi_L&3UPOq7zNTUGAX52q>FAq+yM3k zSsUi_$VUuNZWPSocw4e7qAug+0pViGH6lrs2H%kZFtqa}JEIXKfSDwf zw2C__*l30IAq_@RjiuSbokO-cyJ%$-~YwWS0lq;U=GCL#2kL zw!gC-;$cKV{SD)!6$O!pXnVT=%?jbr@o1fi(kHZoekfK(*%;pp*@e;`Buq;cyTyTc zD*-}g0L3TW)>BfMRp@JzV%IquIOes)AW*#0V!vvzP2?4bs|Z(acNs7Oo` zA-R#~-t8hXGyU8;vlC(P+rE$qPivysj%4J=xmR)XdnKX`^PDs%84Eq?E)e4 zEMJ)$P`#*CYAP^K`6fcQZGab{WX%Ty-S8NeqPowxjMs19C2m^#Mkb)7@QJ;Y>Cd(T zwPHv#=$Tv{tF+(%aYP4k31*sO5~pJQR~`w#uz!t;yMj*pOg$ZQU4Gl1U1G&)feuW?Qo}}2t8aUq{!NFYtfC7v=`?!f&0biq4G~wz$kjdbR zQtYEuh!cv|;%gs85>U|5R>WheQeRCin1L&EB|t$3ivto0`YYf{f{2_MlM#&041VB6 z=Ld1hsvPXAii7uQt-`N}@1P=dksHLo!>f};oGX{nqYtLssivAiRnDSSIqbq#MF#me zQCgyarcV0Hl~nQmqWn9iTml}@y#D=m!9WF?q6!fkx>8b7W@Ndg9ui>n`v<5&tfPjd zG(#Sy6)#k_g|dpG0vy5_#PC1@QlcoW!9#SXDAkyyX|Rf^>7TF%&dIAP0|z!L`a5R6 zzY?NuBnP$X$$3r?GRD~+3y*a^AP!*#Wd&nk0~>8c9e!m}t`8fNxJpB1+q0rGwN6jM zbQNd76MXesvx}MVU-S=f_X9xwdKmGIhB0t!8h|kF*vp!%1>82;w$Ps3Hk!rKGw0|R zE3((UiAQb?A?-{Nv8$ZYjj7s-v^YYN(`YkFte=O;*TmMVwA!=j7pcLvT49tt8W9y# zh6Dpu;Jp*0e?5rQ(0;gOzEQdG6!Qy~^H4qsN&AE=e@lxbz9>nQ4&BL|VrlNx&>e?w z!hiH4Hzbtar2YVlbkq+1U#z`jl%>J8Ets}#+qP}nwr$&XR@!z}T9vkKTUDvb%--kT z+wa_SyWfw~{l?gT_J}>ch_P1e74faL=A6GN&J#EbdHY~@OhrpRkivU~j2T&UZsJyD z<5s84j?@?Zv)l-wWnSQ4qs@*gUbCUQem~=2NhLvyhD*KRx;dpG?3RX_x;f<`D9jH^ zFMe`d2%rnSygRt<4fqZX#si*?n0)(EdCRuqFVr=sw4p8973gqD%K6~?Hm)vUy2nU$ zAq#O$3vq2b`JN&9An1km%{s2!6I@Ux zi{*so$O3F@LTJy8Q7R>sh%H_haddQ?;k z7tXkM39XhIqOm*=ww4~PJzxBY9}#ReLp0&XpZet-G@34>;qU z2tymzy%Odm%K@QkNkf$iA)yVRoBdq?_5Xi zV~NRT`D=XoS3ApCd20xD*5%&zCFPct7up_v2{{NVOGQ8ickuha1yFm+|AcFfuDN8H zBqXh^!Fl%*_OlGyRs%Owo!wK|amyHwQC)M5`Nt~r3{vHrttuq1d5&Lo3w!S*Kpxxd z1w+c;SD!5m2<5Ob5sMiBLLfE|*Ho}zX=vj4J}S>^T2Fw4fgs}k?_Gx;hco^IqY7vP zRng<$ywx9+E1$7FU%8WCrUNzbh!?DPNnk*k{Grb$%-GD?kW9{uBxdxqqr|ozbs6-w zO*-_FtB0+dWZJQ7Hb0v)Dpx3`bYe7eNo=cpk7=&|dY&3%1tGVhjyWDEkB?zN*wE3u zw#GDS-#4;##YQ9Z4>89}DO!r4tpAxD53nl;B4lMcN~W0n2L0F6>dkj_T09^DVFO4& zNd0@gB_ei?rnai)ZvT;gkpJJZtH)5q#Ngt@kH8OmF%vjR3&mqSgFFlX_|?~WV6(B| z0x~F35d(q<&1oeCXEP;5nVo2kx!C7G}(5G2P{*+Pgh(@f$ z$C!7h?ViTl7J0zyqi(w`)2Kr<>~x45KgAHMH0Oj6YbTd?USs7n+UhMqORLvHtTlAf z_jW-_Y};NijWC9d(c#+X6DxDb8)v%Ra)o^1BVN-)S9`FxU9sWs2?e3K*Es8<*H@(Z zW70E;;m?r_KYEHXnf2qh-pWt1yFX+3;z}J&^`}dlA8nk0T&b z=yYj1yeM;ss1qr>ElgbmtAddpI}mDT*SZU3Fisb-FtA!$b^(ejQLsTSRHr0ZUh4ZKOyds+hAb4 zXqiZvXzvr0-m6LT9gsCNa-CfcCx2Y$(Rd<3^ra*_Z{dYM-difJtR+B^#&_00p~~Y| zX$U^6yHI@wC0AK&Cl4mewZ=#8OZimC4?qsB_cc!#tiuW*R~w*Jl_E=-rV+>aRKeU} z6uDPG&G_C9ctV!jvhZ^^qmJZ1waeIB-$;aRvK!_rv1#xcKNMX+wLvQGuM+^j{l!P6 zx#=u$TlTc4%)6A_~vy+viL3mGE}HSr@bR)5)+&jQm4$?#FV-H zp|!uvAh9=0et5)A`!w9=wBYwlR97(1dSq|K9q?D{-88<0+~BoLXHNF8Muw}r{SPXh zY-+fc6u@p70tASElZxkm6Chart3g#|LIxC|zmPuC8tuII62;vaL`tCN1R5$rhVv{JH{x8soCr4zVz>(6Lanh}`gK z<}{24Yr1H|?ZN0>kd|}aB2%i5 z_(GZ&yWYhgFU_);hcaeKgFwSRv9gw0f7>5rxZta%P1m>|?e=09GXp4}iw6O!xFLRS zS8hj)qdKxcHq>7>=sJA)eW}_lqe? z3=T61je=Z`M}}f4k$YMez`b=78HS63L829B#1es(K}ILrNo^cXtkUW0*wM(IZ{Dfm zS1O>vD^uY>Rjza9A-dA}=$>899nsh0a5>8}tX6Erj)~i-f5*ZoxiK5<|WYT zUeBd~Sgo--&$zKNw`aRr)9a~Ehk2Y;trdW`)y(bcd;v)5lyAY|^0Qw3jwo`Ykr}Js zbU>a{t<>%s<)p7uKPzvMWhjQ*3JEek^pAsE5WV%{#?nBUaLw4gWP{UR%Fi!fv4PUY zYm<(~$`E7`UKaS(xuU!ILXPb7VjX~>U8gbC^GRb))`0yr3XV#`)Na|9gR{39ep})g z%f*-@G)fLP)fv9UqQOi`8rc&UiQt6Sm=O8*L9X3V$QSUE_+t< zv6lj;vQwPjm;+$lay&~skX8@i-2vLWFa#ZCo?r!iF0A>@th&n^HndX#1o1=L+Ko4o> zit_X!B-xZPJll;{EMT3cFxblHuc*q6{Mo@j;qRwlxFtN_y}-^e3+bOV%vP}^`iEtw zj#NmnkTE>~#6zqFNMd|c?~X~_aFl9BqKC>ahIt@A{s`v8=oL=$Q%{gM3MpRZ5)q65 zpP_!DBH5zII zIwnUHS4!#X;%_xm@E96J^(aVhAOM#mDI1=#uU%XU^Wp-*AK1z!#7&C z?+Gh8=uDQ76lb6#JGB5=7v5Z9RD?01GAWFYgX#nV=Js5844J%JNHG)2CwssFWgSL% zkHRsbPuJVdbOyYDs1n%69GCzNz`5l~_0?7Lq^5aBSQRqQy(@dB*;=OR4PJx<=s8LOyZiHnv(OdLYS>(7!GmFY>T>5 zlrzfZb1kgfJ6f&Z*Q;`~`9_>k5GUkzpzT?fA{8<(TK%uwe6QWSuUf79UEO{{5jQ$* z8oSN$pZz`i?*IPC^nIP6y!!?cVl<$ZBrTtG#+;oRYxUEkIx-!NjlB2fB*-|zJT_g0 z_W?OCA}60CrD29{%P0gyb!Ce5xaR^HRT}2ALZ@TiswmkI~WBC zjVR*aw-8^7OC22J8XP_0YD$`FYAH(J3-U3_c%k_mCx{yRe&jRFl=<9v5J)t#1`Omp)g1;SEKVhiKl5 z789HXGj5rCSdN_ZK#dF;lWTWZnT&19ZPr@W(ppAQrEZ`}v8Ia0MB(_rwcT?XsXe=c zPme24d@E(}4}~lH?c&*)=;$K^?aGB$pYh>=a{Lzr3tVs&#vOf**hkXIgQeq>UYQ9E zWQc`B76EleL3~V^qxoo8PBk4hcML5$IX5hU3UZuToOdv2_>&?Id-=1K4hZ8^?G&fI z@Rl2$4@q*=qrXv2=`N8<{di-VkKD(~iU27-O|*H1iA0X!-fl7Zab-ruRQj;(B;>Gi zO;MU6+2TYaGfr~;etn&6yJR~(yggUt0ZazF8B^tfGGBQS^o#>v{Qc`0j;N{#OXozP;Xi6NUJ53@1j6up z1F#^z9oMIDZzeQt%Xcq~jEpaIFTbT`B7J=k-zq|nHY_ME{FHoYtlZto>NeuIG?w<*X969mGa z2U9K4$BV@TnH##Ji@EIHVR)X7Yt8lJ133ZNFsLedlRPmP7PP%s(Q|V+%A!0hxg78& zaP5vyp9EXL8IV;9+?i6UKh47o*CTG=+~S(DTQX0AarXX9Copr%zoGN>nd>%@w3sjH zCh9Flk=J9{T4{%EwTyA7*Kn<=UcuZ&60M4uR^SJ&Y+c=?9?!mQd3D;7 z-(u=?k4Sa%yc5(p$_dHyN~c+)N;T;1_GquD0VD7XbU8Ek!QL;#6*inv@3>eUThjl; z&&3cII6g=n;@7n+5$y_IrtmijbE7`-0HbfEqw5v+O{3fKF)Me!G@An_)0DDnB@28B z46y){x($kvq$k5r1eC#*e-ss3hGBz;m??$RlZkt zfRa#=c43rJpd=tzbepJbOG@Kvw&q7m<+<;-cB!8B(%q%;(&b>FIuF4tmM)5=Y>J_S zJNfFD(>;f@*>Zf${rH=YxNpFyH!PqhPPwOep94h=d?O=I+CX80SRlMaFO~SVL-a2h zy;R2*Ot=@ky%T>kiZSU0Xdu1KG)b)~2ylbTi>}x!4zgdavu{4i-bD1V18<5wM?UDY z7k!FCc&E23nRNLYG~vW!C6Pr{bqVzSTIDER5~FBdPn|+qw=Nw&`$+~UE|~3lXv(ZT1Cen-q`|anHOWR<8C(|ET5vcUr~ht z)A@-o7Vk_7Xvr5>e~-<&EKU@{C!Z(rE#4J>ez1ysaC5(bzrB+af5mWr*jn5=W?l5p zOg$ILXEV4@$_ZLWdUeZnEMVkc^dH^cMc*Te-Aj(%D5kx-8k8fRnEMn)$*p9eM?sbA}{t&3{!&rCB#DlsT+zWIG8**2jb=_&o&7G;r8vx{7x}!srHURXBrZA|;W|{V3`FDC+!|v@=!3 ztsjj~N_vpKCvcdP#>&p8*MQ4D{#5XSJzgdKzEIsIo-d3?0x$qgd6}nVS`R6CE-c88 zRR{@aT@~V@*~`zg=P1(y>u|zb5GN1@nK(D zwhNRG%~97^eIu3Epqa(^;c_Nb4v?vY*%9IkpW?d2MYQ66N*L#I`99i)$ z;7!97`rpRD{_Ex8zuznViGkJm2ixydDCT{2GJw%cKua79jggtzdU><8G7OCgzmB~j z57sUnjR6i5#DA$_A#uK=EuX`bH`VPjcKTV={e2IXeW6fZC-SGS$K36Yr>&MVy1=jB zSE@kJ+lWR`Ex>Rj^*P)tSOFZ-0eWLS5x6qD*O3w6@Ev}gH=5Fw6~-kj@wsVbc@0U+NMdLnl?B# z)0>U6(XH2}L)Zl7n!3s6JM@}m;?aXAq{?;nSmkDKW!tzI<)=6}xT~{t_m+=U+;j(0 zYca|Ol*-K}^jcCff77!XmQ!R^VN5@^Ycp0kYhGAiXF{c4TK^OaD9PvC^jPr7b7P}K z{Ha6FM!PedvT93<68sQoijK9L8lTz@2BApHL9(!Bb`_7#Q>F1>m*wt*F>cU!VEnQ2 z#CPs*`Mna|wLdsSO-O3dl$BbyRPR3(?!xK1joilEsBOOr>(X1w@b%f^=&WE~lF;F# zJ|?NP@W5Qmb9;!2Puf|0po%YD3*+YzOu5t);f_zejf%zJf|I535ieoCz@!6U0=^o} zBgs-EtH!XgkGYa{)1P5ep)KM;->U*i@x+Q3%Z)O2T?=P@_Q#K_M zRcNsfIh${sZC{VEu7H3LXEm%ee#{W%M8ZJ-K%dg3EYyd zt^&6~-RRrSd8)0f7bD*9T(f(Np)szVnt9(vGks7EBzR{I_psc}qFkf8U>e-r3PWhn zx6EGF^_|};T#^aH*taTgNXGNLbV~@(OwYI=h@qdtpMckqke7kz_sUeNkQ;TJ^X)S@ z233d+TniTnY_j+Z?%lI*+DwS z!nhmv(QWas z$1@6T=~YL6$`#6YZ&bInU-RrL_*dgUe6Jxl17f&2AY1frR+0Y8`2Vo@|1*I9FM<;Q ziNQFimQ0nBeR5-wQ4l%IJa446w4y2gZFS-eIl~g;5ZXv&;wR_T64Y$_N+4Y2; z^EkrEhd@qi9A=`ne~=jb=snBZ`?~v?3m}#I?Fj^3`??StMaUmTgQ`lgE6<8OfL6|a zZX*X)cu*gKO?dmpbQnqa!ai-|Rd`S&MD;XZhHKTV>Ju*4$6J$ObFWf z3>qzqr`B$2o4jd*n4;n6G;SGviH6#Xe8rdml@7=hJ}c(bN{YeW(v`-bOAH&Ib*jdy z`Y&_VK&=dP-+Y2%ANmtCtS?5T;2-|h9porlQDO~HP1YK$k5U<%L+Ntu%BBjz$Gl}1 zO|#DQ9vYuEZ_5#2k2e?f*x@1y1m7iLjOmQ*FYEZq#9#1FjTxCW;%(xDdWA2oHaSG~ zC4y0j%$Os5qoGnH=p*dU)>=>|$g&`=-?)Gs^hy>rCIt&;uwJ}<3%XT5d-eYC@bLW5 zYpw1`k=$A1XvrGSubDOllDOA90cOD{=VF$IP*&!cY1l8iS-W1>Njo`TR3D_l@sr;| zzOX>QI&EH7!rU;h`9<#3euW)wHn7)rwHi`F90ROtBc>Zelxl9-Jbx!l<2T2$3q`Df zH}lp-jY(M}t*lD$ErCu-+{QThUh3}-qqmR?0KtjwAHC>lbMoE3kS!I+7v;0m(NDX} zZSIHMGZ56|_MMGJ+h3Cbk9$APF$4}NyDSlD^Uyl__p`>_A;%WBah;NE4$x=s$2K{ z$??X^{hTkw90Wh3f|ishjI7+xuvS)%!r}As{DY;Bupi{>pdtKZ&v?Dk0b?p!zd}F- zZ3>-&$+`8F5dbTyQCB6%HMb0W~mN+94r0V+NZG=#wAd zKns}1yVt+g%FljfVc%4aYqTG) z|05`?jz1kPVE_TaD*oFHwf`+H{4*<5rvvS$s{TiSQ(Ahnl)jbDoVKjBjJBxEj#?HI zMx%>}zM0Bo69TGK+Fpn1u#=gmGa-Q|;e#Q8Xeg{3v! z&ZNY>3)wfeIVJ7XzGBH+5VHoytil9csOG4yc6ojTO**tjhIxfs8Oy?C^9`Fym0WXk z9vRMzi#K^9Bm2heqjqpQ`eXC>WK1em?1>8+xyPhhd+v}VZ=GFr{$rZEOkM4?0=SGh z4xy@p`O=NrkcHNUoI$}a+LoJRwG5|+V06C??jF94@GxDn9Mpqr399>>`e0lv8`n!iwuiZMl^TyZ? zn?e@mb0`D?#H~cINw12_HHBoYq89; zO|Q$tj}AV@(!30|$q%G-_uCi8mq&+RpZ->ZP-pQH)ZSsQ>6U@9VM;>w#m6ye0dFV0 z7e8OX(y^w6bDaP!mx`Vp_^*%8TY|e+2rp_#&k&U@Q_%fi9z{=9!%!O z?vnX?cNf(U0PRP_M)qS&EHTWs*$^RJMaap#N(~~c#hY6YD2dp_^JeQ^BUi$u={N8i zBiBYn$&vuNqpiG1er~K@;jZr9-h~$J7JHq!znOuv+0~xed-HKQyD_#4jf#P~0MamME;Q$QO z44>7Z=c*<}X_VcR+|7{7Bes%0<+a08%34*6E%cfb9qA!0ZEO(S8b1LE@(B77CnEY7 z>sI-7at<7nG(^?7&5_Lg)2tmoonn(Xtsx3IYs=n`iH>o*2#` zSD(D6YnZ8%ujs-1C%O_13C4*V{6&g2C#luRYJFqd%2CwLvr>Y@g0+ptUvx4f|TLwp4#g2;VnyKD!W$%DNXNgdZoJs9EvsWKSq-q=*1d!Pu z4h?e?y05r}Q>fPuMGbU6R;He=;8ZzHbgc1QvoHhQrAUSECVrH+>AVm*uTlS$-(uw# z^q3L@aedLQWT+2ESqXp5MNYoGJSBnQESJ#^*Dc4MgFO^Js|6@FjUw5EXDk}l;@vySJ?hVlWl=8f4z+tT_){u`j zNMESzgG=QfW@k&CL2q)UA4(r)&r6LhcNu-_5K~%swe|bCwg#Zuv`IW*CtxtUpCwULEuv7L;+%t#3Pq%@G zUw5zRz+YSfO+ba>KGh(!V{IwnbobuX{jiX_ZDaS;&M2cpud@1y9a8;Mi*RSg`c*;})=C*3 z{E+)?eYipYR>g^m>J@|{ZeR&4<0SE@qA4t&{;vG3gW~{V9&_Gk>l0ew)XmTS6H~N0 zG7abXOZ^%+sih9`o{)njJ+@M(JdwivA2x=C_9brVei}hjFpvy{s5+vi!}gOtMNO`o zevdU`Dz1eUH8U;qQ-YLmYks&{LpQETk*hpfsQ!0GvQ{;r_`?}I=UO@r<}(PZLmArG z_pA6#AB~~(mb7?w=^!nCgewoX@qA(;Y@b)_er+9MvCF7q@3H3Rqd zBf?`3&`XD0>%8Y)0_^;L5Eyqx0Z6CD8<&MEt=oeNW)8Hr?u{H>naQl9oF$=ctRn#` zSyS#`9*T~tik?fGmqLmC{90RErx(Y^ZjEhr`Jr`|Q+RG5kQ}VD9gU%@Bl~ajurtDx zF1EdVPx4sDH%CUe=kO9okki))?a3|El92edp>O!dr&o|#6`}cJ{BbOh3Y7?};)J}F z=&67U_=3s|i3TYK5_Z>DqVJ zTb&g1D?fK{Fz@ut2H1t4y&>KZnxavO&yQg_o(|AKt2B7A#z;Er{Nu;Y4ysJ$5fdu^ z+MWUtmP2;oS!EhVoCH-IGA)+B8m)j@p_m|r;X@Jh+avsXQ#4ii401JTAICc;w50vu zj|(#>4SgQwI>{msft^6S_U#Ef#haZ1exX8k>X^ekDJp#Zv-~}~iHLR>gSr#Zg4^F0 zys`uA9X&a=QhRqHQUTBB_C!67vh$<9gs)G5pw;_x`+5igkE-&oO~v+4Ha#g#J|vm7 zX7=zvRuo9fWSw+fu{~wsnaU!TAmlw1h*L_V_>)bCms26BqBdWGHA_z z%4Cd9JbG!@XPiJc>yb{OnqOp?*U)X5Z7@t)T*ofq2CNlvB+9)KE+h>V?~L3Irbe$G zaZ0zAtAfB&GX9XDDX{{zCqq#bxE#QV`|FmXcjdy83SQQ7FU(R`8we7f&Az|p!bqO= zGLOW{udo_%STQjfgRre1*FRbeO8&t#BlA-&s>)l9Xi|g*xeSCN*X}hxUK!o2f;&yl zl^S)vr3!_$nz>m5JX`LlDmDb9UUkTPS)L!o4AN(sic&Ht4e2FmMocqlr8$)Dv>22Z zHwFRiZrF+TFrD7$I7S6Hox)B(ZWkiRMocjk=wLuX%V5U`)jmU4Fen~Xi2+5Ilj_TQ z`Msj)*jh#tnLH=0y_i4EtoY;?q=!<X*q}T)Y%PIYh3KebGWRQ0qpy8A&oGi~ zJkF&K<7Mq2R}Q~>TrmgU&ADH3Pt1=X@JotIOrLI`a-Ji@&r|ch+(Mtg{F>)1pKv@& zKug14(MDaOE|l6#{NxhldqKOoKsOez#~80y8bUqra{c&n{h)GtRmShu{#kwS_IVfm z8lrqiOX{r=*#U$;gg`@(!A6{ie~=`u7nnZT;FsoD2HYfT<@OQ*snSPErcde43u^uH z0{Bh%+2>^?vdGbyXH2F`#-Jw@zk3#v7nn`M;W$pFM|t?A4%@7N1mNw=iYDwBVA#04gfk&jKBoaJ9aLvm0l z81qK8NefZ;>@VG}aiFCokz~2V%nLiT@_2|m=KCqFNwXs$>eNRq4D{w`oN~ij^H zxEWH+Tt!&zGQa{}i~-I3M{?i2IETSm^~LOyZtYM|S3&nyM0#-LYoQnL|2feKMAi=s z+NDh3aTg$M;PQsBT#XBsPeh`zeK|tpnB(!z?Ay^+jsfdPL%yhO9U&dWaz~&gPMfR% zz#N*`M(Y0tHD>?hQZ@37a;M2kjIo9jj3`@~M)>_SY)TSMM(#Z!r( zKGl#ug^(ZhqWw*#SewcrB-s%O{8Ey0i7j2<;*H9 zL(FSTY-%aYwGjGDXbB6)6bBc18M->~w&dd^L!ZUpT;jE&5eip8YD3Snebhurr)UvM z?;I-7R2*BFe2MHjD;EEWYKJX*H20BI;M}~L!jc608jWHvQn$MK+u(X`?wQ@>TY_AG zA(lgkVaiHYEJ{Lmph-GUi-esl4G$}yNO-mwhE6khLE!HB-LbYvzTnKXrpE`|^WE5YuWT+t-`AD&Q!FK3LlxATzRgCsL(uzC93dbcp z#m+!11>Ji{4ZM>*s2k|G8vG|lh+Zs-6uStydN53r5cvv$&$`eb9NHGm@`Y=28<1+# zARB5WcG5+9wuM%?)Lswk<~0K!F_R6t4G!uQ`|8-F-qy4$PTy<|&~Y3f?qn7@ht6{L z5SLW7NI4b!M=E{`uEZ0Gv!qHBFI?a`NO89yyMWSgp!94W;r7(`8Pg9o?`!1| zi+jEd+!SepJa0SL0SEAPRitIZV4I4ef(p?4>~YgAHgCJYe(!5&P;WZU3_cG6BYhw( zOp?S;4bDXTLP7YHF&EQG(@fJb+Qy^ws7-aFmzB@sCQ4*#ia&vqQUtJ&QjCf63CxK* zU`ZW7$93bTyh3$bNn;L@1Y6KHJJEdYvZ-T#5R=A!NHETs25LleC=pD-pEUJgJ+6ZW zb>lh_g8cjwq=y))=ga<|3&HkT6(X2Q_okb3BH#s5Qv_L275dFa@@aY8WC>VnKSd(H zB~jwZXwH}cM3N@(G5c}T+CdH{#DwYG5-fxR!CO(PyKoOD;*v0sFXq5*XymTswg6CP zpwf>EQL>0cHqJy$cFx3ptWNLaG3O^He`uv|h{^`wQ{0{0G1=$l;9SXdL1fNEzlmZH z=O?PTn^WU==y?R-&AIzE#x&@XmKh2fR^4%Pg~ISt;+)*ESbqnChQj#BS9L&?aW)XQ zO?x^8Kwwn|XN%J82qcbXtl1U-qS}9Bac281_D_=uk7kDXFoZ@;WhfZvQTNN~0MlMQ zM{K{-Ttry&I0%)-{KSVd9wOqOrdE|m+-jkB@TsXuWF7B*26^Ey!} zlZM>I$_cv80>q19po73z7nG@?T=nLaV{RZ1J54EeUN0q<=v$_-qEFu|dIz)9D|sgi zdYcJBhc^IJkpQe;HXv9x2^qXH8`yCpzcrzqFUR#*>lV9V!@eZ$=VWYJc-2N4VyfP+T36V*!g_9l4;#w zx<^4h%bLOO?#XW7GKgw-HYEb;)ie<{KB*=&ig%&LcYwHnX@Ier*JigzNph2#)SD9HTB^Yny|7N{%r>T+m2@Xn@d%B*;Q^ z^XOIT4=J<*t<+6))9qIF$@sn=)H>x}s!x!?p&-#>lKRI1=%^th@}REwewFlo)f8#; zDCtjt)JL>%89?)iChP&*-$7{8#>*Wpi@KDbSHfBl6!u3b_}p*^rqN(*<3738Jxu8* zP3dQj#3tdNFM;Ly_LYpVdG9UJZyijg;LYsFW8@^qOUyDht`a0I#31O{*L)(eL z_o%OTs;_sfg?~YO-e7#*a2CHX7QY;jtOL!ZHW}(#^#M;nD*O`hs4cKFX4^F>j>dpR z*NvE0i*-k`{@w~|)pwTKN{Klb2BL{?roRA8unCxeXVC*cqLrQtM8^rN)oe%?b)P;j zgl)@o9fNAxdvzM;xdU0nq~JHX|IJSXCH7QVfqNF%N}CXbfd@=aIV`JtP^P+HrYih< ziFlQjXq6Qb{c7$Rwxa9tTliP?sPb6Q&!M0<=9u4jT22IXT!a{UK(Gv9;FyCUd&0Gu zLbaJTBk!h!Ow2zzEiwdjCf(iC<>oY#kIHGno>{T`W|ju_GLHXG>zP5Oe8>KHcm z95Chuw#6Lr;T-Xq8!$1)5H+cb)2{UmvSwuB2a!tzSu!1Hbu?;f1_K2QNY*;lpI`@h zW0?3WDAw9V5jSaEMzuXUjl9zY^&%KK4#+wV$p(gJ?t-j*Lo^YDY3*Ul)lSp=vSB4# zmBDY)Ajr`AhK3ag0sjsGCmaq@G#a#Q+=q?&EgSW_W^e=s7OjZ_2g%kv&g7HeJOHSR zka)Eq=sJ+cq^+rRe%3Ba31}hJx5~y`$6aT}LC1-Zd|aollH1I_sIqKwlSElIwXHcs~8>RR!m5-%Jc2AHu=BNsIQsj42%EOQTCZvYs+hxoD(1h*2P0 z?f#iIFH4zF01-xt__n|mM*|-rCt&h%lE!l+aEgsW7VQz@a=HpeXw43Po=$pb;>-5B z2lk^fl^=$Oqaf(&zEqsi43vLadl{n)aK=?_d>vzt>oyiQ-P6h7`s8xWSOlnp}~?V zIB;Ol<{{mRqho#i=yPCEz70lU_2C%ze@z@mw@W5Hv%%t}jgXPML*7qiMqZ6ERTX-9hpoH^qzTsbV zi9Gykk8av+OaR60+l~1d3&pKGxoD^GI^r2De{{n75&v2qlWyV1ic2z#tX6p?A2q2z z_`EVg4UTl6C5$Z+9e41}Ot3wwo#Zf0YBRPL-bqtEzr%S0tl+;^LA`-p0{?-fivmLR+e&d`-w61{5w zkmGv=4oG{Lfg8nQ!}-m$bGM?Vsadx7Gqz2Ue~JyPL%&xd|JRi#y|PZXSrk5({9sa*jILfQy=Wy5r<_Q$dd1+3Y<=n8 z%RrVVseZ)r&--lj8grIX+IITo;0b-r`Tog@4w>RhebKuvc}^xIl1PyWgqKp&wXm}( z^xbq>IOnyOiKK4^XwieMR?PrCi+N9RXd4Ax_K~J%)suHSyWK|wMbZRhcvm>eZ?tIR z7uhld&aI)9x%0!Eic)`nvkv+qkTTUVI~e!n6{fkyCstNMzh}OAw;uG9ele5vuW)EO z5|LpURk2juBK`!hIvn?pFiESm)z}5d#*ZK-AzPZD%;?S#GWDNH60b-|YQy7TDbE`G zO)$~oqD?;)M`Fm@k)uvTbqcZ!<4I(%p+-ZNj--|dNVwq^FR;p)bEWz~{?+fbbxp@1 z0KfYJ{I2kS&hP&VCpGntKX2_p+oKX1`W^%+WcmoZ&q9#b02aXYrf?nFS>sv$N%;SC zeUoPE;fA8G-QJ^sB5{l~{1jZp_epfoeVJN8 zE`QOp?NqJwiKmU0G1ZsdpU9@+WHtrgDVe~BfyS3u_QnXLUPT|SXDv~*lBk6$Wp^>J zsN!~YD8Znek1%E)RDmAF5zrCpDG0WqF<`-5q0P+FDeM^af50c{6Onkynwl9iVE+R? z34;xQPu_UW5s5PkHA|^@g28IV{4)F>$QVjEC*ewfwuZqGo-bHM~eOgAGqsoY)_< zm$obNy{uQnaQPqk+Bk+`aRe%<$BhL`9Bfd1=81rg8P*Q(ZEHQupb`G1M6*aP^h^y4 zM_YVOLMfySA<+3w>JSY?X?-d?Ifh?%2ecO0a=;*}N)z~-ogA?}n*v4E3d13fu(Uja z(MpOS+dYD=a}83EXb~&;Lb7TQkOBl3tkn1;;BH*Wh9|B_<{G=K6_xEM@`=mCH{4E< z|Mg%03*k_l9RdKMMFIlS`#1N2qp7<+015FQr}cmDdLjG2zx>C@KM(LW4P7Tybu@iS zdEY0Spft@v6&09PHa0XdYj0JZ+H!FnD#o_m@=T7T?d9z-2=~7(%Zg)TT$cqUED2ns zLqX?pTx#aWOAo&Q)v)dxO92f0gmH)7=z z&wbtXfU5_kC!z>l8#^tYImAEgEC^hQB~6?$0i>OyPrS|)B3+)uyUx^(lX z%N(1HTkZJ~OMZA`&}kK?87*OZ5>S|uE8Tjh#!R;PNxlF}R}ftgcCFLll6@cRU1tn;595p)m6VDTXAOA_0WSP}kQ z3BLvMgtjBW*{hT z5UjD#&%XoRXd0VJk5X9_V$^(9M(MYHuq}Bj;t-&o=irwYJ2^y+GLkaSzZnnX_qj+MmPYa>tTPs*(2_g~DL#j&)fQ*x)XK!88D zw((+0<$z$x5Kc>uu)h4F58@VbOv$G+s+Os=Gk=?pEH}99pwLd&ZWgAn{(z>P*hb%ODQ#?UI6~GeGm)i#Eep_rraQB>LXP3}p!qO%H7gEr63PZQuC# zISVt~p3!38>eSevwd96;NGFLvXL+Su^GP)(>;sB%TB{V99)wdjWb=+>C1kq0cGc?K zyw`XNf)`1uxt<>F&_0W(6abBm;0II3>xQ0Vg%c>~2F(DB;FB}DW*~trsC2n7eMH-& z@f*Nq?vJ2^uV)u&l`WvW+nO&86t$F;%F>-9E2#LH&9i_w%kt+_9>~FwxSONl zPRQ@Knz;uv?hgcacTWa5{?y$X%NupI4ci}ob(YAz@S)-hA}VIEaT+`f1ZslXjA`*5 zekrV+1=SsDQr`1<8WJ^PVkc)}m1RQTqK9~+=icLZuzHiNpTvoi8!Ghuh?9xTcf$9Z z=vE)HAK~`~IeP-*sUY5G5E-b0dd1`7N*}b45t%f}yoAN>8QkHV*rzA)%Y{=wec&~_ zXV7tuc-^HnLQ-*Lz;@e&wuXp+(Xc~3`}JYv(k+;KgxrZ&0Pta-=l z3a5cM`}u#d_LWg_G;N!>I|SF@9^BpCVQ>rX?(QxL9$bRM1PksG+}#}pchAnV@9uu~ z>pf@BnIChiyX&s*>8ZQq62FjR7WEf0tUslp!*va0-5%Oz_ge(OS;$(9SzhQH0_X=m z3d4gKRvRA&IAHTNg(WTswZP4id9m*ID;HZpzh5_X*`@XMI~C9|i)yi^0i)_~cl15{ z#fR({5tpN*BC`!{M&L_a^g@t;*?UBLH`cOK{K#eeEE&urt??5p&BYcDNQ5KS!_TN% z;5fh%xOxc)?;(~lxnPdH=fB0hLJIUpgtwI>2rVLJ7MG}UE|mC98{;vC19Uvf{#tK` z3vO*TV9=ll8N=`sZp^b}b3rt~(7MIRQR@V1-ap-KfC~UgEdMA>M=RFgZJXnQueYU=cqR>=pTYQv(yK>eY<)?jCmTk>vjPcB} zYFfrf2L*i--li1)3kv5`qG8s6S9j8 zglP`NM%tjnS+_X96exz?U9zg&J)XY-$={{SbZX7%2i4YV?T0>`M~y^jF`{&WIz4O7@a&6D zT$*x|_hFj8$(-$c9J`@*M!>;9j=m-={(#?aoPnPJO8fIiIqF)KbpGq1o+f(P%eLlJNrB;jeRB^>PlViUvB9kOS;~ zK{f_d8xVR`TFGFOJvH;($qV%dJR8)S6{PU|-pNcQZdGq3ay&2%XTo>zi`RWZpSi9( zpzR31^=TqetL~hjj0q8?Uc}SBE%|lX=6q>Kg6p=7-KzddpXj#mt<65&^Q#oYfB>rg zqE>tU4Tj|=oS^-grw(uPL#Zat#DiAkAP=hE0C*yeihfFR@K&X*2vnO6pC2A7MQ6NcTz`A+yix8x%U_795D4Cov{vEQ+1dPgeYP zlhVJ;(Pop`3uS19>3INUR%;)Y6`H?CRa5pQ+6IMUV4uTa!b1?ZjXVm$K9(D)b~6O* zWH|@y%02StlKi}k9PjxZ{_3&GBLy1eZl~&a2OXi>yEtlZ)9O`m;IFH2 z$aaRi1<@T7950K@Bfl6c_A+W{mz;A;xspkQkxf@V_Qj0gdQvOcqRt@W$YUtW(KxP^Fzzf_oA+FxdOw^uU#}xAYkIpFtM@g^x!@jNilJ605F z9s`3mW-oZT%Z&S9K<}L7r=hwXnX8&(YxrE?zkuE+e;u3Y%}N@TEvGvD9@qc3U7h2{ z%j?n>BvtZ*Ifki7EqRfmW)?t1$seL2bFQF@jST|Ti);MVc`6D~Li}6skO^#D)k4q+B!YFD5 zlTNFB^-}G{HJ?t0Ps{>xR@8>+pL8AUGb73fTUwq;?ThPGhnw?&dsX`_48d0qeP zw_7q(CVgF5sVuR<_ZY$g_#a^ef>6d>og%h~Wf1HB=$M8||3k!a1Q`EP^|U=kW7PSZ zxKfR`Zz-3yZHX>)q$vU8jM@+BA6^QP&PLLMlnQAum>d}eS#73dvXko!4Hzzl5SErV zxf9V(DiyTnv>j{Pv~4=ndpy*veU{v<{ou_xnb*K{M5zAgK5RYaN{n~a(0kdF=d-vm zYSyr9a)}A}E9=iftDwcEi`KyMW&A<|>DZ#!w;(7zhyl5hvDVpq2Ncj?B*0nuYh-Vf zd#&Yn#IJFqc_3Q-=^e?zq)Cc`0J6b*r6%)*KyKq!BNaiz4ssXzKMt0#{V7L6%}1>` zS^wL?vZWO5!1r=)K#!jv+&R3o_9#9ndUz7vtKXX(Y%!(?`HxIpl0P|i49yelWUP+y zsbHLYY}WLFEiCa8guoV-;}Mv8-JSf3m!RLhE3(7LJZwnI4Q%UXC?Sv6A=v){c*_KZ zfaDHU&>T}r@81yWUSR?p-yoTZf*_R!l!KygM+cRy^4)SGZ6sT{!lQ+xpLHMop^-O#OWPhlc|Xqfd2* zrK9t7E^mg7?r`NI4*NWcv|h8_#_u%qH?ijStIm;Ame>jLY3VKF>Y1I-r$Q`-1Y4t5b3vq)dhJ6_3JA@ytB_pbiR3=Z|4W9 zb<2EXK3)%hF9WPRJ-yifOi~4M3fxY1+;(mKe9QB(8cLdad%Ft!JZi-{I78UXnW){M z{o#i4m(LSFFr9D3wYhIHac^z!c?wbaR|EF*ru^m(mB1}8eO|7$m4gfCkEYwOswbPe zZ#9;7XZFlnp35t3yo6(`&m*8*PHDoTZ;uzdBEkY|+a)-jpPlUYkKR0Soz)qTS9Q^y zoOTl?l;ty6&JRdhuFUn%?TNPX&Pte0UNoMjD&CGbg}0oZR_4ynTKxSYzafn)1of>R5OBC4 ztPM7K5KzaTO{6I`5y0Xv3?<=gL$&|@1@S)2WK*N}tI^a3G#iKLvF6?92|7$fnUL57n-qG5=y4n^7XUJLG zY=1Cq;aK}~81;&8CZ*V5=exd+*EXOmb&NX7Go%j3ES6%a)-U& zNIICw8ex_^Ver$e6W3>&3gls#Jx?)D`0kIx^?|TcVh#87b72Vx9M(U1^lSdYF#aR(hjMJhCbL5x1P_byXwgt2 z1iMW*9rHz=iOkO&vK`&SM>t=87nZH3<%ld)UrOAr5r-$F#gJ~eC+2D3!rCwXQCitj zIC=xMs5tfnJ<7g$Y$54>@}YV;bLVr4q7QPY4F)n7ITv&;WcQzb%b!@fTdMrN@ogZ~jSGM9KiT1(K5uK{T|lG9HmZ)2RTd`2t#?WwcspvplV8JhFS z-zdoACoRTR(d;D0_cHv#vi8oXj5U-BL=MJC{vJVztO`EKXN)?sig1dvU*W-{QEAdQ zn&yO<@Aos5gd?kg(v3A4lmde6TqOX;6^d-Pg#G%m90U2-7|8Px_O999Qy7Uj+l70b*@Ea8!niDf9u{8P{kX~9J6DH?<&n#}Xop}p(UVZD6KXcRsvFTx{rX_j z%g~G!{QQ#0?%n+9uGjQ++RkI|+l_m!rEuZ!eus&ceNHa6DWHp747 ziEKXr)taT{=1xqY;(wkxhW*9S{|(71GDmGtk|vFq;DSSbE%P`8>8@7Oq7gwP5O1ogMZl>lAIC=(Rov*4QYMV{ z=FJ6)j;mg*&c4_@DZ$TU1XL5yaaH{7YfEE`W3LfyHF$WkaQj5vlD~BGzOOM|>aB?@ z?wCvYDrpa)>ocPFUhaEre6W-_)YSbP8)3u@)V*K5Nc41q>*j2%|0bQo7H#@O2{K_x z#U-8X@ZX_0KMAxcYL=+R)QMxe>sp<0jet_OC#EuUpikJzoZF=D4v*8H-Pm(_T=cjK z{qlKN3qaca`uq4R|KMQlPh*2KxVGs*&jupHc`?x084X^0)&^9bSf_$3P=CdN#Z#cY zfAHd~SL-sVXG`4T9KSRN{NriF%<&Zn?b>@_%f}g-#a)fI#trDV-0A6=AGe{>4$Ne~ z`*LB1UJtKk+3&Rvx5eP(q@Yr7;i2V~4k*8$9T_BQ)>P`Cnbd_>P#dFWZM&Hi(x-i%Be;0()%O7kW*zjF>fNh~AKM zoYRy~qE6lO{Vi}MKRZ1&YfP+DMXRme;7$y?kt$t!>`*wepx<7HI|4I)6&{t~ADRBR zOQ)BNOXaJ7boL@<^uIVci)UB!l|TQhevj;V?fxkMg(v9479-}${&W z@j-&y83mj$ogdGelc?*UPw!wOO+WIXwd|Q$KVhveRw#!L;k{JDuxfT|zM)1wUp`&{ z4Bflw;ZeGILIJ+8nw`=kAsYPhTgxzQ>k&cYvG%ksYNJxLW}!;6E4F(CNIcpv&5{8C zqQRx}(W>}lDaeGdbw_%HLTJc^kR5-f6J>0EELF0dOD=D&j2xf$dBQ&)9p=ZTRq|j& zP;}eo#*~-#`It|n;+*$V#r?xKbsMf4u@z&5VrwX4JS@|8qfO7zH5MPxx0a0?&#;aS zI;Zy=ZgQuvn`W6!$JCab1Bbefjn7UkqiYUkAb33Ox+kGeHAw6`WS{l5AHoJMhVo*R z`<;I9@@H3bMh1p;0@Ydha|0Eq9wrO6Oi`rQP85Br4ZqSLH(yl4k2H2%yV#FcBX+0z zjo5A~aC4AQ`DsjQe6?DMdf4Bt<9k)TfHbiDN&h`U;peP7aH7Znm}W9N60#+KS4l&= zpend9D_Plp{ruYu(w9Y(e2+e2vZw*JR)5IC9W9qp!gD8{V9f?InSIyDHS^f@m%iiY zIKJ2EbETCiSG0n5l50h5e2oF^P(o^Z!_bDBV178O#7`J3is3tH6;s6|H}j9?W{l1E zW~VfNL?&$iavljw6@Mx+r8xmS7{zkT0QsUEi+-ysOcqLxg|x$hG5T>7M|~V_pBgJT zQMwsj7NHxtpGrtR^k4@TG^0zHq~sSV2zW2PiVpU#ty`_L-pfaWY-kg&G4kuepESpN zCh{sj?P54+@c#PY%)T!3G=`xc;|zrroxJTy)r5^mlJr$s?DNmhG5smT#geX-yOYSr z;?${@Vm~%{Qk~1@6jz+nC1BKC7hn{@xHhI{tPuca%AE6qd+=NO5M|w5^2&~E8KcJE zJeJv%lUh}(J^0*{qrxTS?H}l52EikS(R+A1u?o|->RMn}`RJX3``0$RFIgY7Kfu7a zrS0*i?5sfgcQKi=sCVp?6Ba(NU8yo!{P8<|=LhbB4Yd4q$e<0x0ilsQzvPq0&vTa= z7B7PV>;ZU**NWYWh}WW7wbQ4QcLBVwbO?`O+Yq~+7(%4~oKp!#Zp)Ol$6LP4@xC&N z=1G)^p!0MVWS!_tr`^o+{7GR-%Jd~eHU1z^NX}(rw_;6T#}1U?SO#y_(t5FyL?9gY z@sy_9lZrxWDRQt)D-L`uW7sn8U*Uncr*Y(Uf_!ng&NYLf#fF1ghRtXqf(NCiB5CaEtMBUc6d}-j(f|aa82J- z4y|b`*C-iIHxo*%updJ$AI9~lTBH@pRLG8^6WOPVYe=~4ESdH78AAVB|-d7{|_#@W?N?rbI-43w;J)ag+9hJ?}zo=t6U?ZYf(iiqvqG2 z(m1+mv;YR@xsV*OYkMT6ugAS*QdA3S^6E-D7(W^1JOnC@&rZ42YmLnBv{?_~v>?lo z#I(X?rwTN+t1FF`Dl3F~W}+1dkVAS7X&y#LBk1 z4^o`ON<83~o6AYmnpZ=5BZn+SQ)DOGPkbNLD^F$?|3y;Mo_Ic^HJlm=7+!YmA%$Pw z!<@%Xwx#XMr-l5Ta06(+;P-3+o0EPmNCe*ZoI<51(bPLm@O!F^gUiYj9fsodzwBvC zIuQMO-48rn?sO$-moX+$c+mna69liLjc}+9Pm0^-Ch&W*oGzo4EGo|fZ&BxgulxL- z-L?GboSFQd^v+(8kL*-S2eP${$p$*7wdUx@mF9Ahpym65Rn$r%F%Rs|0UW2x%xtI2 zVf?3n)ERzH9?=Wfk$`gZ$9^vKfpT+niiNvH;QldxI(sz#1KkxG#3gy8H_D#}-qAja zc_3}Fy~>0BFsa%CFzSon8Gkx)s@y0!X!$lc0JENzqMVg-!6-z;81@QOZthfmy8ICc zT81R?U|NwS5kRR%55A{3UEbmZEsF_4q8JRPqAmcZzU<*;ULzDeuzr2ac%KIjgR$R- zA|*c)BcMyPhG__^%>iZXOd2bX<>n&fO@WdmuUW3WymJHPqhHk*fbY=YHaVv+0cq1D ziOLhHqfP;_AN-bt(w^VG{h+}c%-J=yhbqmAtom0|@=xf&jnS<&r}qVA+7OpxiE%+{ z%6&JJFVobBtxP=ESpaq)mz)2A10O{aErX=`Hk4D=&!r1~UUPTxC@!UE$)8c96jv3# zwMwY>v#LIb&*R+VQcK{3(#xCDsp7$DKyJrE@IV_eL}pm_DNu6`YRdbR{X%fM?z^fM zWl`_ACnilamtld)t`%@yFsX#qAjv%K%^u z%Y?R9fz-PK)kseYwroMuOizNVtO*lo9Cv2Vs6q>?Hr=T3FE-*MLnjT9bH2Uk1_WG* z9ey$kN+vi|WjsT4w|E`ank;ggX|FV3I|>#OfDsOxV?%3l3hNOI z>ruZAYuXDM)h|%yd$G}*$+tYc#iC0|oe?1L`tdc*UIl)Gpx~7xfx`iQB@44xMI-bt zTxW$ub(Wr4t|OpYAjBOqnI*hG5IxEerdlDHCny-;HHZPyziUPVMv6AL$KBh0F+?r{ z^|%XVIzr4jrUACpV(tw|%qEEA0hbWthQTY)z|9)^#mD11{(p_CcZ!FH)|HQ<}Q zN1*`^(Zs7QnTRF;+}VcTEfbf(yN@0*Tsjiftr8ej&vd~F(97PjJhXiZ*xRLF8NR5L zVBJzxvZ*A}FD88j23CUu6Pits!~!PfOnTh`$*{=3OvTWcL=&@bZJJwyZ6_kw247N` z7FFD%xt1~k6AfZIaBX~?lLlzNkd%Odl?v59-QbIxL@VKE{dub)(expzrL)Z(%LLsN zP=JBp8}pGKv=zox9P4d_QXCFB@&1yFAyJ(V!m!&k890Ri?hj;SPtj@tip5*=*!yUvMOKe!uBie5E9?f#v>_bO2<;amILfC0<|+TA>JSE0 z)ZdhY*~t;m=&D`v?XV2zxG~XF1$?e><8dRwOtH{AP2?S<;XFM-?K|B>Vm=%PnNFqt zx96Pw{Ga#*GCbf=oGs3gu@V!J`yLthEvLTXNOswXmp= zHuUl&2oDiebSSPH1uuS#Zg5^j+6{7-T@%8$5kW1tg1jd#dG9D|{HySHj>4fOvT;Lg zmW7?>d!n;4OwL4RucXB<*^?{JlU}f$*gu?m8odq7n4Xa zn;;lu;SkvTzR)R?-lO_$1g0mf*$<@I4?XI0r&rlm0pdN}w-Sj}$FSKCG(D}T((2K_E$>m6qE5H1 z1kMkDPi7OqgLA7lP^pznt zI}P~2ys(QSNK5#EHVutxN_TL*3mA4M7~rbwVH!;kty@uy+K7$Xpp0H9)!!MS?`@;+ zvop;|=sRsJi9a(Q zwyT~4j#HCH?1EUuA}>RIn{_i+o^1`{|2~&XE($P~5VPQmb37E{D45Vd6KWq?2KbiN zL1aB+P-w)dBgvHQLnGeq*6QiRQ*Yf|7W#!GoZxB;=gEnIj)Q(UTk3g{INNlh*tJSv zsE98@X&z{ec0Cn$nE%sj#y%HzenpfS)|No^2%-t9{5DvxLXT5LojIEplY zF)uF4rJmg+r?FbWq!iW2$XQ~DneI7jRLM!@V8_^#2)oSgZO7Nq1hvUe+Q*wBU(HxC zEJ?iy2@?Pvncp-79oIg%kw<(rFs+gH zKE;zi(FM5-{L)2;**HONa8Ku=*yKa~(%>r1tx#B9u(i?oOE|lU*4H5F&Hd(u_U6Sx z=OxN|B*BU&zKSQdiZ`76;BGiu3;q+X7BtquoaP7nep0Q2JLMAXL@Vb34^ZQMWdrW15@2SD5K*?tj9~?`VaT+*)7P5G1Xr>#N zfG;GtUwcFC0m;zF$;Hk7*$#{adO4@BU(9N8?byISj=Xzx(@-YB;s0hZZ8Y|Y%YOT2 z7U1Gv2D7FGs0vcq+nstiUVF%TLYvr{tQ&i_F7yUEJ~6{vU~q3*0^=L$jJCaH;A*8>R_lFzik#skaSw$9$aT781}g3}7BeX6a@DoHS44 zAE+Eq>koeJ3x*3b6N1LIkAk)83vDpzU8&zT0MtX9Z6E?GyU-~QZGn@6Y>r}SXuw4x z98hV&8f@Db`Qn&Z*>gaqR)e0;VbxdE@%iZH zKP}(fx>>t0v`!ZMcq20Caf%*6$WGykiX~Y4LU7^qG$@p=lbdJ`bPM5!X~Np8z}l}+ z*P~GP*|tui&PlY+X=vV#(hh57b6n5;SSzMD5>lxz7&pvU2nAU<7?!Lrw7WO7yFWCj zFEpueNu^*(1srforY?bZh#62KQHP9jde1l=0NoZOQMVO(CPL`zQC}><(QqIRDJgPZ zEHx%WB4m3V*0^u zY)Qnc5p4AcwQfCFj49G$YSE6>u2|=nYaBgDmuY0!*Uqul8msY~sZ7zYlB_av1Z&ho z{x$CUvNHfXjqYUul@Mh|yWJ|7B|q@j%7UFa0(y=74OKQ=gZ`W6_Sq+d>j{AJ_DNP= zfw(X1;AsF(4(0FB0o>c|dg{CS>CzZ=0MGegUrS0h0G0aVzwt$w!@T~qfPoZp|GsLT zlp`2G?D{|O!~X(g{XZ~81`Ib9BvYwodGm~y^`Ns#)y$lpzwGAm4_a@1;xgT$x%E^{HuZ)|V>leJPjRNu4oM+T^DH35Ax z#Z&%X27hS=Z)g~RV2){ST9S;mN9fD7j&6=P1~sR1gtiAs8hMSt2nBuAOwn@J z>n`&tk~MYCt62u@%W{l7Vy89W^<}T~i2d>&G3?g(eD$Cox<3^*MA>trwjX1Z!$<9r zyFly6sp3EpxBbrSVJ4$YYdKA-Lez^f5iD=&+sk8qi^QaonJ9P()S3D|VxYNu`pG|$ zzZhLFpZUT{;%G5uOBfG7DQ`8Gxy4@ZwIayROyDUx|A6#r!yC0StdG@O;7Cxqk;l6w zockj<(R-JA0Mp9h_$R9Grf_XnNY0P@C7qoB6o^fGjF!wWT3j-2*8pU)H{$!JDQmy< z=iD%ruQu-@1sh)RXk`0Br8piV`GA_-y-4`18i~V6@k5%eZQp*M zcv1b03|?s~qOMHdXS80azXN}Q|1Mx6+sK+{(Psd66FiO)_-%eZyGKqpz~oRa3l`!X zD_ujU5Ak34ZA*lo?lLku=ZD&zcJ$tR3FgXV^9S`K$sfrw=Kd|4=t|SUWPt3knVauCyAh=qs`JHKIpX(p6lCg8tGGm-Lkwzo02ahGv*@^JnSd`0Phkugor z`@|X;OuwuT_96KU!^+(0G&@*JwUUe;BQmDZ8z$02My;%l9vd3VG~VSS;B*MQy?MDq zF$vB~;5q{=H%$YlsWZ(#RjpGK6Z`UadPsf_jc^~OyDN?6utM&@N@i7SLo}Y!FRcGs5Il! zHrd)N0?ce(i{SdlZ&IN`Gg5>j3R)AFK{lSgv=>syN}1u;K?azSLCHbMx$nvkHslYc zSDQ}~J~0DP?{1B}ZqI|;Yl6bMp`-)^fFtWA`wT|EWs`YhEw*mN`SOUGwk6LRo9_RH zYtt0mn?42`v#WxQ+5hb)4mP%M`yaxwrMid!g9QSiOUNul4pAtI)B%VPCX_W8S+nqD z7>v(pgW*(!8AFgpsWYZU_M8yFqC08LwCm{QTv@FU(Au6gxcA>MwZM zyXV~(K`ZtA-JAHfC*tQIcpvsE9(h=3q<609h5#?`-Xzb+XEFkNg|6qe=q42ZstA71 z`%lDF?2Q{s$B%?TZ=>;hAM{xFVq=U>W0xH*ba@W}WA_~{^wIlKP|;L|!P77Js;f_U zT@0tj*lBfs+x>Ga{{0C~Z9onpuBUV&yjDzi%H1Kq_1}XD?dwm?MCiY-NbtHqeUCW5 zo9#gxE)O>gNa^l|#J`!ooRX0sJ@IDzapfSm!)zOc6w*^XU_54U>0o=WbO#mqW(3S?W>wv&-2 zy!cz?1sz3s;MqFZKDHn-JBg5U_{b)jEoIm&hZL~{-1bn@8mq76#&M45 zcTvl!Tb~FJ!ad=N#MF2QIrd&d*7k*aM!glkf6OeKC@L4VG$su-IWyrS#_IR;}m12d?x2^7;IvBQ6E| zVzN+C{~+e|7Lg0u)d{a+;}f6FJP zL4BA{l;drDIY0J?#=;&Bg~({*AY3l#Znb*mTKIexlbOku4{Jnn1G{0dylTL%)^Uzq zT`#wM3U4%exVZNt<@X|10vsA0Kx0Q>%Vru&BBJkpVdhi3OT_p$n=uhA^vJg&sp`CP zTq4A4{Q&;OB~5q!^jZsmA))zq@}OKK+=0*xyH3BeJ7>A;y|-n}-9_z^i>zc(N0ZpX z$wrh3E>yM?ID!*v1E!*wAwhFprAAKPDFocuo1#_Kef9}6+Hcnsp%L0baw$YC4zd!O z>31vM>|s15g(PEFb1G(MpK~Iszca-v^=rAE@@F@);=rWpE9q)}t3Fh2uH61!fyB|p zRR3q(+EL!n4wnIMnbQh?0y`F&tX_8Jc{5P?3nwo|G#WSG)-1EcA!u!*r1jS90e4ux z-9|V0995A$)d_>Y!lkQ=RoT`pC1FuC-bvw4pQ6mL#h)n!sElR~48j!nGPOB_6V8%6 z0UUV%Q(jFNV|u-|0UI>8Px@KL`+D(Vvc(@C&WSj+3sh)|y^-ta{|dfF-gqG9t)aqmRHRisEfj!x$J+iiziU;oX*l*uoAbm>&5c687HzW5Bq_W zQGypVknc^K>=q8S)A=!ZRlvO}fOWYsM@WE(KC~(W-?+oO@~}Jg6o(fym}At4Wb(7L z^{vwyyPrgw5}4Y-E8+dh^Cm9#hspMF_wu(+Zv}_VcwCF5$=?u4#k0B73_A;BLE-h| z$IGqmZqJ}F7{hK~kKDiO7cB3>pUtjSV7C|D*;~l+1T^qBvCw38Lw<9YqkAy1j+Gen zNnqC2$$mds9${^R@qJ}ogd3n|&FF_?Ss{r*yF?Ce5_=!%5*VUbWm-xalf*X*WK+pM z-sGIi26|a?uVbU2Uo48RCgUbvlI~2F6!?{Ka?F9vlLFx<@&qk;xM(?W&;4AX2j z!97Nyx=EYKmY5hzVQ)HKdz@DW{>jzW0{EYpZ(VJcRWNtu0wU*TM%HIwcyQy+kxW`= z=y(VYEQ{^gMzxFWIYv3Yp8O?!+*;&!OLpOOA{@{ih|u zm$d`c3i74~d84tg0KPM_Mn5G)kxk-2L)FWpbL6wc$sxxr+gFQtQ)RfksH*lCi{IZX zuVt#9K^25`e7&YD)uPlJD~PgFeiCpZ_Vx(gDjckEH$nVS+51}dqhvKl)vnV<`GOD zs?W1aN^h&;s$gIRjhHtd=0uK$(=eL(DJ`E1?ijP{sbg+Fsep(O7i)2kB&W{8TIEo3 z&F+uWYswMF@oG}z?>@Wb;msi!F!9{Fr_cpmR7T z)eqDDD^MW3{9{?=9qscyeu$t_X;Mm=RVqUOL>Sulyo~7mj>fbPD8B^kNrnCGhWPcP zWiX`OJ3`2~iQce*J|GFY^r*D>uI?JdgK(Pjc2iR#zZDmN_FcF)N$SKW((_QRbV^0- zL}YghwRPP9(rLksmpmRtlpfu38Gyz*I5Y556Q{@#LAd*nN=Jnx@hA zMoXg07SV<4G|iWj0rgmQalG;_y710aMt({~>qH(KlN)8K@>hMuL`OX)wA z7R{z9L-EClww2#G&dz_+JW(5nuSmjAv2RukAck#EGz}4xHoeEkwG5upz!8iq$~(jirbGK%B!976yM9 zK}H+v%0loNK{=bbKn8XC5x-!GCdGIMOCnH8JTPw$plF=_qr3vwq)MrttGqNsuWU?@ z2#{d%h;=3$$u0{tRK%5lA(pPe0wOpNNcf718`vQ^FelmQ$QE`&>kyi7nP;UdB03ft zlzmG-`W%VN-Vx_8_U%YC;z;zsl}Wp{9;Rtv|A>6kMv;JPRtFf7Kgyu|grockG`XRn zBnMJw*gr)7NFSMHD1CGts^Z;Sh+pNJziUb#GX|cxvZ)lkmX5*ukS-jFOg>9}IDNZ) zJifLWZ-g&rb5kp$mW*Ss0G5ga*txzg#IugFi`E`F;JrDdmU3}*?dPQwY(_gSuA2_qfSif5V=|b^|k;Bw=h}s%8 z%GRz^m8?_k>upN@I0UBt@u}ua5PX2`^Gmzx8u@fhIQYOn*O!qw+@%Nvlh_44JDHOV z6?7-^hUKxwN;oG3A4o#qNqYnH#oi%HA0%#`&7lIre9n~gNd-6^NZV(`NEzj*linli z17!f+R-~^Ivx1)3n<5I}V)~@cL4v=32>uS1zvrBOOo1iRpyR)PKI&ePBh5ij{UzAU z)FfDTvt4f4TRgcFk)fdFVIGm4K)4X+VT-1>VDL`}3DWimV=2IbUzDRGdrXz75f0y(z1Q8*|x` zeZKE^6V^Hbpu)32eZ#EXhq!q|(9z5JmQG>suGCWTbVjvSw z61#-d!ObC1uqh|XSGdqn*4l~Ixc$$PRQPg|uLnj#Wh9zM()po__vpkPOLGjymP4dB z%|wnhiCthc0;MFcVt9u7t(vVccs1EH=kU_ypJ3OAg+^lJI#?rOwja4ACx+mFWP_bU z^IrIzoK%ITgZNx>gxX370Vto4Xet6)*Kf2l^-XdEkTvTlNj%H@> z5Vi|B%)~LwSLUh3aM;ISRbcpQd5C+yM7*U)UwF0+IYlqbxs3t$Bxa+>m0b^!Bp&|s z;b*ClZlRbrrCFv^EB(?L>3f}uOok8X=Zpf&Jyt30Ych&?c*J`O@qkQK@K=>W+FXPeIWf@i+8civAE<6nK71=bnrK$b9z#{*xPrKI!Ogqo&c> z(_VZbUS)J)3G}>D_^Fw&qm$k^UPBU@_LtPbFk88ftAhT!f-ur`nSDn=dzP%%68vC= zq+&~*K!>is_}U_gV7+cyJELN4Ry!Z*8nMNjgjGUaMowEhi<*J*nr}_)x&q8Woz*qG z3{79I|CS>A;L!C|%xh8SgM30y3K-X(oATQGZ8z<)zcOEiB6n+t)LuQ>h@Imr4jSrGo=IZXh{BoNpmJ9z5!YEeK62^FdLdfaro zeExCCXT|e&d+8JeaV$2PaL#)%gp7}qLE*xuHZdlL9?4d;`-v^@Ms%<|Q@Ca~zCOlx zyEik|g)Q&CCrZuqsWKKkK|T~;PT(If;4R;{*3^KFoQCiiVsS)3e|7gsJmt&rJ=Qi|?2X=$|O`S|)oMOY*tM(rk7DEqrpb>G|}|JXtLh zW_kGz2xUuZ+T4a+^20vVl2ev4Hw>IfM_ zTIK!*#cJui634h5!&)TQdto(lCPj?Mni@^#ZL^2bIqlLDr#nu+40N2L4@R&w>izgT zhm3^gV7g|)ox^AiD`ew{>fl)AKBOZ-Gd!?=gG2~0_*@{XH#R9XIaGHV17$ZTb34$K zWe{j;G#2|^yMfdS#nJS;Aqc0$oz|}>Iy!zJoDUt@aTOr;ZqJbOV+JY0pP>sdZH0@P z`+cSd&Z&*LNAZdiY5^#=^i=*OoPBty##153!*6D>R!%l;-l}QPy>KAz-jx@4uR7XM zXnWFMsRZKEu&d5nNnhe<1-&3ajrmI)ovjFkq}oQi7<<+Rohv$H1qOCBhiyQ>`=xD+ zPHijCco7Tzuu{2g%TXD&-q{8$5cnb-uv`*bA1*M1g$rWf^58hLwXMY%$uC!@Cpn%r zhe$!yQ#O11%Nx%SiE%UCyqa|89sHMtt^`_WZ-^dDZ}^p144a6zPJ)_ezTrrLUTYZp zlb$g9_>zD`8U-@B<2Vu{U6Z<`KTt+ z$<4pE)LCAq_?CrQwo`q0PCT#f;XlsPi{+N+xSmp~L{cuS0to{t{^X|aw*XLBEDvIi z`hOV&8+I38m>C8b_Dcu`k)9pSOmfdYPm%qIU`mZVC>p?1@8N9eH z2G&s0{x?&EjfMT!|4bmJlK!XUpJi?;fU~K)^?xjQ*J$V~fYs7ICWpReXD-@0oYvf@ z!#nhT3c!*go1d1YE5)SmnxF|ISW#GBk$uTH4ZD}S>Lr^d)AIGyhEW3o$Sfz{1-AIc z-#*-YU`+@Xuw1=qztDVP`65SWf2>NI6aE|_jYHP@i&3BC-~oC|gPqgyTaD<&-{Z>r zLFm37&w1_e!br4*45RG|Z)0C!KWRcWg%^1C#fpG)Vp;xG1V!vvu9`Pbq2rfuS0NOw zj&lX`?>p0vwTk?@$7`L$oWtu~M-NJC0RF6D@e9csqk=xFnz~KSicOPR>>HX=l}sOd zQStj3YT`0|@}wz>!ufb#7lj3Pe)|Ko{8DqD&toIz;aB&q@RZep2tJ?R^Vly)TbyWs zXi35{f%=2(0U^45i`{CigP+ZlJ&qFe;!2xf4-uML0#_h9~^p5d#E>+l}|_ z7!OY6c4zjpCqZq6)-XQ^Fbxi?v?5QpDtY&M{b>tw-KCGM*80WyfDWncmtczgr|yWb zdeWp7#r~AEo&)aHqSx|QqX1Ye7Owcm`F2fB?KbropCd;!I-Ofn|0-iTc09Wlo$FVq zOXR`-CR<_hsUY71{FbyLK|m<}e|uB@k8nl$nufj>&QLcAmNFL9^0YRjU11rgC^?Risy>dw2=|>z+HdgpX5~tc1^_YL(Gn z+H+p#5rK*O&39uE;i6)b^sC8@_o_ed&svvwpP#3#0zhzk_yU3M!*QtYs_Y^S*w6LY z7JZZ>tkE2TgTbLuj=oaz0e#sP zIK$=Hwwj^E`|vgNc4yBWjTLkZvh*{d5MUdJ98YrHcyy;uN-DFsE1|jU1?s4Hu`o+< zCeu}XM0ehtx|B6yE;Ti{j!qMEax|Gow6zR7JB;F;X<%C_A<;y0c(a+}1<4B7!(x0X zg=AO^MNeCax>FM#!)Gn4jj4Usak}FmNTUU4@|X+7T?QMxeM>lRbjl<4=NAe`(8u#Bb5y?4X3>E6l*c;rGuMSzuUivo96m>|kK| zTK@)t9VH=ZdTCB(U_^%*{=?=$=CUZcDceW>CcCRehsLquvPc*lXVPkUkF0CAYv9sC z6=W-B@(O_z-+Nud%o@i5*N*k1Xe@A3DOVX!P$Wb0^n60HkH9@?@ z0*PqT@O)j-c%*%yeC??-b4uN+o@M6tV^287P58QXXf0_-SO1P_0U_su6{279Zk0SL zM{nMf&DQLl)(qADK5iv<#|udtuiZYhT2C`=&me+-bl$=YbEW`Pu~0s{5YhJpsp7R` zkk9rxh_82`8RaYLM^3uggY#q#MU^XN#J)EhI`eB$wLULiw-qGi3 zL>5m5bF+x(fiy4Q_(0dbWyjG8zxsgs3g>B9yy)pIR+M0r4?9f%-W{|t{1xbr z*!D)GBtX0}+TR%fQl!t<3zyBr#UN|L_k(H*}tKOdm=okvqL%z?^$u?~* z*5Rd5k;0zEGhMn!+fJ$Y_EV4Ff9x@uDhwLW11KLY0LsTd+++NEnfsp$-~Ubauu?%) z#~S^jz+{IOvJ|CTgAGA)G$9Gc2>gx$VKMiyTpO9>WPV63n~T>P+b=`E?;I&(pl^vnV4L_*E(Lu-dOb*&zjiH$u z_q0Xa(xblma#eB-=3tghSM7|$V`K5Ov;u|Qgzn$>`b7j2%x*I4AVj0EBU>U5eV4c9 zU{<8O#M1Fdt;m^_6~9fP&CkDD`l~3G=ylA6)tohpt^Kkco{mlSmi3QRF^1;ll{0R` zl5&{CdGpjv*+BRK3cZ8_>ZFo)=y$YMd!9&SouxYuG_fiu+AbDrG&jXaLv%NA@m-Bj z-nD97J1?bGfI*L$>#6DYu66IviqCv42L*MdRPfXpWl4} zm@HVc7MEQveRE6d`1V@+M=o2jyji&l4Q#gGQbQ*0LNbh((P*l16}f`D{RE(=2KqLj zr^d=F4G}d(i2FN~ulDwh_Nbn8YH-@=A%3q8X1Y89S5C8TtBDPUZk|;2A!^Ul;NH$_ zO!?$UZwTRgSETjssW~?Pr+5K^i()0f1)jnc4Ekr|DVSw2?+|ZXKzr~)qa}jKgVEQ#J0Lgpi z>aRlk1lhx8)9ELuk@bWb&8&Rr%yRAdg0Ig0qW&Yx?U8$P`kO~w(L)|D?bOerl3}qD zYSaSW*FmBq*oaq5Kctcjr6zHYK1sb~q?_a%@4S>{UnwNsc;QE?MHm>?Cw@X$eZR&d zRj9AH{qFc%nF_$x)`Z)BmL&)_ndy0^k<&;vapVE-8&ogQza!-dcoz*d08%am&_D$K zA^x#*v=K44voQJ}R<=0_lkx+CXrW*GYJg7AqH;R=&iiEb*6_L*V8o$q0d@Kubf{R1 zu9Di4KD6rO^xi<oAKDo(p0OM_DExDFHWAo9Tx*(6ntouU)-$ylhJK94-0a-+tDJd&v}gY&J;R7 zV)27*3JZ!ajbYi>^!p+Pq~!d!#lyw0(z7XIiB6$)_;V`mn8n6NmbD~$jh}qA$IR$z zb<#>~fHu(Zb4tLMI8wLu{w`3d^7`*G`ki2#i*;Jc&+r%$V%8Vftw(co|YVNnY+3umYQJ=s^M*!*1(`${9Vh608GF#9l$h>oDyLl(3o zf3mSM$tT7_)cXuuC)%uKUNNuB1=)Sz_=4?5#{N|X8;hEG{fYPGhPo&XIuQLAwQncv z?>0$0AHP=_dVwYPlz>Q}AQ_{>S(PjdL0RvGXbm(2s5gfQ(YBQ94n`}!H3Ea#Yxidc z^1$4{=t%i}GBzjq=&a3{Ht-Dp4(^NDa=H$2EhAX5swiJ}c^9O)yf6cIedelepVu<_WO(g_Fuing8F=OKg=}Xsgbu&E3!giYD!W7YN8`|ZU)QNP z4z-Gv=d??^-;<8DC<=4ywy-F*ro}ZCaG8k~%_=)-D@nsEu@DbPwqOnMVTG&-v4R-D>U@2Xq#_MsWzF8?<{9Ivetl+2T zTb*n$3~lfISk7JMTw9gxCT8s0*lcVMA*Rbw@5Q&({1j`?o*~B6ol^EOO;6$LE|Hn* zE~!pp`o@2HGo~AO4BJ66i@tJIj@153ScgAwG?n5>=$2$8+12^x`gOXi&+xVS3N0tp zK#gMuKjP{@WM__Kuk}77Q6eO*JMfQ}mmkpdafq%0YNHzw8{u*1SVaPw3^9 zT$B1fpDc*29Sp~r$exe)-2D?B?_Gmxp+MoS#SJ1mK|<-%Cs5ug)*pfo1hQ{_@M1&q zJ#oLNhU8Oq9kK$!|L&T!DgN6I<$7RhK!ImawGnFwFO)GZYl|srcqY~y(=nWrgX#L9 z0$(RrUwS_DBVyj$nuXrD2VRpCUQ@#}rZT7B==FWWsNM+BRBiHg+zqPA>yRR8M_mH0 zh%kb#V@r6#W^;}RZmtF(?ESe4XLhT@c~aFnIqEe{29jnC9W$)2@aI!(Q1P#&lJ_iZnj7|6~Bi%GUhm3YB$cclfts} z^I>sPILu_83|QP(Z0~$+Pved()HnEcOx0(A4&aNM!+r#z`|%&XxXbGfNO6Fyo)1V9 zO8+pcyI5QQf9n=M$cTpL2AeFrz8WY<=!$HMr$LrqpxD-QFqgHcrGG@4lJxz!k(0<_ z5A>CCNJe=mfEdX>{LhXtZ*IcwOx|ZXLOd4-kNOmQ}_4GLis(;U-K^S3p2CHVvSM1u*m8j-tXhtMCD*$5V)ZXpXSfqqLS?$nT| z5!V~js+|$H2pMK2ta;16lVYfeV3E6mkj$Se9ht`^I6Tguqm?iwo%{U90->1qdpsBr z{Ukv2mH+>Z{{QM3|1Zb-EZ?CO%Vu9c<@q2j#se|2YGEg-bEEybU- z3W1P*{sPk3q+-EpXixDu8EG5_Wc8`W~h*C!DfJey^#1F~B+Mq`=!bfWgi)xC-lAM7O` z#vNPfX+}>f5Yu&wa=uX6b(au5WgROaf!fg6l%ZzNmgU7(?kz%LdT!|)SUpz{ZBJX( zCeY~^g$D^ZXngC*_^%nn!I9S7%K!`0MRhYt_3qeRBuwVJ7Eb519Iu^YY*I!8!;F2s zZYH#z(Km6$2`3V+&*}_t@4Y&ZR*Yxc3qb`E){3%( zQl(PMRQnKOPMt_zAYO3LB+exwum0g-l1l8j^HASF2dwed6%*+z8Pv$@HAq`{MX!Q~ zB7bV|7r=*uuai0su`{B(Dv*dU37axWZ#&THQ)PJm$EFx&fPry6Am$Q)TGl@__7MMn zdgK4Af|azZfGUJE+PkUS`51Ej-=->^uYaUV=%sy1P~eI4c@$Ys zrj)mR>#lD~SNrHeYIo~NgC~LK(RUJ%!1yfaOkz8Mu>Ik(-=^bs2Z!F$* z7NCW^HsNdoOp_VqGjkS6Nl=XS4aUDCMI*&D+%iBCfc@vyfWNuj|2se|PO);rQ3X^3 z!eml`EUYt2$d}nqgxknuoGfherD&M2Aj>k@TWXnMtAb%V;X2X04_EI!h_bCjpUXc5$TSejP!)g=FJWwXYqxf^N(DmlGU~U$MMb+FL(v}d|d#l+zx*P|?=~_NMns+i>$_Z_lRhORvpib~wJBqH-w&?PyHa^QS|RiBTo;x-><`jr!7&PI zoy}Hlm!mD;rc>4k`1itG(7ZWxRUXXmaIa3YA;X@DZ`t?u5wRjEas}}mPx`@Z<}~q3 zU&M3{tP4&<+?b#_8>w_m5dvQBda^Eg-1iU5M*IR!4L%VObd~a-{y_DXydI-E`a>aQu&+f1aC|jvEh~5*x{awzAZ`u%H7i{f&|X%&g9|M3vAVA{7`DQ zQ3OLdzMovhmiRK7?+hx`BJH#w30{wnxW&Hcr05}-Iet@R?3j6PQpu_Z9CJ_x#6_ohL zjEVoycvNRXyMJF^AKhhP8JA^Fg6h{79xx^nd>$7TmIRU-0O~ge30{T|J3wJ-~@O!kk>QNK0edV{#lRGmorD-fuf$*8ZrNWw4zD}O0>asZeX7NFSPs7-m!ga-(qUk|0IKh0KOv4e| z*dXOPk%pV}TOu_D->y`+og#~YX?a4vP6c|hzCmXvcLdkNHIwW%WfoHY)JL9%W^YxP zM|J#HR9ltd4#(hx^s7rr&c(4;qq|c}O3H&(Mown>^2CHq)quEJsS0dm)BJDtjtOy& z4fEQVoBDccTt34>fFx>L{8n4DIilmjMGKO5dygC=2 ztXX63!s6O7ZOKsjg8C&fQESS<*~PtMb91%of~wr+XnN)8CwU&%?&%9SCUd6J1{dqX z?SpVXMg;5zsmC8+bwsV8o#oB2;?#!bXxeKLAC$sFZXe%q7Vb7F9L?)(R{z|pnV-71 zeOkBSajhxxGWJmnePv7+6FvR=z^iNIs~Y(XgzO1ksj+Y|2yT10c=0HExGdDNr0|h% z#ra->ILROVD+$QAuHsHIlk)TJ^>Z~-BU$Gs+uS#hntfX1!l81=~P+oQiIy69`z+QukLJfU7C8q>~zwPNPH? zs+JP2q}5EwM2AihB}s(hnx^qDChne}LRxWUk{<0w!dW?+RFyFs2$k1(LHRKw%GZ=? z1zLxiR2NKXb+d-DJ^z%Wuvd<}CQCVr2Ww{_hc|h~-ta1}9?!_!#%YMyL5Nl*5U=Pb zmyh_CZyBVK)HYo>kMd19cH;e-3xsmH?DHpX)$+?{f{s$f!PTu6=z0i-5h-Lj&X3(R zLJZbEUBFlD!HWx;#%0&EBNa)SPKP5cBeFi8X65of@JhM48$T%?Pe65IL2iAf6Y0^F zGKsmFYab1T^zP>8TCcY?YCz3;3{&B0CK~rhI!2O6&&8g5HO##cl%St2G`)?{k+NH& zs7a=-4VH+`1i6-u6PXEAbgH=#o$DARDit;VDK!>JaDJsUUaQ3@=9*sOrmR08xW@pf z95nAcFZ&ZTGpMi=Rf(iB?-0!$>=Jlx9MC+vzW!N|eD~)-insr6$=-+i^*k)nUHHMJ z8hFe5o|v~`?Jt5#J}c*G8m>^G0+zR=7Uj!tk(#QB-V$%CCZ;)dg`R+OieVSpc8n>O z(Dh3g?(kA0f$-yM_RPJCawZ2<*RQvdg7e_li;=z3V-Vx6gw`cK)-i>_W_pLT65NkV zNJ!r62^n#r0c49FK?QR$JY~0U_?LESWWJR42Gg8s^3Z*6P6!JgD$>&=TRt%AgaNW)^tB#2(_WjF%eb!b-A9 zqo-@Z!-j335YE3pw!6CvN%lnKDH$NT`{`=f_58vFD4%3VKF+u?xL8*PlX=|6ZWG?R zg?7~}ynP>&#H!{q1~3gaxj>Mow-(O0#RMToN9AH{s3q&_5cP=Lx&b%$DQ z>=wP}P!ZH-PdLkxI;yJr`*GHFXsjITJc5mW9ZPbQQ?2`TU2?m zu64KDm@n;O+Q&TsAnR`YZa+o?D!w(cl}jD_%8h>1ItZjwBN;+VGM!U=SO=1dQ7t;c z#Yy9Yv)85&&1>)*sXQNomedaft>NvkmzU6@Tv3FJeqw7b?LZ0Pz_93`9MLe~-L^B= zI{BM^de60f-p8sSwO>!2=ThRo?}5(rX>jgei`Skd*y+e93KgFgJFOT4i_wrpw=c1S6&$$V=hpwZkr4lOVCybm{k zn8wJ=S(FVTkVUP<`8|I!sa;^0c?)~gt ze~FQ6vU-p?1MGKE{3g66-iQSY9072o{R^dQt))#~oVjHA*#B!zr~< zMo|15`OWdNuW^*kT?at*KCh+)N%tA_o~4Q~_zIU;FT{~rE+%$jyl2EBU%T^MV#+j32XG6WOPbxI-xX2BjcFA|cBy9?#ShNVt-K=$&Z7pDsh9g1UW8 zTGbj|)hNI+ylf@hW_a5*{D&;|5jh2&&=<3$R%`-AxgiVEt?vdgDSH`#E#bEuDqe34 zcuGUEsu>CNU=NK1&-hptrQ!L_PU={-i3UexM}p_`1M0~MVpx7JdpCIF>fsz0;ZRUq zea&Topdbw!R9?#+HeA?`$^&{%c-HeL<4VUh{t6 zNbyI;NN{4W!^i8LT)x zW8uA%6Aur4?k)`0-vfyqu0ca^JyYNGASBrNtM~~Sf5OE6fuH}wqkKtce`Nzd>N>Q) z_PcG8>)D2F{=k8jXQ;j$g7cZ^#uu*rOAy2dWcLp$3IDRawS;W!55e8}{(9>WBNZ2? zE2~dCm$8{XTGNvADPb{MvB7$LoY)^_K}PEkTqDecN1RX@qFmO@=#5oic%9+&E7SGa zlCj4)r&yCAUA$wHrBrYa8A%hGz{^b8QyNNu!3*}+#2$a(<4r=RNZC5#8JQqy1J|cO zS)y}kvVCZR_G67-u;FcDCmE$(>}kXT$JS$vX#r`%THx?7QIFCOvas=wI!4<^(+$Vs zuQ_lPxS}+4vOtX12o|NUeM$4-;UX%s#>%mbFohaX4>F}x7t6LFlsD&^HYAlt=0q-W z$84;f1ExB9u)fkh&FRYW@7bUjs@M60XM}R}EOLWEnua*;LY{a@3z)Q#qqUc_cW%zq zLVH?uhEWZm3h|$oG~aDRibnhDuL0vM*b~%b{nXk zL-jsauVbjd4zJh zLh;u83U6|Cx}M|b1znjZZpDsJ(JuJt&Z50_TBs4n<(@{aQmhXMQJ(NvZ(sfFUgj*S z{S^i%p3~t;&i>Xv%}PHJ;y0lY{OE)tNUbw z3Gz}4YV<5eLU$b1tOsYOD>ZyPC!D=>3kc)s;3`edhN;+z`fX^g6V?HyBv_sm!%=S0 zY6AZZ)F2}-wAkyFQKr)`icwk4l1zJ9Ho79&#R$o2G1kQ;an+JxNji?^j8v?>HQf*+ zfyH4aGZZ`)7a?1YqZ&cSYEj2(VaKPllQo+T&J)%NrbQ}67o6`o2&%Zqfh=WXM{<4j zd6#?Xi-e=H{7_u5!Vr|BtWc}3fSYvf5aAewA?8v`2OAY9vco-z?(g4Bus#KX<>{+; z0{j3(v6dCDGw1nyPeZ6o7AEOvEdawr?ve5C0{>=p>79HzgZF=oq?Wzq|X*1|*2RF#bjYL`Y%1`jW0xkx@ z6>3xgJ^Fpo*ZxYrXywP=8sItNldKNfTk8e{JZ`Yw>#wIjKhyl4Qw`}r<0o(|A5^;p z(F=!U%`R~}fw&_d;643J$Lqw*m7A&u2{8)k;ChBE^Mt9$4XrRkIyXZOH3AH@YJbI# zk4M8eQJ+S1qzdH$kLQJ7<3R#EdQ&1ySUr$50Ga(n!o zW(Ua&II9n|oSx9)Dl2}3im_?t7++DumeN~Hfr+Bf;uW-cVhXRU+9W|kItdcG^i77r zI31FSJW1ucylZ1n^+sGo^@%xVIgX^h$3nA zNO}26Q(l_aUj?c?Q)v|-Fs?RN{T?o@e})AE+gm~)0s1{&aM;b#uDZOg$< zizJUc3HEUdMv=g7R1mZgMtxP35K|}+$-qvibml)phQ2s_v)V$n8F4X^`vV;{6oFx> z4S*e&bVPnlH6O9BhG;5M8P3pY6lm3fVepdDx@YGq(qbtV=;6`59e?x(H=sN0mhxsj zFmZoV$o?2>V4DrsK8;^QkX1h}fBTNTe6vUL(!P?6FF4RY_* z9mg+Au}l+Gu)9%Et_aM1b3wC`G*8(vWUCD-fuD0`X3YVSD-~X}$TakkR;g0Bq+E$K zj#Ldy_YGeUG<*`HTQNJ+#2?l|F4mwSj%?o0sLzEr0EU7ckSV-dP;<9{EB8f+bb*X~ z+6o@_jP4Mv_=?C~RI0MXE5uSHgR{q`U4hl_52@QD*05)yZ3Dx&3Iw(EGcl9XKhp3`V&wsucZSon5~JJS zE6caJ<*rwv!e@W}mWH5(ne=y*4jahIzcZ!m0{`qp|J;O6@hV^N#$8UgE9E-TTLAfm zZ{VU*xMH7G@iqIHSn!1-<|l&p=PBXsl8x+o03*29(*b^T3RrS@Gyb=(Bp+D$i_nFE zqz{ntH@GBDP!v536x{C-wP%#qna0xZO5vV(1-XJ2U;LI9z0$SkfTNVfKTwr6oT5{n znV`H726Dq%b^Tj)gIjfl4Y~pse9?>lXbmj*=IkJa++)5~#xAH0;tur@WuDp3jA7D+F*l_d1onm2f6r+S@=Ym z=!w+Y@GInSNp>x4X~LyQeby-~wviGd*B-a6R|+MIDbZdiA3MmGmLXr(AfLyR!Jw;? zl~UaBD{Xa7c9rx~Df%SuF18sDS~`!v2wnn_9Cq4PhAStF=T=eKu(OhW$Hy<;P8YS% zu3+2(S7Q5aT^^&gal7EfE#1i^ZNVX){LCv-Y}1cC7f6zC!r#>lw4()OM^~UFgUhD5 zVNq}50Jz<}PX)9Q$j6`mb-UySf{pbHE!kkO9r^)~7|w%%=ym$&v>I~1XsyO!wJvRyV17(ltu{ZQqGeNX{9Wt1K$TD{s&T78wW=vKTn)f1q1IxPw#qPP zyFtaSSO6+9QAUu>33cUXi}3rdEm>(WM~;^lhMaDvNVRo`xF4->mNxXo#8N2C9^#vj z`TXtQE1i|}y^yYeEwC$q3nAY>+xq;w(y44>`rrKioK!0S8|J^LkFZUOO6HT*f4K#v zv?N<;Q!Z_gHf=S{aJB`2D?9aX2S?a_5c>k{yb4z>B5)hwXVkO!QjUIcbrvZR<_{Xr zUblbbPOcx%_WFLJ_sLa-%!SS)X*tO7+fI(=5Pma?X^V1zM~#_dEH{v@DLpnUK^EFd zntaD00As`zqzyKmvT!d0a3TZ!{VaTcewFksAHf>UmXT8b)+x|GlJi=@$d-p; zl{JA~Ux@CDk!&!xp@7T1Nmu4H!U5;0pHkh?_-(qH9bE(cdJ>scA}GVG&A52%J<_BW zEgQ>IJ$?|Hpv_WMrPG&vfF}&VrGVM2Q}9e8;N@AfY$MvHR5zG`IjcYn|1poFF@a^ z>pJa0GCw>J}Z?PK9LLTfO<+plZ;pDf^*~!pWM#_=Q2n0VhgVLnGgY zMte<%Lz;{xiz;pEslg_ZS+fPBL@H12Ssg*V{4W1U)FQ?)5cMXF5jCQ{nq&myp z9ill_WOpd%-js+GVUg?RUg?eM%mzM{&Y+9nbjO?=u6N;Fl+h*6#4BekLU-V)$AcS! zZo3-O;XcRRL)2Uxas{HkMhwZTVhn=fw|=2C zoNYG85lfAlc(N*u0o7C?6dqcSTz4*nmAa+G58&xm#5@kyM;~fe zG&g-?cV;qBOJ{v8Rmm6kH-E-P-V7BaZv1)gWfwG&n#;7MN2hG{8Wnk*g|7;A&sVyQ z3NIoz2G?+L!~=1^JE8=(H3ai-tX{4-@DF$F!(fY85Yk)33a$pXsPT2jzY=Pk7NNUK@g!|(0PL;cE zT2EQLT?Fq?WgR@u_)QR>9m{8P&6Rj)9&c>tw7Rxg#>JTjFYR!^pM|bh9*WJda}ThY zd95u?x}GtU4Eq9#d<*5aZHgn{BFQ!UZ~wvM35DUwz5$3`D-nT!mT+|ITpL|I7C~OJY%R0fX{3Raq;Moj0Y$KR8jENh%;&Sg5*nycnL8BWJ4#b?JUm zNdW)bVVPg-hQkmxGDOu(xQMDaKfYdG?A!S(mc$<;ofp!g+9tVxxGkp{{`afKl^w6` zEbUf--*A2G*^Pw|kXL1)v+j7T1Uc;d2q}Yc^sof!?~8qSl&^LrXlL#lPQ$oLpQglF6pT0VEAUV$qJ&Q32L z!Wg>bd?p_VR*{uya?<4>hWik@Sf0)+G24u^<_nZ;;@$@Hg6 zDT+g$>;BNaZSHzqSr|)6m{~BLg(bh-#~YlH+@j8_c(?UNa$F_SVC2-4;8Vz^K1>4g zGFQcUBh!3W_D7=>dnOUSjAa+AN}mQ9*K`a0>gh)ITedrRR|RSAy4vNAB=73hv%MoL zx>Bd1xOz?Yrg*iuDV|0Q8$z~lFKB7~W&n%(Qb3A^Nxu;SZ!B=CRRX>J9yBXVl{RAt z0wtEcK9VjZaX5GWK^17T2ALvHttYtt9&Ura#@^i@zzUR07W`nL#avyqT;{M8m@X*c zP-ygQ6tNn>u_D=vVp0sGZ!Y>KR96>-Sa}ecmD_E?J zLf}!hkGfB4jBni$pX}p-BR^%7qfjiidX0XRHs4d@cl5#~?F3UW4BR3C$?`AWg#6M} zNG+jD3|6Tz9;f*A-)otmZ?XvHhaiGBLJ9;~5v{hyvUjV5qqHTj0mE_@EZRz^WJYW!AU)r>hJ0A}$PcpcW>f%Qn zA*14(+&+am@wn+C6ykJ89z3nJ4dHNmGRdVqK1)-FY_x!yu23&KCa-v4_nJA$6>Nvj z9d}sUoX#EB`t>A(qQUdbw8#H?ln%Z!*6Y+4wdE7hr)w&%`}2=#qI(RwFTU3u1VX(B zTpeyk6pZO)S#AQlU(f!>2TS`8_AP`JR+&BNSiw~gFl%tAHB#U(Xo^$jvwTuGO}yko zX9zoo7aL~xFsR*PpKQ1tl9HGC(5Ru8epUzqO{X9s^;{uL>^8EXA8R>ANVBTFJ&I2> zvdN>IRSh?q&dm=?S|d7H60O1~doXUbDBElke~gH;($zlRyzjqJN>|Oilc+)T!3$>^ z3-{#zks0V1N7Y;WwL)y@Q%70PokqK2*Y-}wh6XSYh@s0)l!o8o%`Mn7B+CQEwO_)}Zq=Q@)Nn7_rC(HJGatoDY{Ae4 zEuq>eU&IspI|e1@M;wDWCRrJ3@ftm?IjY)gh>cQx%jr-@D-__|_%+S^-?8C}hMa?+vP%IHJS=#8Wj0QR_PgA@QU{~LS!QH1Mr_QtUuyofo2_q1X5*e&;ztF!j= z^BNH->6JBBK6=;z_)uDw(qM>^oW~wi1;@6+p#v1hlyxiez!mM=F!Crqd?OAs&I#)j z?2yxPriz`S8rWmD&7^0GVMmQKctQJsSzM0>emYuPs-Go4i?(>B7L#=&^>(Ia;>f9( zJPXLRQ>qOc2H2a5M`@2mx_1Xz%0not&8o(Jg=LMec2dS;rXcBMaCk=63v( zs#D=WPED5zGmVw$w(_Mu%fea%RHJ*9S=5%e)u4I1$tvu@?Q2-aZE~ing;yAfNmeBk zSmM_(CDLXx{4OM7tAM6#@$A^$?H%Z+@^QJr%DJZgXLhXN4bkrQp_8wgSp}iiBuw_X zX}eDH=6g?}Q?az-hP|}KhsKV|*Enm3ttrfF0D$M3)^)R?EiF`tEMNdLJiYvFyz3E(2crqd$g?glc>D zFa!sF{8`UEBjh44YAvtby=SR<4ErI^jiUin0l4mRShbbXQoM& z**NHnJFEmYyeVYM_LygtkJBA0wKf?owC^0o+r`kRe7+mQP_Z@iE0M~jjgJ{A;Pk#W z>&Gsd36Wmi=hDm=%B5W~jsUR`89*$A&;G}X=%Ms4v5NcM*+Xm<9bdh&jC3x^F=!S%Np2(FwhA@N4*5-A| zvx!z9MlMFpK3`wfkJ0x>qC4Qi*Pb2;Eacdcv05m;@vmVbTA1X7yg7^=F)u7XVVdaf zU~=&nU%bO!&JK>xKvNtDCgDY*qHYJU!=1CiMS8x^_py z2%z^gkzyS>qAR#QXGBAkrLWGJb1Yz;VrQGdorBwOrWVb?9*DeBWnghteS6 zi?_!fuY|L^Oo0=><{UhBO6l-Q)RD<8;6EX|<|(=+r~~Z`WAN~!llL|sxgD3>-AQw{ zA*rT%s7e*jW|WExi$Z?u;J zj6DrpI$ul6Du8&kPq|*YeLXo!PA<@zkt_hqKsehG zOWmyE3N?8P6B;8fF!Ts3^Okt}WBA2Xh|U-6Qh}#bWAro5aom7Zm%$n+(#{;ZbPyY# zKk{u&*|s%SQl05+t0u|T-I6u|GaII4+4WVY0DF-#ok4pF_*HICp1i2^O_|mLUiW>` z7>vuh<3*pa2$PD;D$vNETDc(;Y_hJ)H6awF3q5wsIZjrkH3~2w1$j6YY=XgsOM*MPlshQGeH zeD=IzKEENy^Jlk0Veg^00^9ka7!_o(|5kH7##?~Rep>g~Jyc=w?oQ;qZ%-r~zlPWR z6wAJ7vTPJaA&>%(E_*P_zp=v~VPj8$utP`trTp-im-~)|x3XS-atGH;$b3-x_`&sVS0fYgbUKh4c;iYH_e{HLx2_aAg7nH4Pr_R**JcTGO$o)T2Iu7sk3V-!Jo<7xXPgjZ0Lm3kq^6-cqb4;IV0HGksC>x% z?ptK6m(Z7u?l@PxB?sC0Jv8DO9ii*}FW5c4n;wNF#PFxTMAH|eaK9+9220b2%@AB6 zljg&PD1u#3sxzOs;1uZ_2}~2I5k8K%8U3O`KXDLV@gct>sv&qW_ID&VdrW7%c-?Wi z_2xtBCEn3^-m&quDIoUrqkGHr+&+6Cxq>k8rPq2gDj<4F-5B+o*Fbj5GXYKa7C5ji zp;`Kds~{@&9vW9{+hFUb5RxFwkm1{v`jCLZ|H83-bC`@XM-uY>x!)2B4j+Y+3MR}|Y28B2tiH(tKEO4Z z7*l1j*3twH(r(E9<^I(FU3^daGvj{i>?|js&Qe}DP_;Iw8-r$@*3zA$fw22b0 ziJf$2c-s~2mRjJiR0 z|7OOOdqw@nZm9{8T^sfn4Cn4`+u4@d*@|?hj48H1QbfCa9%7lO8vNRs&{Msu{Z50{ zQrdpXER8PDCKTGOnWY+TiEtpeW}vxmtElH5|{b@G@$z(u`@XHuOJ7&Xa1wI=x)_*;BZ3h81jR?LV_BRM%5WzVB_)X(!er z@$73(_yA2B0i<*iQ@@Rf9wJ02gQxc7G41j7Ylqn47aRIR?y%~`0n{~`qLxnOx5lJ_^vv@Y$LXRLgLh2_sFSK{TRG;(R z2>D2vhtR0yi4UPSzUMS%`h$bH)erj0w_Se(3_{?Y!~KEW53YA%zx3jm7w~E~aSH#@ zAio_FOWfxe+sFaMr%;y_+#}YuiT7g&M7{dn2G6PG?+0j{&A!;<|}-Hk6vAJ)+^sdBel-Y!W`MLi&_%Op!Y# z84i;E`vOSbIM8AP42+Mk5YPC_5;>yCv<&k?FT6=@ecS^p9^_`h#1^u%_x*kUkv1N1 z$QW}0Y2z9a2uSdsr41PqkN*jM{*^LvlKhs@JidYS+rx@wr!_l+qP|^ z<8+*kI<{@wwmP=iG56?i{+RPyd#!8Fe;w`9cbq+AjC${?yPm297#tzWWF=}9?R{h? zQxLjJGAb2eK^x@ZTq94wbz71GSvQu|0?Dl>wl~NwG`x!(mZf-%%o|}Ye)D=+9!$iH z%=hf^4~FjF8O{&Y-Tv=*0?-ISn1ZC?(&5x7%H;eK37A62FxW1OMWH!{iv3Dont^}9 z6Nj&1C$p{3I;i)29`9V*NNsyvmi~nbTB;n;X$@y$lBfFUE3z=KCe&tyt<;Ptqngpa z8{5kur5TZPjJCe%`Dr&#qPj)-JiuKQs>#44tr1i(m0F7I_&9^q=3>rjqa~M^(Gl3~ z30;SRgMb^hlRBk~88*Y6pzO3O z#U$-i5-W@;ShW;zaQo1rLav!ELuvwB5$8sN9kBATFT-jg*aG%LW`sPx$qPN9Y6g5) zjzw%f$XTtZKK5$g(6iXmQeaC~DiwW~1dAIJnW)RckXlCgEpjzo>YQ|98xLKESHD2R{JaZP)o~RK9GSYWnE}SzXTYLF*nBy zn@yWR9!O-l-s)($YBeYEB#2I5&^kP)M`&&)sFn&mYBiA>^E(Z_Z?=6ISC3vL)Bue@U_glO59K(L1+mv4XzmuZsqPrvc~gb4ISjgeNA8%(1fa-8cgdKb)~2I)7i^qFzc zcHx@#;I83S)=yO|o9!+Te$f&`dd&cDG#&XP*_SOBm#mW$z$FUG%>H*5KjCzLnrdPd z;BQwI^KMWSt&u(4-F9&f382}vL+E_`{^C=$Ss8{YfWi!C`tc57;HbCI?aSjCi(|4- z|G>`~Mc;KU%D@L~+Z8I_PlSJ6E%ueQItT;SiW(SSzVQCr|9vAv=YNVxs8qLB!8OP7 z14nmT#Ul(L4b_1J6~b`iNSB@`7a$B4h|omGnPat#a`^_tuIuJ#&K{?t-T07aTiN-O zU9GY)#iMkI)z+D@xG0%`PcK&7->c*O&Vvj8K707|w=WB9zZntfje}d)bJf*v{;S`e zSJw#$e%HcZw6EI;1f!lEQIK~Xg?KNic1W;#IF` zBH{O$3Um8vb?r$2|8iY|;O>3%6C>991`O=uqe?^lD7P!Q#)P#n z`fMney+GVP_IIObKy!OBO;fdBdf={yxV`%Oq>rU+0kT@i(*7@7z7e1BWutp;)7aQ$A8*I^v{&wU9|TD}4@1nbn`*U;PgWo$+{L z75;v%S{WStn6m_DazKL)PcB6m4>Q&Us%0`Bm~HQnu{0~aJ7=deKIv$q4-hRoi{>BO)nWM9-{-xy!qdn43`i)XqMt#V zA?yeAk>ox{I`+Kmu3PeuXm(A%C+3>Vl=UYI^vp$Utaa{>|Hv*85F?P!UbvX&jl#C| zE=7!wN3GbtQ6iC~W5d4SVEMj4>ArZ_ebHCqry*@N==vzjRlGp|<#xn_dDF7E3r<~k zhs|tS8><63QO1voOE(^&&VFpQi|O+{v!2Y}{7hkPszW6z+}@u%9gA3**pc4Zw0E*E zEn+gf%mY|o<%ZM+O@7A`O%~GgCMtqqCkkU)37z97hYD|4J#|;q5t_=>hAtJiV*nWR zFL;uIU7Dvd41MJrV6V=nwm{uwIuta9T^w2g=Zc4d(EHM^idBv}j!aoN99?DMm*7;1 zVwH~I6xEJEb=8c1EVQkGW)%_8Ec-p$d>^!pk|+2WYK?9SAC(SrjVF3=R24c6In9J2 z8RtAM?97aeb>3FrdQRuHWIFA9aW7*vLu40Uc_7qvCtt9*!r$2JZUst~$}IPW*48GL z+P2OMpB`ymsEdXlmFGCTf{qHirt6F@(*oQqOhtt*dPm5cJwQR)Ej)D^d7M-&9C>*P zkC6ww6^^5kXtV^91)&fnin*x)w7-)AH@AuPxg!@t*Y~cr9qFWF6fPHcR86}kdeOCE z*BXUsSO?sPvcT#i@N&SMb5MFze~8niW`w0=i=<O?R4l`!3v|x^aOwd?2H1amMOS11aNKInCDCs!gLeJNn7AhB{G0!eE1Db3@3l}qk!Pdq_HL*^;z2imV6 zLbt-yp(cI40;*40QCcT#^=ycBasp;V*F{ z#uaMBqBlsjDB{q6^*Js9yQR~jF>2QjJZ}^jauysSxyqlz&j_vV!G@8|FZkjfYChGw zbq+PH;z^%fOvEtR_v6G1nhl-KchJFX3*b-XDU~4(aQT$99<##11muAr zqzpr7o%G!5oG$E~E^af*Fymb5QycWODcfJYkbrRFv9rW1iJoYcui?k`c1Bo}IK3%|@N)@c=aSknZ;XSV6sveI5j7-3&V@1D*#*fOU&)f% zb#v_N1-lJ`Hsi%XPPMc_4un7gq&4L9sp-Z0fNfTQaCY#3{nt#+z{{Q85)Fn&bOVvT z_TG>Z6}B*6M7Ys;Uc@81bIxw|QsTzV#xQ}SYh)Hjs^aLtt|=5NYJQuUug1LF{J0FRG$F zsUEPZ(ur=YYox9Ean9ef3SoIeBz9;>>@|=iQHGaNeuE??75`x0e4(G`OEf8G`PFW) zcr^hh$4owH7%h()fvrgiQhIYbZ$w5l9?prP72N-#&UI^=g7cMBkUxZ(cXEWcAJsW@ z);DI3JF@f5W0QP7KJ2$37L%Y%F-Z4(%uf%VkyYTXM;;;X1$3=FU?FW&7&>vC#>A*N zxRtyj|HgFKERJRHd$c)LU-zX_Q4A z5r=?yzXY1iF-ammE~4G?r}FqpZKo@T2j+kdX{L|x zg^r^iI+?MO|&qjNB%^fyd;mtJHt@ zJR9nsA^2Wh=p85bBlGv?_QeMU%4fIEG9f7y>T=HbcQ1^~Q1X2KaH6#U4qJ#e3`YZ9 ze267U2=@JVbPGdUj4f4f)3b-|t&DdBzNc@HpON=6*p1LfXb5gpqQ^=Ry7<9lH+?~N z!$Edl4jCi9m}aUqyqtuCUxMj#4=qG(2Ztg{+P@LEt220)o!gdK#C0wnnWBPKFk2d+ ztu1PZi=rBc2;mKwCO7@$ix0|vBz(wbT;<9gnk&h`gm z3%*{2=M(M!pwyf1W7VpFkU}>6`)tZu6t$0UHA~}AnnbH`;U{m16&wWw@ zyC-ETeNdJM=OeV)bxZ3*X}Bku7!LCL%1Sv*$y1{qROxXcTr}}Ja>}&X4a~pQh$^!( zW!)XwY+(RAJvvY)Yplu?bfQ#84xOAi*;YDhW94y)Rg~mFq`;=w22NqMbfq;}KDmxr zUFD(8O=cb|wo(A>7lN~BPdjlWi<2fgs2qg1by$f78YSIKZMS9!`B9~eB-HB|Pw1MZ z$JglQy42#PHF%WkU#iZwz1Tmgxw3>rXVf>XdU;6dqLanoD~*bI zc~Pg20SIR;PmOqa?FH0j#1k#UWM$O(hGI0!Lw1DR_FH!;y34ibEND^S7D^e&vs~#> z+WY7Y8Gm&DAcFg=P%I&Pt5a@LzW&uze-M~eAhs4X#Vq*oB38pZxWD+!$%>Z%76)Ju z&)(LGdY>wllW}(W{4$Mxs`~^t>#O z(r@;Hk&j;mon5D|&O@4JwuL-id7i>Hb}rN&_hh5FqnNO9`_cH+722P(zj(wJU!mNC z82L&p#D>2x^}j*U?<(u`n`5_UjzSU^2x}D2lxb#*5Lio?@&(uI^~A=2%mT#c2gjab zJVsrOm9t*RGo{5tRlci-ZRf1bVhH`XYiX}*G(HajgsvenAK@;0cTdEn0Cjwka(s~! zL4?uHwh?OlyJMp-*#3eBwI>?NdnCM%h*`3krE0~d-$VmNSf>aXz;VV0AKC(yL9NZM z^X|L;p1PM-oh~&G(2>Uf{oVWj3RnNBKL2NQ8z?)JbS)KHt`!n6DUl&n$PzMiOE5J&rnVqpmJMPn5?vDT|$s5c7 z8UgrNl=ho+c)6JpTWI#A3WuG6R=@1xw2N?mMW{Ca`hy|uw=ew54&wb8p~0b^0X@Rc zdF0szV~an&W!2GYN+-*#B{zM$+POVk9;eBr3a~yYK6I`(Z5Si#XC9xcO7pbzNjhL8 znqkv#h`0v}h<9jHT4R^Fyp$lzNGLMJIm<|z6lW-7Mp{L@CZ_?Tnn|bEVqT*>GP#IP zrEw(tS+zeo7ph59=IK4Fy+ws=b|W$_>V#97FLf82jlNQxoY<|7von zR~Q*P46xkt=~|eopr`-^IZG0wV^EKvW_rI8^Hfs(9)mDjy+@DkLQ9;thkto?+^-6! ze=K1nN$3btSZvuYglX{(wZiv{*%NMH01l8G?-=m?i4`4(6!*%s~ z)o7I$1MM{Na6Ur>0t_DPT|uW~H~O=qObn!Jv7Fih5Cl0i+&9QZDf#fQHE^8ezKLB@ zvI_n2eQZ9kocZ$CRJM>h#Td&=kJmlpo8cc3F_U-M=e)%IORp&0eBQ^m+Xxn^D>xQL zMxVo&Tjv9QZ)}UKQN&V$L%wRW%7sZtDffCcLKzpzlR)b_@eOe#Z-#G;mk&|DKgS+j=JA+e3xg+msEy?jyGi{YogFqM0EGE@|uu z@A~}tw`gCFYo?2iq?(-~c6QsMJ@GZ^9e|u&02EMy(1;v``sR1s*^a z8HXE+_LT)|BipfvEO-}YzQ5LMhFYH*Uz9GXw!sNAHG(&%YlYBkC0e8zV~(5^UD_~C zkgAlcDzkcN9rd+Nu+6JI99QLD_;2mE?gI&z7^rgf*OaAqEZ8M_TIp<)`sZy=DUbKST)`fsEC!l7Zb%cF*-uTu*WP$S~0%TL*BnTNNBn~ zh{4Yj0!mgmBqIXG3PZ9hmCF%v3X)eve-6<^v@Ta45gy-|FdQQ;B2_(3<7NK{R=4nOw9gqjfiVm< zWGLQc81)^dz>9G{JT8;C+7i|XT=?gpYsAl?4ubeoL3pGo*L4R+G=da4TFD*353$8Q z*2|VSQG~iXdK1eXw5q4b;c(E7#yh4wAfFVjXQ-EeD&=$Yp52x6qwf>>X+taDevy^YY|! z?J>(+ZY%5g`~iXhsALdDucEh8uR^Tc;u2-@oy#VWKX~SF2xyi7b&`l+-9wQIpFw)dxCCCoJtv$DOc26uDxUrMXg>hwl z*0rX!L9O?6Thdkn2P#U0B;Y6dVzgkTIs&fMo^?L3y|uWrMA{P7$R<)uNCFR91p~qm z$~#bW5lGw0YQ8lS$;_0Z${8n135S{swZld9;|Vl6SU*!I9ooe#3Z9mHFbi0(M>YD% z09XfVMFcUoA%-R_IhxauicPD_qnas8|%ga43g)aEkBE zrix0eq$_K-F6Y7|-TeXDZxJHpj1?*URY^KQcj%^#+DK8u zd|zflbI(DhK34K+c9SLZOGF{|>i9z{{j)Rc`LOv+2C2a)OTw1v;eD+HuZ4{ENSR5u z8Y$)khE6xD_{17Taq?E$tbn)t*^!pzMrW*jDR2s(m#DkhU$>f!k+^(@Yif9@4UMEM z2W}R%JnGCGwZrxK97d{%&3su>cc*lQiqPXlS)14aQld~xrJMnNXdo*^#8C;SRYr)#s-y-b62yghn4;970PoK%u2d#?L`;1ADy&T%lDDPBB|B(bIIzi6R2AN`Z|Zx-&=2nf%YlIxFb?%R z=#dnS1)CI2Z8x0OURe{xgDJJ1SE-pi*hiA#6sWX~)D(!bM(+V2d=&Sar1Ez7e0N!= zF%;ks4L_&6dBX;0Z5?2+%Cj!?u#t(efQVe%8H?*9JaK3=e28(+&X!2pzHDSNyBNVv zs!>+L^f>*zG;z8?&D0i*YNf7S?D$#q4SK50y!U5DXiG)9S%tN9D%Mp2)B&;=D}O<3 zzNz5k6ux}~*$-#BRGDCJCCLpb1)u1Gcv>DmaWIJasHjn~XEm2Kx!$4M29Twx6M#kd z4l5x4=IcUoU|R?V7>qZYf6UYSH;|BBw><*o+?J@7Bd08P!nJ$ci-M3KU$??f>_llF z=bXe!^(i-E81b3_`*B&C#9ZJw`=smnut31(xNE8x3gcDaz}vwE%)Z8%ny9I2e8ee+ zcAu>I-d&Q5mSvD81i~7>R^~T^cNxQPk|A9F z5j=SfQLBW`sV;E9$aXz}<=5_x31G})XcVu}mV|WS`PZBd_;$-+Eg2uR&B7nGWoNAJ z(p{iYaCIDlXd^mdE!;v1<}FTYfeKjRmlrdxD>flrV?CPZkK;2$3E54hZw;zjeaJY9 zG5s08WBbl};>&7buGw44hSXZC^nc8_8DQvM_UWyr&y2ch^(P%TYc^z=$Tu%1Qa@y}QT%=!#1p5f zpfQ6!p^k5Y*6C2+a;t9<#&Ogl+s7BdSV~nj3)_o#qP?(1hE8HxD2T_?Sd64|9_MQm z7|dBRn3@^HS*sxKblm4PwFt@>N4-KZ`AS8mE8n%5N9ge!DSDFsNQWu!m~MRm>-8B;s%BQ(q-WL4 zt#&A$Y2^|=SoJDI!#_gTcBbtBhA3Lr1z`cp-l&tWZm({AfeY}J7V9FB-eUPqFwz&x zEAZ8jz)!B6r&~q7X3l0=m&F%-v~8`wj2*>eSt`dg8T6KgG>!p9KNbgM^w0`0KeL`DwhJAh6m+U-)kX?cAyD}*LnIXNxiF@&92abk2{^6#&VB;`qI{jlb zBR}$0!9tu0^nOs7?T#;p@Zuh6N5Xay9NeyRJ?Z)eQ_zML+zCxjJ!AaqM)n6Vq4XGF zBF+U&#Df2KFT($rhgG%z6!v_$(PtnE)lzBX>LCh^gg7W^MIc5j60&BJ#()^T4&eTv zE6B<)ar!~t^~CW8)%92U`C5F~)Kflgx33&FrVNq^vpFEAEydp7`XaOYFaNqFFEk)& zP*6u$>bob|onXWrqMfl|KVIP#ykLJ`s5cNT7$O{Tcq}WewZ?4RYz;Nyi2Au%l@ z(0|*vz;9bCFC?_K)jmpZCIH^8GJtnW^_Oct={-XPu9-!XRxR};Tfm7%*V4)|+$Fw* zX$J+|_);@xIriGtk|}u?$@citn34gheyvHZ>PAAet?~4}6sJB7)?v(SNr|WX>@sf& z;@EpvJdH@D`@>y~Zc`@dWd!$(SLH&P)HoL=(~E7AzQJubBDBS8T`4hRb2)SE6Igw= z9IhhDpd7%Zk=JvJ7HIKcEmQu^)g^%$<}?2tnRVC?!v-%3?qMV~uad)X7(tSs*PY5ZI@!v!2^f9GfRlg{!iw%n{~sP){$TCM)5+2MH} zra~XcYJVTwdJ%hE(;70W&J``B%~Ip_<;Yv!RI+iNZHUUZUfX&B0aiL0416`Won3dt z`n1FC3SUb%iOzJ&;06WstZVHhZX0wuWg<#7|BlA zy~P5UHKqY(4Uq@ol%tOT`3EpF3c0ZKUv>Sq+X(k4u z1D=e^-hRNGEWsbfxjz!*IF?h-Ep^7^6^I{$X1Al;gVh=Kh$XxYV&-Va2o+!ct!ElDUNx)OV-f0PGdpr`L>7KZFI|dA83bd7MEj<>L^YT=hOgW1`RYO zsU>R&Igcq8JZjFFe&I#xMHmKU6TuE$wHZQV@pT^T8K(ZZlmjmg48!DxcEsou&CUfQ z7V)~pdXxm#>w0nh1_83_=`d#4mjOOC+&|1`qKDzk0>cG0C=q78Q+g&6)GanA1=23H z9IIl+I*4H>*qN2#Q5oK$8hClnGr_S4FU#DU*MAr`;>hA_mVQ26#!NY)+#Jpuaf}<1 zTunp|w>w9;LjolJj}BZq{LDP(266L-Na}BxlJ2z=+!Ej7w~&00@u9=AjGxS(5b&0U zGsTb+Ik0*v&5=1u`f+v5okJym3_WDvV!r(?9C=G;1|10yj?4xqxe)y~fx_O{&_>uE z(EeuXq2lTAPacj!#eZaAqpXP-H~vEJP2U|vV9esxD3uUI3`|Mh|6w!IME2hi z*fxBYf}-eVTi!gs&Dw>JXroP-P!;>6XclTE#PSr-K2fdbzcUA)6;4r4 zCgel~&P7Gr)+toT>$4=9EfW1@$-Y{@z0KzlieXd`oy6c&i+Uyy}}ZUfM$mbANo=$GRIB>7^FmDzlwBH;A5{ zB96Rw?a2dYuUIaswDkMiMkYOiYZn1<=0t!q|98Rp&zXzbnA)1!{S!I)*Yj4Jj==cZ z6Ar;Jt0y7|si)<&RS>B=im|G)JAGQZ-Ak|?i%g-7KphxCJ2BOf`M6p0`}XAyb{mur zLwd!b<|Jn?N4jQOwQP*v(EjU41dseaahgQ6)UHB=iZ@6VGT^ui{TYc_>FaAr8$goA z)+~|7j41nl#>>Tt661dtTD<33p`?&Pq3=>vlf?H{Jy!Lqh#m!I;#RMfG11y&+(t=j zd!RUfVPh<}mr`}IdvM64f_2BP zvR*23pq#jRj>I;N7Htn@NnuHs0P7A)Ru`pjR$dr+oiRJP)<@wUG|c*(UVlKQVJ2Ai z`jZ1|=MVwBym7g^T=yi>SmW*cTiaXyKqN!otl{DB?|`yGKPHGyrn;KZSvIQ_7Vi}! zmzoJ9UmV7g5WKxcYpY-S|2lf0aa?;h0!9yZz~~|Q?;(n;p@*mk;3|x>rQ5$;hWW<` zQkkSJk0TC{f;Os23)gU=P@ooz<|+_Q=W`i%VGBrw4bj)n&Cy=hAceUyDYazuSfi z^jbNDN=UMJ7TPX&oTX~bTas$kotAY~HnHAZ!hvV_PMT4|M^#|S>YgkmR&CU5kaot` z{i1U_^IBVie`-^;$60r2vIx`&YT7pV`N5zByuLRzDgi6S>nIonH#dwl$7vPW$7n)- zf>|q1F%6IYSb->Hx#~e7q+-iT-SOLQMWL(8d+jI|rr2T8s`=DM80B<}TY5}X5s|sd zP-ke^gVY%8H?z~ocuPb{@G!Gl?ND4BXnhog2lXBbDkk|fE$6Rx-(kxtN~z*`&GU6_ zRIKE>)%G#D)`c~J-o`0~CjzNZ!{-S~h_cPYraI$eu*gl%W`k6@E&BtbRR}V(IM~RC z0V}2`WBkW zTF0G1SoQ9?i6Q#s)-M~jYZ;j1H_n$~mC`l5#SR0`A<*|K5p$kY^x3`kk;2a=*YSC9 z_b&LjPZzxXLT>|?Dw)Y&DtkVsZBk*>2#eqxOBPrwS96k9IBiZMni zPVBIIP8jt5mUti%hdN@vY-x!IlP*pvI2QbnSq)sUYl}O;H#uN6A^Q!!+|f%C?9*Ah zfE4Qc#O(XV*GCg@cVn`BPek@3ZWud6N4VG4dxi-%K{s#p6|_^v00HuxNbqakEbfM` zr_FXP48N>G{@p0>I>Yu0xBc7;Pt{btZ)SHPtkBU4VdiHcU3Zc?A~cY|bjI2PWU&QC zfNRi3KQS5RV z>o`V+)(2qz?nO`==qYXZA7jH`SK|Ih*g)@U+Fq8Sa2vezfXcoRd7x|jSg4;*kXv1- ziZd%EtBOy2FRaQ}zsVhp39V#$k-D17b@cY|)qKeR{r&9fOWg`2NuUR&u>@oSDmj}B zIbR?wIvHi&WQ;(cE|fIUI*cKC6yv3|M)I{lpKxgH?R=(Dp@Nqlot^!JDVANbUKxay z`U!TMQ5itAx5}i^S1Cz1#vHRQI;>!x7?M`AmRGcN%Z?mmt4eE9D&!FMeUME!LSBOn z2wdETjsIbGE45Z~v&7O^G%wL$vZ(5-ZELx^fdk9=nl@R(#8_v>>RPC++~(HrmT)IF zX4P!5bl+5ockNof$=-5;YWe?;4YL0OY*7CHIX3K)X=EvL?zRercu|XCr8M&9qNwYjUUB!|%-5_lM5~G@DS;(d!b(aNC=b?zbGdI!EBhdRg063(+9|xL9HcySNar=H+4dxTjmr;q#&Ort8SF2dmsYwX^e?gzv})EFaYCqb!mj(_8Dzb= zjU?2ysc{O~&+n7U|AD`gB=F+FeEkxK43O@lg{pG5oA{0~Lr3Xn&wT^+$ZH@#AL4Qd zW-Veat9aROR=~2!OB7#BfG#l{d^4LZ-tp9rR=cLQl)!VHZQ`ar=aRR^XdpwrWbC{8ht2T`6XL=ntawX`jy0{a}n`Xb_aw=_{7!P~jz zFTvWBQRi@VOdL0TU;lM%$W=M@tpPv-1z>FWH(Oc&W5fS`jc2cnt&TdBO|wm0k;^os zGEYAAb>ypV9uvFJ0%(3MhzqxtwH_CYO#mu-s4lSY{GTOWb7LmEG0(iqY2?J6u8{&nS=itVmIG$8-OS-}@cH}9(x8J%sjm(~vJgrHVqDklyo zh$zQYyjB>*UIIg>7cVygiB;hhlQMYgtQ?A_S#|SOo!6>d60#nps>6)kT7+jlnYxq& z#N$MNuF(RIU&-DGRkOlL^OUG5v2Eg9s7y9^pQ+KSy=0aFOEnH{l(2z{t=cMqRpzCO zUevEUlQ4MiLZ=*d^H;E)l5Ma;uj{)l=MIu3ntgP@Ul5OPZYJ%>pm#ac^ek47neEJ! zU?ShuSYnw>1W!GapX&g++5p`g5a-j)QU%jAj?d8a(piJi9~9r)R~K9Tcju3QopV{* z>#aG)%$RPfC^}+!-j2b0-1pds5Fop!@uxg}EUJIo!GXL11;rmrhm%Z!Gm4!#cjQL_ zU?C&gHSd~e2*{j0Abo=98j1h%@CBZ}h07{lpYfXZodP0dWTwqOc-S>c5aZ+9kMEtK z#Ca572RuykDSlVC$n??@>tKtlV3E89h2I$zZ5L*mETF#q9AY$ch@>fET-HT85rjuM zLbu~-(ZWbMN>*|q^fzNe7`BCAo)4Jlf=kWxkG9r5V(I|F)4#(M26@hp>2pQPxEb66BjDT4V!@D{A}0<)=ru zekHK16y7qA+oYII5di^r_dePTe9h|`xR$@h0eg#ii5Qb9trn zWb0V|*w%7UtU(DSDN^EHQFW@K89p~O5LMIL%*||yYr4zX?CtSu_a_u#v=1VYND!v5 z%+D6a?}p5yNCh>Nf=ISrpvZQT8qnKrUswb|9mV_Vg4>ZVnWB=Q58m9Wo;s9P#-W|=I(5ox{S7h*}xS*5C(Vtu0ZMW@81sqCqQ9jK@&2+Ze)#;6HK{##!g@#O{#-D&6O)Cua#K1MNQV;=?(h&6$CNhRW@(rT?m`5;f|9&Z$xOcPp+9aCj zi3@jR=2|3izY@2v^eR1?Hx6aX5|$G|t_fzcd~{v)sjVH=8XTYb9M9FEO#kI;Wd_4* z&H$`Ze*qtpHte2?vk;7^dbI9=dX+O$C8;XPaw;mx8j@)*gI7YY*kldXFrGx})RC-49g05q+xk>|e4FbqhhX*}=5Mo4a*9 z9^v1LIg&XCY9RC}V*NxM22*&`?mGE%M3Cz=^5d*WxNH%)0}bn>S-rz@QlQT112#yG zUs=;~+i4=F6KHYWdI4dNx)6eoPcR#>Fc5-Q7_5cnd8=^yN6! z`4|2U>IHF)Ts@9RizKMNVhnJlhmXwEO;-j|3blaZp>8r*7%1d>z;@)dgoalGnM!UHvG5DVEqp&F|!X+SMlwKk;0vvFs#U5$m5MDNyohe4?Qfi8an-+|))iKlS=@G0u5>;~hjw*_751E5 z$WRSk^%%9fpr)R@bgXR|Qk_>TyE7|^^|QFuF-j*=sKL%4Qks*|v&3QB^eR|#!Tz3H z(N<<(PAA*p9Ry@9UysEOF18d^ROMnVwQRRy_hVB+lO@tj*M996zkc(nZBV*gJb5^q z1NWwazq{F2=2#wLKVM}2c$34QQ zO??7@{{tG1IR6D2*uAAamFVx;6&xyAP(Q+c7;5mdjdhhZw^s5p-35wXb!gYf6kjzv zb)5$xvq*%BdK)!j4wW7TqeoPwwT~?~ns?Bj8b@`UZCzw4>An@NZ1DJa0ADJPR>5t5ylaC3Tz1@a! z#`PDK(C>R}xPxHxQzOTD!V>%>3Vri{Db4VM_+AKrhIwU4Jk!lM05p(}vV{h(kpsS} zRRA=E{|y>E@JIgx8Zgvv9R3p;wBvr!VbrY$Rb&KLm~8IUad?EsRdXbB57Z!R6~*ci zb|6a-$bxU;DiA|?Rw$0Jp{_SU;Po@ElBIPD1BM2-l%7kZJ74U{*^Q)Oa{QL%@T! zRO0b!KCXX315+%uh~gn%GFS>|_*>}p{IP_}A80`2bx_TAfcXm=4$1YN{&p3;G{gMp ze@Z1R?f&;v;y+x(90)cN$wNv~Ay$#R!Mwdi3K3*f2Ew_VlDH6mBD^G*NZD3R>e9)( zZmge>d}z3T37Xr8>$wae96WWWW7fzb4UL|+x=&|$PuYJyu1{wBzrXN&1I2$v5?P6* z370@gB4?LDK`;P{gl6R;2Uc(p@BM)=&M))2Gpq|n1AR%Qfd*;f?wl&#n)yCl4;7G} zYX0KfneS?)I=NsSx;O(9`rsKeU(lmaW~6rR8j$Kxv`K5pot+GamBHaMKlk9FKL6Nl zi8(qF@Qp&30UNkiW{}mXQft%V^6Z(KFF(~wup0k(GNR*(i_fjq2#Oc?XRDI6N~4_K znTF^%)!e-ajoA>Rw3}zSp2Z^U{AOWFj-Ip-q|7@;(KjvTb3g2WLWljpFFyIU5ysNG zHl3raz~9HKRV)1$_3~m*wI>5>b>rLQ z;ZYqG9|9t*F_mwaF3UCgGa^WpsH==rdO^_6RuDBha4REZee!mR=73SIY}o8{R-16F z)0XU-G1kWA;tNG~V;)G;PcE}W){s};x+jTiZl_SE@2$pb8YmjA+NQko6ROhP{5MVq zrMgvB1xgoNaqf$HFxzFza#UUG3w)FP%}`C`b#~_Zmc#DN@+;EC;$O!vxf@!7=V&vQ zbNNhG*SwiCMu{=t(OX_r2Wj!KRfPlbn`ncgRJ!9XW#lBB?lF{q; z+K$$@a6OSaa(Hti$oahJ81Va;xj&qn4bqZrJ&3?xBYkZXyx#DT9RumRs!wsoC-`;N zp&b?pkRP$VfgA@?VfGsQhIxjL&sus{JvgARjDa1@5?V%afeE(z^#C{2L&NgX-@&Si zQ@?Vyh$b)nCh52|hHbrpmSX?FjtI|uLp(}~%%ttuX9jZ)cd~>;GLO1NApRAW8XD^s zp*Rm|@JC~ytNJyA5OgTeerZeq8?R&}2- zeBIjCwZast`^4;b%lBrT^)woMbnu5t7zR;s#JLU8yFm6gNc(uD%+P?gi`S?MZ54Bj zBB(>Jd2D}^N3seAP>Bs>04Tu!p%T+~u76R9T){t7g6}`5#1d9}Z~}lzM9Mcywg?9f zSJaOGMJ1L}SQhecnZ|WuO*e^v0=s)ZU04~*x_Uq8$$TU#Gr7z2v^T=qf<1lJQ|wQn8QhKDo1TpCIByLRMwjCOHGn8g!aMJ(k*+ zHY-z`_?g5;qP#7|s5pfk;+p>>#o2sTd1Fi)SelOQC~__2$&S3s`heDSKrddW_1UWN z$MizkVUSd7(|g>Rh;2P-XwPE309b=;JvACs27-9v=S`sEuc+eErUt5wDr~edNZ1B7 za>WVPe1(Kx9qn+gAS%nJJ@ZCHjmNjaWRgPxqHGs1$!vG3pZ5c zE)59Zv3E;PKxBlFQmUv0zy9Z zJ%H=4atjup+ppZZLVTA*YbPoaX~bbX*?#v;sHMKh;ZOP1D^}UqW0A28uh*$@(Bd0n z4#}0MnfiziZAFa7NJ=|WM|RZL2t5Awp=vh7y|n|}ZcqGvP1QW<-NReNeu9@-Tdt!D zGrl!~$MMS&FWyPJuJI~+1zPS-&gMYOWmOJLqyKZA&u}pKx2Kq6^|PkwWe2zGG9}K>253pC<7Hdymi? z1(4o)M;%nMk%-#&KIzou3)hMrc!o8y3YwMjC{c(!YHw!h@#sM9Ln|4yj0*U*0DW8t zH95zg_*)dwCOn^-;%)lJ(rJu8szcdLdIFBRCa_4i~KH1=lE zIxFQ{2t05GO9Z;u5+|TGKk=h_1NG~58lP)q+t)I&7nLxWLY-}6Q>)v*si@=?HXu@f zW%nXr*$rqk{bKKA&S2SKMl%MO^9&oW-gZG$~Y{2<;+(Zj@y}*ma zK?6Zx2?RzOgB%wUmZ`I$ zcs}ZdI`E9HMF`SI)o1(4ushftn?I)!+}AA8NkLcm)o8Sqy6`hW9v{bNJ^S1W_* z|3lkbM#b4C?V<_p8l1-6U4y&32lwFa5Zs&K5Zv9}-QC@TyGtPK&U`cbn|b$<_3nMn zTK((krq|t7Maf-N*9Gd3Ggewn&SFdtXtL5_5ayUS_qXO^GeFYs=vPPlBGCNPWM zW_Q`Jq5Q0v5~4!pJR=Smj3%{p)Kl)76y)9*$eQ*tqnS{0LUAyQZa$2x5>55%mWW?) z^W1Y^CeKsg>i4}jsTfjPO>sbjz5QRjnb}IS`5t7q79MlGxLJQJIfXRj6-6KQK@_R9 zb7V}I%hbW~5< z9#hBj%GC&Kb1vN*sh4NS*;(?+B$Sl?sLKal6y$oT55|d~0eTW!H0ToCf^^8r8-iRQ zb(61|v310yhH0C5n5Z^@KRkVDL9-Ke&-6PsQj9mifQyq+2>+VOG}D}kro+fs^W$d2n)NeG6C%U(>AR2*7m&ob+i65uN_6omlK0SQ7&OBM+tzmF}9`h*c z<#+R*vz#08BhsS6nj2JBC#!sZ*TO~}WUtTB6+v)7gpIP)>;Xq4%vBo@K`fJGfk=i> z>%$d><6#tCxPp;FJjGtT!d76j{ucX{uPF>eFx#iZU^in-w&zJ_xDvNjiO^fQn`V_?S`&yUDNgu&v)_15{&(=a4 zXDTM9K|bI@gXg_BR-Re3;%%nFSR=2pA6KK*h@dN>&urU(7!)a|J`XVtmmi7!6bc!!+(;|&Jeu)%Siw{Q!3L>m2TE1(d zG1nUXl!xcuuJ-Kk$O3{JicjPT;FF(^ezFp|r76j*Sfw{CH`xPpzoon6h4MW0N(|53 zlU}-W0}^hDG^O?nBW9hGh=5^uIwIQG{HIK!ab z4(y~o82+R@#CZ|>>2?rZXXS}yb3EF{QC|NCJEYd^`}OnvPC){v?>Ow6wL*UOg1;C( z+z*j5q=l-t6{Ej~{IphEw&Dzny(2FKc%vFAR~?h*5Z!Rsye3s?|BI$SElGa3mmT+9K>kcMdgViQ_Fj zt^psb;J6tO(qH0D9-^POvH{QKwIc$-7lwaM%5)r!-{7eakgS#(SKL8BHTzP{|NG;| zi(5ANY6#NW-ZyAxqr@7WJ}&)vx93dEYTYO?K4a2a%G}x`%ykl0{6t7jY3en9EFicH z7T0#w?l*m&Y>%s_a%dH6*cr@Q$MU;vt4!P3Ks(7|Cjl{J788#MSnF83w%))n5K)xD z$i0EoV)4~B`eNj{|FKC|k@mwWpLLASlL;tFsZ%cqWdIm-Bcp`;i?(7b!;lSP%T;4v z2|{~@aQPb78OIvbp3B4O2#E6Z&?wJj4V@5m&-ZOP$vfG1vl^11a#xxk#QyhBiTUFTFO7o_tmzDYP z%!oRes*ru$B4vST>N{6L;~fx3onsWZHti9)^h5YkyO6lK;ttLQv#Z4}Ja9rMM02JD zKBT6$e!yjoCCIA}G5)*kN{Pd5QrqmMm%+G|^uYI4H2yl12H6njk;Y&hwie}p--$1q zG~uOgh#h4oG)yQYOY3M6#kq8ehhr7KRD?|ZiI?%j0#vYlC*AdG0t~E2Wy%2&bFNmq zvM(jI`qpRb*GLMaKnFzbkXyfqe*3!$<wW2(((608pN>F$s(!wIqm1;XZUlw2dc`@x90LRMeaMH*zKe`*= z5QORdQ+@hT1ExV8yVQLmd5{Xo31eI#3dtc|oLPv5#6VWSeSpO0X5mS(pX||Sl8sPQ z+Q<=JVV8cq%5`i%xI&f?l@YDjW$h`vH;Z__iV-_B#V|D!4&|WHG3Sb|a@frGP8MT| zNWM;S_BKTfTlE{pkM7N%}xKP#GF1IKVQa)QtMfhf#$LnTfXf4(Qt&-p6NA zZXvD~MDh5B9ENyJ{27)3jid4_R#1#ar+V+25*Bf_s0HwwuqMEip?A#B0;t91?R15; zXVq`0C7ikyP{DcTrWvts9$b~pXxWS1RaW8^gZ`*wXhS1o{4PhdK;b|e{4lgW?Rn<>cMsMmmUNw zmn5-8v$4d#%prP%p?y988JHl*z%>5ga5EFDyTYwLNrd1{PP$jm4YxmOsnL-12(v%&B#Bzc2PmoVg{vcd`^L(u zw;tP*DeH`jHR5=w$?D@pRcq#JzRe5nWWo~nxsF`Kv{}_-^-ei@f;EHPkA0RzHboU9 z$062M__lWwY4%|F@bVjHG2k&C=vgpFaB>L2_nSjFJhfw)3)eXRjouB^u6J$yns;NPpNcSe|vMbc$@Ytk(!KU2$ z?pOGxx&=2y!?sCUNCJa6(#Q^)HR^}2)`vAgA-aadx0(i4bxZZM0)H7PuIR;|Nd%eJ zJ}7AYO-P+TRo4Gq&|>+gMXBg8f`j~&yiP`=H1&zR7~yn39AiEMGMW-~_;>La4jpve zl?@KwiutJW=C#Bu9Mq42m0@s7|xI@ zZzAOT^vKB~E6dt-b-q^AcOww1Thk1^%Y@l#S1znmj58*jYz7nK)oQDVuhqzr>)NE- z9}Lf(hS1O@!NzX9w2(X6s(tb)wj;k|^-KBdnRbW;mi7 z`IkOQ6*-at{xEOQZQQXRY^G47c-Aw9e1DT?AbzYUh`0=w{Y?|pFV(THwvf3mGvz&9 z<4s*yU5er(rZWfjwV|wE`0mgaY6_IduIrc=Z*Y z!tfkxktr0V>qDpAE5301Q0#U?avh*D)E!Ia`HKFC!b0-q2h8Ycm=U-SzA2B*kpvt} z?neZu@7~+G)g*zzyap;+-)xwdT|Xq9*ZX|9%_Bx|a)Tl5aSk#67B0At?U^EL|7nje zKuT6(PvJj@mFz>E?g~H#Knbedg#QnH%RiMK{|}`Pz0cY5YP%F&Bs}!ctGlc02nA5= z50LNLG*a-?CYu!{zG!BW5qN(flulo92`7R;=5?A}aq@j#G?`2P&2u-><4fFV7A!loTA$K7+YEJPvTpEbI@H%Xw z6%6N%hdjzptNdhB=n_kaTA2cd)s2BpBhxBsou4gm#$)ZjMBHfv{;*dNEslD}um9mv zfWsj`PCMJQ2HaRYq+wuC5HsRXs-6|8nQ|{(2X?T#nh+? zpmBq-@?O2*5b^yQ9)3F-7r3dk|5BhDClb1(fQ6^dKPDy@RDjT}ca3in^Fyn@4IcPO zzbuz9En>w1hpZ$;&|$K_$99)P7*_rf0j-~^E$G=kyE0nY931kC2O7x;=)82?-=|6L<+bhL8= z&8^9STG9W=RSew~jE!9!o&GI(ji0hbXGR(9l4@jzrG5jaSA@%Fll+7dDR?)nDprg( z8)4#QQKD$KS&@i)?wRL;)@$q_yxR?ar5L7F6s8PDAJDhDcm4D@;Xb6_>HC7P&3v(_ zIH=}-3MK=h^J;>?4H_-vXzdcy>{yz-sbutG;aC1mB}YOYeedRxINI^Zx1ha7>Atp- zLo#09ptM62t=dVM7sPjaPM0*&Iqp)!@9OzRY6Ck5;9d>i6S57gPewWMXQtVb&u@rm z(wF2in9c5I)C8l_D48_PRfaEoJ06D|@q>Ez@|)t? z1e8a)-brqK@Lc$3PukF0B!3To-k|NS1yT1Wokc|oaML$V%bV4saR8{2M6pxfT5Z2LZT0!s{e6W&3oMtkF&y=&MLy-iIB2Nb5ATN>FKcGA<-h)+fDsz0VCY zs7y?Ai0Cd{BfvURCBRi8i4OmWT^+|eM&6!3hH&3Rt2s* zkXrd%LTh!RBuH>Qz$T)4`x z(_+>%wjKCxIRH>YCNNi*GGKHpYJG=ZqlK9kIY5E73SC2WD$H4@auja&m^;iY^fEKr z#ERW3$?y*GpT5FejBru~q;zqP@v|%LMr@1qMG5zd% zN(`dtX#Lp8WrgL-@mhx;R!vd;&5%W~AmqaXqZ;ix^dKKiw$QsJwuC55_T))0 zEyUIu$pd+L{T@BZI>r1ssSdp1+yJ%NuX9uh)lm7XJfo_8xhZ5tU}+|)^>pX>H<}cw z62Ia9Q)2R}=qlOM32+4zChe+7nI_o0fBGj&2FL$ zy{XQnWJvjv4Xg)rsPRKzS}9e8PdOsVa!$)sfd^7Vk>M~#W}d#75$-f_YKK`SW$Dy% z&CiW>(l^T`U`4aBwz5g%RJW?+qzXZ`?Z&<2^)BZMTu+w50eq7OVpM!;YnMLfF29K| za|1bK1AfJ%!f5y@Rt+=wQR>|H5hHBk_)#!^f4aKEr=JXYHM+9N%;XEq#KzG)wBWSP zqJ>^IsP8H_@=`+jqaAUptf_Kzak@PW*oL&!F|jxElv?{z<5(6qp^@^f@M+fRI~U zhT+Spu^37bnC;wj)`A^)Vz!-J{5jL9`VdtZr7!bLd!ai+JwzP4afEfgQI?Wc&E>?T z(<#_t$W521%RIhXU8TuJ1=bX1Ct7_!mQ=*gY9RDuV4oDSd`!HZt9=Odr3r zzpQ6*%ms%+TwLN$?VB6(EREx^^w;O4snd;AmHQs7wmXzt31|B#v<0+(x=cZ(E z+?d}TBY5TRwIpPwPTyKSpF1yN9n2;Pa>ddf1v^jTPfW&he*XGH+?Od&C#h#9=&;jL zK02|`nA~bm8OC+WC_m>*X$t#zK-97xL8dSsT{!Kuw%qq`99ExxUc*?QohcV#jU63W z(`gMCO=!tm&>eY9qAni;WI;8aXJN5?^UsjA5qmxONmJHvAxdK2(#h%a0ry8|h9Z?` zrUm=?$PInR%;ZT0^0Fp^#c81 zLM!GL9=+RA?PlWbe$bcMn&$qktWhp?Bnqbi?@??i8D!h*TG=eRWG2^KdIat>tNd%*8menuBB z`_epX_AsJ&6_K3%A^*VKJgNIZk0FC)`(2zIC7=&9O}tArD~gTFXK0IY2^`G zE=lc|3gt(Fhj;4jnCo-8S)8>kWrMRour&=eNdMOVclNOSp)LRCN zpbnof>Yr~&EbrQe-mjegKauPM3s{eZ4(n^Lj?J_8?^)&m&<6S#S}Mw=^4ZK35L@n z-{CCT)=|B(p#kB#Z?oTY=oMy50NPcVc4@G40(_)e;gN_xpaCg^_fuZNPP2&@iswi=4xX?uZnQVICrkx#(V) z$$%Q{rzysZ4*gb4WoZ(~AC<@r`c}tjLW&K7;0Ou=;#HZXA&pg0hEQX>tGUz+7vsmq zc?S7Qh?D}g(w5BBnT1-N^3(dw95PL?K98RaQM(;7?|;bt1+Y$!+C<;D!{pc!4!m`# zdWqoD*O}M2l~WUN9HW5b8+iZ|$|M`M48FzYQ6qn`h~{4W@-0u}yA8tYU)VePj~u=( zf%4LO(B{?Ogn;;0l>PV6`_KF|(MCl_3_IkK9G24VTfscseX#Jib`*JO_y!0|OOzk- zXoDYX-avpc7|QWZEZm_KzSnk7=&v+?rX|Zs33>Kn9NQnsAo{-0L1)t>%0DF%o0Y#zj!6s7Z6e( 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

x3Wgq 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

  • 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 z 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%0De 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 z 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

    RUsm!Gh(tei|@fIHwF(+)iibT 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

    p#eizc*`|A8?<17ni<4gwpYZ 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
  • SIYM`xtO7S=_ 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 z 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 y5j=1+(NG2074qgwaw8Di(IAyKqcPF^ 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

    Validates the XML, printing error messages when the XML is invalid. Note + * that this method will properly validate any instance of a compiled schema + * type because all of these types extend XmlObject.

    + * + *

    Note that in actual practice, you'll probably want to use an assertion + * when validating if you want to ensure that your code doesn't pass along + * invalid XML. This sample prints the generated XML whether or not it's + * valid so that you can see the result in both cases.

    + * + * @param xml The XML to validate. + * @return true if the XML is valid; otherwise, false + */ + public static boolean validateXml(XmlObject xml) + { + boolean isXmlValid = false; + + // A collection instance to hold validation error messages. + ArrayList validationMessages = new ArrayList(); + + // Validate the XML, collecting messages. + isXmlValid = xml.validate( + new XmlOptions().setErrorListener(validationMessages)); + + // If the XML isn't valid, print the messages. + if (!isXmlValid) + { + printErrors(validationMessages); + } + return isXmlValid; + } + + /** + * Receives the collection containing errors found during + * validation and print the errors to the console. + * + * @param validationErrors The validation errors. + */ + public static void printErrors(ArrayList validationErrors) + { + Iterator iter = validationErrors.iterator(); + while (iter.hasNext()) + { + System.out.println(">> " + iter.next() + "\n"); + } + } + + /** + *

    Creates a File from the XML path provided in main arguments, then + * parses the file's contents into a type generated from schema.

    + *

    + *

    Note that this work might have been done in main. Isolating it here + * makes the code separately available from outside this class.

    + * + * @param xmlFilePath A path to XML based on the schema in inventory.xsd. + * @return An instance of a generated schema type that contains the parsed + * XML. + */ + public XmlObject parseXml(String xmlFilePath) + { + File xmlFile = new File(xmlFilePath); + XmlObject xml = null; + try + { + xml = XmlObject.Factory.parse(xmlFile); + } catch (XmlException e) + { + e.printStackTrace(); + } catch (IOException e) + { + e.printStackTrace(); + } + return xml; + } +} diff --git a/xmlbeans/samples/Any/src/org/apache/xmlbeans/samples/anytype/AnyTest.java b/xmlbeans/samples/Any/src/org/apache/xmlbeans/samples/anytype/AnyTest.java new file mode 100644 index 000000000..be7e3e8bd --- /dev/null +++ b/xmlbeans/samples/Any/src/org/apache/xmlbeans/samples/anytype/AnyTest.java @@ -0,0 +1,45 @@ +/* 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.samples.anytype; + +import org.apache.xmlbeans.samples.any.RootDocument; + +/** + * A class with which to test the Any sample. + */ +public class AnyTest +{ + /** + * Tests the Any sample. + */ + public static void main(String[] args) + { + Any sample = new Any(); + boolean newDocIsValid = sample.buildDocFromScratch(); +// assert !newDocIsValid; + + RootDocument rootDoc = (RootDocument)sample.parseXml(args[0]); + + boolean domEditsAreValid = sample.editExistingDocWithDOM(rootDoc); +// assert !domEditsAreValid; + + boolean selectPathEditsAreValid = sample.editExistingDocWithSelectPath(rootDoc); +// assert !selectPathEditsAreValid; + + boolean selectChildrenEditsAreValid = sample.editExistingDocWithSelectChildren(rootDoc); +// assert !selectChildrenEditsAreValid; + } +} diff --git a/xmlbeans/samples/Any/xml/any.xml b/xmlbeans/samples/Any/xml/any.xml new file mode 100644 index 000000000..5aff5d986 --- /dev/null +++ b/xmlbeans/samples/Any/xml/any.xml @@ -0,0 +1,28 @@ + + + + some text + some text + + some text + + + string1 + string2 + + + + diff --git a/xmlbeans/samples/DateTime/README.txt b/xmlbeans/samples/DateTime/README.txt new file mode 100644 index 000000000..6e12baeb0 --- /dev/null +++ b/xmlbeans/samples/DateTime/README.txt @@ -0,0 +1,47 @@ +Sample: DateTime +Author: Rashmi Banthia (rjain29@gmail.com) +Last Updated: Oct. 11, 2004 + +Versions: + xmlbeans-1.0.3 + + +----------------------------------------------------------------------------- + +This sample demonstrates how you can work with XML Schema primitive types date, +dateTime, time, duration, gDay. + +This sample illustrates how you can +(1) Convert org.apache.xmlbeans.XmlDate to java.util.Calendar,org.apache.xmlbeans.GDate, java.util.Date +(2) Convert org.apache.xmlbeans.XmlTime to java.util.Calendar,org.apache.xmlbeans.GDate, java.util.Date +(3) Convert org.apache.xmlbeans.XmlDuration to org.apache.xmlbeans.GDuration +(4) Convert org.apache.xmlbeans.XmlGday to java.util.Calendar,org.apache.xmlbeans.GDate, Day - primitive java int +(5) Get/Set XML Schema primitive types date, dateTime, time, duration, and gDay. + + +XMLBean Types provide mapping between natural Java classes and W3C Schema types. +For eg: + +Schema Type Formal Class Natural Java Class +xs:date XmlDate java.util.Calendar (XmlCalendar) +xs:duration XmlDuration org.apache.xmlbeans.GDuration +xs:dateTime XmlDateTime java.util.Calendar (XmlCalendar) +xs:time XmlTime java.util.Calendar (XmlCalendar) + +The XmlCalendar is a subclass of GregorianCalendar that modifies several key +details in the behavior of GregorianCalendar to make it more useful when +dealing with XML dates. + + +When you run this sample: +(1) It will print element values using different formats ie. Calendar, Date, GDate. Please +note it prints only first occurence of element's value for the purpose of simplicity. +(2) It will create a new element and saves the same in a XML Document. + + +To try out this sample: + +1. Set XMLBEANS_HOME in your environment +2. Ant must be on your PATH +3. To compile the schemas and sample source, run "ant build" +4. To execute the sample, run "ant run" diff --git a/xmlbeans/samples/DateTime/build.xml b/xmlbeans/samples/DateTime/build.xml new file mode 100644 index 000000000..12be9c329 --- /dev/null +++ b/xmlbeans/samples/DateTime/build.xml @@ -0,0 +1,121 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/xmlbeans/samples/DateTime/schemas/datetime.xsd b/xmlbeans/samples/DateTime/schemas/datetime.xsd new file mode 100644 index 000000000..cda18fa36 --- /dev/null +++ b/xmlbeans/samples/DateTime/schemas/datetime.xsd @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/xmlbeans/samples/DateTime/src/org/apache/xmlbeans/samples/datetime/DateTime.java b/xmlbeans/samples/DateTime/src/org/apache/xmlbeans/samples/datetime/DateTime.java new file mode 100644 index 000000000..800e01f13 --- /dev/null +++ b/xmlbeans/samples/DateTime/src/org/apache/xmlbeans/samples/datetime/DateTime.java @@ -0,0 +1,308 @@ +/* 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.samples.datetime; + +import java.io.File; +import java.io.IOException; +import java.util.Calendar; +import java.util.ArrayList; + +import org.apache.xmlbeans.XmlException; +import org.apache.xmlbeans.XmlOptions; +import org.apache.xmlbeans.XmlError; +import org.apache.xmlbeans.XmlObject; + +import org.apache.xmlbeans.GDuration; +import org.apache.xmlbeans.XmlDate; +import org.apache.xmlbeans.XmlCalendar; + +import java.util.Calendar; +import java.text.SimpleDateFormat; +import java.util.Date; + +import org.apache.xmlbeans.samples.datetime.ImportantDate; +import org.apache.xmlbeans.samples.datetime.DatetimeDocument; + +/** + * The sample illustrates how you can work with XML Schema types date, + * dateTime, time, duration, gDay. + * It parses the XML Document, prints first occurence of + * value, creates a new element and saves it in a new XML Document. + * This sample illustrates how you can convert XMLBean types to Java types + * (java.util.Date, java.util.Calendar). + * It uses the schema defined in datetime.xsd. + */ +public class DateTime { + + /** + * Receives an XML Instance and prints the element values, + * Also creates a new XML Instance. + * + * @param args An array containing + * (a)Path to the XML Instance conforming to the XML schema in datetime.xsd. + * (b)Path for creating a new XML Instance. + */ + public static void main(String args[]){ + // Create an instance of this class to work with. + DateTime dt = new DateTime(); + + // Create an instance of a Datetime type based on the received XML's schema + DatetimeDocument doc = dt.parseXml(args[0]); + + // Prints the element values from the XML + dt.printInstance(doc); + + // Creates a new XML and saves the file + dt.createDocument(doc,args[1]); + + } + + /** + * Creates a File from the XML path provided in main arguments, then + * parses the file's contents into a type generated from schema. + */ + public DatetimeDocument parseXml(String file){ + // Get the XML instance into a file using the path provided. + File xmlfile = new File(file); + + // Create an instance of a type generated from schema to hold the XML. + DatetimeDocument doc = null; + + try { + // Parse the instance into the type generated from the schema. + doc = DatetimeDocument.Factory.parse(xmlfile); + } + catch(XmlException e){ + e.printStackTrace(); + } + catch(IOException e){ + e.printStackTrace(); + } + return doc; + } + + /** + * This method prints first occurence of + * value. It also prints converted values from XMLBean types to Java types + * (java.util.Date, java.util.Calendar) and org.apache.xmlbeans.GDate. + */ + public void printInstance(DatetimeDocument doc){ + // Retrieve the element and get an array of + // the elements it contains. + DatetimeDocument.Datetime dtelement = doc.getDatetime(); + ImportantDate[] impdate = dtelement.getImportantDateArray(); + + // Loop through the elements, printing the + // values for each. + for (int i=0;i elements within element + XmlDate[] holiday = impdate[i].xgetHolidayArray(); + System.out.println("Holiday(xs:date): "); + + for (int j=0;j element and attaches to the existing XML Instance, and saves the + * new Instance to a file(args[1]). + */ + public void createDocument(DatetimeDocument doc , String file){ + // Retrieve the element and add a new element. + DatetimeDocument.Datetime dtelement = doc.getDatetime(); + + // + // add an important date using XmlCalendar + // + + ImportantDate impdate = dtelement.addNewImportantDate(); + + //Creating value for element + Calendar holiday = new XmlCalendar("2004-07-04"); + + //Creating value for element + Calendar funbegintime = new XmlCalendar("10:30:33"); + + //Creating value for element + Calendar funendtime = new XmlCalendar("12:40:12"); + + //Creating value for element + Calendar birthdatetime = new XmlCalendar("1977-11-29T10:10:12"); + + //Creating value for element + GDuration jobduration = new GDuration(1,2,4,5,10,12,15,null); + + //Creating value for element + Calendar payday = new XmlCalendar("---12"); + + //Setting all the elements + impdate.addHoliday(holiday); + impdate.setFunBeginTime(funbegintime); + impdate.setFunEndTime(funendtime); + impdate.setJobDuration(jobduration); + impdate.setBirthdatetime(birthdatetime); + impdate.setPayday(payday); + impdate.setDescription("Using XmlCalendar"); + + + // + // add another important date using Calendar + // + + impdate = dtelement.addNewImportantDate(); + + //Creating value for element using XmlCalendar + holiday = new XmlCalendar("2004-07-04"); + + //Creating value for element using GregorianCalendar + funbegintime = Calendar.getInstance(); + funbegintime.clear(); + funbegintime.set(Calendar.AM_PM , Calendar.AM); + funbegintime.set(Calendar.HOUR, 10); + funbegintime.set(Calendar.MINUTE, 30 ); + funbegintime.set(Calendar.SECOND, 35 ); + + //Creating value for element + funendtime = Calendar.getInstance(); + funendtime.clear(); + funendtime.set(Calendar.AM_PM , Calendar.AM); + funendtime.set(Calendar.HOUR, 12); + funendtime.set(Calendar.MINUTE, 40 ); + funendtime.set(Calendar.SECOND, 12 ); + + //Creating value for element + birthdatetime = Calendar.getInstance(); + birthdatetime.clear(); + birthdatetime.set(1977,10,29,10,10,12); + + //Creating value for element + jobduration = new GDuration(1,2,4,5,10,12,15,null); + + //Creating value for element + payday = Calendar.getInstance(); + payday.clear(); + payday.set(Calendar.DAY_OF_MONTH,12); + + //Setting all the elements + impdate.addHoliday(holiday); + impdate.setFunBeginTime(funbegintime); + impdate.setFunEndTime(funendtime); + impdate.setJobDuration(jobduration); + impdate.setBirthdatetime(birthdatetime); + impdate.setPayday(payday); + impdate.setDescription("Using Calendar"); + + XmlOptions xmlOptions = new XmlOptions(); + xmlOptions.setSavePrettyPrint(); + + // Validate the new XML + boolean isXmlValid = validateXml(doc); + if (isXmlValid) { + File f = new File(file); + + try{ + //Writing the XML Instance to a file. + doc.save(f,xmlOptions); + } + catch(IOException e){ + e.printStackTrace(); + } + System.out.println("\nXML Instance Document saved at : " + f.getPath()); + } + } + + /** + *

    Validates the XML, printing error messages when the XML is invalid. Note + * that this method will properly validate any instance of a compiled schema + * type because all of these types extend XmlObject.

    + * + *

    Note that in actual practice, you'll probably want to use an assertion + * when validating if you want to ensure that your code doesn't pass along + * invalid XML. This sample prints the generated XML whether or not it's + * valid so that you can see the result in both cases.

    + * + * @param xml The XML to validate. + * @return true if the XML is valid; otherwise, false + */ + public boolean validateXml(XmlObject xml) + { + boolean isXmlValid = false; + + // A collection instance to hold validation error messages. + ArrayList validationMessages = new ArrayList(); + + // Validate the XML, collecting messages. + isXmlValid = xml.validate(new XmlOptions().setErrorListener(validationMessages)); + + if (!isXmlValid) + { + System.out.println("Invalid XML: "); + for (int i = 0; i < validationMessages.size(); i++) + { + XmlError error = (XmlError) validationMessages.get(i); + System.out.println(error.getMessage()); + System.out.println(error.getObjectLocation()); + } + } + return isXmlValid; + } + +} + + diff --git a/xmlbeans/samples/DateTime/src/org/apache/xmlbeans/samples/datetime/DateTimeTest.java b/xmlbeans/samples/DateTime/src/org/apache/xmlbeans/samples/datetime/DateTimeTest.java new file mode 100644 index 000000000..1572a0347 --- /dev/null +++ b/xmlbeans/samples/DateTime/src/org/apache/xmlbeans/samples/datetime/DateTimeTest.java @@ -0,0 +1,49 @@ +/* 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.samples.datetime; + +import org.apache.xmlbeans.samples.datetime.DatetimeDocument ; + +/** + * A class with which to test the DateTime sample. + */ +public class DateTimeTest +{ + /** + * Tests the DateTime sample. + * + * @param args An array in which the first item is a path to an XML file + * based on the schema in datetime.xsd. + */ + public static void main(String[] args) + { + // Create an instance of this sample to work with. + DateTime sample = new DateTime(); + + // Create an schema type instance from the XML indicated by the path. + DatetimeDocument doc = sample.parseXml(args[0]); + + sample.printInstance(doc); + + // Validate the XML. + boolean exampleIsValid = sample.validateXml(doc); + assert exampleIsValid; + + //Creating a new XML document + sample.createDocument(doc,args[1]); + + } +} diff --git a/xmlbeans/samples/DateTime/xml/datetimesample.xml b/xmlbeans/samples/DateTime/xml/datetimesample.xml new file mode 100644 index 000000000..091b68cb9 --- /dev/null +++ b/xmlbeans/samples/DateTime/xml/datetimesample.xml @@ -0,0 +1,37 @@ + + + + + 2004-11-02 + 18:00:00 + 23:00:00 + P1Y1DT20H25M30S + 2001-04-16T15:23:15 + ---15 + 2nd-Nov-2004, 6:00PM, 11:00PM, 1Yr and a day - 20hours, 16th Apr 2001 3:23 and 15 seconds + + + 2004-07-04 + 10:30:35 + 12:40:12 + P2Y4M5DT10H12M15S + 1977-11-29T10:10:12 + ---30 + Description + + + diff --git a/xmlbeans/samples/DateTime/xml/newdatetimesample.xml b/xmlbeans/samples/DateTime/xml/newdatetimesample.xml new file mode 100644 index 000000000..827cd4add --- /dev/null +++ b/xmlbeans/samples/DateTime/xml/newdatetimesample.xml @@ -0,0 +1,53 @@ + + + + + 2004-11-02 + 18:00:00 + 23:00:00 + P1Y1DT20H25M30S + 2001-04-16T15:23:15 + ---15 + 2nd-Nov-2004, 6:00PM, 11:00PM, 1Yr and a day - 20hours, 16th Apr 2001 3:23 and 15 seconds + + + 2004-07-04 + 10:30:35 + 12:40:12 + P2Y4M5DT10H12M15S + 1977-11-29T10:10:12 + ---30 + Description + + + 2004-07-04 + 10:30:33 + 12:40:12 + P2Y4M5DT10H12M15S + 1977-11-29T10:10:12 + ---12 + Using XmlCalendar + + + 2004-07-04 + 10:30:35 + 12:40:12 + P2Y4M5DT10H12M15S + 1977-11-29T10:10:12 + ---12 + Using Calendar + + + \ No newline at end of file diff --git a/xmlbeans/samples/MixedContent/README.txt b/xmlbeans/samples/MixedContent/README.txt new file mode 100644 index 000000000..40a2de3c8 --- /dev/null +++ b/xmlbeans/samples/MixedContent/README.txt @@ -0,0 +1,34 @@ +Sample: MixedContent +Author: Steven Traut (straut@bea.com) +Last Updated: Sept. 6, 2004 + +Versions: + xmlbeans-1.0.3 + xmlbeans-v2 + +----------------------------------------------------------------------------- + +This sample illustrates how you can work with mixed content XML by combining +strong types generated from schema with an XmlCursor instance. The XmlCursor +interface is provided with XMLBeans for just this kind of use. With strong types +you can only get or set the full value of an element; by using a cursor you can +"dive into" the contents of an element, manipulating child elements that are +embedded in the content and surrounded by other text. + +The sample's XML is a pseudo-inventory of nonsensical items, each with a unique +ID and a description. Where the name of one item is mentioned in the description +of another, the sample code wraps the name with a element whose id +attribute is the ID of the named item. + +When you run this sample, you'll see it print potentially three blocks of +information: +- The XML it got from the inventoryitems.xml file. +- The XML it generated by associating cross-mentioned items. +- The results from validating the resulting XML, if the XML is invalid. + +To try out this sample: + +1. Set XMLBEANS_HOME in your environment +2. Ant must be on your PATH +3. To compile the schemas and sample source, run "ant build" +4. To execute the sample, run "ant run" diff --git a/xmlbeans/samples/MixedContent/build.xml b/xmlbeans/samples/MixedContent/build.xml new file mode 100644 index 000000000..b264ae04c --- /dev/null +++ b/xmlbeans/samples/MixedContent/build.xml @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/xmlbeans/samples/MixedContent/schemas/inventory.xsd b/xmlbeans/samples/MixedContent/schemas/inventory.xsd new file mode 100755 index 000000000..f61d1923b --- /dev/null +++ b/xmlbeans/samples/MixedContent/schemas/inventory.xsd @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/xmlbeans/samples/MixedContent/src/org/apache/xmlbeans/samples/cursor/MixedContent.java b/xmlbeans/samples/MixedContent/src/org/apache/xmlbeans/samples/cursor/MixedContent.java new file mode 100644 index 000000000..5b36ee798 --- /dev/null +++ b/xmlbeans/samples/MixedContent/src/org/apache/xmlbeans/samples/cursor/MixedContent.java @@ -0,0 +1,263 @@ +/* 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 + * + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * Unless required by applicable law or agreed to in writing, software + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.xmlbeans.samples.cursor; + +import org.apache.xmlbeans.*; +import org.apache.xmlbeans.samples.cursor.mixedcontent.DescriptionType; +import org.apache.xmlbeans.samples.cursor.mixedcontent.InventoryDocument; +import org.apache.xmlbeans.samples.cursor.mixedcontent.ItemType; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; + +/** + *

    This sample illustrates how you can use an XML cursor + * to manipulate the content of an element. Even though + * working with strongly-typed XML (in which you are accessing + * the XML through an API generated from schema) provides easy + * access for getting and setting the entire value of an + * element or attribute, it does not easily provide finer + * grained access to an element's content. This sample + * shows how you can use an XML cursor to "dive into" an + * element's content, manipulating it on a character-by- + * character level.

    + *

    + *

    The code in this sample is designed to look at the + * description of each item in an inventory list, creating + * a link wherever the description contains a reference + * to another item in the inventory list. This alters the + * <description> element so that it contains a mix of text and + * link elements. Such an element is said to have "mixed + * content."

    + *

    + * This sample uses the schema defined in inventory.xsd. + */ +public class MixedContent +{ + /** + * Receives an inventory XML instance and rewrites it so that items listed + * in the inventory point to one another via <link> elements. + * + * @param args An array containing one argument: the path to an XML instance + * conforming to the schema in inventory.xsd. + */ + public static void main(String[] args) + { + // Create an instance of this sample to work with. + MixedContent thisSample = new MixedContent(); + + // Create an schema type instance from the XML indicated by the path. + InventoryDocument inventoryDoc = thisSample.parseXml(args[0]); + + // Print what was received. + System.out.println("Received XML: \n\n" + inventoryDoc.toString()); + + // Edit the XML, adding elements to associate related items. + InventoryDocument linkedResultDoc = thisSample.linkItems(inventoryDoc); + + // Print the updated XML. + System.out.println("XML with linked items: \n\n" + linkedResultDoc.toString()); + + // Validate the result. + System.out.println("New XML is valid: " + + thisSample.validateXml(linkedResultDoc)); + } + + /** + *

    Creates "links" between items in an inventory list by inserting + * a <link> element for each linked item. An XmlCursor + * instance passes through each <description> element, looking + * for text matching the name of an item.

    + * + * @param inventoryDoc An XML document conforming to the schema in + * inventory.xsd. + */ + public InventoryDocument linkItems(InventoryDocument inventoryDoc) + { + // Retrieve the <inventory> element and get an array of + // the <item> elements it contains. + InventoryDocument.Inventory inventory = inventoryDoc.getInventory(); + ItemType[] items = inventory.getItemArray(); + + // Loop through the <item> elements, examining the + // description for each to see if another inventory item + // is mentioned. + for (int i = 0; i < items.length; i++) + { + // Get details about the current item, including + // its length. This will be used to measure text + // while exploring the description. + String itemName = items[i].getName(); + String itemId = new Integer(items[i].getId()).toString(); + int itemCharCount = itemName.length(); + + // Loop through the item descriptions, looking at each + // for the name of the current item. + for (int j = 0; j < items.length; j++) + { + DescriptionType description = items[j].getDescription(); + + // Insert an XmlCursor instance and set it at + // the beginning of the <<description> element's text, + // just after the start tag. + XmlCursor cursor = description.newCursor(); + cursor.toLastAttribute(); + cursor.toNextToken(); + + // Get a String containing the characters to the + // immediate right of the cursor, up to the next + // token (in this case, the next element after + // the description element). Get the number of + // characters to the right of the cursor; this will + // be used to mark the distance the cursor should move + // before trying another item's description. Also, + // create a charCount variable to mark the cursor's + // current position. + String cursorChars = cursor.getChars(); + int descCharCount = cursorChars.length(); + int charCount = 0; + + // As long at the cursor hasn't reached the end of the + // description text, check to see if the text to the + // cursor's immediate right matches the item name sought. + // If it does match, remove the text and create a link + // element to replace it. + while (charCount < descCharCount) + { + + // A char array to hold the characters currently being + // checked. + char[] chars = new char[itemCharCount]; + + // Pass the char array with the getChars method. This + // method will find the chars from the cursor's + // immediate right to the char at itemCharCount (the + // length of the item name currently sought). The + // method's second argument indicates where in the char + // array the found text should begin -- in this case, at the + // beginning. + int charsReturned = cursor.getChars(chars, 0, itemCharCount); + + // If the characters in chars match the item name, then + // make a link from the text. + if (new String(chars).equals(itemName)) + { + // Remove the found item name. + cursor.removeChars(itemCharCount); + + // Begin a new link element whose namespace is the + // same as the rest of the inventory document. The + // beginElement method creates a new element with the + // name specified around the current cursor. + cursor.beginElement("link", + "http://xmlbeans.apache.org/samples/cursor/mixedcontent"); + + // Insert an id attribute and make its value the id of + // the item sought. + cursor.insertAttributeWithValue("id", itemId); + + // Insert the item name as the element's value. + cursor.insertChars(itemName); + } + + // Move on to the next character in the description. + cursor.toNextChar(1); + + // Increment the counter tracking the cursor's position. + charCount++; + } + + // Be sure to dispose of a cursor that's no longer needed. + // This allows it to be garbage collected. + cursor.dispose(); + } + } + + // Return the edited document. + return inventoryDoc; + } + + /** + *

    Validates the XML, printing error messages when the XML is invalid. Note + * that this method will properly validate any instance of a compiled schema + * type because all of these types extend XmlObject.

    + * + *

    Note that in actual practice, you'll probably want to use an assertion + * when validating if you want to ensure that your code doesn't pass along + * invalid XML. This sample prints the generated XML whether or not it's + * valid so that you can see the result in both cases.

    + * + * @param xml The XML to validate. + * @return true if the XML is valid; otherwise, false + */ + public boolean validateXml(XmlObject xml) + { + boolean isXmlValid = false; + + // A collection instance to hold validation error messages. + ArrayList validationMessages = new ArrayList(); + + // Validate the XML, collecting messages. + isXmlValid = xml.validate( + new XmlOptions().setErrorListener(validationMessages)); + + // If the XML isn't valid, print the messages. + if (!isXmlValid) + { + System.out.println("Invalid XML: "); + for (int i = 0; i < validationMessages.size(); i++) + { + XmlError error = (XmlError) validationMessages.get(i); + System.out.println(error.getMessage()); + System.out.println(error.getObjectLocation()); + } + } + return isXmlValid; + } + + /** + *

    Creates a File from the XML path provided in main arguments, then + * parses the file's contents into a type generated from schema.

    + * + *

    Note that this work might have been done in main. Isolating it here + * makes the code separately available from outside this class.

    + * + * @param xmlFilePath A path to XML based on the schema in inventory.xsd. + * @return An instance of a generated schema type that contains the parsed + * XML. + */ + public InventoryDocument parseXml(String xmlFilePath) + { + // Get the XML instance into a file using the path provided. + File inventoryFile = new File(xmlFilePath); + + // Create an instance of a type generated from schema to hold the XML. + InventoryDocument inventoryDoc = null; + try + { + // Parse the instance into the type generated from the schema. + inventoryDoc = InventoryDocument.Factory.parse(inventoryFile); + } catch (XmlException e) + { + e.printStackTrace(); + } catch (IOException e) + { + e.printStackTrace(); + } + return inventoryDoc; + } +} diff --git a/xmlbeans/samples/MixedContent/src/org/apache/xmlbeans/samples/cursor/MixedContentTest.java b/xmlbeans/samples/MixedContent/src/org/apache/xmlbeans/samples/cursor/MixedContentTest.java new file mode 100644 index 000000000..0bf6f33ae --- /dev/null +++ b/xmlbeans/samples/MixedContent/src/org/apache/xmlbeans/samples/cursor/MixedContentTest.java @@ -0,0 +1,50 @@ +/* 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.samples.cursor; + +import org.apache.xmlbeans.samples.cursor.mixedcontent.InventoryDocument; + +/** + * A class with which to test the MixedContent sample. + */ +public class MixedContentTest +{ + /** + * Tests the MixedContent sample. + * + * @param args An array in which the first item is a path to an XML file + * based on the schema in inventory.xsd. + */ + public static void main(String[] args) + { + // Create an instance of this sample to work with. + MixedContent sample = new MixedContent(); + + // Create an schema type instance from the XML indicated by the path. + InventoryDocument inventoryDoc = sample.parseXml(args[0]); + + // Validate the XML. + boolean exampleIsValid = sample.validateXml(inventoryDoc); + assert exampleIsValid; + + // Edit the XML, adding elements to associate related items. + InventoryDocument linkedResultDoc = sample.linkItems(inventoryDoc); + + // Validate the XML. + boolean newXmlIsValid = sample.validateXml(linkedResultDoc); + assert newXmlIsValid; + } +} diff --git a/xmlbeans/samples/MixedContent/xml/inventoryitems.xml b/xmlbeans/samples/MixedContent/xml/inventoryitems.xml new file mode 100644 index 000000000..358a521b0 --- /dev/null +++ b/xmlbeans/samples/MixedContent/xml/inventoryitems.xml @@ -0,0 +1,36 @@ + + + + locking flange harbinger + Completely myopic gyrating mill-flange. + 21.79 + 4594 + + + protaic calliphange + Asymmetrical flared-gill spongimass. Complements the locking flange harbinger + with perfect precision. + 19.95 + 2 + + + gyrating mill-flange + Polymorphic atrophical mylobium. Not compatible with any other device ever made. + .99 + 1205987 + + diff --git a/xmlbeans/samples/OrderMatters/README.txt b/xmlbeans/samples/OrderMatters/README.txt new file mode 100644 index 000000000..9a67b51d1 --- /dev/null +++ b/xmlbeans/samples/OrderMatters/README.txt @@ -0,0 +1,29 @@ +Sample: MixedContent +Author: Eric Vasilik (ericvas@bea.com) +Last Updated: Oct. 28, 2004 + +Versions: + xmlbeans-1.0.3 + xmlbeans-v2 + +----------------------------------------------------------------------------- + +This samples gives an quick overview of how to use XmlBeans with both the +strongly typed XmlObjects (StatementDocument, Transaction) and with the +XmlCursor. + +In the sample, a instance of a statement is iterated over twice -- +once using the strongly typed array approach and once with an XmlCursor. When +walking over the array the programmer naivly adds up deposit amounts before +the withdrawal amounts. The end result is a positive balance. When walking +over the array using XmlCursor, the transaction amounts are processed in order +and the end result is a negative balance. + +In this situation, the order of the xml elements matters! + +To try out this sample: + +1. Set XMLBEANS_HOME in your environment +2. Ant must be on your PATH +3. To compile the schemas and sample source, run "ant build" +4. To execute the sample, run "ant run" diff --git a/xmlbeans/samples/OrderMatters/build.xml b/xmlbeans/samples/OrderMatters/build.xml new file mode 100644 index 000000000..989675fe3 --- /dev/null +++ b/xmlbeans/samples/OrderMatters/build.xml @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/xmlbeans/samples/OrderMatters/schemas/stmt.xsd b/xmlbeans/samples/OrderMatters/schemas/stmt.xsd new file mode 100644 index 000000000..e77c7eaab --- /dev/null +++ b/xmlbeans/samples/OrderMatters/schemas/stmt.xsd @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/xmlbeans/samples/OrderMatters/src/org/apache/xmlbeans/samples/cursor/OrderMatters.java b/xmlbeans/samples/OrderMatters/src/org/apache/xmlbeans/samples/cursor/OrderMatters.java new file mode 100644 index 000000000..0bcc5d537 --- /dev/null +++ b/xmlbeans/samples/OrderMatters/src/org/apache/xmlbeans/samples/cursor/OrderMatters.java @@ -0,0 +1,102 @@ +/* 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.samples.cursor; + +import statement.StatementDocument; +import statement.StatementDocument.Statement; +import statement.Transaction; +import java.io.File; + +import org.apache.xmlbeans.XmlCursor; + +import javax.xml.namespace.QName; + +public class OrderMatters +{ + private static QName deposit = new QName( "http://statement", "deposit" ); + + public static void main ( String[] args ) throws Exception + { + // load the xml instance into the store and return a + // strongly typed instance of StatementDocument + StatementDocument stmtDoc = StatementDocument.Factory.parse( new File( args[ 0 ] ) ); + + System.out.println( "Valid statement instance? " + stmtDoc.validate() ); + + float balance = balanceOutOfOrder(stmtDoc); + + System.out.println( "Ending balance: $" + balance ); + + balance = balanceInOrder(stmtDoc); + + System.out.println( "Ending balance: $" + balance ); + } + + /** + * Out of order balance: the ease of stronly-typed XmlObjects! + */ + public static float balanceOutOfOrder(StatementDocument stmtDoc) + { + Statement stmt = stmtDoc.getStatement(); + + float balance = 0; + + Transaction[] deposits = stmt.getDepositArray(); + Transaction[] withdrawals = stmt.getWithdrawalArray(); + + for ( int i = 0 ; i < deposits.length ; i++ ) + balance += deposits[ i ].getAmount(); + + for ( int i = 0 ; i < withdrawals.length ; i++ ) + balance -= withdrawals[ i ].getAmount(); + + return balance; + } + + /** + * In order balance: the power of XmlCursor! + */ + public static float balanceInOrder(StatementDocument stmtDoc) + { + float balance = 0; + + XmlCursor cursor = stmtDoc.newCursor(); + + // use xpath to select elements + cursor.selectPath( "*/*" ); + + // iterate over the selection + while ( cursor.toNextSelection() ) + { + // two views of the same data: + // move back and forth between XmlObject <-> XmlCursor + Transaction trans = (Transaction) cursor.getObject(); + + float amount = trans.getAmount(); + + if (cursor.getName().equals( deposit )) + balance += amount; + else if ((balance -= amount) < 0) + { + // doh! + System.out.println( "Negative balance: $" + balance ); + balance -= 50; + } + } + + return balance; + } + +} diff --git a/xmlbeans/samples/OrderMatters/src/org/apache/xmlbeans/samples/cursor/OrderMattersTest.java b/xmlbeans/samples/OrderMatters/src/org/apache/xmlbeans/samples/cursor/OrderMattersTest.java new file mode 100644 index 000000000..22aaa5eff --- /dev/null +++ b/xmlbeans/samples/OrderMatters/src/org/apache/xmlbeans/samples/cursor/OrderMattersTest.java @@ -0,0 +1,46 @@ +/* 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.samples.cursor; + +import statement.StatementDocument; +import statement.StatementDocument.Statement; +import statement.Transaction; +import java.io.File; + +import org.apache.xmlbeans.XmlCursor; + +import javax.xml.namespace.QName; + +public class OrderMattersTest +{ + private static QName deposit = new QName( "http://statement", "deposit" ); + + public static void main ( String[] args ) throws Exception + { + StatementDocument stmtDoc = StatementDocument.Factory.parse( new File( args[ 0 ] ) ); + + if (!stmtDoc.validate()) + throw new RuntimeException("expected valid instance: " + args[0]); + + float balance = OrderMatters.balanceOutOfOrder(stmtDoc); + if (1010F != balance) + throw new RuntimeException("expected out of order to return $1010.0: " + balance); + + balance = OrderMatters.balanceInOrder(stmtDoc); + if (960F != balance) + throw new RuntimeException("expected in order to return $960.0: " + balance); + } + +} diff --git a/xmlbeans/samples/OrderMatters/xml/stmt.xml b/xmlbeans/samples/OrderMatters/xml/stmt.xml new file mode 100644 index 000000000..1e8d74710 --- /dev/null +++ b/xmlbeans/samples/OrderMatters/xml/stmt.xml @@ -0,0 +1,33 @@ + + + + Vegas winnings! + 3000.00 + + + OSCON Registration + 1890.00 + + + Four Seasons Hotel + 1200.00 + + + Paycheck + 1100.00 + + diff --git a/xmlbeans/samples/SampleTemplate/README.txt b/xmlbeans/samples/SampleTemplate/README.txt new file mode 100644 index 000000000..00a0a3717 --- /dev/null +++ b/xmlbeans/samples/SampleTemplate/README.txt @@ -0,0 +1,44 @@ +Sample: SampleTemplate +Category: template +Author: Steven Traut (straut@bea.com) +Last Updated: Sept. 6, 2004 + +Versions: + xmlbeans-v1 1.0.3 + xmlbeans-v2 + +----------------------------------------------------------------------------- + +This sample template should be used when authoring new samples for XMLBeans. + +Each sample MUST consist of the following: + + - Apache License 2.0 must appear on all files. + + - README.txt: in the same format as this README. Sample name, author, + last upated, and versions of XMLBeans this sample works with are listed + at the top. + + - build.xml: with 'clean', 'build', 'run', and 'test' targets. Follow the + conventions in the build.xml distributed with this template. + + - schemas directory: contains any XMLSchema files used in compilation. + Typically, the target namespace of the schema will be + "http://xmlbeans.apache.org/samples/category/samplename" where + "category" and "samplename" are replaced appropriately. + + - xml directory: contains any xml files used for validation by the sample. + + - src directory: contains any java source files. The package of the + sample should be 'org.apache.xmlbeans.samples.category' and the main + class should be given the sample name. + +At the end of the README's description, the desired output of running the sample +should be given and the steps to build and run should be provided. + +To try out this sample: + +1. Set XMLBEANS_HOME in your environment +2. Ant must be on your PATH +3. To compile the schemas and sample source, run "ant build" +4. To execute the sample, run "ant run" diff --git a/xmlbeans/samples/SampleTemplate/build.xml b/xmlbeans/samples/SampleTemplate/build.xml new file mode 100644 index 000000000..fae0472b1 --- /dev/null +++ b/xmlbeans/samples/SampleTemplate/build.xml @@ -0,0 +1,122 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/xmlbeans/samples/SampleTemplate/schemas/hello.xsd b/xmlbeans/samples/SampleTemplate/schemas/hello.xsd new file mode 100755 index 000000000..eaaf4d47c --- /dev/null +++ b/xmlbeans/samples/SampleTemplate/schemas/hello.xsd @@ -0,0 +1,29 @@ + + + + + + + + + + + + + diff --git a/xmlbeans/samples/SampleTemplate/src/org/apache/xmlbeans/samples/template/SampleTemplate.java b/xmlbeans/samples/SampleTemplate/src/org/apache/xmlbeans/samples/template/SampleTemplate.java new file mode 100644 index 000000000..e1f4b39bd --- /dev/null +++ b/xmlbeans/samples/SampleTemplate/src/org/apache/xmlbeans/samples/template/SampleTemplate.java @@ -0,0 +1,81 @@ +/* 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.samples.template; + +import org.apache.xmlbeans.*; +import org.apache.xmlbeans.samples.template.sampletemplate.HelloDocument; + +import java.io.File; +import java.util.ArrayList; +import java.util.Iterator; + +/** + * This is a template sample. A nice description would go here. + */ +public class SampleTemplate +{ + /** + * Prints out the names in the xml instance conforming to hello.xsd. + */ + public static void main(String[] args) + throws org.apache.xmlbeans.XmlException, java.io.IOException + { + SampleTemplate sample = new SampleTemplate(); + sample.start(args); + } + + public void start(String[] args) + throws org.apache.xmlbeans.XmlException, java.io.IOException + { + for (int i = 0; i < args.length; i++) + { + validate(args[i]); + } + } + + public void validate(String filename) + throws org.apache.xmlbeans.XmlException, java.io.IOException + { + System.out.println("parsing document: " + filename); + HelloDocument doc = HelloDocument.Factory.parse(new File(filename)); + + ArrayList errors = new ArrayList(); + XmlOptions opts = new XmlOptions(); + opts.setErrorListener(errors); + + if (doc.validate(opts)) + { + System.out.println("document is valid."); + + String[] names = doc.getHello().getNameArray(); + for (int i = 0; i < names.length; i++) + { + System.out.println(" hi there, " + names[i] + "!"); + } + } + else + { + System.out.println("document is invalid!"); + + Iterator iter = errors.iterator(); + while (iter.hasNext()) + { + System.out.println(">> " + iter.next()); + } + } + System.out.println(); + } +} diff --git a/xmlbeans/samples/SampleTemplate/src/org/apache/xmlbeans/samples/template/SampleTemplateTest.java b/xmlbeans/samples/SampleTemplate/src/org/apache/xmlbeans/samples/template/SampleTemplateTest.java new file mode 100644 index 000000000..f8047840c --- /dev/null +++ b/xmlbeans/samples/SampleTemplate/src/org/apache/xmlbeans/samples/template/SampleTemplateTest.java @@ -0,0 +1,34 @@ +/* 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.samples.template; + +/** + * A class with which to test the SampleTemplate sample. + */ +public class SampleTemplateTest +{ + /** + * Tests the SampleTemplate sample. + */ + public static void main(String[] args) + throws org.apache.xmlbeans.XmlException, java.io.IOException + { + // all we're checking for is that the sample doesn't throw anything. + // a real sample test might assert something more interesting. + SampleTemplate sample = new SampleTemplate(); + sample.start(args); + } +} diff --git a/xmlbeans/samples/SampleTemplate/xml/bad.xml b/xmlbeans/samples/SampleTemplate/xml/bad.xml new file mode 100644 index 000000000..258771da3 --- /dev/null +++ b/xmlbeans/samples/SampleTemplate/xml/bad.xml @@ -0,0 +1,19 @@ + + + bob + 4 + diff --git a/xmlbeans/samples/SampleTemplate/xml/hello.xml b/xmlbeans/samples/SampleTemplate/xml/hello.xml new file mode 100644 index 000000000..34810bbf5 --- /dev/null +++ b/xmlbeans/samples/SampleTemplate/xml/hello.xml @@ -0,0 +1,21 @@ + + + bob + sally + joanne + kevin + diff --git a/xmlbeans/samples/SchemaEnum/README.txt b/xmlbeans/samples/SchemaEnum/README.txt new file mode 100644 index 000000000..33ac8056c --- /dev/null +++ b/xmlbeans/samples/SchemaEnum/README.txt @@ -0,0 +1,28 @@ +Sample: SchemaEnum +Author: Steven Traut (straut@bea.com) +Last Updated: Aug. 11th, 2004 + +Versions: + xmlbeans-1.0.3 + xmlbeans-v2 + +----------------------------------------------------------------------------- + +This sample illustrates how you can access XML values that are +defined in schema as enumerations. When a schema containing +enumerations is compiled, the generated Java types represent the +schema enumerations with Java enumerations. You can access these through +their constants and corresponding int values. + +When you run this sample, you'll see it print three blocks of information: +- The XML it got from the PurchaseOrder.xml file. +- The XML it generated by taking data from the PurchaseOrder.xml file and + copying it into a new XML document created from another schema. +- A few lines of data extracted from the newly generated XML file. + +To try out this sample: + +1. Set XMLBEANS_HOME in your environment +2. Ant must be on your PATH +3. To compile the schemas and sample source, run "ant build" +4. To execute the sample, run "ant run" diff --git a/xmlbeans/samples/SchemaEnum/build.xml b/xmlbeans/samples/SchemaEnum/build.xml new file mode 100644 index 000000000..9ae3e1f39 --- /dev/null +++ b/xmlbeans/samples/SchemaEnum/build.xml @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/xmlbeans/samples/SchemaEnum/schemas/EasyPO.xsd b/xmlbeans/samples/SchemaEnum/schemas/EasyPO.xsd new file mode 100755 index 000000000..6dab37a85 --- /dev/null +++ b/xmlbeans/samples/SchemaEnum/schemas/EasyPO.xsd @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/xmlbeans/samples/SchemaEnum/schemas/PriceSummary.xsd b/xmlbeans/samples/SchemaEnum/schemas/PriceSummary.xsd new file mode 100755 index 000000000..fd451e8f9 --- /dev/null +++ b/xmlbeans/samples/SchemaEnum/schemas/PriceSummary.xsd @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/xmlbeans/samples/SchemaEnum/src/org/apache/xmlbeans/samples/enumeration/SchemaEnum.java b/xmlbeans/samples/SchemaEnum/src/org/apache/xmlbeans/samples/enumeration/SchemaEnum.java new file mode 100644 index 000000000..f48104b0c --- /dev/null +++ b/xmlbeans/samples/SchemaEnum/src/org/apache/xmlbeans/samples/enumeration/SchemaEnum.java @@ -0,0 +1,279 @@ +/* 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.samples.enumeration; + +import org.apache.xmlbeans.XmlError; +import org.apache.xmlbeans.XmlException; +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.XmlOptions; +import org.apache.xmlbeans.samples.enumeration.schemaenum.easypo.LineItem; +import org.apache.xmlbeans.samples.enumeration.schemaenum.easypo.PurchaseOrderDocument; +import org.apache.xmlbeans.samples.enumeration.schemaenum.pricesummary.ItemType; +import org.apache.xmlbeans.samples.enumeration.schemaenum.pricesummary.PriceSummaryDocument; +import org.apache.xmlbeans.samples.enumeration.schemaenum.pricesummary.PriceType; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; + +/** + * This sample illustrates how you can access XML values that are + * defined in schema as enumerations. When a schema containing + * enumerations is compiled, the generated Java types represent the + * schema enumerations with Java enumerations. You can access these through + * their constants and corresponding int values. + *

    + * The schemas used by this sample are defined in PriceSummary.xsd and + * EasyPO.xsd. + */ +public class SchemaEnum +{ + /** + * Receives an PO XML instance and uses its data to create an XML + * document based another schema, and which summarizes the items + * in the PO by price. + * + * @param args An array containing one argument: the path to an XML instance + * conforming to the schema in EasyPO.xsd. + */ + public static void main(String[] args) + { + // Create an instance of this class to work with. + SchemaEnum thisSample = new SchemaEnum(); + + // Create an instance of a type based on the received XML's schema + // and use it to print what the sample received. + PurchaseOrderDocument poDoc = thisSample.parseXml(args[0]); + System.out.println("Received XML: \n\n" + poDoc.toString()); + + // Print the summarized items in XML based on a different schema. + PriceSummaryDocument summaryDoc = thisSample.summarizeItems(poDoc); + System.out.println("Summarized items: \n\n" + summaryDoc.toString()); + + // Print a simple non-XML list of items by threshold. + String sortedItems = thisSample.sortByThreshold(summaryDoc); + System.out.println("Sorted items: \n" + sortedItems); + + // Validate the result. + System.out.println("New XML is valid: " + + thisSample.validateXml(summaryDoc)); + } + + /** + *

    This method uses values in the incoming XML to construct + * a new XML document of a different schema. PriceSummary.xsd, the schema + * for the new document, defines XML enumerations for a price + * threshold attribute. Items whose price is between $10 and $20 receive + * a threshold value of "Between10And20Dollars"; items above 20 get a threshold + * value of "Above20Dollars".

    + *

    + *

    This method loops through the purchase order items, creating a summary + * document that specifies their threshold value.

    + *

    + *

    You can verify this method's work by comparing the resulting XML with + * the XML in PriceSummary.xml. You can also use this method's return value + * to test the sortByThreshold method.

    + */ + public PriceSummaryDocument summarizeItems(PurchaseOrderDocument poDoc) + { + PurchaseOrderDocument.PurchaseOrder po = poDoc.getPurchaseOrder(); + + // Create a new instance of the PriceSummary schema. This is the document + // the code creates, extracting values from the purchase order. + PriceSummaryDocument summaryDoc = PriceSummaryDocument.Factory.newInstance(); + PriceSummaryDocument.PriceSummary summary = summaryDoc.addNewPriceSummary(); + + // Create elements to hold elements according to their + // price threshold. + PriceType priceZero = summary.addNewPrice(); + PriceType priceTen = summary.addNewPrice(); + PriceType priceTwenty = summary.addNewPrice(); + + // Set the threshold attribute value for the two new elements. + priceZero.setThreshold(PriceType.Threshold.BELOW_10_DOLLARS); + priceTen.setThreshold(PriceType.Threshold.BETWEEN_10_AND_20_DOLLARS); + priceTwenty.setThreshold(PriceType.Threshold.ABOVE_20_DOLLARS); + + // Loop through the purchase order elements. If their + // child element is between 10.00 and 20.00, add the + // to the element whose threshold is 10.00. For those over 20.00, + // add them to the element whose threshold is 20.00. + + // There don't happen to be any under 10.00, but handle this case anyway. + LineItem[] items = po.getLineItemArray(); + for (int i = 0; i < items.length; i++) + { + LineItem item = items[i]; + + if (item.getPrice() < 10.00) + { + + ItemType newItem = priceZero.addNewItem(); + newItem.setTitle(item.getDescription()); + newItem.xsetQuantity(item.xgetQuantity()); + newItem.setAmount(item.getPrice()); + + } else if (item.getPrice() >= 10.00 && item.getPrice() < 20.00) + { + + ItemType newItem = priceTen.addNewItem(); + newItem.setTitle(item.getDescription()); + newItem.xsetQuantity(item.xgetQuantity()); + newItem.setAmount(item.getPrice()); + + } else if (item.getPrice() >= 20.00) + { + + ItemType newItem = priceTwenty.addNewItem(); + newItem.setTitle(item.getDescription()); + newItem.xsetQuantity(item.xgetQuantity()); + newItem.setAmount(item.getPrice()); + } + } + return summaryDoc; + } + + /** + *

    This method loops through a price summary XML document to + * create a string that lists the items grouped by threshold. + * Unlike the summarizeItems method, which creates a new XML + * document that contains an attribute whose value is enumerated, + * this method retrieves values from an enumeration.

    + *

    + *

    This method illustrates how you can use the int value corresponding + * to enumerations to specify them in Java switch statements.

    + */ + public String sortByThreshold(PriceSummaryDocument summaryDoc) + { + // Extract the summary element from the incoming XML, then use it + // to extract an array of the price elements. + PriceSummaryDocument.PriceSummary summary = summaryDoc.getPriceSummary(); + PriceType[] priceElements = summary.getPriceArray(); + + StringBuffer responseBuffer = new StringBuffer(); + + // Create string buffers to hold the sorted results of the values + // retrieved. + StringBuffer zeroBuffer = new StringBuffer("\nItems under 10 dollars: \n"); + StringBuffer tenBuffer = new StringBuffer("\nItems between 10 and 20 dollars: \n"); + StringBuffer twentyBuffer = new StringBuffer("\nItems more than 20 dollars: \n"); + + // Loop through the price elements, extracting the array of child + // elements in each. + for (int i = 0; i < priceElements.length; i++) + { + ItemType[] itemElements = priceElements[i].getItemArray(); + + // Loop through the elements, discovering which threshold + // the item belongs to, then using the element's value + // in in a sorted list. + for (int j = 0; j < itemElements.length; j++) + { + ItemType item = itemElements[j]; + + // For each <item> element, find out the int value of its <price> + // parent element's threshold attribute value. Append the item's + // title to the appropriate string buffer. + switch (priceElements[i].getThreshold().intValue()) + { + + case PriceType.Threshold.INT_BELOW_10_DOLLARS: + zeroBuffer.append(" " + item.getTitle() + "\n"); + break; + + case PriceType.Threshold.INT_BETWEEN_10_AND_20_DOLLARS: + tenBuffer.append(" " + item.getTitle() + "\n"); + break; + + case PriceType.Threshold.INT_ABOVE_20_DOLLARS: + twentyBuffer.append(" " + item.getTitle() + "\n"); + break; + + default: + System.out.println("Yo! Something unexpected happened!"); + break; + } + } + } + responseBuffer.append(tenBuffer); + responseBuffer.append(twentyBuffer); + return responseBuffer.toString(); + } + + /** + * <p>Validates the XML, printing error messages when the XML is invalid. Note + * that this method will properly validate any instance of a compiled schema + * type because all of these types extend XmlObject.</p> + * <p/> + * <p>Note that in actual practice, you'll probably want to use an assertion + * when validating if you want to ensure that your code doesn't pass along + * invalid XML. This sample prints the generated XML whether or not it's + * valid so that you can see the result in both cases.</p> + * + * @param xml The XML to validate. + * @return <code>true</code> if the XML is valid; otherwise, <code>false</code> + */ + public boolean validateXml(XmlObject xml) + { + boolean isXmlValid = false; + + // A collection instance to hold validation error messages. + ArrayList validationMessages = new ArrayList(); + + // Validate the XML, collecting messages. + isXmlValid = xml.validate(new XmlOptions().setErrorListener(validationMessages)); + + if (!isXmlValid) + { + System.out.println("Invalid XML: "); + for (int i = 0; i < validationMessages.size(); i++) + { + XmlError error = (XmlError) validationMessages.get(i); + System.out.println(error.getMessage()); + System.out.println(error.getObjectLocation()); + } + } + return isXmlValid; + } + + /** + * <p>Creates a File from the XML path provided in main arguments, then + * parses the file's contents into a type generated from schema.</p> + * <p/> + * <p>Note that this work might have been done in main. Isolating it here + * makes the code separately available from outside this class.</p> + * + * @param xmlFilePath A path to XML based on the schema in inventory.xsd. + * @return An instance of a generated schema type that contains the parsed + * XML. + */ + public PurchaseOrderDocument parseXml(String xmlFilePath) + { + File poFile = new File(xmlFilePath); + PurchaseOrderDocument poDoc = null; + try + { + poDoc = PurchaseOrderDocument.Factory.parse(poFile); + } catch (XmlException e) + { + e.printStackTrace(); + } catch (IOException e) + { + e.printStackTrace(); + } + return poDoc; + } +} diff --git a/xmlbeans/samples/SchemaEnum/src/org/apache/xmlbeans/samples/enumeration/SchemaEnumTest.java b/xmlbeans/samples/SchemaEnum/src/org/apache/xmlbeans/samples/enumeration/SchemaEnumTest.java new file mode 100644 index 000000000..3aa9aeea6 --- /dev/null +++ b/xmlbeans/samples/SchemaEnum/src/org/apache/xmlbeans/samples/enumeration/SchemaEnumTest.java @@ -0,0 +1,52 @@ +/* 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.samples.enumeration; + +import org.apache.xmlbeans.samples.enumeration.schemaenum.easypo.PurchaseOrderDocument; +import org.apache.xmlbeans.samples.enumeration.schemaenum.pricesummary.PriceSummaryDocument; + +/** + * A class to test the SchemaEnum sample. + */ +public class SchemaEnumTest +{ + /** + * Tests the SchemaEnum sample. + * + * @param args An array in which the first item is a path to an XML file + * based on the schema in inventory.xsd. + */ + public static void main(String[] args) + { + SchemaEnum sample = new SchemaEnum(); + PurchaseOrderDocument poDoc = sample.parseXml(args[0]); + + boolean exampleIsValid = sample.validateXml(poDoc); + assert exampleIsValid; + + // Create a new document that summarizes the PO doc. + PriceSummaryDocument summaryDoc = sample.summarizeItems(poDoc); + + boolean summaryIsValid = sample.validateXml(summaryDoc); + assert summaryIsValid; + + // Create a summary of the items based on price. + String sortedItems = sample.sortByThreshold(summaryDoc); + + boolean stringExists = (sortedItems != null); + assert stringExists; + } +} diff --git a/xmlbeans/samples/SchemaEnum/xml/PriceSummary.xml b/xmlbeans/samples/SchemaEnum/xml/PriceSummary.xml new file mode 100644 index 000000000..8bfd1b986 --- /dev/null +++ b/xmlbeans/samples/SchemaEnum/xml/PriceSummary.xml @@ -0,0 +1,36 @@ +<!-- +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. + --> +<price-summary xmlns="http://xmlbeans.apache.org/samples/enumeration/schemaenum/pricesummary"> + <price threshold="Above20Dollars"> + <item> + <title>Burnham's Celestial Handbook, Vol 1 + 21.79 + 1 + +
    + + + Burnham's Celestial Handbook, Vol 2 + 19.89 + 2 + + + Burnham's Celestial Handbook, Vol 3 + 19.89 + 1 + + + diff --git a/xmlbeans/samples/SchemaEnum/xml/PurchaseOrder.xml b/xmlbeans/samples/SchemaEnum/xml/PurchaseOrder.xml new file mode 100644 index 000000000..5ecfd44c1 --- /dev/null +++ b/xmlbeans/samples/SchemaEnum/xml/PurchaseOrder.xml @@ -0,0 +1,44 @@ + + + + Gladys Kravitz +
    Anytown, PA
    +
    + 2001-12-17T09:30:47-05:00 + + Burnham's Celestial Handbook, Vol 1 + 5 + 21.79 + 2 + + + Burnham's Celestial Handbook, Vol 2 + 5 + 19.89 + 2 + + + Burnham's Celestial Handbook, Vol 3 + 5 + 19.89 + 1 + + + UPS + 0.74 + +
    diff --git a/xmlbeans/samples/SubstitutionGroup/README.txt b/xmlbeans/samples/SubstitutionGroup/README.txt new file mode 100644 index 000000000..59a3eb2bd --- /dev/null +++ b/xmlbeans/samples/SubstitutionGroup/README.txt @@ -0,0 +1,52 @@ +Sample: SubstitutionGroup +Author: Rashmi Banthia (rjain29@gmail.com) +Last Updated: Oct. 6th, 2004 + +Versions: + xmlbeans-1.0.3 + + +----------------------------------------------------------------------------- + +This sample illustrates substitution group elements in an XML document. + +When you run this sample, you'll see it print substitution group element names and values. +Also it creates a new XML document to demonstrate how to write substitution group elements. + + +For example, for the following schema and XML fragment: + + + + + + + Sample ship comment + + + Sample comment + + + +It will print: +-------------- +ship-comment +Sample ship comment + +comment +Sample comment + + +Also it will write the following fragment to a XML document: + + Sample bill comment + + + + +To try out this sample: + +1. Set XMLBEANS_HOME in your environment +2. Ant must be on your PATH +3. To compile the schemas and sample source, run "ant build" +4. To execute the sample, run "ant run" diff --git a/xmlbeans/samples/SubstitutionGroup/build.xml b/xmlbeans/samples/SubstitutionGroup/build.xml new file mode 100644 index 000000000..bacc79c10 --- /dev/null +++ b/xmlbeans/samples/SubstitutionGroup/build.xml @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/xmlbeans/samples/SubstitutionGroup/schemas/EasyPo.xsd b/xmlbeans/samples/SubstitutionGroup/schemas/EasyPo.xsd new file mode 100644 index 000000000..8d99165d6 --- /dev/null +++ b/xmlbeans/samples/SubstitutionGroup/schemas/EasyPo.xsd @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/xmlbeans/samples/SubstitutionGroup/src/org/apache/xmlbeans/samples/substitutiongroup/SubstitutionGroup.java b/xmlbeans/samples/SubstitutionGroup/src/org/apache/xmlbeans/samples/substitutiongroup/SubstitutionGroup.java new file mode 100644 index 000000000..84ddf1353 --- /dev/null +++ b/xmlbeans/samples/SubstitutionGroup/src/org/apache/xmlbeans/samples/substitutiongroup/SubstitutionGroup.java @@ -0,0 +1,235 @@ +/* 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.samples.substitutiongroup; + +import org.apache.xmlbeans.XmlCursor; +import org.apache.xmlbeans.XmlError; +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.XmlOptions; +import org.apache.xmlbeans.XmlException; + +import org.apache.xmlbeans.samples.substitutiongroup.easypo.PurchaseOrderDocument; +import org.apache.xmlbeans.samples.substitutiongroup.easypo.InvoiceHeaderDocument; +import org.apache.xmlbeans.samples.substitutiongroup.easypo.NameAddress; +import org.apache.xmlbeans.samples.substitutiongroup.easypo.BookType; +import org.apache.xmlbeans.samples.substitutiongroup.easypo.ClothingType; + +import javax.xml.namespace.QName; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; + +/** + * This sample illustrates how you can access substitution group element names and + * values defined in the XML document. This sample also demonstrates how to write + * substitution group elements. + * + * The schema used by this sample are defined in EasyPo.xsd + */ +public class SubstitutionGroup +{ + /** + * Receives an XML Instance and prints the substitution group element names and values, + * Also creates a new XML Instance. + * + * @param args An array containing + * (a)Path to the XML Instance conforming to the XML schema in EasyPo.xsd. + * (b)Path for creating a new XML Instance. + */ + public static void main(String args[]) + { + // Create an instance of this class to work with. + SubstitutionGroup subGrp = new SubstitutionGroup(); + + // Create an instance of a type based on the received XML's schema + PurchaseOrderDocument poDoc = subGrp.parseXml(args[0]); + + // Validate it + validateXml(poDoc); + + // Prints the comments from the XML, also the name of the substitute tokens. + subGrp.printComments(poDoc); + + // Creates a new XML and saves the file + subGrp.createDocument(poDoc,args[1]); + } + + public PurchaseOrderDocument parseXml(String file) + { + File xmlfile = new File(file); + PurchaseOrderDocument poDoc = null; + + try + { + poDoc = PurchaseOrderDocument.Factory.parse(xmlfile); + } + catch(XmlException e){ + e.printStackTrace(); + } + catch(IOException e){ + e.printStackTrace(); + } + return poDoc; + } + + /** + * This method prints the substitution group element names(local part) and values for each Invoice-header + * element in the XML Instance. (The rest of elements are ignored for the sake of simplicity) + */ + public void printComments(PurchaseOrderDocument poDoc) + { + // Get object reference of root element. + PurchaseOrderDocument.PurchaseOrder purchaseOrderElement = poDoc.getPurchaseOrder(); + + // Get all the invoice-header elements for purchase-order. + InvoiceHeaderDocument.InvoiceHeader[] invHeaders = purchaseOrderElement.getInvoiceHeaderArray(); + + System.out.println("\n\n=========Contents==========\n"); + // Iterate through each invoice-header elements printing only the element name and value for substitution group + // comment as defined in Easypo.xsd. + for (int i=0;iValidates the XML, printing error messages when the XML is invalid. Note + * that this method will properly validate any instance of a compiled schema + * type because all of these types extend XmlObject.

    + * + *

    Note that in actual practice, you'll probably want to use an assertion + * when validating if you want to ensure that your code doesn't pass along + * invalid XML. This sample prints the generated XML whether or not it's + * valid so that you can see the result in both cases.

    + * + * @param xml The XML to validate. + * @return true if the XML is valid; otherwise, false + */ + public static boolean validateXml(XmlObject xml) + { + boolean isXmlValid = false; + + // A collection instance to hold validation error messages. + ArrayList validationMessages = new ArrayList(); + + // Validate the XML, collecting messages. + isXmlValid = xml.validate( + new XmlOptions().setErrorListener(validationMessages)); + + // If the XML isn't valid, print the messages. + if (!isXmlValid) + { + System.out.println("\nInvalid XML: "); + for (int i = 0; i < validationMessages.size(); i++) + { + XmlError error = (XmlError) validationMessages.get(i); + System.out.println(error.getMessage()); + System.out.println(error.getObjectLocation()); + } + } + return isXmlValid; + } +} diff --git a/xmlbeans/samples/SubstitutionGroup/src/org/apache/xmlbeans/samples/substitutiongroup/SubstitutionGroupTest.java b/xmlbeans/samples/SubstitutionGroup/src/org/apache/xmlbeans/samples/substitutiongroup/SubstitutionGroupTest.java new file mode 100644 index 000000000..958f462ac --- /dev/null +++ b/xmlbeans/samples/SubstitutionGroup/src/org/apache/xmlbeans/samples/substitutiongroup/SubstitutionGroupTest.java @@ -0,0 +1,49 @@ +/* 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.samples.substitutiongroup; + +import org.apache.xmlbeans.samples.substitutiongroup.easypo.PurchaseOrderDocument; + +/** + * A class to test the SubstitutionGroup sample. + */ +public class SubstitutionGroupTest +{ + /** + * Tests the SubstitutionGroup sample. + * + * @param args An array in which the first item is a path to an XML file + * based on the schema in EasyPo.xsd. The second item is a path to an XML + * file that should be created by the sample. + */ + public static void main(String[] args) + { + // Create an instance of the sample to test. + SubstitutionGroup sample = new SubstitutionGroup(); + + // Create a schema type instance from the XML indicated by the path. + SubstitutionGroup subGrp = new SubstitutionGroup(); + PurchaseOrderDocument poDoc = subGrp.parseXml(args[0]); + + // Validate the XML. + assert sample.validateXml(poDoc); + + // Create a new document that adds two elements. + PurchaseOrderDocument newDoc = sample.createDocument(poDoc, args[1]); + + // Validate the XML. + assert sample.validateXml(newDoc); + } +} diff --git a/xmlbeans/samples/SubstitutionGroup/xml/Purchase-Order.xml b/xmlbeans/samples/SubstitutionGroup/xml/Purchase-Order.xml new file mode 100644 index 000000000..6faeb2d34 --- /dev/null +++ b/xmlbeans/samples/SubstitutionGroup/xml/Purchase-Order.xml @@ -0,0 +1,55 @@ + + + + + + + + Any Inc. +
    AnyTown, AnyCity
    +
    + + Any Inc. +
    AnyTown, AnyCity
    +
    + + The Little Engine That Could + + + Please ship this to Any Inc. asap. + +
    + + + + Some Corp. +
    SomeTown, SomeCity
    +
    + + This Corp. +
    ThisTown, ThisCity
    +
    + + green + + + This is being billed to This Corp. + +
    + + +
    diff --git a/xmlbeans/samples/SubstitutionGroup/xml/newPurchase-Order.xml b/xmlbeans/samples/SubstitutionGroup/xml/newPurchase-Order.xml new file mode 100644 index 000000000..c4a87b0a9 --- /dev/null +++ b/xmlbeans/samples/SubstitutionGroup/xml/newPurchase-Order.xml @@ -0,0 +1,72 @@ + + + + + + Any Inc. +
    AnyTown, AnyCity
    +
    + + Any Inc. +
    AnyTown, AnyCity
    +
    + + The Little Engine That Could + + Please ship this to Any Inc. asap. +
    + + + Some Corp. +
    SomeTown, SomeCity
    +
    + + This Corp. +
    ThisTown, ThisCity
    +
    + + green + + This is being billed to This Corp. +
    + + + New Company +
    NewTown, NewCity
    +
    + + New Company +
    NewTown, NewCity
    +
    + + Where the Red Fern Grows + + This is a new bill-comment +
    + + + Other Company +
    OtherTown, OtherCity
    +
    + + Other Company +
    OtherTown, OtherCity
    +
    + + blue + + This is a new bill-comment +
    +
    \ No newline at end of file diff --git a/xmlbeans/samples/Validation/README.txt b/xmlbeans/samples/Validation/README.txt new file mode 100644 index 000000000..10efa3a29 --- /dev/null +++ b/xmlbeans/samples/Validation/README.txt @@ -0,0 +1,38 @@ +Sample: Validation +Author: Steven Traut (straut@bea.com) +Last Updated: May 25, 2005 + +Versions: + xmlbeans-v1 1.0.3 + xmlbeans-v2 + +----------------------------------------------------------------------------- + +This sample illustrates how you can use the XMLBeans API to validate +XML instances against schema. The API provides two validation features: + +- A validate method (available from XmlOjbect and types generated from schema) +with which you can validate the bound instance and collect error messages that +result. +- An option through which you can specify that simple schema types should +be validated by XMLBeans when your code sets their value. This feature +will simply throw an exception if setting the value renders the instance +invalid. + +Because it uses invalid XML for illustration, this sample is designed to "fail" +when it runs. When you run this sample, you'll see it print two blocks of information +in the console: +- A message containing errors resulting from calling the validate method +on invalid XML. +- The stack trace of an exception resulting from setting an invalid value +when the XmlOptions.VALIDATE_ON_SET option has been specified. + +Note that you can also validate at the command line using tools provided +in the bin directory of the XMLBeans distribution. + +To try out this sample: + +1. Set XMLBEANS_HOME in your environment +2. Ant must be on your PATH +3. To compile the schemas and sample source, run "ant build" +4. To execute the sample, run "ant run" diff --git a/xmlbeans/samples/Validation/build.xml b/xmlbeans/samples/Validation/build.xml new file mode 100644 index 000000000..2fb70f509 --- /dev/null +++ b/xmlbeans/samples/Validation/build.xml @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/xmlbeans/samples/Validation/schemas/todolist.xsd b/xmlbeans/samples/Validation/schemas/todolist.xsd new file mode 100644 index 000000000..6491684af --- /dev/null +++ b/xmlbeans/samples/Validation/schemas/todolist.xsd @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/xmlbeans/samples/Validation/src/org/apache/xmlbeans/samples/validation/Validation.java b/xmlbeans/samples/Validation/src/org/apache/xmlbeans/samples/validation/Validation.java new file mode 100644 index 000000000..ca89d098e --- /dev/null +++ b/xmlbeans/samples/Validation/src/org/apache/xmlbeans/samples/validation/Validation.java @@ -0,0 +1,188 @@ +/* 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.samples.validation; + +import org.apache.xmlbeans.*; +import org.apache.xmlbeans.samples.validation.todolist.*; +import org.apache.xmlbeans.samples.validation.todolist.TodolistDocument.Todolist; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; + +/** + * A sample to illustrate two means for validating XML against schema + * using features of the XMLBeans API. The features illustrated are: + * + * - Validating after changes by using the XmlObject.validate method. + * This method is exposed by types generated by compiling schema. The + * validate method validates instances against all aspects of schema. + * Also, with this method you can specify a Collection instance to + * capture errors that occur during validation. + * + * - Validating "on the fly" using the XmlOptions.VALIDATE_ON_SET constant. + * This option prompts XMLBeans to validate XML against simple schema types + * as you set them, rather than by expressly calling for validation. + * You can set this option by calling XmlOptions.setValidateOnSet, then + * specifying the XmlOptions instance as a parameter when creating + * a new instance from schema or parsing an existing one. + * + * Note that it is also possible to validate instances from the + * command line by using tools you'll find in the bin directory of the + * XMLBeans distribution. + */ +public class Validation +{ + private static XmlOptions m_validationOptions; + + /** + * Receives a todo list XML instance, twice rendering it invalid + * and validating it using the XMLBeans API. + * + * @param args An array in which the first item is a + * path to the XML instance file. + */ + public static void main(String[] args) + { + Validation thisSample = new Validation(); + + // Use the validate method to validate an instance after + // updates. + boolean isValidAfterChanges = thisSample.isValidAfterChanges(args[0]); + + // Use the VALIDATE_ON_SET option to validate an instance + // as updates are made. + boolean isValidOnTheFly = thisSample.isValidOnTheFly(args[0]); + } + + /** + * Illustrates use of the validate method by making changes to incoming + * XML that invalidate the XML, then validating the instance and + * printing resulting error messages. + * + * Because this code is designed to generate invalid XML, it + * returns false when successful. + * + * @param xmlPath A path to the XML instance file. + * @return true if the XML is valid after changes; + * otherwise, false. + */ + public boolean isValidAfterChanges(String xmlPath) + { + System.out.println("Validating after changes: \n"); + // Set up the validation error listener. + ArrayList validationErrors = new ArrayList(); + m_validationOptions = new XmlOptions(); + m_validationOptions.setErrorListener(validationErrors); + + TodolistDocument todoList = (TodolistDocument)parseXml(xmlPath, null); + + // Schema defines the element as required (minOccurs = '1'). + // So this statement renders the XML invalid because it sets the + // element to nil. + todoList.getTodolist().getItemArray(0).setName(null); + + // During validation, errors are added to the ArrayList for + // retrieval and printing by the printErrors method. + boolean isValid = todoList.validate(m_validationOptions); + + if (!isValid) + { + printErrors(validationErrors); + } + return isValid; + } + + /** + * Illustrates the "validate on set" feature, which validates XML + * for simple types on the fly. As XML for those types is "set" through + * accessors generated by compiling schema, XMLBeans checks the XML's + * validity. The code here uses generated types to retrieve the first + * in a , then update the 's id attribute. The code + * throws an exception when it tries to set an id attribute value that + * is too high. + * + * Because this code is designed to generate invalid XML, it + * returns false when successful. + * + * @param xmlPath A path to the XML instance file. + * @return true if valid XML is successfully created; + * otherwise, false. + */ + public boolean isValidOnTheFly(String xmlPath) + { + System.out.println("Validating on-the-fly: \n"); + m_validationOptions = new XmlOptions(); + m_validationOptions.setValidateOnSet(); + + TodolistDocument todoList = (TodolistDocument)parseXml(xmlPath, m_validationOptions); + Todolist list = todoList.getTodolist(); + ItemType firstItem = list.getItemArray(0); + + // Schema defines the element as allowing values up to 100. So + // this line throws an exception because it invalidates the XML the + // code is updating. + firstItem.setId(8587); + + // This line will not be reached. + return todoList.validate(); + } + + /** + * Receives the collection containing errors found during + * validation and print the errors to the console. + * + * @param validationErrors The validation errors. + */ + public void printErrors(ArrayList validationErrors) + { + System.out.println("Errors discovered during validation: \n"); + Iterator iter = validationErrors.iterator(); + while (iter.hasNext()) + { + System.out.println(">> " + iter.next() + "\n"); + } + } + + /** + *

    Creates a File from the XML path provided in main arguments, then + * parses the file's contents into a type generated from schema.

    + *

    + *

    Note that this work might have been done in main. Isolating it here + * makes the code separately available from outside this class.

    + * + * @param xmlFilePath A path to XML based on the schema in inventory.xsd. + * @return An instance of a generated schema type that contains the parsed + * XML. + */ + public XmlObject parseXml(String xmlFilePath, XmlOptions validationOptions) + { + File xmlFile = new File(xmlFilePath); + XmlObject xml = null; + try + { + xml = XmlObject.Factory.parse(xmlFile, validationOptions); + } catch (XmlException e) + { + e.printStackTrace(); + } catch (IOException e) + { + e.printStackTrace(); + } + return xml; + } +} diff --git a/xmlbeans/samples/Validation/src/org/apache/xmlbeans/samples/validation/ValidationTest.java b/xmlbeans/samples/Validation/src/org/apache/xmlbeans/samples/validation/ValidationTest.java new file mode 100644 index 000000000..00c400dd8 --- /dev/null +++ b/xmlbeans/samples/Validation/src/org/apache/xmlbeans/samples/validation/ValidationTest.java @@ -0,0 +1,43 @@ +/* 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.samples.validation; + +import org.apache.xmlbeans.samples.validation.Validation; + +/** + * A class with which to test the Validation sample. + */ +public class ValidationTest +{ + /** + * Tests the Validation sample. + */ + public static void main(String[] args) + { + // all we're checking for is that the sample doesn't throw anything. + // a real sample test might assert something more interesting. + Validation sample = new Validation(); + // Use the validate method to validate an instance after + // updates. + boolean isValidAfterChanges = sample.isValidAfterChanges(args[0]); + assert !isValidAfterChanges; + + // Use the VALIDATE_ON_SET option to validate an instance + // as updates are made. + boolean isValidOnTheFly = sample.isValidOnTheFly(args[0]); + assert !isValidOnTheFly; + } +} diff --git a/xmlbeans/samples/Validation/src/org/apache/xmlbeans/samples/validation/todolist/ActionType.java b/xmlbeans/samples/Validation/src/org/apache/xmlbeans/samples/validation/todolist/ActionType.java new file mode 100644 index 000000000..25bc9abc9 --- /dev/null +++ b/xmlbeans/samples/Validation/src/org/apache/xmlbeans/samples/validation/todolist/ActionType.java @@ -0,0 +1,170 @@ +/* + * XML Type: actionType + * Namespace: http://xmlbeans.apache.org/samples/validation/todolist + * Java type: org.apache.xmlbeans.samples.validation.todolist.ActionType + * + * Automatically generated - do not modify. + */ +package org.apache.xmlbeans.samples.validation.todolist; + + +/** + * An XML actionType(@http://xmlbeans.apache.org/samples/validation/todolist). + * + * This is an atomic type that is a restriction of org.apache.xmlbeans.XmlString. + */ +public interface ActionType extends org.apache.xmlbeans.XmlString +{ + public static final org.apache.xmlbeans.SchemaType type = (org.apache.xmlbeans.SchemaType)schema.system.s59A663BF38731BA9F8026B121E40FDD3.TypeSystemHolder.typeSystem.resolveHandle("actiontype5fa0type"); + + org.apache.xmlbeans.StringEnumAbstractBase enumValue(); + void set(org.apache.xmlbeans.StringEnumAbstractBase e); + + static final Enum DO = Enum.forString("do"); + static final Enum DELEGATE = Enum.forString("delegate"); + static final Enum SOMEDAY_MAYBE_DEFER = Enum.forString("someday_maybe_defer"); + static final Enum TOSS = Enum.forString("toss"); + static final Enum INCUBATE = Enum.forString("incubate"); + static final Enum FILE = Enum.forString("file"); + + static final int INT_DO = Enum.INT_DO; + static final int INT_DELEGATE = Enum.INT_DELEGATE; + static final int INT_SOMEDAY_MAYBE_DEFER = Enum.INT_SOMEDAY_MAYBE_DEFER; + static final int INT_TOSS = Enum.INT_TOSS; + static final int INT_INCUBATE = Enum.INT_INCUBATE; + static final int INT_FILE = Enum.INT_FILE; + + /** + * Enumeration value class for org.apache.xmlbeans.samples.validation.todolist.ActionType. + * These enum values can be used as follows: + *
    +     * enum.toString(); // returns the string value of the enum
    +     * enum.intValue(); // returns an int value, useful for switches
    +     * // e.g., case Enum.INT_DO
    +     * Enum.forString(s); // returns the enum value for a string
    +     * Enum.forInt(i); // returns the enum value for an int
    +     * 
    + * Enumeration objects are immutable singleton objects that + * can be compared using == object equality. They have no + * public constructor. See the constants defined within this + * class for all the valid values. + */ + static final class Enum extends org.apache.xmlbeans.StringEnumAbstractBase + { + /** + * Returns the enum value for a string, or null if none. + */ + public static Enum forString(java.lang.String s) + { return (Enum)table.forString(s); } + /** + * Returns the enum value corresponding to an int, or null if none. + */ + public static Enum forInt(int i) + { return (Enum)table.forInt(i); } + + private Enum(java.lang.String s, int i) + { super(s, i); } + + static final int INT_DO = 1; + static final int INT_DELEGATE = 2; + static final int INT_SOMEDAY_MAYBE_DEFER = 3; + static final int INT_TOSS = 4; + static final int INT_INCUBATE = 5; + static final int INT_FILE = 6; + + public static final org.apache.xmlbeans.StringEnumAbstractBase.Table table = + new org.apache.xmlbeans.StringEnumAbstractBase.Table + ( + new Enum[] + { + new Enum("do", INT_DO), + new Enum("delegate", INT_DELEGATE), + new Enum("someday_maybe_defer", INT_SOMEDAY_MAYBE_DEFER), + new Enum("toss", INT_TOSS), + new Enum("incubate", INT_INCUBATE), + new Enum("file", INT_FILE), + } + ); + private static final long serialVersionUID = 1L; + private java.lang.Object readResolve() { return forInt(intValue()); } + } + + /** + * A factory class with static methods for creating instances + * of this type. + */ + + public static final class Factory + { + public static org.apache.xmlbeans.samples.validation.todolist.ActionType newValue(java.lang.Object obj) { + return (org.apache.xmlbeans.samples.validation.todolist.ActionType) type.newValue( obj ); } + + public static org.apache.xmlbeans.samples.validation.todolist.ActionType newInstance() { + return (org.apache.xmlbeans.samples.validation.todolist.ActionType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().newInstance( type, null ); } + + public static org.apache.xmlbeans.samples.validation.todolist.ActionType newInstance(org.apache.xmlbeans.XmlOptions options) { + return (org.apache.xmlbeans.samples.validation.todolist.ActionType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().newInstance( type, options ); } + + /** @param xmlAsString the string value to parse */ + public static org.apache.xmlbeans.samples.validation.todolist.ActionType parse(java.lang.String xmlAsString) throws org.apache.xmlbeans.XmlException { + return (org.apache.xmlbeans.samples.validation.todolist.ActionType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( xmlAsString, type, null ); } + + public static org.apache.xmlbeans.samples.validation.todolist.ActionType parse(java.lang.String xmlAsString, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (org.apache.xmlbeans.samples.validation.todolist.ActionType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( xmlAsString, type, options ); } + + /** @param file the file from which to load an xml document */ + public static org.apache.xmlbeans.samples.validation.todolist.ActionType parse(java.io.File file) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (org.apache.xmlbeans.samples.validation.todolist.ActionType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( file, type, null ); } + + public static org.apache.xmlbeans.samples.validation.todolist.ActionType parse(java.io.File file, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (org.apache.xmlbeans.samples.validation.todolist.ActionType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( file, type, options ); } + + public static org.apache.xmlbeans.samples.validation.todolist.ActionType parse(java.net.URL u) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (org.apache.xmlbeans.samples.validation.todolist.ActionType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( u, type, null ); } + + public static org.apache.xmlbeans.samples.validation.todolist.ActionType parse(java.net.URL u, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (org.apache.xmlbeans.samples.validation.todolist.ActionType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( u, type, options ); } + + public static org.apache.xmlbeans.samples.validation.todolist.ActionType parse(java.io.InputStream is) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (org.apache.xmlbeans.samples.validation.todolist.ActionType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( is, type, null ); } + + public static org.apache.xmlbeans.samples.validation.todolist.ActionType parse(java.io.InputStream is, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (org.apache.xmlbeans.samples.validation.todolist.ActionType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( is, type, options ); } + + public static org.apache.xmlbeans.samples.validation.todolist.ActionType parse(java.io.Reader r) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (org.apache.xmlbeans.samples.validation.todolist.ActionType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( r, type, null ); } + + public static org.apache.xmlbeans.samples.validation.todolist.ActionType parse(java.io.Reader r, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (org.apache.xmlbeans.samples.validation.todolist.ActionType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( r, type, options ); } + + public static org.apache.xmlbeans.samples.validation.todolist.ActionType parse(javax.xml.stream.XMLStreamReader sr) throws org.apache.xmlbeans.XmlException { + return (org.apache.xmlbeans.samples.validation.todolist.ActionType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( sr, type, null ); } + + public static org.apache.xmlbeans.samples.validation.todolist.ActionType parse(javax.xml.stream.XMLStreamReader sr, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (org.apache.xmlbeans.samples.validation.todolist.ActionType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( sr, type, options ); } + + public static org.apache.xmlbeans.samples.validation.todolist.ActionType parse(org.w3c.dom.Node node) throws org.apache.xmlbeans.XmlException { + return (org.apache.xmlbeans.samples.validation.todolist.ActionType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( node, type, null ); } + + public static org.apache.xmlbeans.samples.validation.todolist.ActionType parse(org.w3c.dom.Node node, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (org.apache.xmlbeans.samples.validation.todolist.ActionType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( node, type, options ); } + + /** @deprecated {@link XMLInputStream} */ + public static org.apache.xmlbeans.samples.validation.todolist.ActionType parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (org.apache.xmlbeans.samples.validation.todolist.ActionType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( xis, type, null ); } + + /** @deprecated {@link XMLInputStream} */ + public static org.apache.xmlbeans.samples.validation.todolist.ActionType parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (org.apache.xmlbeans.samples.validation.todolist.ActionType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( xis, type, options ); } + + /** @deprecated {@link XMLInputStream} */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return org.apache.xmlbeans.XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, null ); } + + /** @deprecated {@link XMLInputStream} */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return org.apache.xmlbeans.XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, options ); } + + private Factory() { } // No instance of this class allowed + } +} diff --git a/xmlbeans/samples/Validation/src/org/apache/xmlbeans/samples/validation/todolist/IdType.java b/xmlbeans/samples/Validation/src/org/apache/xmlbeans/samples/validation/todolist/IdType.java new file mode 100644 index 000000000..07bdad377 --- /dev/null +++ b/xmlbeans/samples/Validation/src/org/apache/xmlbeans/samples/validation/todolist/IdType.java @@ -0,0 +1,98 @@ +/* + * XML Type: idType + * Namespace: http://xmlbeans.apache.org/samples/validation/todolist + * Java type: org.apache.xmlbeans.samples.validation.todolist.IdType + * + * Automatically generated - do not modify. + */ +package org.apache.xmlbeans.samples.validation.todolist; + + +/** + * An XML idType(@http://xmlbeans.apache.org/samples/validation/todolist). + * + * This is an atomic type that is a restriction of org.apache.xmlbeans.XmlInt. + */ +public interface IdType extends org.apache.xmlbeans.XmlInt +{ + public static final org.apache.xmlbeans.SchemaType type = (org.apache.xmlbeans.SchemaType)schema.system.s59A663BF38731BA9F8026B121E40FDD3.TypeSystemHolder.typeSystem.resolveHandle("idtypef11btype"); + + /** + * A factory class with static methods for creating instances + * of this type. + */ + + public static final class Factory + { + public static org.apache.xmlbeans.samples.validation.todolist.IdType newValue(java.lang.Object obj) { + return (org.apache.xmlbeans.samples.validation.todolist.IdType) type.newValue( obj ); } + + public static org.apache.xmlbeans.samples.validation.todolist.IdType newInstance() { + return (org.apache.xmlbeans.samples.validation.todolist.IdType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().newInstance( type, null ); } + + public static org.apache.xmlbeans.samples.validation.todolist.IdType newInstance(org.apache.xmlbeans.XmlOptions options) { + return (org.apache.xmlbeans.samples.validation.todolist.IdType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().newInstance( type, options ); } + + /** @param xmlAsString the string value to parse */ + public static org.apache.xmlbeans.samples.validation.todolist.IdType parse(java.lang.String xmlAsString) throws org.apache.xmlbeans.XmlException { + return (org.apache.xmlbeans.samples.validation.todolist.IdType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( xmlAsString, type, null ); } + + public static org.apache.xmlbeans.samples.validation.todolist.IdType parse(java.lang.String xmlAsString, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (org.apache.xmlbeans.samples.validation.todolist.IdType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( xmlAsString, type, options ); } + + /** @param file the file from which to load an xml document */ + public static org.apache.xmlbeans.samples.validation.todolist.IdType parse(java.io.File file) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (org.apache.xmlbeans.samples.validation.todolist.IdType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( file, type, null ); } + + public static org.apache.xmlbeans.samples.validation.todolist.IdType parse(java.io.File file, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (org.apache.xmlbeans.samples.validation.todolist.IdType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( file, type, options ); } + + public static org.apache.xmlbeans.samples.validation.todolist.IdType parse(java.net.URL u) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (org.apache.xmlbeans.samples.validation.todolist.IdType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( u, type, null ); } + + public static org.apache.xmlbeans.samples.validation.todolist.IdType parse(java.net.URL u, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (org.apache.xmlbeans.samples.validation.todolist.IdType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( u, type, options ); } + + public static org.apache.xmlbeans.samples.validation.todolist.IdType parse(java.io.InputStream is) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (org.apache.xmlbeans.samples.validation.todolist.IdType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( is, type, null ); } + + public static org.apache.xmlbeans.samples.validation.todolist.IdType parse(java.io.InputStream is, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (org.apache.xmlbeans.samples.validation.todolist.IdType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( is, type, options ); } + + public static org.apache.xmlbeans.samples.validation.todolist.IdType parse(java.io.Reader r) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (org.apache.xmlbeans.samples.validation.todolist.IdType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( r, type, null ); } + + public static org.apache.xmlbeans.samples.validation.todolist.IdType parse(java.io.Reader r, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (org.apache.xmlbeans.samples.validation.todolist.IdType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( r, type, options ); } + + public static org.apache.xmlbeans.samples.validation.todolist.IdType parse(javax.xml.stream.XMLStreamReader sr) throws org.apache.xmlbeans.XmlException { + return (org.apache.xmlbeans.samples.validation.todolist.IdType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( sr, type, null ); } + + public static org.apache.xmlbeans.samples.validation.todolist.IdType parse(javax.xml.stream.XMLStreamReader sr, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (org.apache.xmlbeans.samples.validation.todolist.IdType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( sr, type, options ); } + + public static org.apache.xmlbeans.samples.validation.todolist.IdType parse(org.w3c.dom.Node node) throws org.apache.xmlbeans.XmlException { + return (org.apache.xmlbeans.samples.validation.todolist.IdType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( node, type, null ); } + + public static org.apache.xmlbeans.samples.validation.todolist.IdType parse(org.w3c.dom.Node node, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (org.apache.xmlbeans.samples.validation.todolist.IdType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( node, type, options ); } + + /** @deprecated {@link XMLInputStream} */ + public static org.apache.xmlbeans.samples.validation.todolist.IdType parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (org.apache.xmlbeans.samples.validation.todolist.IdType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( xis, type, null ); } + + /** @deprecated {@link XMLInputStream} */ + public static org.apache.xmlbeans.samples.validation.todolist.IdType parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (org.apache.xmlbeans.samples.validation.todolist.IdType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( xis, type, options ); } + + /** @deprecated {@link XMLInputStream} */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return org.apache.xmlbeans.XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, null ); } + + /** @deprecated {@link XMLInputStream} */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return org.apache.xmlbeans.XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, options ); } + + private Factory() { } // No instance of this class allowed + } +} diff --git a/xmlbeans/samples/Validation/src/org/apache/xmlbeans/samples/validation/todolist/ItemType.java b/xmlbeans/samples/Validation/src/org/apache/xmlbeans/samples/validation/todolist/ItemType.java new file mode 100644 index 000000000..3f5038da7 --- /dev/null +++ b/xmlbeans/samples/Validation/src/org/apache/xmlbeans/samples/validation/todolist/ItemType.java @@ -0,0 +1,225 @@ +/* + * XML Type: itemType + * Namespace: http://xmlbeans.apache.org/samples/validation/todolist + * Java type: org.apache.xmlbeans.samples.validation.todolist.ItemType + * + * Automatically generated - do not modify. + */ +package org.apache.xmlbeans.samples.validation.todolist; + + +/** + * An XML itemType(@http://xmlbeans.apache.org/samples/validation/todolist). + * + * This is a complex type. + */ +public interface ItemType extends org.apache.xmlbeans.XmlObject +{ + public static final org.apache.xmlbeans.SchemaType type = (org.apache.xmlbeans.SchemaType)schema.system.s59A663BF38731BA9F8026B121E40FDD3.TypeSystemHolder.typeSystem.resolveHandle("itemtypeb663type"); + + /** + * Gets the "name" element + */ + java.lang.String getName(); + + /** + * Gets (as xml) the "name" element + */ + org.apache.xmlbeans.XmlString xgetName(); + + /** + * Sets the "name" element + */ + void setName(java.lang.String name); + + /** + * Sets (as xml) the "name" element + */ + void xsetName(org.apache.xmlbeans.XmlString name); + + /** + * Gets the "description" element + */ + java.lang.String getDescription(); + + /** + * Gets (as xml) the "description" element + */ + org.apache.xmlbeans.XmlString xgetDescription(); + + /** + * True if has "description" element + */ + boolean isSetDescription(); + + /** + * Sets the "description" element + */ + void setDescription(java.lang.String description); + + /** + * Sets (as xml) the "description" element + */ + void xsetDescription(org.apache.xmlbeans.XmlString description); + + /** + * Unsets the "description" element + */ + void unsetDescription(); + + /** + * Gets the "due_by" element + */ + java.util.Calendar getDueBy(); + + /** + * Gets (as xml) the "due_by" element + */ + org.apache.xmlbeans.XmlDateTime xgetDueBy(); + + /** + * True if has "due_by" element + */ + boolean isSetDueBy(); + + /** + * Sets the "due_by" element + */ + void setDueBy(java.util.Calendar dueBy); + + /** + * Sets (as xml) the "due_by" element + */ + void xsetDueBy(org.apache.xmlbeans.XmlDateTime dueBy); + + /** + * Unsets the "due_by" element + */ + void unsetDueBy(); + + /** + * Gets the "action" element + */ + org.apache.xmlbeans.samples.validation.todolist.ActionType.Enum getAction(); + + /** + * Gets (as xml) the "action" element + */ + org.apache.xmlbeans.samples.validation.todolist.ActionType xgetAction(); + + /** + * Sets the "action" element + */ + void setAction(org.apache.xmlbeans.samples.validation.todolist.ActionType.Enum action); + + /** + * Sets (as xml) the "action" element + */ + void xsetAction(org.apache.xmlbeans.samples.validation.todolist.ActionType action); + + /** + * Gets the "id" attribute + */ + int getId(); + + /** + * Gets (as xml) the "id" attribute + */ + org.apache.xmlbeans.samples.validation.todolist.IdType xgetId(); + + /** + * True if has "id" attribute + */ + boolean isSetId(); + + /** + * Sets the "id" attribute + */ + void setId(int id); + + /** + * Sets (as xml) the "id" attribute + */ + void xsetId(org.apache.xmlbeans.samples.validation.todolist.IdType id); + + /** + * Unsets the "id" attribute + */ + void unsetId(); + + /** + * A factory class with static methods for creating instances + * of this type. + */ + + public static final class Factory + { + public static org.apache.xmlbeans.samples.validation.todolist.ItemType newInstance() { + return (org.apache.xmlbeans.samples.validation.todolist.ItemType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().newInstance( type, null ); } + + public static org.apache.xmlbeans.samples.validation.todolist.ItemType newInstance(org.apache.xmlbeans.XmlOptions options) { + return (org.apache.xmlbeans.samples.validation.todolist.ItemType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().newInstance( type, options ); } + + /** @param xmlAsString the string value to parse */ + public static org.apache.xmlbeans.samples.validation.todolist.ItemType parse(java.lang.String xmlAsString) throws org.apache.xmlbeans.XmlException { + return (org.apache.xmlbeans.samples.validation.todolist.ItemType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( xmlAsString, type, null ); } + + public static org.apache.xmlbeans.samples.validation.todolist.ItemType parse(java.lang.String xmlAsString, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (org.apache.xmlbeans.samples.validation.todolist.ItemType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( xmlAsString, type, options ); } + + /** @param file the file from which to load an xml document */ + public static org.apache.xmlbeans.samples.validation.todolist.ItemType parse(java.io.File file) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (org.apache.xmlbeans.samples.validation.todolist.ItemType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( file, type, null ); } + + public static org.apache.xmlbeans.samples.validation.todolist.ItemType parse(java.io.File file, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (org.apache.xmlbeans.samples.validation.todolist.ItemType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( file, type, options ); } + + public static org.apache.xmlbeans.samples.validation.todolist.ItemType parse(java.net.URL u) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (org.apache.xmlbeans.samples.validation.todolist.ItemType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( u, type, null ); } + + public static org.apache.xmlbeans.samples.validation.todolist.ItemType parse(java.net.URL u, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (org.apache.xmlbeans.samples.validation.todolist.ItemType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( u, type, options ); } + + public static org.apache.xmlbeans.samples.validation.todolist.ItemType parse(java.io.InputStream is) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (org.apache.xmlbeans.samples.validation.todolist.ItemType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( is, type, null ); } + + public static org.apache.xmlbeans.samples.validation.todolist.ItemType parse(java.io.InputStream is, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (org.apache.xmlbeans.samples.validation.todolist.ItemType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( is, type, options ); } + + public static org.apache.xmlbeans.samples.validation.todolist.ItemType parse(java.io.Reader r) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (org.apache.xmlbeans.samples.validation.todolist.ItemType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( r, type, null ); } + + public static org.apache.xmlbeans.samples.validation.todolist.ItemType parse(java.io.Reader r, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (org.apache.xmlbeans.samples.validation.todolist.ItemType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( r, type, options ); } + + public static org.apache.xmlbeans.samples.validation.todolist.ItemType parse(javax.xml.stream.XMLStreamReader sr) throws org.apache.xmlbeans.XmlException { + return (org.apache.xmlbeans.samples.validation.todolist.ItemType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( sr, type, null ); } + + public static org.apache.xmlbeans.samples.validation.todolist.ItemType parse(javax.xml.stream.XMLStreamReader sr, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (org.apache.xmlbeans.samples.validation.todolist.ItemType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( sr, type, options ); } + + public static org.apache.xmlbeans.samples.validation.todolist.ItemType parse(org.w3c.dom.Node node) throws org.apache.xmlbeans.XmlException { + return (org.apache.xmlbeans.samples.validation.todolist.ItemType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( node, type, null ); } + + public static org.apache.xmlbeans.samples.validation.todolist.ItemType parse(org.w3c.dom.Node node, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (org.apache.xmlbeans.samples.validation.todolist.ItemType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( node, type, options ); } + + /** @deprecated {@link XMLInputStream} */ + public static org.apache.xmlbeans.samples.validation.todolist.ItemType parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (org.apache.xmlbeans.samples.validation.todolist.ItemType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( xis, type, null ); } + + /** @deprecated {@link XMLInputStream} */ + public static org.apache.xmlbeans.samples.validation.todolist.ItemType parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (org.apache.xmlbeans.samples.validation.todolist.ItemType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( xis, type, options ); } + + /** @deprecated {@link XMLInputStream} */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return org.apache.xmlbeans.XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, null ); } + + /** @deprecated {@link XMLInputStream} */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return org.apache.xmlbeans.XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, options ); } + + private Factory() { } // No instance of this class allowed + } +} diff --git a/xmlbeans/samples/Validation/src/org/apache/xmlbeans/samples/validation/todolist/NameType.java b/xmlbeans/samples/Validation/src/org/apache/xmlbeans/samples/validation/todolist/NameType.java new file mode 100644 index 000000000..dabf23514 --- /dev/null +++ b/xmlbeans/samples/Validation/src/org/apache/xmlbeans/samples/validation/todolist/NameType.java @@ -0,0 +1,98 @@ +/* + * XML Type: nameType + * Namespace: http://xmlbeans.apache.org/samples/validation/todolist + * Java type: org.apache.xmlbeans.samples.validation.todolist.NameType + * + * Automatically generated - do not modify. + */ +package org.apache.xmlbeans.samples.validation.todolist; + + +/** + * An XML nameType(@http://xmlbeans.apache.org/samples/validation/todolist). + * + * This is an atomic type that is a restriction of org.apache.xmlbeans.XmlString. + */ +public interface NameType extends org.apache.xmlbeans.XmlString +{ + public static final org.apache.xmlbeans.SchemaType type = (org.apache.xmlbeans.SchemaType)schema.system.s59A663BF38731BA9F8026B121E40FDD3.TypeSystemHolder.typeSystem.resolveHandle("nametypeabebtype"); + + /** + * A factory class with static methods for creating instances + * of this type. + */ + + public static final class Factory + { + public static org.apache.xmlbeans.samples.validation.todolist.NameType newValue(java.lang.Object obj) { + return (org.apache.xmlbeans.samples.validation.todolist.NameType) type.newValue( obj ); } + + public static org.apache.xmlbeans.samples.validation.todolist.NameType newInstance() { + return (org.apache.xmlbeans.samples.validation.todolist.NameType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().newInstance( type, null ); } + + public static org.apache.xmlbeans.samples.validation.todolist.NameType newInstance(org.apache.xmlbeans.XmlOptions options) { + return (org.apache.xmlbeans.samples.validation.todolist.NameType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().newInstance( type, options ); } + + /** @param xmlAsString the string value to parse */ + public static org.apache.xmlbeans.samples.validation.todolist.NameType parse(java.lang.String xmlAsString) throws org.apache.xmlbeans.XmlException { + return (org.apache.xmlbeans.samples.validation.todolist.NameType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( xmlAsString, type, null ); } + + public static org.apache.xmlbeans.samples.validation.todolist.NameType parse(java.lang.String xmlAsString, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (org.apache.xmlbeans.samples.validation.todolist.NameType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( xmlAsString, type, options ); } + + /** @param file the file from which to load an xml document */ + public static org.apache.xmlbeans.samples.validation.todolist.NameType parse(java.io.File file) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (org.apache.xmlbeans.samples.validation.todolist.NameType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( file, type, null ); } + + public static org.apache.xmlbeans.samples.validation.todolist.NameType parse(java.io.File file, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (org.apache.xmlbeans.samples.validation.todolist.NameType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( file, type, options ); } + + public static org.apache.xmlbeans.samples.validation.todolist.NameType parse(java.net.URL u) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (org.apache.xmlbeans.samples.validation.todolist.NameType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( u, type, null ); } + + public static org.apache.xmlbeans.samples.validation.todolist.NameType parse(java.net.URL u, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (org.apache.xmlbeans.samples.validation.todolist.NameType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( u, type, options ); } + + public static org.apache.xmlbeans.samples.validation.todolist.NameType parse(java.io.InputStream is) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (org.apache.xmlbeans.samples.validation.todolist.NameType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( is, type, null ); } + + public static org.apache.xmlbeans.samples.validation.todolist.NameType parse(java.io.InputStream is, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (org.apache.xmlbeans.samples.validation.todolist.NameType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( is, type, options ); } + + public static org.apache.xmlbeans.samples.validation.todolist.NameType parse(java.io.Reader r) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (org.apache.xmlbeans.samples.validation.todolist.NameType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( r, type, null ); } + + public static org.apache.xmlbeans.samples.validation.todolist.NameType parse(java.io.Reader r, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (org.apache.xmlbeans.samples.validation.todolist.NameType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( r, type, options ); } + + public static org.apache.xmlbeans.samples.validation.todolist.NameType parse(javax.xml.stream.XMLStreamReader sr) throws org.apache.xmlbeans.XmlException { + return (org.apache.xmlbeans.samples.validation.todolist.NameType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( sr, type, null ); } + + public static org.apache.xmlbeans.samples.validation.todolist.NameType parse(javax.xml.stream.XMLStreamReader sr, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (org.apache.xmlbeans.samples.validation.todolist.NameType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( sr, type, options ); } + + public static org.apache.xmlbeans.samples.validation.todolist.NameType parse(org.w3c.dom.Node node) throws org.apache.xmlbeans.XmlException { + return (org.apache.xmlbeans.samples.validation.todolist.NameType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( node, type, null ); } + + public static org.apache.xmlbeans.samples.validation.todolist.NameType parse(org.w3c.dom.Node node, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (org.apache.xmlbeans.samples.validation.todolist.NameType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( node, type, options ); } + + /** @deprecated {@link XMLInputStream} */ + public static org.apache.xmlbeans.samples.validation.todolist.NameType parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (org.apache.xmlbeans.samples.validation.todolist.NameType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( xis, type, null ); } + + /** @deprecated {@link XMLInputStream} */ + public static org.apache.xmlbeans.samples.validation.todolist.NameType parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (org.apache.xmlbeans.samples.validation.todolist.NameType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( xis, type, options ); } + + /** @deprecated {@link XMLInputStream} */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return org.apache.xmlbeans.XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, null ); } + + /** @deprecated {@link XMLInputStream} */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return org.apache.xmlbeans.XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, options ); } + + private Factory() { } // No instance of this class allowed + } +} diff --git a/xmlbeans/samples/Validation/src/org/apache/xmlbeans/samples/validation/todolist/TodolistDocument.java b/xmlbeans/samples/Validation/src/org/apache/xmlbeans/samples/validation/todolist/TodolistDocument.java new file mode 100644 index 000000000..a8c1d01c5 --- /dev/null +++ b/xmlbeans/samples/Validation/src/org/apache/xmlbeans/samples/validation/todolist/TodolistDocument.java @@ -0,0 +1,177 @@ +/* + * An XML document type. + * Localname: todolist + * Namespace: http://xmlbeans.apache.org/samples/validation/todolist + * Java type: org.apache.xmlbeans.samples.validation.todolist.TodolistDocument + * + * Automatically generated - do not modify. + */ +package org.apache.xmlbeans.samples.validation.todolist; + + +/** + * A document containing one todolist(@http://xmlbeans.apache.org/samples/validation/todolist) element. + * + * This is a complex type. + */ +public interface TodolistDocument extends org.apache.xmlbeans.XmlObject +{ + public static final org.apache.xmlbeans.SchemaType type = (org.apache.xmlbeans.SchemaType)schema.system.s59A663BF38731BA9F8026B121E40FDD3.TypeSystemHolder.typeSystem.resolveHandle("todolist637cdoctype"); + + /** + * Gets the "todolist" element + */ + org.apache.xmlbeans.samples.validation.todolist.TodolistDocument.Todolist getTodolist(); + + /** + * Sets the "todolist" element + */ + void setTodolist(org.apache.xmlbeans.samples.validation.todolist.TodolistDocument.Todolist todolist); + + /** + * Appends and returns a new empty "todolist" element + */ + org.apache.xmlbeans.samples.validation.todolist.TodolistDocument.Todolist addNewTodolist(); + + /** + * An XML todolist(@http://xmlbeans.apache.org/samples/validation/todolist). + * + * This is a complex type. + */ + public interface Todolist extends org.apache.xmlbeans.XmlObject + { + public static final org.apache.xmlbeans.SchemaType type = (org.apache.xmlbeans.SchemaType)schema.system.s59A663BF38731BA9F8026B121E40FDD3.TypeSystemHolder.typeSystem.resolveHandle("todolist39fcelemtype"); + + /** + * Gets array of all "item" elements + */ + org.apache.xmlbeans.samples.validation.todolist.ItemType[] getItemArray(); + + /** + * Gets ith "item" element + */ + org.apache.xmlbeans.samples.validation.todolist.ItemType getItemArray(int i); + + /** + * Returns number of "item" element + */ + int sizeOfItemArray(); + + /** + * Sets array of all "item" element + */ + void setItemArray(org.apache.xmlbeans.samples.validation.todolist.ItemType[] itemArray); + + /** + * Sets ith "item" element + */ + void setItemArray(int i, org.apache.xmlbeans.samples.validation.todolist.ItemType item); + + /** + * Inserts and returns a new empty value (as xml) as the ith "item" element + */ + org.apache.xmlbeans.samples.validation.todolist.ItemType insertNewItem(int i); + + /** + * Appends and returns a new empty value (as xml) as the last "item" element + */ + org.apache.xmlbeans.samples.validation.todolist.ItemType addNewItem(); + + /** + * Removes the ith "item" element + */ + void removeItem(int i); + + /** + * A factory class with static methods for creating instances + * of this type. + */ + + public static final class Factory + { + public static org.apache.xmlbeans.samples.validation.todolist.TodolistDocument.Todolist newInstance() { + return (org.apache.xmlbeans.samples.validation.todolist.TodolistDocument.Todolist) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().newInstance( type, null ); } + + public static org.apache.xmlbeans.samples.validation.todolist.TodolistDocument.Todolist newInstance(org.apache.xmlbeans.XmlOptions options) { + return (org.apache.xmlbeans.samples.validation.todolist.TodolistDocument.Todolist) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().newInstance( type, options ); } + + private Factory() { } // No instance of this class allowed + } + } + + /** + * A factory class with static methods for creating instances + * of this type. + */ + + public static final class Factory + { + public static org.apache.xmlbeans.samples.validation.todolist.TodolistDocument newInstance() { + return (org.apache.xmlbeans.samples.validation.todolist.TodolistDocument) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().newInstance( type, null ); } + + public static org.apache.xmlbeans.samples.validation.todolist.TodolistDocument newInstance(org.apache.xmlbeans.XmlOptions options) { + return (org.apache.xmlbeans.samples.validation.todolist.TodolistDocument) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().newInstance( type, options ); } + + /** @param xmlAsString the string value to parse */ + public static org.apache.xmlbeans.samples.validation.todolist.TodolistDocument parse(java.lang.String xmlAsString) throws org.apache.xmlbeans.XmlException { + return (org.apache.xmlbeans.samples.validation.todolist.TodolistDocument) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( xmlAsString, type, null ); } + + public static org.apache.xmlbeans.samples.validation.todolist.TodolistDocument parse(java.lang.String xmlAsString, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (org.apache.xmlbeans.samples.validation.todolist.TodolistDocument) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( xmlAsString, type, options ); } + + /** @param file the file from which to load an xml document */ + public static org.apache.xmlbeans.samples.validation.todolist.TodolistDocument parse(java.io.File file) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (org.apache.xmlbeans.samples.validation.todolist.TodolistDocument) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( file, type, null ); } + + public static org.apache.xmlbeans.samples.validation.todolist.TodolistDocument parse(java.io.File file, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (org.apache.xmlbeans.samples.validation.todolist.TodolistDocument) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( file, type, options ); } + + public static org.apache.xmlbeans.samples.validation.todolist.TodolistDocument parse(java.net.URL u) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (org.apache.xmlbeans.samples.validation.todolist.TodolistDocument) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( u, type, null ); } + + public static org.apache.xmlbeans.samples.validation.todolist.TodolistDocument parse(java.net.URL u, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (org.apache.xmlbeans.samples.validation.todolist.TodolistDocument) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( u, type, options ); } + + public static org.apache.xmlbeans.samples.validation.todolist.TodolistDocument parse(java.io.InputStream is) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (org.apache.xmlbeans.samples.validation.todolist.TodolistDocument) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( is, type, null ); } + + public static org.apache.xmlbeans.samples.validation.todolist.TodolistDocument parse(java.io.InputStream is, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (org.apache.xmlbeans.samples.validation.todolist.TodolistDocument) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( is, type, options ); } + + public static org.apache.xmlbeans.samples.validation.todolist.TodolistDocument parse(java.io.Reader r) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (org.apache.xmlbeans.samples.validation.todolist.TodolistDocument) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( r, type, null ); } + + public static org.apache.xmlbeans.samples.validation.todolist.TodolistDocument parse(java.io.Reader r, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (org.apache.xmlbeans.samples.validation.todolist.TodolistDocument) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( r, type, options ); } + + public static org.apache.xmlbeans.samples.validation.todolist.TodolistDocument parse(javax.xml.stream.XMLStreamReader sr) throws org.apache.xmlbeans.XmlException { + return (org.apache.xmlbeans.samples.validation.todolist.TodolistDocument) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( sr, type, null ); } + + public static org.apache.xmlbeans.samples.validation.todolist.TodolistDocument parse(javax.xml.stream.XMLStreamReader sr, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (org.apache.xmlbeans.samples.validation.todolist.TodolistDocument) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( sr, type, options ); } + + public static org.apache.xmlbeans.samples.validation.todolist.TodolistDocument parse(org.w3c.dom.Node node) throws org.apache.xmlbeans.XmlException { + return (org.apache.xmlbeans.samples.validation.todolist.TodolistDocument) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( node, type, null ); } + + public static org.apache.xmlbeans.samples.validation.todolist.TodolistDocument parse(org.w3c.dom.Node node, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (org.apache.xmlbeans.samples.validation.todolist.TodolistDocument) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( node, type, options ); } + + /** @deprecated {@link XMLInputStream} */ + public static org.apache.xmlbeans.samples.validation.todolist.TodolistDocument parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (org.apache.xmlbeans.samples.validation.todolist.TodolistDocument) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( xis, type, null ); } + + /** @deprecated {@link XMLInputStream} */ + public static org.apache.xmlbeans.samples.validation.todolist.TodolistDocument parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (org.apache.xmlbeans.samples.validation.todolist.TodolistDocument) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( xis, type, options ); } + + /** @deprecated {@link XMLInputStream} */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return org.apache.xmlbeans.XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, null ); } + + /** @deprecated {@link XMLInputStream} */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return org.apache.xmlbeans.XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, options ); } + + private Factory() { } // No instance of this class allowed + } +} diff --git a/xmlbeans/samples/Validation/src/org/apache/xmlbeans/samples/validation/todolist/impl/ActionTypeImpl.java b/xmlbeans/samples/Validation/src/org/apache/xmlbeans/samples/validation/todolist/impl/ActionTypeImpl.java new file mode 100644 index 000000000..8839b4ccb --- /dev/null +++ b/xmlbeans/samples/Validation/src/org/apache/xmlbeans/samples/validation/todolist/impl/ActionTypeImpl.java @@ -0,0 +1,26 @@ +/* + * XML Type: actionType + * Namespace: http://xmlbeans.apache.org/samples/validation/todolist + * Java type: org.apache.xmlbeans.samples.validation.todolist.ActionType + * + * Automatically generated - do not modify. + */ +package org.apache.xmlbeans.samples.validation.todolist.impl; +/** + * An XML actionType(@http://xmlbeans.apache.org/samples/validation/todolist). + * + * This is an atomic type that is a restriction of org.apache.xmlbeans.XmlString. + */ +public class ActionTypeImpl extends org.apache.xmlbeans.impl.values.JavaStringEnumerationHolderEx implements org.apache.xmlbeans.samples.validation.todolist.ActionType +{ + + public ActionTypeImpl(org.apache.xmlbeans.SchemaType sType) + { + super(sType, false); + } + + protected ActionTypeImpl(org.apache.xmlbeans.SchemaType sType, boolean b) + { + super(sType, b); + } +} diff --git a/xmlbeans/samples/Validation/src/org/apache/xmlbeans/samples/validation/todolist/impl/IdTypeImpl.java b/xmlbeans/samples/Validation/src/org/apache/xmlbeans/samples/validation/todolist/impl/IdTypeImpl.java new file mode 100644 index 000000000..f8a746f72 --- /dev/null +++ b/xmlbeans/samples/Validation/src/org/apache/xmlbeans/samples/validation/todolist/impl/IdTypeImpl.java @@ -0,0 +1,26 @@ +/* + * XML Type: idType + * Namespace: http://xmlbeans.apache.org/samples/validation/todolist + * Java type: org.apache.xmlbeans.samples.validation.todolist.IdType + * + * Automatically generated - do not modify. + */ +package org.apache.xmlbeans.samples.validation.todolist.impl; +/** + * An XML idType(@http://xmlbeans.apache.org/samples/validation/todolist). + * + * This is an atomic type that is a restriction of org.apache.xmlbeans.XmlInt. + */ +public class IdTypeImpl extends org.apache.xmlbeans.impl.values.JavaIntHolderEx implements org.apache.xmlbeans.samples.validation.todolist.IdType +{ + + public IdTypeImpl(org.apache.xmlbeans.SchemaType sType) + { + super(sType, false); + } + + protected IdTypeImpl(org.apache.xmlbeans.SchemaType sType, boolean b) + { + super(sType, b); + } +} diff --git a/xmlbeans/samples/Validation/src/org/apache/xmlbeans/samples/validation/todolist/impl/ItemTypeImpl.java b/xmlbeans/samples/Validation/src/org/apache/xmlbeans/samples/validation/todolist/impl/ItemTypeImpl.java new file mode 100644 index 000000000..c3a9f9939 --- /dev/null +++ b/xmlbeans/samples/Validation/src/org/apache/xmlbeans/samples/validation/todolist/impl/ItemTypeImpl.java @@ -0,0 +1,445 @@ +/* + * XML Type: itemType + * Namespace: http://xmlbeans.apache.org/samples/validation/todolist + * Java type: org.apache.xmlbeans.samples.validation.todolist.ItemType + * + * Automatically generated - do not modify. + */ +package org.apache.xmlbeans.samples.validation.todolist.impl; +/** + * An XML itemType(@http://xmlbeans.apache.org/samples/validation/todolist). + * + * This is a complex type. + */ +public class ItemTypeImpl extends org.apache.xmlbeans.impl.values.XmlComplexContentImpl implements org.apache.xmlbeans.samples.validation.todolist.ItemType +{ + + public ItemTypeImpl(org.apache.xmlbeans.SchemaType sType) + { + super(sType); + } + + private static final javax.xml.namespace.QName NAME$0 = + new javax.xml.namespace.QName("http://xmlbeans.apache.org/samples/validation/todolist", "name"); + private static final javax.xml.namespace.QName DESCRIPTION$2 = + new javax.xml.namespace.QName("http://xmlbeans.apache.org/samples/validation/todolist", "description"); + private static final javax.xml.namespace.QName DUEBY$4 = + new javax.xml.namespace.QName("http://xmlbeans.apache.org/samples/validation/todolist", "due_by"); + private static final javax.xml.namespace.QName ACTION$6 = + new javax.xml.namespace.QName("http://xmlbeans.apache.org/samples/validation/todolist", "action"); + private static final javax.xml.namespace.QName ID$8 = + new javax.xml.namespace.QName("", "id"); + + + /** + * Gets the "name" element + */ + public java.lang.String getName() + { + synchronized (monitor()) + { + check_orphaned(); + org.apache.xmlbeans.SimpleValue target = null; + target = (org.apache.xmlbeans.SimpleValue)get_store().find_element_user(NAME$0, 0); + if (target == null) + { + return null; + } + return target.getStringValue(); + } + } + + /** + * Gets (as xml) the "name" element + */ + public org.apache.xmlbeans.XmlString xgetName() + { + synchronized (monitor()) + { + check_orphaned(); + org.apache.xmlbeans.XmlString target = null; + target = (org.apache.xmlbeans.XmlString)get_store().find_element_user(NAME$0, 0); + return target; + } + } + + /** + * Sets the "name" element + */ + public void setName(java.lang.String name) + { + synchronized (monitor()) + { + check_orphaned(); + org.apache.xmlbeans.SimpleValue target = null; + target = (org.apache.xmlbeans.SimpleValue)get_store().find_element_user(NAME$0, 0); + if (target == null) + { + target = (org.apache.xmlbeans.SimpleValue)get_store().add_element_user(NAME$0); + } + target.setStringValue(name); + } + } + + /** + * Sets (as xml) the "name" element + */ + public void xsetName(org.apache.xmlbeans.XmlString name) + { + synchronized (monitor()) + { + check_orphaned(); + org.apache.xmlbeans.XmlString target = null; + target = (org.apache.xmlbeans.XmlString)get_store().find_element_user(NAME$0, 0); + if (target == null) + { + target = (org.apache.xmlbeans.XmlString)get_store().add_element_user(NAME$0); + } + target.set(name); + } + } + + /** + * Gets the "description" element + */ + public java.lang.String getDescription() + { + synchronized (monitor()) + { + check_orphaned(); + org.apache.xmlbeans.SimpleValue target = null; + target = (org.apache.xmlbeans.SimpleValue)get_store().find_element_user(DESCRIPTION$2, 0); + if (target == null) + { + return null; + } + return target.getStringValue(); + } + } + + /** + * Gets (as xml) the "description" element + */ + public org.apache.xmlbeans.XmlString xgetDescription() + { + synchronized (monitor()) + { + check_orphaned(); + org.apache.xmlbeans.XmlString target = null; + target = (org.apache.xmlbeans.XmlString)get_store().find_element_user(DESCRIPTION$2, 0); + return target; + } + } + + /** + * True if has "description" element + */ + public boolean isSetDescription() + { + synchronized (monitor()) + { + check_orphaned(); + return get_store().count_elements(DESCRIPTION$2) != 0; + } + } + + /** + * Sets the "description" element + */ + public void setDescription(java.lang.String description) + { + synchronized (monitor()) + { + check_orphaned(); + org.apache.xmlbeans.SimpleValue target = null; + target = (org.apache.xmlbeans.SimpleValue)get_store().find_element_user(DESCRIPTION$2, 0); + if (target == null) + { + target = (org.apache.xmlbeans.SimpleValue)get_store().add_element_user(DESCRIPTION$2); + } + target.setStringValue(description); + } + } + + /** + * Sets (as xml) the "description" element + */ + public void xsetDescription(org.apache.xmlbeans.XmlString description) + { + synchronized (monitor()) + { + check_orphaned(); + org.apache.xmlbeans.XmlString target = null; + target = (org.apache.xmlbeans.XmlString)get_store().find_element_user(DESCRIPTION$2, 0); + if (target == null) + { + target = (org.apache.xmlbeans.XmlString)get_store().add_element_user(DESCRIPTION$2); + } + target.set(description); + } + } + + /** + * Unsets the "description" element + */ + public void unsetDescription() + { + synchronized (monitor()) + { + check_orphaned(); + get_store().remove_element(DESCRIPTION$2, 0); + } + } + + /** + * Gets the "due_by" element + */ + public java.util.Calendar getDueBy() + { + synchronized (monitor()) + { + check_orphaned(); + org.apache.xmlbeans.SimpleValue target = null; + target = (org.apache.xmlbeans.SimpleValue)get_store().find_element_user(DUEBY$4, 0); + if (target == null) + { + return null; + } + return target.getCalendarValue(); + } + } + + /** + * Gets (as xml) the "due_by" element + */ + public org.apache.xmlbeans.XmlDateTime xgetDueBy() + { + synchronized (monitor()) + { + check_orphaned(); + org.apache.xmlbeans.XmlDateTime target = null; + target = (org.apache.xmlbeans.XmlDateTime)get_store().find_element_user(DUEBY$4, 0); + return target; + } + } + + /** + * True if has "due_by" element + */ + public boolean isSetDueBy() + { + synchronized (monitor()) + { + check_orphaned(); + return get_store().count_elements(DUEBY$4) != 0; + } + } + + /** + * Sets the "due_by" element + */ + public void setDueBy(java.util.Calendar dueBy) + { + synchronized (monitor()) + { + check_orphaned(); + org.apache.xmlbeans.SimpleValue target = null; + target = (org.apache.xmlbeans.SimpleValue)get_store().find_element_user(DUEBY$4, 0); + if (target == null) + { + target = (org.apache.xmlbeans.SimpleValue)get_store().add_element_user(DUEBY$4); + } + target.setCalendarValue(dueBy); + } + } + + /** + * Sets (as xml) the "due_by" element + */ + public void xsetDueBy(org.apache.xmlbeans.XmlDateTime dueBy) + { + synchronized (monitor()) + { + check_orphaned(); + org.apache.xmlbeans.XmlDateTime target = null; + target = (org.apache.xmlbeans.XmlDateTime)get_store().find_element_user(DUEBY$4, 0); + if (target == null) + { + target = (org.apache.xmlbeans.XmlDateTime)get_store().add_element_user(DUEBY$4); + } + target.set(dueBy); + } + } + + /** + * Unsets the "due_by" element + */ + public void unsetDueBy() + { + synchronized (monitor()) + { + check_orphaned(); + get_store().remove_element(DUEBY$4, 0); + } + } + + /** + * Gets the "action" element + */ + public org.apache.xmlbeans.samples.validation.todolist.ActionType.Enum getAction() + { + synchronized (monitor()) + { + check_orphaned(); + org.apache.xmlbeans.SimpleValue target = null; + target = (org.apache.xmlbeans.SimpleValue)get_store().find_element_user(ACTION$6, 0); + if (target == null) + { + return null; + } + return (org.apache.xmlbeans.samples.validation.todolist.ActionType.Enum)target.getEnumValue(); + } + } + + /** + * Gets (as xml) the "action" element + */ + public org.apache.xmlbeans.samples.validation.todolist.ActionType xgetAction() + { + synchronized (monitor()) + { + check_orphaned(); + org.apache.xmlbeans.samples.validation.todolist.ActionType target = null; + target = (org.apache.xmlbeans.samples.validation.todolist.ActionType)get_store().find_element_user(ACTION$6, 0); + return target; + } + } + + /** + * Sets the "action" element + */ + public void setAction(org.apache.xmlbeans.samples.validation.todolist.ActionType.Enum action) + { + synchronized (monitor()) + { + check_orphaned(); + org.apache.xmlbeans.SimpleValue target = null; + target = (org.apache.xmlbeans.SimpleValue)get_store().find_element_user(ACTION$6, 0); + if (target == null) + { + target = (org.apache.xmlbeans.SimpleValue)get_store().add_element_user(ACTION$6); + } + target.setEnumValue(action); + } + } + + /** + * Sets (as xml) the "action" element + */ + public void xsetAction(org.apache.xmlbeans.samples.validation.todolist.ActionType action) + { + synchronized (monitor()) + { + check_orphaned(); + org.apache.xmlbeans.samples.validation.todolist.ActionType target = null; + target = (org.apache.xmlbeans.samples.validation.todolist.ActionType)get_store().find_element_user(ACTION$6, 0); + if (target == null) + { + target = (org.apache.xmlbeans.samples.validation.todolist.ActionType)get_store().add_element_user(ACTION$6); + } + target.set(action); + } + } + + /** + * Gets the "id" attribute + */ + public int getId() + { + synchronized (monitor()) + { + check_orphaned(); + org.apache.xmlbeans.SimpleValue target = null; + target = (org.apache.xmlbeans.SimpleValue)get_store().find_attribute_user(ID$8); + if (target == null) + { + return 0; + } + return target.getIntValue(); + } + } + + /** + * Gets (as xml) the "id" attribute + */ + public org.apache.xmlbeans.samples.validation.todolist.IdType xgetId() + { + synchronized (monitor()) + { + check_orphaned(); + org.apache.xmlbeans.samples.validation.todolist.IdType target = null; + target = (org.apache.xmlbeans.samples.validation.todolist.IdType)get_store().find_attribute_user(ID$8); + return target; + } + } + + /** + * True if has "id" attribute + */ + public boolean isSetId() + { + synchronized (monitor()) + { + check_orphaned(); + return get_store().find_attribute_user(ID$8) != null; + } + } + + /** + * Sets the "id" attribute + */ + public void setId(int id) + { + synchronized (monitor()) + { + check_orphaned(); + org.apache.xmlbeans.SimpleValue target = null; + target = (org.apache.xmlbeans.SimpleValue)get_store().find_attribute_user(ID$8); + if (target == null) + { + target = (org.apache.xmlbeans.SimpleValue)get_store().add_attribute_user(ID$8); + } + target.setIntValue(id); + } + } + + /** + * Sets (as xml) the "id" attribute + */ + public void xsetId(org.apache.xmlbeans.samples.validation.todolist.IdType id) + { + synchronized (monitor()) + { + check_orphaned(); + org.apache.xmlbeans.samples.validation.todolist.IdType target = null; + target = (org.apache.xmlbeans.samples.validation.todolist.IdType)get_store().find_attribute_user(ID$8); + if (target == null) + { + target = (org.apache.xmlbeans.samples.validation.todolist.IdType)get_store().add_attribute_user(ID$8); + } + target.set(id); + } + } + + /** + * Unsets the "id" attribute + */ + public void unsetId() + { + synchronized (monitor()) + { + check_orphaned(); + get_store().remove_attribute(ID$8); + } + } +} diff --git a/xmlbeans/samples/Validation/src/org/apache/xmlbeans/samples/validation/todolist/impl/NameTypeImpl.java b/xmlbeans/samples/Validation/src/org/apache/xmlbeans/samples/validation/todolist/impl/NameTypeImpl.java new file mode 100644 index 000000000..3afa7eb06 --- /dev/null +++ b/xmlbeans/samples/Validation/src/org/apache/xmlbeans/samples/validation/todolist/impl/NameTypeImpl.java @@ -0,0 +1,26 @@ +/* + * XML Type: nameType + * Namespace: http://xmlbeans.apache.org/samples/validation/todolist + * Java type: org.apache.xmlbeans.samples.validation.todolist.NameType + * + * Automatically generated - do not modify. + */ +package org.apache.xmlbeans.samples.validation.todolist.impl; +/** + * An XML nameType(@http://xmlbeans.apache.org/samples/validation/todolist). + * + * This is an atomic type that is a restriction of org.apache.xmlbeans.XmlString. + */ +public class NameTypeImpl extends org.apache.xmlbeans.impl.values.JavaStringHolderEx implements org.apache.xmlbeans.samples.validation.todolist.NameType +{ + + public NameTypeImpl(org.apache.xmlbeans.SchemaType sType) + { + super(sType, false); + } + + protected NameTypeImpl(org.apache.xmlbeans.SchemaType sType, boolean b) + { + super(sType, b); + } +} diff --git a/xmlbeans/samples/Validation/src/org/apache/xmlbeans/samples/validation/todolist/impl/TodolistDocumentImpl.java b/xmlbeans/samples/Validation/src/org/apache/xmlbeans/samples/validation/todolist/impl/TodolistDocumentImpl.java new file mode 100644 index 000000000..39ae0a6c1 --- /dev/null +++ b/xmlbeans/samples/Validation/src/org/apache/xmlbeans/samples/validation/todolist/impl/TodolistDocumentImpl.java @@ -0,0 +1,209 @@ +/* + * An XML document type. + * Localname: todolist + * Namespace: http://xmlbeans.apache.org/samples/validation/todolist + * Java type: org.apache.xmlbeans.samples.validation.todolist.TodolistDocument + * + * Automatically generated - do not modify. + */ +package org.apache.xmlbeans.samples.validation.todolist.impl; +/** + * A document containing one todolist(@http://xmlbeans.apache.org/samples/validation/todolist) element. + * + * This is a complex type. + */ +public class TodolistDocumentImpl extends org.apache.xmlbeans.impl.values.XmlComplexContentImpl implements org.apache.xmlbeans.samples.validation.todolist.TodolistDocument +{ + + public TodolistDocumentImpl(org.apache.xmlbeans.SchemaType sType) + { + super(sType); + } + + private static final javax.xml.namespace.QName TODOLIST$0 = + new javax.xml.namespace.QName("http://xmlbeans.apache.org/samples/validation/todolist", "todolist"); + + + /** + * Gets the "todolist" element + */ + public org.apache.xmlbeans.samples.validation.todolist.TodolistDocument.Todolist getTodolist() + { + synchronized (monitor()) + { + check_orphaned(); + org.apache.xmlbeans.samples.validation.todolist.TodolistDocument.Todolist target = null; + target = (org.apache.xmlbeans.samples.validation.todolist.TodolistDocument.Todolist)get_store().find_element_user(TODOLIST$0, 0); + if (target == null) + { + return null; + } + return target; + } + } + + /** + * Sets the "todolist" element + */ + public void setTodolist(org.apache.xmlbeans.samples.validation.todolist.TodolistDocument.Todolist todolist) + { + synchronized (monitor()) + { + check_orphaned(); + org.apache.xmlbeans.samples.validation.todolist.TodolistDocument.Todolist target = null; + target = (org.apache.xmlbeans.samples.validation.todolist.TodolistDocument.Todolist)get_store().find_element_user(TODOLIST$0, 0); + if (target == null) + { + target = (org.apache.xmlbeans.samples.validation.todolist.TodolistDocument.Todolist)get_store().add_element_user(TODOLIST$0); + } + target.set(todolist); + } + } + + /** + * Appends and returns a new empty "todolist" element + */ + public org.apache.xmlbeans.samples.validation.todolist.TodolistDocument.Todolist addNewTodolist() + { + synchronized (monitor()) + { + check_orphaned(); + org.apache.xmlbeans.samples.validation.todolist.TodolistDocument.Todolist target = null; + target = (org.apache.xmlbeans.samples.validation.todolist.TodolistDocument.Todolist)get_store().add_element_user(TODOLIST$0); + return target; + } + } + /** + * An XML todolist(@http://xmlbeans.apache.org/samples/validation/todolist). + * + * This is a complex type. + */ + public static class TodolistImpl extends org.apache.xmlbeans.impl.values.XmlComplexContentImpl implements org.apache.xmlbeans.samples.validation.todolist.TodolistDocument.Todolist + { + + public TodolistImpl(org.apache.xmlbeans.SchemaType sType) + { + super(sType); + } + + private static final javax.xml.namespace.QName ITEM$0 = + new javax.xml.namespace.QName("http://xmlbeans.apache.org/samples/validation/todolist", "item"); + + + /** + * Gets array of all "item" elements + */ + public org.apache.xmlbeans.samples.validation.todolist.ItemType[] getItemArray() + { + synchronized (monitor()) + { + check_orphaned(); + java.util.List targetList = new java.util.ArrayList(); + get_store().find_all_element_users(ITEM$0, targetList); + org.apache.xmlbeans.samples.validation.todolist.ItemType[] result = new org.apache.xmlbeans.samples.validation.todolist.ItemType[targetList.size()]; + targetList.toArray(result); + return result; + } + } + + /** + * Gets ith "item" element + */ + public org.apache.xmlbeans.samples.validation.todolist.ItemType getItemArray(int i) + { + synchronized (monitor()) + { + check_orphaned(); + org.apache.xmlbeans.samples.validation.todolist.ItemType target = null; + target = (org.apache.xmlbeans.samples.validation.todolist.ItemType)get_store().find_element_user(ITEM$0, i); + if (target == null) + { + throw new IndexOutOfBoundsException(); + } + return target; + } + } + + /** + * Returns number of "item" element + */ + public int sizeOfItemArray() + { + synchronized (monitor()) + { + check_orphaned(); + return get_store().count_elements(ITEM$0); + } + } + + /** + * Sets array of all "item" element + */ + public void setItemArray(org.apache.xmlbeans.samples.validation.todolist.ItemType[] itemArray) + { + synchronized (monitor()) + { + check_orphaned(); + arraySetterHelper(itemArray, ITEM$0); + } + } + + /** + * Sets ith "item" element + */ + public void setItemArray(int i, org.apache.xmlbeans.samples.validation.todolist.ItemType item) + { + synchronized (monitor()) + { + check_orphaned(); + org.apache.xmlbeans.samples.validation.todolist.ItemType target = null; + target = (org.apache.xmlbeans.samples.validation.todolist.ItemType)get_store().find_element_user(ITEM$0, i); + if (target == null) + { + throw new IndexOutOfBoundsException(); + } + target.set(item); + } + } + + /** + * Inserts and returns a new empty value (as xml) as the ith "item" element + */ + public org.apache.xmlbeans.samples.validation.todolist.ItemType insertNewItem(int i) + { + synchronized (monitor()) + { + check_orphaned(); + org.apache.xmlbeans.samples.validation.todolist.ItemType target = null; + target = (org.apache.xmlbeans.samples.validation.todolist.ItemType)get_store().insert_element_user(ITEM$0, i); + return target; + } + } + + /** + * Appends and returns a new empty value (as xml) as the last "item" element + */ + public org.apache.xmlbeans.samples.validation.todolist.ItemType addNewItem() + { + synchronized (monitor()) + { + check_orphaned(); + org.apache.xmlbeans.samples.validation.todolist.ItemType target = null; + target = (org.apache.xmlbeans.samples.validation.todolist.ItemType)get_store().add_element_user(ITEM$0); + return target; + } + } + + /** + * Removes the ith "item" element + */ + public void removeItem(int i) + { + synchronized (monitor()) + { + check_orphaned(); + get_store().remove_element(ITEM$0, i); + } + } + } +} diff --git a/xmlbeans/samples/Validation/xml/todolist.xml b/xmlbeans/samples/Validation/xml/todolist.xml new file mode 100644 index 000000000..79583d9fa --- /dev/null +++ b/xmlbeans/samples/Validation/xml/todolist.xml @@ -0,0 +1,36 @@ + + + + + Buy a south Pacific island. + Contingent on inheriting lots of money. + 2005-05-01T23:36:28 + someday_maybe_defer + + + Get that new PowerBook I've been eyeing. + Resulting productivity increase will be exponential! + 2005-05-01T23:36:28 + do + + + Clean the garage. + Remove at least enough junk so that my bicycle fits. + 2005-05-30T23:36:28 + delegate + + diff --git a/xmlbeans/samples/XQueryXPath/README.txt b/xmlbeans/samples/XQueryXPath/README.txt new file mode 100644 index 000000000..418e48255 --- /dev/null +++ b/xmlbeans/samples/XQueryXPath/README.txt @@ -0,0 +1,48 @@ +Sample: XQueryXPath +Author: Steven Traut (straut@bea.com) +Last Updated: May 14, 2008 + +Versions: + xmlbeans-v1 1.0.3 + xmlbeans-v2 2.4.0 + +----------------------------------------------------------------------------- + +This sample illustrates how you can use the XMLBeans API to execute +XPath and XQuery expressions. The sample illustrates these features: + +- Using the XmlObject.selectPath and XmlCursor.selectPath methods +to execute XPath expressions. The selectPath method's results (if +any) are always chunks of the instance queried against. In other +words, changes to query results change the original instance. +However, you work with results differently depending on whether +selectPath was called from an XmlObject or XmlCursor instance. See +the SelectPath class for more information. + +- Using the XmlObject.execQuery and XmlCursor.execQuery methods +to execute XQuery expressions. Results of these queries are copied +into new XML, meaning that changes to results do not change the +original instance. Here again, you work with results differently +depending how which method you used to query. See the ExecQuery +class for more information. + +A note about dependencies. Very simple XPath expressions -- e.g., +expressions without predicates or function calls -- require only +the xbean.jar on your class path. More complex XPath expressions +and XQuery expressions require an XPath/XQuery engine, such as +Saxon. XMLBeans 2.4.0 supports the use of Saxon 9. Two Saxon jars, +saxon9.jar and saxon9-dom.jar, as well as xbean_xpath.jar, are +required on the classpath for code in this sample to run. +These jars are created in the build/lib directory if you build +XMLBeans from Apache source. + +To try out this sample: + +1. Set XMLBEANS_HOME in your environment +2. Ant must be on your PATH +3. xbean_xpath.jar, saxon9.jar, and saxon9-dom.jar must be on your + classpath. + These files are created in the build/lib directory when you + build XMLBeans from source. +4. To compile the schemas and sample source, run "ant build" +5. To execute the sample, run "ant run" diff --git a/xmlbeans/samples/XQueryXPath/build.xml b/xmlbeans/samples/XQueryXPath/build.xml new file mode 100644 index 000000000..c9cf79236 --- /dev/null +++ b/xmlbeans/samples/XQueryXPath/build.xml @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/xmlbeans/samples/XQueryXPath/schemas/employeeschema.xsd b/xmlbeans/samples/XQueryXPath/schemas/employeeschema.xsd new file mode 100644 index 000000000..cae8bf7ae --- /dev/null +++ b/xmlbeans/samples/XQueryXPath/schemas/employeeschema.xsd @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/xmlbeans/samples/XQueryXPath/src/org/apache/xmlbeans/samples/xquery/ExecQuery.java b/xmlbeans/samples/XQueryXPath/src/org/apache/xmlbeans/samples/xquery/ExecQuery.java new file mode 100644 index 000000000..b307ac2ba --- /dev/null +++ b/xmlbeans/samples/XQueryXPath/src/org/apache/xmlbeans/samples/xquery/ExecQuery.java @@ -0,0 +1,154 @@ +/* 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.samples.xquery; + +import org.apache.xmlbeans.XmlCursor; +import org.apache.xmlbeans.XmlObject; + +/** + * This class demonstrates how to use the execQuery method to execute XQuery + * expressions. Compare the code here with the code in the SelectPath class. + * That class uses the selectPath method to execute XPath expressions. + *

    + * You can call the execQuery method from either an XmlObject or XmlCursor + * instance. Calling from XmlObject returns an XmlObject array. Calling + * from XmlCursor returns a new XmlCursor instance positioned at the root + * of a fragment containing copies of the XML queried against. Results of the + * query (if any) are sibling children of the fragment's root. + */ +public class ExecQuery +{ + final static String m_namespaceDeclaration = + "declare namespace xq='http://xmlbeans.apache.org/samples/xquery/employees';"; + + /** + * Uses XQuery to retrieve work elements from the incoming XML, then + * changes the number in the results. + * + * This method demonstrates the following characteristics of the execQuery method: + * + * - it supports XQuery. + * - the XML it returns is a copy of the XML queried against; contrast this with + * the selectPath method, which returns a portion of the original document. + * Changes to returned XML do not impact the XML queried against. + * - execQuery called from an XmlCursor returns a cursor positioned at + * the STARTDOC token of a new XML fragment. Contrast this with the + * XmlCursor.selectPath method, which stores results as "selections" in + * the cursor used to execute the query. + * + * @param empDoc The incoming XML. + * @return true if the XPath expression returned results; + * otherwise, false. + */ + public boolean updateWorkPhone(XmlObject empDoc) + { + boolean hasResults = false; + + // A cursor instance to query with. + XmlCursor empCursor = empDoc.newCursor(); + + // The expression: Get the elements with elements whose + // value is "WA". + String queryExpression = + "for $e in $this/xq:employees/xq:employee " + + "let $s := $e/xq:address/xq:state " + + "where $s = 'WA' " + + "return $e//xq:phone[@location='work']"; + + // Execute the query. Results, if any, will be available at + // the position of the resultCursor in a new XML document. + XmlCursor resultCursor = + empCursor.execQuery(m_namespaceDeclaration + queryExpression); + + System.out.println("The query results, element copies made " + + "from the received document: \n"); + System.out.println(resultCursor.getObject().toString() + "\n"); + + // If there are results, the results will be children of the fragment root + // where the new cursor is positioned. This statement tests for children + // and moves the cursor if to the first if it exists. + if (resultCursor.toFirstChild()) + { + hasResults = true; + // Use the cursor to loop through the results, printing each sibling + // element returned by the query. + int i = 0; + do + { + // Change the phone numbers. + XmlCursor editCursor = resultCursor.newCursor(); + editCursor.toLastAttribute(); + editCursor.toNextToken(); + editCursor.removeXml(); + editCursor.insertChars("(206)555-1234"); + } while (resultCursor.toNextSibling()); + + resultCursor.toStartDoc(); + System.out.println("The query results after changes: \n"); + System.out.println(resultCursor.getObject().toString() + "\n"); + + System.out.println("The received document -- note that it is unchanged. " + + "Changes were made to the copy created by the execQuery method. \n"); + System.out.println(empDoc + "\n"); + } + return hasResults; + } + + /** + * Uses XQuery to retrieve work elements from the incoming XML, adding the + * elements as children to a element. + * + * This method demonstrates the following characteristics of the execQuery method: + * + * - it supports XQuery. + * - execQuery called from an XmlObject returns an array of XmlObject instances. + * These are bound to copies of the received XML. + * + * @param empDoc The incoming XML. + * @return true if the XPath expression returned results; + * otherwise, false. + */ + public boolean collectZips(XmlObject empDoc) + { + // The query is designed to return results, so return + // true if it does. + boolean hasResults = false; + + // The expression: Get the elements and return them as children + // of a new element. + String queryExpression = + "let $e := $this/xq:employees " + + "return " + + " " + + "{for $z in $e/xq:employee/xq:address/xq:zip " + + "return $z} " + + ""; + + // Execute the query. Results will be copies of the XML queried against, + // stored as members of an XmlObject array. + XmlObject[] results = + empDoc.execQuery(m_namespaceDeclaration + queryExpression); + + // Print the results. + if (results.length > 0) + { + hasResults = true; + System.out.println("The query results: \n"); + System.out.println(results[0].toString() + "\n"); + } + return hasResults; + } +} diff --git a/xmlbeans/samples/XQueryXPath/src/org/apache/xmlbeans/samples/xquery/SelectPath.java b/xmlbeans/samples/XQueryXPath/src/org/apache/xmlbeans/samples/xquery/SelectPath.java new file mode 100644 index 000000000..a72bf4340 --- /dev/null +++ b/xmlbeans/samples/XQueryXPath/src/org/apache/xmlbeans/samples/xquery/SelectPath.java @@ -0,0 +1,172 @@ +/* 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.samples.xquery; + +import org.apache.xmlbeans.XmlCursor; +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.XmlException; +import org.apache.xmlbeans.samples.xquery.employees.PhoneType; + +/** + * This class demonstrates how to use the selectPath method to execute XPath + * expressions. Compare the code here with the code in the ExecQuery class. + * That class uses the execQuery method to execute XQuery expressions. + *

    + * You can call the selectPath method from either an XmlObject or XmlCursor + * instance. Calling from XmlObject returns an XmlObject array. Calling + * from XmlCursor returns void, and you use methods of the cursor to + * navigate among returned "selections". + */ +public class SelectPath +{ + // Declare a namespace corresponding to the namespace declared in the XML + // instance. The string here will be used as part of the XPath expression to + // ensure that the query finds namespace-qualified elements in the XML. + final static String m_namespaceDeclaration = + "declare namespace xq='http://xmlbeans.apache.org/samples/xquery/employees';"; + + /** + * Prints the XML bound to empDoc, uses XPath to + * retrieve elements containing work phone numbers, changes the numbers + * to another number, then prints the XML again to display the changes. + * + * This method demonstrates the following characteristics of the selectPath method: + * + * - it supports expressions that include predicates + * - the XML it returns is the XML queried against -- not a copy, as with results + * returned via execQuery methods and XQuery. Changes to this XML update + * the XML queried against. + * - selectPath called from an XMLBean type (instead of a cursor) returns an + * array of results (if any). These results can be cast to a matching type + * generated from schema. + * + * @param empDoc The incoming XML. + * @return true if the XPath expression returned results; + * otherwise, false. + */ + public boolean updateWorkPhone(XmlObject empDoc) + { + boolean hasResults = false; + + // Print the XML received. + System.out.println("XML as received by updateWorkPhone method: \n\n" + + empDoc.toString()); + + // Create a variable with the query expression. + String pathExpression = + "$this/xq:employees/xq:employee/xq:phone[@location='work']"; + + // Execute the query. + XmlObject[] results = empDoc.selectPath(m_namespaceDeclaration + + pathExpression); + if (results.length > 0) + { + hasResults = true; + + // elements returned from the expression will conform to the + // schema, so bind them to the appropriate XMLBeans type generated + // from the schema. + PhoneType[] phones = (PhoneType[]) results; + + // Change all the work phone numbers to the same number. + for (int i = 0; i < phones.length; i++) + { + phones[i].setStringValue("(206)555-1234"); + } + // Print the XML with updates. + System.out.println("\nXML as updated by updateWorkPhone method (each work \n" + + "phone number has been changed to the same number): \n\n" + + empDoc.toString() + "\n"); + } + return hasResults; + } + + /** + * Uses the XPath text() function to get values from + * elements in received XML, then collects those values as the value of a + * element created here. + *

    + * Demonstrates the following characteristics of the selectPath method: + *

    + * - It supports expressions that include XPath function calls. + * - selectPath called from an XmlCursor instance (instead of an XMLBeans + * type) places results (if any) into the cursor's selection set. + * + * @param empDoc The incoming XML. + * @return true if the XPath expression returned results; + * otherwise, false. + */ + public boolean collectNames(XmlObject empDoc) + { + boolean hasResults = false; + + // Create a cursor with which to execute query expressions. The cursor + // is inserted at the very beginning of the incoming XML, then moved to + // the first element's START token. + XmlCursor pathCursor = empDoc.newCursor(); + pathCursor.toFirstChild(); + + // Execute the path expression, qualifying it with the namespace + // declaration. + pathCursor.selectPath(m_namespaceDeclaration + + "$this//xq:employee/xq:name/text()"); + + // If there are results, then go ahead and do stuff. + if (pathCursor.getSelectionCount() > 0) + { + hasResults = true; + + // Create a new element into which names from the XML + // will be copied. Note that this element is in the default + // namespace; it's not part of the schema. + XmlObject namesElement = null; + try + { + namesElement = XmlObject.Factory.parse(""); + } catch (XmlException e) + { + e.printStackTrace(); + } + + // Add a cursor the new element and put it between its START and END + // tokens, where new values can be inserted. + XmlCursor namesCursor = namesElement.newCursor(); + namesCursor.toFirstContentToken(); + namesCursor.toEndToken(); + + // Loop through the selections, appending the incoming element's + // value to the new element's value. (Of course, this could have + // been done with a StringBuffer, but that wouldn't show the cursor in + // use.) + while (pathCursor.toNextSelection()) + { + namesCursor.insertChars(pathCursor.getTextValue()); + if (pathCursor.hasNextSelection()) + { + namesCursor.insertChars(", "); + } + } + // Dispose of the cursors now that they're not needed. + pathCursor.dispose(); + namesCursor.dispose(); + + // Print the new element. + System.out.println("\nNames collected by collectNames method: \n\n" + + namesElement + "\n"); + } + return hasResults; + } +} diff --git a/xmlbeans/samples/XQueryXPath/src/org/apache/xmlbeans/samples/xquery/XQueryXPath.java b/xmlbeans/samples/XQueryXPath/src/org/apache/xmlbeans/samples/xquery/XQueryXPath.java new file mode 100644 index 000000000..a75521f78 --- /dev/null +++ b/xmlbeans/samples/XQueryXPath/src/org/apache/xmlbeans/samples/xquery/XQueryXPath.java @@ -0,0 +1,117 @@ +/* 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.samples.xquery; + +import org.apache.xmlbeans.XmlException; +import org.apache.xmlbeans.XmlObject; + +import java.io.File; +import java.io.IOException; + +/** + * A sample to XMLBeans API features for executing XPath and XQuery + * expressions. The sample illustrates these features: + * + * - Using the XmlObject.selectPath and XmlCursor.selectPath methods + * to execute XPath expressions. The selectPath method's results (if + * any) are always chunks of the instance queried against. In other + * words, changes to query results change the original instance. + * However, you work with results differently depending on whether + * selectPath was called from an XmlObject or XmlCursor instance. See + * the SelectPath class for more information. + * - Using the XmlObject.execQuery and XmlCursor.execQuery methods + * to execute XQuery expressions. Results of these queries are copied + * into new XML, meaning that changes to results do not change the + * original instance. Here again, you work with results differently + * depending how which method you used to query. See the ExecQuery + * class for more information. + */ +public class XQueryXPath +{ + /** + * Receives an employees list XML instance, passing the instance to + * methods that execute queries against it. + * + * @param args An array in which the first item is a + * path to the XML instance file. + */ + public static void main(String[] args) + throws org.apache.xmlbeans.XmlException, java.io.IOException + { + XQueryXPath sample = new XQueryXPath(); + sample.executeQueries(args); + } + + /** + * Returns true if all of the sample methods returned true + * (i.e., their query expressions returned results). + * + * @param args An array in which the first item is a + * path to the XML instance file. + * @return true if all of the sample methods returned true + * (i.e., their query expressions returned results); otherwise, + * false. + */ + public boolean executeQueries(String[] args) + { + XmlObject xml = this.parseXml(args[0]); + + // Execute the XQuery samples. + ExecQuery xquerySample = new ExecQuery(); + + System.out.println("Running ExecQuery.selectEmpsByStateCursor\n"); + boolean xqWorkPhoneSuccessful = xquerySample.updateWorkPhone(xml); + + System.out.println("Running ExecQuery.selectZipsNewDocCursor\n"); + boolean xqCollectZips = xquerySample.collectZips(xml); + + // Execute the XPath samples. + SelectPath xpathSample = new SelectPath(); + + System.out.println("Running SelectPath.updateWorkPhone \n"); + boolean xpWorkPhoneSuccessful = xpathSample.updateWorkPhone(xml); + + System.out.println("Running SelectPath.collectNames \n"); + boolean xpCollectNames = xpathSample.collectNames(xml); + + return (xqWorkPhoneSuccessful && xqCollectZips + && xpWorkPhoneSuccessful && xpCollectNames) ? true : false; + } + + /** + *

    Creates a File from the XML path provided in main arguments, then + * parses the file's contents into a type generated from schema.

    + + * @param xmlFilePath A path to XML based on the schema in inventory.xsd. + * @return An instance of a generated schema type that contains the parsed + * XML. + */ + public XmlObject parseXml(String xmlFilePath) + { + File xmlFile = new File(xmlFilePath); + XmlObject xml = null; + try + { + xml = XmlObject.Factory.parse(xmlFile); + } catch (XmlException e) + { + e.printStackTrace(); + } catch (IOException e) + { + e.printStackTrace(); + } + return xml; + } +} diff --git a/xmlbeans/samples/XQueryXPath/src/org/apache/xmlbeans/samples/xquery/XQueryXPathTest.java b/xmlbeans/samples/XQueryXPath/src/org/apache/xmlbeans/samples/xquery/XQueryXPathTest.java new file mode 100644 index 000000000..0dabf731a --- /dev/null +++ b/xmlbeans/samples/XQueryXPath/src/org/apache/xmlbeans/samples/xquery/XQueryXPathTest.java @@ -0,0 +1,32 @@ +/* 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.samples.xquery; + +/** + * A class with which to test the XQueryXPath sample. + */ +public class XQueryXPathTest +{ + /** + * Tests the XQueryXPath sample. + */ + public static void main(String[] args) + throws org.apache.xmlbeans.XmlException, java.io.IOException + { + XQueryXPath sample = new XQueryXPath(); + boolean queriesSuccessful = sample.executeQueries(args); + assert queriesSuccessful; + } +} diff --git a/xmlbeans/samples/XQueryXPath/xml/employees.xml b/xmlbeans/samples/XQueryXPath/xml/employees.xml new file mode 100644 index 000000000..5aee4fe16 --- /dev/null +++ b/xmlbeans/samples/XQueryXPath/xml/employees.xml @@ -0,0 +1,71 @@ + + + + Fred Jones +
    + 900 Aurora Ave. + Seattle + WA + 98115 +
    +
    + 2011 152nd Avenue NE + Redmond + WA + 98052 +
    + (425)555-5665 + (206)555-5555 + (206)555-4321 +
    + + Sally Smith +
    + 1430 Oak Place + Salem + OR + 97125 +
    +
    + 765 Main St. + Keizer + OR + 97303 +
    + (503)555-3856 + (503)555-6951 + (503)555-5152 +
    + + Gladys Kravitz +
    + 1313 Mockingbird Lane + Seattle + WA + 98115 +
    +
    + 2011 152nd Avenue NE + Redmond + WA + 98052 +
    + (425)555-6897 + (206)555-6594 + (206)555-7894 +
    +
    diff --git a/xmlbeans/samples/XmlSort/README.txt b/xmlbeans/samples/XmlSort/README.txt new file mode 100644 index 000000000..157701fae --- /dev/null +++ b/xmlbeans/samples/XmlSort/README.txt @@ -0,0 +1,51 @@ +Sample: XmlSort +Category: cursor sample +Author: Radu Preotiuc-Pietro +Last Updated: Feb. 3, 2009 + +Versions: + xmlbeans-v2 + +----------------------------------------------------------------------------- + +This is another practical sample on how to use XmlCursor. It sorts all the +children elements of a given parent in (reverse) alphabetical order. It uses +insertion sort to minimize the number of swaps (and because it is stable) and +XmlCursor.moveXml() to perform the swaps. + +The algorithm works by conceptually separating the list of children into a +sorted list and an unsorted list. Each list is represented by an XmlCursor +positioned at the head of the list. At the beginning, the sorted list +contains the first child and the unsorted list contains the rest of the +children (if any). Then, each of the elements in the unsorted list is +inserted in the already-sorted list in its appropriate place using the +moveXml() method (the text following each element is then moved along with +the element). + +To build this sample, call 'ant build' and to run it against the provided +sample XML file, call 'ant run'. + +To run the sample from the command line using 'java', provide as the first +parameter the name of the XML file to process and as the second argument +(optional), an XPath pointing to the element whose children are to be sorted +(by default, the children of the root element are sorted). The XPath must +evaluate to an element and one element only, otherwise an error will be +reported. The console output will mirror the input file, with the children +of the given element sorted in ascending alphabetical order. + +This sample can also be used as a library routine by calling its main +static method: XmlSort.sort(XmlObject, Comparator). The XmlObject whose +children are to be sorted is passed directly as a parameter and the +Comparator defines the order in which the elements are to be sorted. The +parameters to the compare() method are two XmlCursors pointing to the +two elements to be compared. The inner class XmlSort.QNameComparator +implements comparison based on the QName of the elements (ascending or +descending) but custom comparison methods (based for instance on the +value of some attribute etc) can also be passed in. + +To try out this sample: + +1. Set XMLBEANS_HOME in your environment +2. Ant must be on your PATH +3. To compile the sample source, run "ant build" +4. To execute the sample, run "ant run" diff --git a/xmlbeans/samples/XmlSort/build.xml b/xmlbeans/samples/XmlSort/build.xml new file mode 100644 index 000000000..852748bcf --- /dev/null +++ b/xmlbeans/samples/XmlSort/build.xml @@ -0,0 +1,96 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/xmlbeans/samples/XmlSort/src/org/apache/xmlbeans/samples/cursor/XmlSort.java b/xmlbeans/samples/XmlSort/src/org/apache/xmlbeans/samples/cursor/XmlSort.java new file mode 100644 index 000000000..d32cae739 --- /dev/null +++ b/xmlbeans/samples/XmlSort/src/org/apache/xmlbeans/samples/cursor/XmlSort.java @@ -0,0 +1,219 @@ +/* Copyright 2009 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.samples.cursor; + +import java.io.File; +import java.io.IOException; +import java.util.Comparator; + +import org.apache.xmlbeans.XmlCursor; +import org.apache.xmlbeans.XmlException; +import org.apache.xmlbeans.XmlObject; + +import javax.xml.namespace.QName; + +/** + */ +public final class XmlSort +{ + /** + * Receives an XML element instance and sorts the children of this + * element in lexicographical (by default) order. + * + * @param args An array in which the first item is a + * path to the XML instance file and the second item (optional) is + * an XPath inside the document identifying the element to be sorted + */ + public static void main(String[] args) + { + if (args.length < 1 || args.length > 2) + { + System.out.println(" java XmlSort []"); + return; + } + File f = new File(args[0]); + try + { + XmlObject docInstance = XmlObject.Factory.parse(f); + XmlObject element = null; + if (args.length > 1) + { + String xpath = args[1]; + XmlObject[] result = docInstance.selectPath(xpath); + if (result.length == 0) + { + System.out.println("ERROR: XPath \"" + xpath + "\" did not return any results"); + } + else if (result.length > 1) + { + System.out.println("ERROR: XPath \"" + xpath + "\" returned more than one " + + "node (" + result.length + ")"); + } + else + element = result[0]; + } + else + { + // Navigate to the root element + XmlCursor c = docInstance.newCursor(); + c.toFirstChild(); + element = c.getObject(); + c.dispose(); + } + if (element != null) + sort(element, new QNameComparator(QNameComparator.ASCENDING)); + System.out.println(docInstance.xmlText()); + } + catch (IOException ioe) + { + System.out.println("ERROR: Could not open file: \"" + args[0] + "\": " + + ioe.getMessage()); + } + catch (XmlException xe) + { + System.out.println("ERROR: Could not parse file: \"" + args[0] + "\": " + + xe.getMessage()); + } + } + + /** + * Sorts the children of element according to the order indicated by the + * comparator. + * @param element the element whose content is to be sorted. Only element children are sorted, + * attributes are not touched. When elements are reordered, all the text, comments and PIs + * follow the element that they come immediately after. + * @param comp a comparator that is to be used when comparing the QNames of two + * elements. See {@link org.apache.xmlbeans.samples.cursor.XmlSort.QNameComparator} for a simple + * implementation that compares two elements based on the value of their QName, but more + * complicated implementations are possible, for instance, ones that compare two elements based + * on the value of a specifc attribute etc. + * @throws IllegalArgumentException if the input XmlObject does not represent + * an element + */ + public static void sort(XmlObject element, Comparator comp) + { + XmlCursor headCursor = element.newCursor(); + if (!headCursor.isStart()) + throw new IllegalStateException("The element parameter must point to a STARTDOC"); + // We use insertion sort to minimize the number of swaps, because each swap means + // moving a part of the document + /* headCursor points to the beginning of the list of the already sorted items and + listCursor points to the beginning of the list of unsorted items + At the beginning, headCursor points to the first element and listCursor points to the + second element. The algorithm ends when listCursor cannot be moved to the "next" + element in the unsorted list, i.e. the unsorted list becomes empty */ + boolean moved = headCursor.toFirstChild(); + if (!moved) + { + // Cursor was not moved, which means that the given element has no children and + // therefore there is nothing to sort + return; + } + XmlCursor listCursor = headCursor.newCursor(); + boolean moreElements = listCursor.toNextSibling(); + while (moreElements) + { + moved = false; + // While we can move the head of the unsorted list, it means that there are still + // items (elements) that need to be sorted + while (headCursor.comparePosition(listCursor) < 0) + { + if (comp.compare(headCursor, listCursor) > 0) + { + // We have found the position in the sorted list, insert the element and the + // text following the element in the current position + /* + * Uncomment this code to cause the text before the element to move along + * with the element, rather than the text after the element. Notice that this + * is more difficult to do, because the cursor's "type" refers to the position + * to the right of the cursor, so to get the type of the token to the left, the + * cursor needs to be first moved to the left (previous token) + * + headCursor.toPrevToken(); + while (headCursor.isComment() || headCursor.isProcinst() || headCursor.isText()) + headCursor.toPrevToken(); + headCursor.toNextToken(); + listCursor.toPrevToken(); + while (listCursor.isComment() || listCursor.isProcinst() || listCursor.isText()) + listCursor.toPrevToken(); + listCursor.toNextToken(); + while (!listCursor.isStart()) + listCursor.moveXml(headCursor); + listCursor.moveXml(headCursor); + */ + // Move the element + listCursor.moveXml(headCursor); + // Move the text following the element + while (!listCursor.isStart() && !listCursor.isEnd()) + listCursor.moveXml(headCursor); + moreElements = listCursor.isStart(); + moved = true; + break; + } + headCursor.toNextSibling(); + } + if (!moved) + { + // Because during the move of a fragment of XML, the listCursor is also moved, in + // case we didn't need to move XML (the new element to be inserted happened to + // be the last one in order), we need to move this cursor + moreElements = listCursor.toNextSibling(); + } + // Reposition the head of the sorted list + headCursor.toParent(); + headCursor.toFirstChild(); + } + } + + /** + * Implements a java.util.Comparator for comparing QNamevalues. + * The namespace URIs are compared first and if they are equal, the local parts are compared. + *

    + * The constructor accepts an argument indicating whether the comparison order is the same as + * the lexicographic order of the strings or the reverse. + */ + public static final class QNameComparator implements Comparator + { + public static final int ASCENDING = 1; + public static final int DESCENDING = 2; + + private int order; + + public QNameComparator(int order) + { + this.order = order; + if (order != ASCENDING && order != DESCENDING) + throw new IllegalArgumentException("Please specify one of ASCENDING or DESCENDING "+ + "comparison orders"); + } + + public int compare(Object o, Object o1) + { + XmlCursor cursor1 = (XmlCursor) o; + XmlCursor cursor2 = (XmlCursor) o1; + QName qname1 = cursor1.getName(); + QName qname2 = cursor2.getName(); + int qnameComparisonRes = qname1.getNamespaceURI().compareTo(qname2.getNamespaceURI()); + if (qnameComparisonRes == 0) + return order == ASCENDING ? + qname1.getLocalPart().compareTo(qname2.getLocalPart()) : + -qname1.getLocalPart().compareTo(qname2.getLocalPart()); + else + return order == ASCENDING ? qnameComparisonRes : -qnameComparisonRes; + } + } +} + \ No newline at end of file diff --git a/xmlbeans/samples/XmlSort/xml/unsorted.xml b/xmlbeans/samples/XmlSort/xml/unsorted.xml new file mode 100644 index 000000000..86427372a --- /dev/null +++ b/xmlbeans/samples/XmlSort/xml/unsorted.xml @@ -0,0 +1,22 @@ + + + bravo + charlie1 + alpha + delta + charlie2 + diff --git a/xmlbeans/samples/XmlTree/README.txt b/xmlbeans/samples/XmlTree/README.txt new file mode 100644 index 000000000..46c57d357 --- /dev/null +++ b/xmlbeans/samples/XmlTree/README.txt @@ -0,0 +1,38 @@ +Sample: XmlTree +Author: Steven Traut (straut@bea.com) +Last Updated: June 14, 2005 + +Versions: + xmlbeans-v1 1.0.3 + xmlbeans-v2 + +----------------------------------------------------------------------------- + +This sample illustrates how you can use the XMLBeans API to create a Java +tree view of an XML document. The JTree implementation in the sample supports +binding to any XML document. By accessing bound XML using an XmlCursor +instance and XPath rather than through accessors provided by compiling +schema, the data model behind this tree can support XML without regard +to schema. The XmlEntry contains the simple code that is XMLBeans-aware. +The XmlModel class, with which the tree implementation interacts directly, +in turn knows nothing of XMLBeans or the underlying XML, instead reaching +the data through XmlEntry instances. + +When you run this sample, it will display a window with the following bits of +UI: + +- A box at the top with the path to the XML that the tree represents. By +default, this is the PurchaseOrder.xml file included with the sample. You can +change this path to point to another XML file, then click the Refresh +button to update the tree. +- A pane on the left displaying the tree itself. You can click nodes in the +tree to display the XML the node represents. +- A pane on the right displaying XML for the tree node that is selected in +the left pane. + +To try out this sample: + +1. Set XMLBEANS_HOME in your environment +2. Ant must be on your PATH +3. To compile the sample source, run "ant build" +4. To execute the sample, run "ant run" diff --git a/xmlbeans/samples/XmlTree/build.xml b/xmlbeans/samples/XmlTree/build.xml new file mode 100644 index 000000000..cc1054845 --- /dev/null +++ b/xmlbeans/samples/XmlTree/build.xml @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/xmlbeans/samples/XmlTree/src/org/apache/xmlbeans/samples/xmltree/XmlEntry.java b/xmlbeans/samples/XmlTree/src/org/apache/xmlbeans/samples/xmltree/XmlEntry.java new file mode 100644 index 000000000..4590da513 --- /dev/null +++ b/xmlbeans/samples/XmlTree/src/org/apache/xmlbeans/samples/xmltree/XmlEntry.java @@ -0,0 +1,130 @@ +/* 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.samples.xmltree; + +import org.apache.xmlbeans.XmlCursor; +import org.apache.xmlbeans.XmlObject; + +import javax.xml.namespace.QName; + +/** + * Represents the data for a single node in the XmlTree. This class (known as a + * "user object" from the JTree perspective) provides a way to get information + * about the node by essentially wrapping the XmlObject instance that the node + * represents. The {@link XmlModel}class represents the XML data model to the + * tree by calling methods of this object. + */ +public final class XmlEntry +{ + private XmlObject[] m_children = new XmlObject[0]; + + private final XmlObject m_currentXml; + + private String m_label; + + /** + * Constructs a entry using xml as the data source. + * + * @param xml The XML this entry will represent. + */ + public XmlEntry(XmlObject xml) + { + m_currentXml = xml; + m_children = collectChildren(xml); + + // Add a cursor and use it to extract information to display in the + // tree. + XmlCursor cursor = xml.newCursor(); + if (!cursor.currentTokenType().isStart()) + { + cursor.toFirstChild(); + } + m_label = cursor.getAttributeText(new QName("label")); + if (m_label == null || m_label.equals("")) + { + m_label = cursor.getName().getLocalPart(); + } + cursor.dispose(); + } + + /** + * Collects the children of the xml element. + * + * @param xml The XML element whose children should be collected. + * @return An array of xml's children. + */ + private XmlObject[] collectChildren(XmlObject xml) + { + return xml.selectPath("./*"); + } + + /** + * Gets the number of children of the XML this entry represents. + * + * @return The number of children. + */ + public int getChildCount() + { + return m_children.length; + } + + /** + * Gets the child at index from among the children of the XML + * this entry represents. + * + * @param index The index number for the child to get. + * @return An entry representing the child. + */ + public XmlEntry getChild(int index) + { + XmlEntry childEntry = new XmlEntry(m_children[index]); + return childEntry; + } + + /** + * Gets the children of the XML this entry represents. + * + * @return An entry array representing the children. + */ + public XmlEntry[] getChildren() + { + XmlEntry[] entryChildren = new XmlEntry[getChildCount()]; + for (int i = 0; i < getChildCount(); i++) + { + entryChildren[i] = new XmlEntry(m_children[i]); + } + return entryChildren; + } + + /** + * Returns a name that can be used as a tree node label. + * + * @return The name of the element or attribute this entry represents. + */ + public String toString() + { + return m_label; + } + + /** + * Gets the XML that this instance represents. + * + * @return An XmlObject instance representing the XML. + */ + public XmlObject getXml() + { + return m_currentXml; + } +} \ No newline at end of file diff --git a/xmlbeans/samples/XmlTree/src/org/apache/xmlbeans/samples/xmltree/XmlModel.java b/xmlbeans/samples/XmlTree/src/org/apache/xmlbeans/samples/xmltree/XmlModel.java new file mode 100644 index 000000000..5fa7025af --- /dev/null +++ b/xmlbeans/samples/XmlTree/src/org/apache/xmlbeans/samples/xmltree/XmlModel.java @@ -0,0 +1,154 @@ +/* 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.samples.xmltree; + +import javax.swing.tree.TreeModel; +import javax.swing.tree.TreePath; +import javax.swing.event.TreeModelListener; +import java.util.Vector; + +/** + * Defines a data model for the XmlTree. Through the data model, the tree can + * retrieve information about the underlying hierarchical data, including the + * root of the hierarchy, children of specified nodes, and so on. This data + * model interacts with the underlying XML data through {@link XmlEntry} + * instances (known as "user objects" in the context of JTree data models). The + * XmlEntry class knows how to retrieve XML-specific hierarchical information as + * it is represented by the XmlObject XMLBeans type. In other words, from the + * tree's perspective, XmlEntry wraps XmlObject. + */ +final class XmlModel implements TreeModel +{ + private final XmlEntry m_rootEntry; + + private final Vector m_treeModelListeners = new Vector(); + + /** + * Creates a new instance of the model using entry as a root + * node. + * + * @param entry The root node. + */ + public XmlModel(XmlEntry entry) + { + m_rootEntry = entry; + } + + /** + * Gets the child of node at index. + * + * @param node The parent whose child to get. + * @param index The index of the child to get. + * @return The child as an XmlEntry instance. + */ + public Object getChild(Object node, int index) + { + XmlEntry entry = (XmlEntry) node; + return entry.getChild(index); + } + + /** + * Gets the number of children that node has. + * + * @param node The tree node whose children should be counted. + * @return The number of children. + */ + public int getChildCount(Object node) + { + XmlEntry entry = (XmlEntry) node; + return entry.getChildCount(); + } + + /** + * Gets the index of childNode as a child of parentNode. + * + * @param parentNode The parent tree node whose children should be checked. + * @param childNode The tree node whose child index should be returned. + * @return The index of childNode; -1 if either + * parentNode or childNode is null. + */ + public int getIndexOfChild(Object parentNode, Object childNode) + { + int childIndex = 0; + XmlEntry parent = (XmlEntry) parentNode; + XmlEntry[] children = parent.getChildren(); + for (int i = 0; i < children.length; i++) + { + if (children[i].equals(childNode)) + { + childIndex = i; + } + } + return childIndex; + } + + /** + * Gets the root of this model. + * + * @return An XmlEntry instance representing the XML's root element. + */ + public Object getRoot() + { + return m_rootEntry; + } + + /** + * Determines whether node has any children, returning + * true if it doesn't. + * + * @param node The node to test. + * @return true if node has no children; + * otherwise, false. + */ + public boolean isLeaf(Object node) + { + XmlEntry entry = (XmlEntry) node; + return entry.getChildCount() == 0; + } + + /** + * Called when the user has altered the value for the item identified by + * treePath to newValue. + * + * @param treePath The item whose path has changed. + * @param newValue The new value. + */ + public void valueForPathChanged(TreePath treePath, Object newValue) + { + System.out.println("Path changing: " + treePath.toString() + "; " + + newValue.toString()); + } + + /** + * Adds a listener. + * + * @param treeModelListener The listener to add. + */ + public void addTreeModelListener(TreeModelListener treeModelListener) + { + m_treeModelListeners.addElement(treeModelListener); + } + + /** + * Removes a listener added by addTreeModelListener. + * + * @param treeModelListener The listener to remove. + */ + public void removeTreeModelListener(TreeModelListener treeModelListener) + { + m_treeModelListeners.removeElement(treeModelListener); + } +} \ No newline at end of file diff --git a/xmlbeans/samples/XmlTree/src/org/apache/xmlbeans/samples/xmltree/XmlTree.java b/xmlbeans/samples/XmlTree/src/org/apache/xmlbeans/samples/xmltree/XmlTree.java new file mode 100644 index 000000000..01b5f50bc --- /dev/null +++ b/xmlbeans/samples/XmlTree/src/org/apache/xmlbeans/samples/xmltree/XmlTree.java @@ -0,0 +1,154 @@ +/* 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.samples.xmltree; + +import org.apache.xmlbeans.XmlException; +import org.apache.xmlbeans.XmlObject; + +import javax.swing.ImageIcon; +import javax.swing.JTree; +import javax.swing.tree.DefaultTreeCellRenderer; +import javax.swing.tree.TreeSelectionModel; +import java.io.File; +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; + +/** + * A tree view on XML, with nodes representing both elements and attributes. See + * {@link XmlEntry}and {@link XmlModel}for information on how information + * about the underlying XML is retrieved for use in the tree. Those classes use + * XMLBeans to provide a wrapper by which the tree exposes the underlying XML. + */ +final class XmlTree extends JTree +{ + /** + * Receives XML instance, executing methods that + * edit the received instance or create a new one. + * + * @param args An array in which the first item is a + * path to the XML instance file. + */ + public static void main(String[] args) + { + System.out.println("Creating XmlTree.\n"); + File xmlFile = new File(args[0]); + XmlTreeFrame thisSample = new XmlTreeFrame(xmlFile); + } + + /** + * Constructs the tree using xmlFile as an original source of + * nodes. + * + * @param xmlFile The XML file the new tree should represent. + */ + public XmlTree(File xmlFile) + { + setXmlFile(xmlFile); + } + + /** + * Sets the XML file that should be used to build the tree; the tree will be + * refreshed to represent xmlFile. + * + * @param xmlFile The XML file the new tree should represent. + */ + public void setXmlFile(File xmlFile) + { + initComponents(xmlFile); + } + + /** + * Parses xmlFile into XMLBeans types (XmlObject instances), + * returning the instance representing the root. + * + * @param xmlFile The XML file to parse. + * @return An XmlObject representing the root of the parsed XML. + */ + private static XmlObject parseXml(File xmlFile) + { + XmlObject xml = XmlObject.Factory.newInstance(); + try + { + xml = XmlObject.Factory.parse(xmlFile); + } catch (XmlException xmle) + { + System.err.println(xmle.toString()); + } catch (IOException ioe) + { + System.err.println(ioe.toString()); + } + return xml; + } + + /** + * Sets up the components that make up this tree. + * + * @param xmlFile The XML file the new tree should represent. + */ + private void initComponents(File xmlFile) + { + // Parse the XML create an XmlModel from its root. + XmlEntry rootEntry = new XmlEntry(parseXml(xmlFile)); + XmlModel treemodel = new XmlModel(rootEntry); + + // Set UI properties. + setModel(treemodel); + setRootVisible(true); + setShowsRootHandles(true); + setAutoscrolls(true); + setEditable(false); + getSelectionModel().setSelectionMode( + TreeSelectionModel.SINGLE_TREE_SELECTION); + DefaultTreeCellRenderer renderer = new DefaultTreeCellRenderer(); + // Uncomment these lines to provide your own GIF files for + // tree icons. + // renderer.setLeafIcon(createImageIcon("images/leaf.gif")); + // renderer.setOpenIcon(createImageIcon("images/minus.gif")); + // renderer.setClosedIcon(createImageIcon("images/plus.gif")); + setCellRenderer(renderer); + setRootVisible(false); + setAutoscrolls(false); + } + + /** + * Creates an icon from a path that points at a GIF file. This method is + * called to create tree node icons. + * + * @param path The path to a GIF file. + * @return An icon instance. + */ + private static ImageIcon createImageIcon(String path) + { + File imgFile = new File(path); + URL imgUrl = null; + try + { + imgUrl = imgFile.toURL(); + } catch (MalformedURLException e) + { + e.printStackTrace(); + } + if (imgUrl != null) + { + return new ImageIcon(imgUrl); + } else + { + System.err.println("Couldn't find file: " + path); + return null; + } + } +} \ No newline at end of file diff --git a/xmlbeans/samples/XmlTree/src/org/apache/xmlbeans/samples/xmltree/XmlTreeFrame.java b/xmlbeans/samples/XmlTree/src/org/apache/xmlbeans/samples/xmltree/XmlTreeFrame.java new file mode 100644 index 000000000..80f5c2ffb --- /dev/null +++ b/xmlbeans/samples/XmlTree/src/org/apache/xmlbeans/samples/xmltree/XmlTreeFrame.java @@ -0,0 +1,252 @@ +/* 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.samples.xmltree; + +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.XmlCursor; +import org.apache.xmlbeans.XmlOptions; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.io.File; + +/** + * Provides a frame within which to display an instance of the {@link XmlTree}, + * along with a pane within which to display the XML corresponding to a node + * selected in the tree. The tree's data is managed by the {@link XmlModel}and + * {@link XmlEntry}classes, along with XmlTree. The XmlTreeFrame class is + * merely a container to show the tree in use. + */ +final class XmlTreeFrame extends JFrame +{ + // Variables for UI components. + private XmlTree treeXmlTree; + + private JButton btnRefresh; + + private JPanel pnlContent; + + private JPanel pnlSelectionPanel; + + private JPanel pnlTree; + + private JScrollPane scrContent; + + private JScrollPane scrTree; + + private JSplitPane splTreeContent; + + private JTextField txtFileName; + + private JTextPane txtpnlContent; + + /** + * Constructs the frame with an XML file to use for the tree. + * + * @param xmlFile The file containing XML that the tree should represent. + */ + public XmlTreeFrame(File xmlFile) + { + initComponents(xmlFile); + } + + /** + * Initializes UI components, setting properties and adding event listeners. + * + * @param xmlFile The XML file to be represented by the tree. + */ + private void initComponents(File xmlFile) + { + // Set properties for this frame. + getContentPane().setLayout(new GridBagLayout()); + setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); + setTitle("XML Tree View"); + setName("frmXmlTreeView"); + + // Create the top panel that will contain text box and refresh button. + pnlSelectionPanel = new JPanel(); + pnlSelectionPanel.setLayout(new GridBagLayout()); + + // Create the text box to display the XML file path. + txtFileName = new JTextField(); + GridBagConstraints gridBagConstraints; + gridBagConstraints = new GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 0; + gridBagConstraints.anchor = GridBagConstraints.WEST; + gridBagConstraints.insets = new Insets(4, 4, 0, 4); + gridBagConstraints.weightx = 1; + gridBagConstraints.fill = GridBagConstraints.HORIZONTAL; + txtFileName.setText(xmlFile.getAbsolutePath()); + pnlSelectionPanel.add(txtFileName, gridBagConstraints); + + // Create the refresh button. + btnRefresh = new JButton(); + btnRefresh.setText("Refresh"); + gridBagConstraints = new GridBagConstraints(); + gridBagConstraints.gridwidth = 1; + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 0; + gridBagConstraints.anchor = GridBagConstraints.EAST; + pnlSelectionPanel.add(btnRefresh, gridBagConstraints); + + // Add the selection panel to this frame. + gridBagConstraints = new GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 0; + gridBagConstraints.fill = GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = GridBagConstraints.NORTHWEST; + gridBagConstraints.weightx = 1; + gridBagConstraints.weighty = 0; + getContentPane().add(pnlSelectionPanel, gridBagConstraints); + + // Create the split plane that separates the tree and the content panes. + splTreeContent = new JSplitPane(); + + // Create the components for the left side of the split pane: + // the panel, scrolling panel, and the XML tree it will contain. + pnlTree = new JPanel(); + scrTree = new JScrollPane(); + treeXmlTree = new XmlTree(xmlFile); + scrTree.setViewportView(treeXmlTree); + pnlTree.setLayout(new GridBagLayout()); + gridBagConstraints = new GridBagConstraints(); + gridBagConstraints.fill = GridBagConstraints.BOTH; + gridBagConstraints.anchor = GridBagConstraints.NORTH; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.weighty = 1.0; + pnlTree.add(scrTree, gridBagConstraints); + + // Put the tree panel in the left side of the split pane. + splTreeContent.setLeftComponent(pnlTree); + + // Create the components for the left side of the split pane: + // the panel, scrolling panel, and the XML tree it will contain. + pnlContent = new JPanel(); + scrContent = new JScrollPane(); + txtpnlContent = new JTextPane(); + scrContent.setViewportView(txtpnlContent); + pnlContent.setLayout(new GridBagLayout()); + gridBagConstraints = new GridBagConstraints(); + gridBagConstraints.fill = GridBagConstraints.BOTH; + gridBagConstraints.anchor = GridBagConstraints.NORTHWEST; + gridBagConstraints.weightx = 1; + gridBagConstraints.weighty = 1; + pnlContent.add(scrContent, gridBagConstraints); + + // Put the content panel in the right side of the split pane. + splTreeContent.setRightComponent(pnlContent); + + // Set the rest of the split pane's properties, + splTreeContent.setDividerLocation(170); + gridBagConstraints = new GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 1; + gridBagConstraints.weightx = 1; + gridBagConstraints.weighty = 1; + gridBagConstraints.fill = GridBagConstraints.BOTH; + gridBagConstraints.gridheight = GridBagConstraints.REMAINDER; + gridBagConstraints.anchor = GridBagConstraints.NORTH; + getContentPane().add(splTreeContent, gridBagConstraints); + + // Add a listener to get mouse clicks on the tree nodes. + treeXmlTree.addMouseListener(new MouseListener() + { + public void mouseClicked(MouseEvent event) + { + if (event.getClickCount() == 1) + { + XmlEntry selection = (XmlEntry) treeXmlTree + .getLastSelectedPathComponent(); + // selection might be null if the user clicked one of the + // expandy/collapsy things without selecting a node. + if (selection == null) + { + return; + } + // Get the pretty-printed XML text and put it in the + // window on the right. + XmlObject node = selection.getXml(); + XmlCursor nodeCursor = node.newCursor(); + XmlOptions options = new XmlOptions(); + options.setSavePrettyPrint(); + options.setSavePrettyPrintIndent(4); + String xmlString = nodeCursor.xmlText(options); + txtpnlContent.setText(xmlString); + } + } + + // Don't respond to these events. + public void mouseEntered(MouseEvent event) + {} + + public void mouseExited(MouseEvent event) + {} + + public void mousePressed(MouseEvent event) + {} + + public void mouseReleased(MouseEvent event) + {} + }); + + // Add a listener to get mouse clicks on the Refresh button. + btnRefresh.addMouseListener(new MouseListener() + { + public void mouseClicked(MouseEvent event) + { + // Get the text from the file path box and make a file from it. + String filePath = txtFileName.getText(); + File xmlFile = new File(filePath); + + // If the path points to a file, build the tree all over again. + if (xmlFile.exists()) + { + treeXmlTree.setXmlFile(xmlFile); + txtpnlContent.setText(""); + } else + { + JOptionPane.showMessageDialog(null, + "The path you gave appears " + + "not to point to a file.", + "XmlTree Message", JOptionPane.ERROR_MESSAGE); + } + + } + + // Don't respond to these events. + public void mouseEntered(MouseEvent event) + {} + + public void mouseExited(MouseEvent event) + {} + + public void mousePressed(MouseEvent event) + {} + + public void mouseReleased(MouseEvent event) + {} + }); + + // Size all the components to their preferred size. + pack(); + this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + this.setSize(600, 640); + this.setVisible(true); + } +} \ No newline at end of file diff --git a/xmlbeans/samples/XmlTree/src/org/apache/xmlbeans/samples/xmltree/XmlTreeTest.java b/xmlbeans/samples/XmlTree/src/org/apache/xmlbeans/samples/xmltree/XmlTreeTest.java new file mode 100644 index 000000000..317606efe --- /dev/null +++ b/xmlbeans/samples/XmlTree/src/org/apache/xmlbeans/samples/xmltree/XmlTreeTest.java @@ -0,0 +1,42 @@ +/* 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.samples.xmltree; + +import java.io.File; + +/** + * A class with which to test the XmlTree sample. + */ +final class XmlTreeTest +{ + /** + * Tests the XmlTree sample. + * + * @param args An array in which the first item is a path to an XML file. + */ + public static void main(String[] args) + { + boolean isStarted = start(args); +// assert !isStarted; + } + + private static boolean start(String[] args) + { + File xmlFile = new File(args[0]); + XmlTreeFrame frame = new XmlTreeFrame(xmlFile); + return frame.isVisible(); + } +} \ No newline at end of file diff --git a/xmlbeans/samples/XmlTree/xml/PurchaseOrder.xml b/xmlbeans/samples/XmlTree/xml/PurchaseOrder.xml new file mode 100644 index 000000000..5ecfd44c1 --- /dev/null +++ b/xmlbeans/samples/XmlTree/xml/PurchaseOrder.xml @@ -0,0 +1,44 @@ + + + + Gladys Kravitz +

    Anytown, PA
    + + 2001-12-17T09:30:47-05:00 + + Burnham's Celestial Handbook, Vol 1 + 5 + 21.79 + 2 + + + Burnham's Celestial Handbook, Vol 2 + 5 + 19.89 + 2 + + + Burnham's Celestial Handbook, Vol 3 + 5 + 19.89 + 1 + + + UPS + 0.74 + + diff --git a/xmlbeans/samples/XsdConfig/README.txt b/xmlbeans/samples/XsdConfig/README.txt new file mode 100644 index 000000000..4d7346fdd --- /dev/null +++ b/xmlbeans/samples/XsdConfig/README.txt @@ -0,0 +1,41 @@ +Sample: XSDConfig +Author: Rashmi Banthia (rjain29@gmail.com) +Last Updated: Oct. 18th, 2004 + +Versions: + xmlbeans-1.0.3 + +----------------------------------------------------------------------------- + +This sample illustrates how you can specify package names to be used for xml +namespaces. You can also specify class names to be used for individual qualified names. + +To customize the package names and the class names, you'll need to create .xsdconfig file. +For eg: "filename.xsdconfig" + +Schema for xsdconfig can be obtained from XMLBeans source. + +For this sample: +(1) The java class names generated without the XsdConfig are: + * org.apache.xmlbeans.samples.catalog.ArticleDocument + * org.apache.xmlbeans.samples.catalog.AVeryLongDescriptionElementDocument + * org.apache.xmlbeans.samples.catalog.CatalogDocument + * org.apache.xmlbeans.samples.catalog.JournalDocument +(CatalogXsd.java uses above mentioned classes) + + +(2) The java class names generated with XsdConfig are: + * com.catalog.XmlArticleDocumentBean + * com.catalog.XmlShortItemBean + * com.catalog.XmlCatalogDocumentBean + * com.catalog.XmlJournalDocumentBean +(CatalogXsdConfig.java uses above mentioned classes) + +When you run this sample, you will see it print all the element values from XML document +instance (with and without XsdConfig file). + +To try out this sample: + +1. Set XMLBEANS_HOME in your environment +2. Ant must be on your PATH +3. To compile the schemas and sample source, run "ant build" diff --git a/xmlbeans/samples/XsdConfig/build.xml b/xmlbeans/samples/XsdConfig/build.xml new file mode 100644 index 000000000..b133812cb --- /dev/null +++ b/xmlbeans/samples/XsdConfig/build.xml @@ -0,0 +1,175 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/xmlbeans/samples/XsdConfig/schemas/catalog.xsd b/xmlbeans/samples/XsdConfig/schemas/catalog.xsd new file mode 100644 index 000000000..023f641a3 --- /dev/null +++ b/xmlbeans/samples/XsdConfig/schemas/catalog.xsd @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/xmlbeans/samples/XsdConfig/schemas/myconfig.xsdconfig b/xmlbeans/samples/XsdConfig/schemas/myconfig.xsdconfig new file mode 100644 index 000000000..fb5bdd2cf --- /dev/null +++ b/xmlbeans/samples/XsdConfig/schemas/myconfig.xsdconfig @@ -0,0 +1,49 @@ + + + + + + + + + + com.catalog + + + + + + + + Xml + Bean + + + + + + + + + diff --git a/xmlbeans/samples/XsdConfig/src/org/apache/xmlbeans/samples/xsdconfig/CatalogXsd.java b/xmlbeans/samples/XsdConfig/src/org/apache/xmlbeans/samples/xsdconfig/CatalogXsd.java new file mode 100644 index 000000000..5e084df9a --- /dev/null +++ b/xmlbeans/samples/XsdConfig/src/org/apache/xmlbeans/samples/xsdconfig/CatalogXsd.java @@ -0,0 +1,155 @@ +/* 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.samples.xsdconfig; + +/* + *This class uses the auto generated package names and class names. It doesn't consider XsdConfig file. + *Note the difference between the imports in two files (CatalogXsdConfig.java and CatalogXsd.java) + */ + +import org.apache.xmlbeans.samples.catalog.CatalogDocument; +import org.apache.xmlbeans.samples.catalog.JournalDocument; +import org.apache.xmlbeans.samples.catalog.ArticleDocument; +import org.apache.xmlbeans.samples.catalog.AVeryLongDescriptionElementDocument; + +import org.apache.xmlbeans.XmlException; +import org.apache.xmlbeans.XmlError; +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.XmlOptions; + +import java.util.ArrayList; +import java.io.IOException; +import java.io.File; + +public class CatalogXsd +{ + + public static void main(String[] args) + { + // Create an instance of this class to work with. + CatalogXsd catalogxsd = new CatalogXsd(); + + // Create an instance of a type based on the received XML's schema + CatalogDocument catdoc = catalogxsd.parseXml(args[0]); + + //Prints the element values from the XML. + catalogxsd.printElements(catdoc); + + } + + /** + * Creates a File from the XML path provided in main arguments, then + * parses the file's contents into a type (CatalogDocument) generated from schema. + * + * @param xmlFilePath A path to XML based on the schema in EasyPo.xsd + * @return An instance of a generated schema type (CatalogDocument) that contains the + * parsed XML. + */ + public CatalogDocument parseXml(String xmlFilePath) + { + File xmlfile = new File(xmlFilePath); + CatalogDocument catdoc = null; + + try + { + catdoc = CatalogDocument.Factory.parse(xmlfile); + } + catch (XmlException e) + { + e.printStackTrace(); + } + catch (IOException e) + { + e.printStackTrace(); + } + return catdoc; + } + + + /** + * This method prints all the element values in the given XML document based on Catalog.xsd + */ + public void printElements(CatalogDocument catdoc) + { + // Get object reference of root element. + CatalogDocument.Catalog catalogelement = catdoc.getCatalog(); + + //Get all element from the root element. + JournalDocument.Journal[] journalarray = catalogelement.getJournalArray(); + + //Loop through element array. + for (int i = 0; i < journalarray.length; i++) + { + + //Retrieve all
    elements within each element + ArticleDocument.Article[] articlearray = journalarray[i].getArticleArray(); + + //Loop through
    array retrieved above + for (int j = 0; j < articlearray.length; j++) + { + System.out.println(articlearray[j].getTitle()); + + String[] str = articlearray[j].getAuthorArray(); + + for (int k = 0; k < str.length; k++) + System.out.println(str[k]); + + //Note the method for retrieving element. + System.out.println(articlearray[j].getAVeryLongDescriptionElement() + .getForsample()); + } + } + System.out.println("\n\n\n"); + } + + /** + *

    Validates the XML, printing error messages when the XML is invalid. Note + * that this method will properly validate any instance of a compiled schema + * type because all of these types extend XmlObject.

    + *

    + *

    Note that in actual practice, you'll probably want to use an assertion + * when validating if you want to ensure that your code doesn't pass along + * invalid XML. This sample prints the generated XML whether or not it's + * valid so that you can see the result in both cases.

    + * + * @param xml The XML to validate. + * @return true if the XML is valid; otherwise, false + */ + public static boolean validateXml(XmlObject xml) + { + boolean isXmlValid = false; + + // A collection instance to hold validation error messages. + ArrayList validationMessages = new ArrayList(); + + // Validate the XML, collecting messages. + isXmlValid = xml.validate( + new XmlOptions().setErrorListener(validationMessages)); + + // If the XML isn't valid, print the messages. + if (!isXmlValid) + { + System.out.println("\nInvalid XML: "); + for (int i = 0; i < validationMessages.size(); i++) + { + XmlError error = (XmlError) validationMessages.get(i); + System.out.println(error.getMessage()); + System.out.println(error.getObjectLocation()); + } + } + return isXmlValid; + } +} diff --git a/xmlbeans/samples/XsdConfig/src/org/apache/xmlbeans/samples/xsdconfig/CatalogXsdConfig.java b/xmlbeans/samples/XsdConfig/src/org/apache/xmlbeans/samples/xsdconfig/CatalogXsdConfig.java new file mode 100644 index 000000000..619cf2eb1 --- /dev/null +++ b/xmlbeans/samples/XsdConfig/src/org/apache/xmlbeans/samples/xsdconfig/CatalogXsdConfig.java @@ -0,0 +1,155 @@ +/* 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.samples.xsdconfig; + +/** + *This class uses the package names and class names mentioned in XsdConfig. + *Note the difference between the imports in two files (CatalogXsdConfig.java and CatalogXsd.java) + */ + +import com.catalog.XmlCatalogDocumentBean; +import com.catalog.XmlJournalDocumentBean; +import com.catalog.XmlArticleDocumentBean; +import com.catalog.XmlShortItemBean; + +import org.apache.xmlbeans.XmlException; +import org.apache.xmlbeans.XmlError; +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.XmlOptions; + +import java.util.ArrayList; +import java.io.IOException; +import java.io.File; + +public class CatalogXsdConfig +{ + + public static void main(String[] args) + { + // Create an instance of this class to work with. + CatalogXsdConfig catxsdconfig = new CatalogXsdConfig(); + + // Create an instance of a type based on the received XML's schema + XmlCatalogDocumentBean catdoc = catxsdconfig.parseXml(args[0]); + + //Prints the element values from the XML. + catxsdconfig.printElements(catdoc); + } + + /** + * Creates a File from the XML path provided in main arguments, then + * parses the file's contents into a type (CatalogDocument) generated from schema. + * + * @param xmlFilePath A path to XML based on the schema in EasyPo.xsd + * @return An instance of a generated schema type (CatalogDocument) that contains the + * parsed XML. + */ + public XmlCatalogDocumentBean parseXml(String xmlFilePath) + { + File xmlfile = new File(xmlFilePath); + XmlCatalogDocumentBean catdoc = null; + + try + { + catdoc = XmlCatalogDocumentBean.Factory.parse(xmlfile); + } + catch (XmlException e) + { + e.printStackTrace(); + } + catch (IOException e) + { + e.printStackTrace(); + } + return catdoc; + } + + /* + * This method prints all the element values in the given XML document based on Catalog.xsd + */ + public void printElements(XmlCatalogDocumentBean catdoc) + { + // Get object reference of root element. + XmlCatalogDocumentBean.Catalog catalogelement = catdoc.getCatalog(); + + //Get all element from the root element. + XmlJournalDocumentBean.Journal[] journalarray = catalogelement.getJournalArray(); + + //Loop through element array. + for (int i = 0; i < journalarray.length; i++) + { + + //Retrieve all
    elements within each element + XmlArticleDocumentBean.Article[] articlearray = journalarray[i].getArticleArray(); + + //Loop through
    array retrieved above + for (int j = 0; j < articlearray.length; j++) + { + System.out.println(articlearray[j].getTitle()); + + String[] str = articlearray[j].getAuthorArray(); + + for (int k = 0; k < str.length; k++) + System.out.println(str[k]); + + //Note the method for retrieving element. + System.out.println( + articlearray[j].getXmlShortItemBean().getGoodName()); + + } + } + System.out.println("\n\n\n"); + } + + /** + *

    Validates the XML, printing error messages when the XML is invalid. Note + * that this method will properly validate any instance of a compiled schema + * type because all of these types extend XmlObject.

    + *

    + *

    Note that in actual practice, you'll probably want to use an assertion + * when validating if you want to ensure that your code doesn't pass along + * invalid XML. This sample prints the generated XML whether or not it's + * valid so that you can see the result in both cases.

    + * + * @param xml The XML to validate. + * @return true if the XML is valid; otherwise, false + */ + public static boolean validateXml(XmlObject xml) + { + boolean isXmlValid = false; + + // A collection instance to hold validation error messages. + ArrayList validationMessages = new ArrayList(); + + // Validate the XML, collecting messages. + isXmlValid = xml.validate( + new XmlOptions().setErrorListener(validationMessages)); + + // If the XML isn't valid, print the messages. + if (!isXmlValid) + { + System.out.println("\nInvalid XML: "); + for (int i = 0; i < validationMessages.size(); i++) + { + XmlError error = (XmlError) validationMessages.get(i); + System.out.println(error.getMessage()); + System.out.println(error.getObjectLocation()); + } + } + return isXmlValid; + } + +} diff --git a/xmlbeans/samples/XsdConfig/src/org/apache/xmlbeans/samples/xsdconfig/XsdConfigTest.java b/xmlbeans/samples/XsdConfig/src/org/apache/xmlbeans/samples/xsdconfig/XsdConfigTest.java new file mode 100644 index 000000000..46bef3b37 --- /dev/null +++ b/xmlbeans/samples/XsdConfig/src/org/apache/xmlbeans/samples/xsdconfig/XsdConfigTest.java @@ -0,0 +1,41 @@ +/* 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.samples.xsdconfig; + +import com.catalog.XmlCatalogDocumentBean; + +public class XsdConfigTest +{ + + /** + * Tests the CatalogXsdConfig.java class. This does consider XsdConfig file. + */ + public static void main(String[] args) + { + // Create an instance of the sample to test. + CatalogXsdConfig sample = new CatalogXsdConfig(); + + XmlCatalogDocumentBean catdoc = sample.parseXml(args[0]); + + //Prints the element values from the XML. + sample.printElements(catdoc); + + // Validate the XML. + assert sample.validateXml(catdoc); + + + } +} \ No newline at end of file diff --git a/xmlbeans/samples/XsdConfig/src/org/apache/xmlbeans/samples/xsdconfig/XsdTest.java b/xmlbeans/samples/XsdConfig/src/org/apache/xmlbeans/samples/xsdconfig/XsdTest.java new file mode 100644 index 000000000..4c49ec642 --- /dev/null +++ b/xmlbeans/samples/XsdConfig/src/org/apache/xmlbeans/samples/xsdconfig/XsdTest.java @@ -0,0 +1,40 @@ +/* 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.samples.xsdconfig; + +import org.apache.xmlbeans.samples.catalog.CatalogDocument; + +public class XsdTest +{ + + /** + * Tests the CatalogXsd.java class. This does not consider XsdConfig file. + */ + public static void main(String[] args) + { + // Create an instance of the sample to test. + CatalogXsd sample = new CatalogXsd(); + + CatalogDocument catdoc = sample.parseXml(args[0]); + + //Prints the element values from the XML. + sample.printElements(catdoc); + + // Validate the XML. + assert sample.validateXml(catdoc); + + } +} \ No newline at end of file diff --git a/xmlbeans/samples/XsdConfig/xml/catalog.xml b/xmlbeans/samples/XsdConfig/xml/catalog.xml new file mode 100644 index 000000000..f04451741 --- /dev/null +++ b/xmlbeans/samples/XsdConfig/xml/catalog.xml @@ -0,0 +1,38 @@ + + + + + +
    + Java programming for high-performance numerical computing + J. E. Moreira et.al. + + This is a sample element for journal-1 + +
    +
    + +
    + Dynamically Binding EJBs Using the Java Reflection API + Douglas A. Clark + + This document can be found at http://www.cuj.com/documents/s=8467/cujjsup2010clark/clark.htm + +
    +
    + +
    \ No newline at end of file diff --git a/xmlbeans/samples/build.xml b/xmlbeans/samples/build.xml new file mode 100644 index 000000000..979cd771e --- /dev/null +++ b/xmlbeans/samples/build.xml @@ -0,0 +1,335 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/xmlbeans/samples/vxsdb/README.txt b/xmlbeans/samples/vxsdb/README.txt new file mode 100644 index 000000000..63aba62cb --- /dev/null +++ b/xmlbeans/samples/vxsdb/README.txt @@ -0,0 +1,51 @@ +Sample: VelocityXmlBeans +Category: sql +Author: Philip Mark Donaghy +Last Updated: Apr. 23, 2007 + +Versions: + xmlbeans-v1 1.0.3 + xmlbeans-v2 + +-------------------------------------------------------------------------------- + +Vxsdb is a XmlBeans sample application which derives a Apache DB DdlUtils data +model from an xml schema. It was conceived from things I have learned from using +XmlBeans and talking to people at the ASF conference. Vxsdb uses Jakarta +Velocity as its templating engine. + +Features: + + - Inputs a xml schema + - Outputs an Apache DB DdlUtils data model in xml + +Building this sample requires Apache dependancies which are automatically +downloaded to the lib directory when Ant is executed. + +To try out this sample: + +1. Set XMLBEANS_HOME in your environment +2. Ant must be on your PATH +3. To compile the sample source, run "ant" +4. To execute the sample, run "ant -f run.xml" +5. The files build/datamodel.xml and build/create.sql are generated + +To build this sample without downloading dependencies +----------------------------------------------------- +ant -Ddeps.exist=true + +By default run creates a ddl for the Derby RDBMS. To change the target +database add a directive on the command line. + +Change database +--------------- +ant -f run.xml -DtargetDatabase=postgresql + +Postgres quickstart +------------------- +$ su - +# su - postgres +$ initdb +$ createdb easypo +$ psql easypo +# \i xml/create.sql diff --git a/xmlbeans/samples/vxsdb/build.xml b/xmlbeans/samples/vxsdb/build.xml new file mode 100644 index 000000000..f9ceb7f2e --- /dev/null +++ b/xmlbeans/samples/vxsdb/build.xml @@ -0,0 +1,85 @@ + + + + + + + + + Sample integration of Velocity and XMLBeans that produces a Apache DB DddUtils datamodel.xml file from a xml schema. + + + + + + + + + + + + Execute 'ant -f run.xml' to run the sample xml schema generator + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/xmlbeans/samples/vxsdb/datamodel.vm b/xmlbeans/samples/vxsdb/datamodel.vm new file mode 100644 index 000000000..e10d5ba92 --- /dev/null +++ b/xmlbeans/samples/vxsdb/datamodel.vm @@ -0,0 +1,47 @@ +## Copyright 2002-2004 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. +## +## Database template used by the sample XmlBeans Velocity integration. +## Using the SchemaTypeSystem of XmlBeans this template produces an +## Jakarta commons-sql datamodel.xml file. +## This template expoits the SchemaTypeSystem XmlBeans object +## present in the Velocity context using the $xsd identifier. + + + + + +#foreach($global in $xsd.globalElements())## SchemaGlobalElement[] + + + + + #set($global = $global.type) + #parse("global.vm") + +
    +#end + + +#foreach($global in $xsd.globalTypes())## SchemaType[] + + + + + #parse("global.vm") + +
    +#end + +
    diff --git a/xmlbeans/samples/vxsdb/doc/NOTES.txt b/xmlbeans/samples/vxsdb/doc/NOTES.txt new file mode 100644 index 000000000..919b014a6 --- /dev/null +++ b/xmlbeans/samples/vxsdb/doc/NOTES.txt @@ -0,0 +1,27 @@ +This document keeps track of issues with sql-commons, xmlbeans, or velocity +integration in this sample. + +The easypo.xsd file implies a foreign key in the table line-item. This can +be determined by the unbounded definition of the purchase order element. A +better mechanism would be to include database primary and foreign key +relationships in the xml schema itself. + +Problems running the sample. Java 1.5.0 seems to be the only runtime to +resolve the String method replace("-","_"). + +The run target fails with the following error: + +BUILD FAILED: /home/phil/soft/work/vxsdb/run.xml:30: +org.apache.xmlbeans.XmlException: Thread main: The 0th supplied input is +not a schema or a config document: its type is N= + +Execute a script containing the java command below if Ant is not available. + +Unix: +run + +Cygwin: +runcygwin + +Windows: +run diff --git a/xmlbeans/samples/vxsdb/doc/vxsdb.html b/xmlbeans/samples/vxsdb/doc/vxsdb.html new file mode 100644 index 000000000..3482d6f0b --- /dev/null +++ b/xmlbeans/samples/vxsdb/doc/vxsdb.html @@ -0,0 +1,407 @@ + + + + + + + + + + + + +

    Creating +a Jakarta Commons SQL datamodel using XmlBeans and Velocity

    +

    Philip +Mark Donaghy

    +

    1 About Vxsdb

    +

    Vxsdb is a sample XmlBeans +application which derives a Jakarta Commons SQL data model from an +xml schema. It was conceived from things I have learned from using +XmlBeans and talking to people at the ASF conference.

    +

    Vxsdb uses Jakarta Velocity as its +templating engine. At runtime a SchemaTypeSystem XmlBeans object is +created from compiling an xml schema. This object is placed in a +Velocity context. A template processes the objects global elements, +global types and generates a Jakarta Commons SQL xml datamodel +descriptor of tables and columns.

    +

    1.1 Requirements

    +

    Java 1.5

    +

    1.2 Getting Started

    +

    The basic utilization compiles the +sample and produces a database schema for a given xml schema.

    +

    Execute the command “antâ€

    +

    This compiles the sample.

    +

    Execute the command “ant -f run.xmlâ€

    +

    This creates the Jakarta Commons SQL +datamodel.xml and creates the create.sql ddl.

    +

    1.3 +Configuration

    +

    Vxsdb can be configured by modifying the +command line parameters to specify another template, output or xml +schema.

    +

    ant -f run.xml -Dtemplate=datamodel.vm +-Doutput=database.xml -Dschema=easypo.xsd

    +

    1.4 Generating database schema

    +

    Included in the sample run.xml is an Ant +target which generates the ddl used to create the database tables. +The default database is PostgreSQL.

    +

    ant -f run.xml

    +

    To change the target database use,

    +

    ant -f run.xml -DtargetDatabase=oracle

    +

    1.5 Determining Tables, Columns, and Table +relationships

    +

    Tables are created from all global +elements and most global types.

    +

    For each schema property the sample +application determines if it is a column, an exported key (foreign +key to another table), or an imported foreign key (another entity +who's table contains a foreign back to this entity).

    +

    If a schema property (attribute or +element) is a simple type without restriction a column is created and +one of the following Commons SQL values is assigned to the property. +DATE, DECIMAL, FLOAT, INTEGER, TIME, TIMESTAMP, or VARCHAR.

    +

    If a schema property is a simple type +with a restriction then a column is created and one of the above +values is assigned in addition to a size attribute.

    +

    If a schema property is a complex type +with no maxOccurs or minOccurs (meaning that it is required) then a +foreign key column is entered into the database table descriptor and +the required attribute is set to true.

    +

    If a schema property is a complex type +with maxOccurs equal to one then a foreign key column is entered into +the database table.

    +

    If a schema property is a complex type +with maxOccurs greater than one or unbounded then a imported key +(foreign key from this type's table) is required. This presents a +problem. The Velocity template may have already encountered this +complex type and created its table descriptor without even knowing +about this relationship. This is known as the Imported Key Question.

    +

    1.6 Solving the Imported Key Question

    +

    Iterate the SchemaTypeSystem in the Java +class to determine imported keys.

    +

    Cliff told me that ms has a solution to +this which may be included in the xml schema.

    +

    1.7 Additional ideas

    +

    Combining XmlBeans and +Velocity templates can result in other interesting xml schema related +technologies.

    +

    Using a similar approach to this sample +XmlBeans and Velocity can harness the xml schema and generate +documentation, a relational database model, or even data access +objects.

    +

    1.8 Sample datamodel.xml

    +

    <?xml +version="1.0" encoding="UTF-8"?>

    +


    +

    +

    <database +name="sample">

    +


    +

    +

    <!-- +Global Elements -->

    +


    +

    +

    <table +name="PURCHASE_ORDER">

    +


    +

    +

    <column +name="PK" type="INTEGER" required="true" +primaryKey="true"/>

    +

    <!-- +T=customer@http://openuri.org/easypo -->

    +

    <column +name="FK_CUSTOMER" required="true" type="INTEGER" +/>

    +

    <foreign-key +foreignTable="CUSTOMER">

    +

    <reference +local="FK_CUSTOMER" foreign="PK"/>

    +

    </foreign-key>

    +

    <!-- +T=dateTime@http://www.w3.org/2001/XMLSchema -->

    +

    <column +name="DATE" type="TIMESTAMP" />

    +

    <!-- +Foreign key imported from table named LINE_ITEM -->

    +

    <!-- +T=shipper@http://openuri.org/easypo -->

    +

    <column +name="FK_SHIPPER" type="INTEGER" />

    +

    <foreign-key +foreignTable="SHIPPER">

    +

    <reference +local="FK_SHIPPER" foreign="PK"/>

    +

    </foreign-key>

    +

    </table>

    +


    +

    +

    <!-- +Global Types -->

    +


    +

    +

    <table +name="CUSTOMER">

    +


    +

    +

    <column +name="PK" type="INTEGER" required="true" +primaryKey="true"/>

    +

    <!-- +T=string@http://www.w3.org/2001/XMLSchema -->

    +

    <column +name="NAME" type="VARCHAR" />

    +

    <!-- +T=string@http://www.w3.org/2001/XMLSchema -->

    +

    <column +name="ADDRESS" type="VARCHAR" />

    +

    <!-- +T=int@http://www.w3.org/2001/XMLSchema -->

    +

    <column +name="AGE" type="TINYINT" />

    +

    <!-- +T=int@http://www.w3.org/2001/XMLSchema -->

    +

    <column +name="MOO" type="TINYINT" />

    +

    <!-- +T=int@http://www.w3.org/2001/XMLSchema -->

    +

    <column +name="POO" type="TINYINT" />

    +

    </table>

    +


    +

    +

    <table +name="LINE_ITEM">

    +


    +

    +

    <column +name="PK" type="INTEGER" required="true" +primaryKey="true"/>

    +

    <!-- +T=string@http://www.w3.org/2001/XMLSchema -->

    +

    <column +name="DESCRIPTION" type="VARCHAR" />

    +

    <!-- +T=decimal@http://www.w3.org/2001/XMLSchema -->

    +

    <column +name="PER_UNIT_OUNCES" type="DECIMAL" />

    +

    <!-- +T=decimal@http://www.w3.org/2001/XMLSchema -->

    +

    <column +name="PRICE" type="DECIMAL" />

    +

    <!-- +T=integer@http://www.w3.org/2001/XMLSchema -->

    +

    <column +name="QUANTITY" type="INTEGER" />

    +

    <!-- +Exported key -->

    +

    <column +name="FK_PURCHASE_ORDER" required="true" +type="INTEGER" />

    +

    <foreign-key +foreignTable="PURCHASE_ORDER">

    +

    <reference +local="FK_PURCHASE_ORDER" foreign="PK"/>

    +

    </foreign-key>

    +

    </table>

    +


    +

    +

    <table +name="SHIPPER">

    +


    +

    +

    <column +name="PK" type="INTEGER" required="true" +primaryKey="true"/>

    +

    <!-- +T=string@http://www.w3.org/2001/XMLSchema -->

    +

    <column +name="NAME" type="VARCHAR" />

    +

    <!-- +T=decimal@http://www.w3.org/2001/XMLSchema -->

    +

    <column +name="PER_OUNCE_RATE" type="DECIMAL" />

    +

    </table>

    +


    +

    +

    </database>

    +

    1.9 Sample create.sql

    +

    drop +table SHIPPER;

    +


    +

    +

    drop +table LINE_ITEM;

    +


    +

    +

    drop +table CUSTOMER;

    +


    +

    +

    drop +table PURCHASE_ORDER;

    +


    +

    +

    -- +-----------------------------------------------------------------------

    +

    -- +PURCHASE_ORDER

    +

    -- +-----------------------------------------------------------------------

    +


    +

    +

    create +table PURCHASE_ORDER

    +

    (

    +

    PK +INTEGER NOT NULL ,

    +

    FK_CUSTOMER +INTEGER NOT NULL ,

    +

    DATE +TIMESTAMP NULL ,

    +

    FK_SHIPPER +INTEGER NULL ,

    +

    PRIMARY +KEY (PK)

    +

    );

    +


    +

    +

    ALTER +TABLE PURCHASE_ORDER

    +

    ADD +CONSTRAINT PURCHASE_ORDER_FK_1 FOREIGN KEY (FK_CUSTOMER)

    +

    REFERENCES +CUSTOMER (PK)

    +

    ;

    +


    +

    +

    ALTER +TABLE PURCHASE_ORDER

    +

    ADD +CONSTRAINT PURCHASE_ORDER_FK_2 FOREIGN KEY (FK_SHIPPER)

    +

    REFERENCES +SHIPPER (PK)

    +

    ;

    +


    +

    +

    -- +-----------------------------------------------------------------------

    +

    -- +CUSTOMER

    +

    -- +-----------------------------------------------------------------------

    +


    +

    +

    create +table CUSTOMER

    +

    (

    +

    PK +INTEGER NOT NULL ,

    +

    NAME +VARCHAR NULL ,

    +

    ADDRESS +VARCHAR NULL ,

    +

    AGE +TINYINT NULL ,

    +

    MOO +TINYINT NULL ,

    +

    POO +TINYINT NULL ,

    +

    PRIMARY +KEY (PK)

    +

    );

    +


    +

    +

    -- +-----------------------------------------------------------------------

    +

    -- +LINE_ITEM

    +

    -- +-----------------------------------------------------------------------

    +


    +

    +

    create +table LINE_ITEM

    +

    (

    +

    PK +INTEGER NOT NULL ,

    +

    DESCRIPTION +VARCHAR NULL ,

    +

    PER_UNIT_OUNCES +DECIMAL NULL ,

    +

    PRICE +DECIMAL NULL ,

    +

    QUANTITY +INTEGER NULL ,

    +

    FK_PURCHASE_ORDER +INTEGER NOT NULL ,

    +

    PRIMARY +KEY (PK)

    +

    );

    +


    +

    +

    ALTER +TABLE LINE_ITEM

    +

    ADD +CONSTRAINT LINE_ITEM_FK_1 FOREIGN KEY (FK_PURCHASE_ORDER)

    +

    REFERENCES +PURCHASE_ORDER (PK)

    +

    ;

    +


    +

    +

    -- +-----------------------------------------------------------------------

    +

    -- +SHIPPER

    +

    -- +-----------------------------------------------------------------------

    +


    +

    +

    create +table SHIPPER

    +

    (

    +

    PK +INTEGER NOT NULL ,

    +

    NAME +VARCHAR NULL ,

    +

    PER_OUNCE_RATE +DECIMAL NULL ,

    +

    PRIMARY +KEY (PK)

    +

    );

    +


    +

    +



    +

    + + diff --git a/xmlbeans/samples/vxsdb/external/DdlUtils-1.0-RC1.jar b/xmlbeans/samples/vxsdb/external/DdlUtils-1.0-RC1.jar new file mode 100644 index 0000000000000000000000000000000000000000..925647beaf2bdf619e2b1abb0621c073433b2cbd GIT binary patch literal 347708 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⋙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

    vXAB6)^uU|AUKg35t;{lBGjsc4(DZFyIY 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 R5GvrmOhW>}pC8;b;eSGq4NCw3 literal 0 HcmV?d00001 diff --git a/xmlbeans/samples/vxsdb/global.vm b/xmlbeans/samples/vxsdb/global.vm new file mode 100644 index 000000000..6f612d14f --- /dev/null +++ b/xmlbeans/samples/vxsdb/global.vm @@ -0,0 +1,33 @@ +## Copyright 2002-2004 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. +## +## This template expoits the SchemaType XmlBeans object using the $global +## identifier. + + + #foreach($property in $global.properties)## SchemaProperty[] + ## Column name and data type. Columns may be foreign keys + + #parse("property.vm") + #end + #if( $exportedKeyMap.get($global.name.toString()) )## Map returns a List + #foreach($exportedKey in $exportedKeyMap.get($global.name.toString()))## String in List + + + + + + + #end + #end diff --git a/xmlbeans/samples/vxsdb/property.vm b/xmlbeans/samples/vxsdb/property.vm new file mode 100644 index 000000000..81e4b371c --- /dev/null +++ b/xmlbeans/samples/vxsdb/property.vm @@ -0,0 +1,46 @@ +## Copyright 2002-2004 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. +## +## Property template used by the sample XmlBeans Velocity integration. +## This template expoits the SchemaProperty XmlBeans object to determine +## if the column is a data type or foreign key +#if($property.type.simpleType) + + + +#elseif( $property.maxOccurs.intValue() == 1 && $property.minOccurs.intValue() == 0 ) + + + + + + +#elseif( $property.maxOccurs.intValue() == 1 ) + + + + + + +#elseif( $property.maxOccurs.intValue() > 1 || "$!property.maxOccurs" == "")## Greater than one or unbounded + + +#else + + + + + + +#end diff --git a/xmlbeans/samples/vxsdb/run.xml b/xmlbeans/samples/vxsdb/run.xml new file mode 100644 index 000000000..0cfc8a889 --- /dev/null +++ b/xmlbeans/samples/vxsdb/run.xml @@ -0,0 +1,102 @@ + + + + + + Execute vxsdb sample. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/xmlbeans/samples/vxsdb/schemas/easypo.xsd b/xmlbeans/samples/vxsdb/schemas/easypo.xsd new file mode 100644 index 000000000..40e83738f --- /dev/null +++ b/xmlbeans/samples/vxsdb/schemas/easypo.xsd @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/xmlbeans/samples/vxsdb/sql/create.sample.sql b/xmlbeans/samples/vxsdb/sql/create.sample.sql new file mode 100644 index 000000000..f165fc4f4 --- /dev/null +++ b/xmlbeans/samples/vxsdb/sql/create.sample.sql @@ -0,0 +1,84 @@ +-- +-- Copyright 2002-2004 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. +-- + +drop table SHIPPER; + +drop table LINE_ITEM; + +drop table CUSTOMER; + +drop table PURCHASE_ORDER; + +-- ----------------------------------------------------------------------- +-- PURCHASE_ORDER +-- ----------------------------------------------------------------------- + +create table PURCHASE_ORDER +( + PK INTEGER NOT NULL , + FK_CUSTOMER INTEGER NULL , + DATE INTEGER NULL , + FK_SHIPPER INTEGER NULL , + PRIMARY KEY (PK) +); + +-- ----------------------------------------------------------------------- +-- CUSTOMER +-- ----------------------------------------------------------------------- + +create table CUSTOMER +( + PK INTEGER NOT NULL , + NAME INTEGER NULL , + ADDRESS INTEGER NULL , + AGE INTEGER NULL , + MOO INTEGER NULL , + POO INTEGER NULL , + PRIMARY KEY (PK) +); + +-- ----------------------------------------------------------------------- +-- LINE_ITEM +-- ----------------------------------------------------------------------- + +create table LINE_ITEM +( + PK INTEGER NOT NULL , + DESCRIPTION INTEGER NULL , + PER_UNIT_OUNCES INTEGER NULL , + PRICE INTEGER NULL , + QUANTITY INTEGER NULL , + FK_PURCHASE_ORDER INTEGER NULL , + PRIMARY KEY (PK) +); + +ALTER TABLE LINE_ITEM + ADD CONSTRAINT LINE_ITEM_FK_1 FOREIGN KEY (FK_PURCHASE_ORDER) + REFERENCES PURCHASE_ORDER (PK) +; + +-- ----------------------------------------------------------------------- +-- SHIPPER +-- ----------------------------------------------------------------------- + +create table SHIPPER +( + PK INTEGER NOT NULL , + NAME INTEGER NULL , + PER_OUNCE_RATE INTEGER NULL , + PRIMARY KEY (PK) +); + diff --git a/xmlbeans/samples/vxsdb/src/java/log4j.xml b/xmlbeans/samples/vxsdb/src/java/log4j.xml new file mode 100644 index 000000000..a31898e38 --- /dev/null +++ b/xmlbeans/samples/vxsdb/src/java/log4j.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + diff --git a/xmlbeans/samples/vxsdb/src/java/org/apache/xmlbeans/samples/vxsdb/VelocityXmlBeansDB.java b/xmlbeans/samples/vxsdb/src/java/org/apache/xmlbeans/samples/vxsdb/VelocityXmlBeansDB.java new file mode 100644 index 000000000..60de328c1 --- /dev/null +++ b/xmlbeans/samples/vxsdb/src/java/org/apache/xmlbeans/samples/vxsdb/VelocityXmlBeansDB.java @@ -0,0 +1,192 @@ +/* Copyright 2003-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.samples.vxsdb; + +import java.io.File; +import java.io.FileWriter; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Task; +import org.apache.velocity.Template; +import org.apache.velocity.VelocityContext; +import org.apache.velocity.app.Velocity; +import org.apache.xmlbeans.SchemaGlobalElement; +import org.apache.xmlbeans.SchemaProperty; +import org.apache.xmlbeans.SchemaTypeSystem; +import org.apache.xmlbeans.XmlBeans; +import org.apache.xmlbeans.XmlObject; + +/** + * @author Philip Mark Donaghy + */ +public class VelocityXmlBeansDB extends Task { + + private static final Log log = LogFactory.getLog(VelocityXmlBeansDB.class); + + private String template; + + private String output; + + private String schema; + + /** + * @param output + * The output to set. + */ + public void setOutput(String output) { + this.output = output; + } + + /** + * @param schema + * The schema to set. + */ + public void setSchema(String schema) { + this.schema = schema; + } + + /** + * @param template + * The template to set. + */ + public void setTemplate(String template) { + this.template = template; + } + + /** + * Default Constructor + */ + public VelocityXmlBeansDB() { + } + + /** + * Puts the XmlBeans SchemaTypeSystem into the Velocity Context + */ + public void execute() throws BuildException { + + // Create a Velocity Context and a Velocity Template + VelocityContext ctx = new VelocityContext(); + Template template = null; + + // Output to a file + FileWriter writer = null; + + // XmlBeans + SchemaTypeSystem schemaTypeSystem = null; + + try { + + // Initialize Velocity + Velocity.init(); + log.info("Using the Velocity template, " + this.template); + template = Velocity.getTemplate(this.template); + + // Create Schema Type System + log.info("Using the xml schema, " + this.schema); + schemaTypeSystem = XmlBeans.compileXsd( + new XmlObject[] { XmlBeans.typeLoaderForClassLoader(this.getClass().getClassLoader()). + parse(new File(this.schema), null, null) }, + XmlBeans.getBuiltinTypeSystem(), + null); + + // Place SchemaTypeSystem in the Velocity Context + ctx.put("xsd", schemaTypeSystem); + + // Place a exported key Map in the Velocity Context + ctx.put("exportedKeyMap", createExportedKeyMap(schemaTypeSystem)); + + // Write to the file + log.info("Using the output file, " + this.output); + writer = new FileWriter(new File(this.output)); + template.merge(ctx, writer); + writer.close(); + + } catch (Exception e) { + throw new BuildException(e); + } + } + + /** + * + * @param sts + * @return + */ + private Map createExportedKeyMap(SchemaTypeSystem sts) { + + // Map of exported keys (foreign keys) + // The key is the name of the element exporting key(s) + // The value is a List of tables importing this key + Map exportedKeyMap = new HashMap(); + + // For all global elements and all global types + // Create a map of exported key lists + SchemaGlobalElement[] globals = sts.globalElements(); + for (int i = 0; i < globals.length; i++) { + processProperties(globals[i].getName().getLocalPart().toUpperCase(), globals[i].getType().getProperties(), exportedKeyMap); + } + return exportedKeyMap; + } + + private void processProperties(String tableName, SchemaProperty[] properties, Map exportedKeyMap) { + // For all properties + for (int i = 0; i < properties.length; i++) { + processProperty(tableName, properties[i], exportedKeyMap); + } + } + + private void processProperty(String tableName, SchemaProperty property, Map exportedKeyMap) { + // If property maxOccurs is greater than one or unbounded (null) + if (property.getMaxOccurs() == null || property.getMaxOccurs().compareTo(BigInteger.ONE) > 0) { + + // Tables that import this properties type (ex. line-item type exports a foreign key to purchase-order, + // PURCHASE_ORDER is in the list of importers) + List importers = (List) exportedKeyMap.get(property.getType().getName().toString()); + if (importers == null) { + importers = new ArrayList(); + exportedKeyMap.put(property.getType().getName().toString(), importers); + } + importers.add(tableName); + } + } + + /** + * @param args + */ + public static void main(String[] args) { + VelocityXmlBeansDB beans = new VelocityXmlBeansDB(); + + // Verify arguments + if (args.length < 3) { + log + .error("Usage : java org.apache.xmlbeans.samples.vxsdb.VelocityXmlBeansDB TEMPLATE OUTPUT SCHEMA1 [SCHEMA2] [...]"); + System.exit(1); + } + beans.setTemplate(args[0]); + beans.setOutput(args[1]); + beans.setSchema(args[2]); + try { + beans.execute(); + } catch (Exception e) { + e.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/xmlbeans/samples/vxsdb/type.vm b/xmlbeans/samples/vxsdb/type.vm new file mode 100644 index 000000000..b06186b24 --- /dev/null +++ b/xmlbeans/samples/vxsdb/type.vm @@ -0,0 +1,22 @@ +## Copyright 2002-2004 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. +## +## Type template used by the sample XmlBeans Velocity integration. +## This template expoits the SchemaProperty XmlBeans object to determine +## the data type for the given column. Type returns a SchemaType XmlBeans +## object. +## +## See doc for constant values: +## http://xmlbeans.apache.org/docs/v2/reference/constant-values.html +#if($property.type.simpleVariety == 1)#if($property.type.primitiveType.name.localPart == "boolean")BOOLEAN#elseif($property.type.primitiveType.name.localPart == "dateTime")TIMESTAMP#elseif($property.type.primitiveType.name.localPart == "decimal")DECIMAL#elseif($property.type.primitiveType.name.localPart == "int")INTEGER#elseif($property.type.primitiveType.name.localPart == "integer")INTEGER#elseif($property.type.primitiveType.name.localPart == "long")INTEGER#elseif($property.type.primitiveType.name.localPart == "string")VARCHAR#elseif(true)OTHER#end#end diff --git a/xmlbeans/samples/vxsdb/xml/datamodel.sample.xml b/xmlbeans/samples/vxsdb/xml/datamodel.sample.xml new file mode 100644 index 000000000..de17e0477 --- /dev/null +++ b/xmlbeans/samples/vxsdb/xml/datamodel.sample.xml @@ -0,0 +1,118 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + +
    + +
    diff --git a/xmlbeans/src/common/org/apache/xmlbeans/impl/common/ConcurrentReaderHashMap.java b/xmlbeans/src/common/org/apache/xmlbeans/impl/common/ConcurrentReaderHashMap.java new file mode 100644 index 000000000..3e3a3e40e --- /dev/null +++ b/xmlbeans/src/common/org/apache/xmlbeans/impl/common/ConcurrentReaderHashMap.java @@ -0,0 +1,1287 @@ +/* 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. + */ + +/* + File: ConcurrentReaderHashMap + + Written by Doug Lea. Adapted and released, under explicit + permission, from JDK1.2 HashMap.java and Hashtable.java which + carries the following copyright: + + * Copyright 1997 by Sun Microsystems, Inc., + * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A. + * All rights reserved. + * + * This software is the confidential and proprietary information + * of Sun Microsystems, Inc. ("Confidential Information"). You + * shall not disclose such Confidential Information and shall use + * it only in accordance with the terms of the license agreement + * you entered into with Sun. + + History: + Date Who What + 28oct1999 dl Created + 14dec1999 dl jmm snapshot + 19apr2000 dl use barrierLock + 12jan2001 dl public release + 17nov2001 dl Minor tunings + 20may2002 dl BarrierLock can now be serialized. + 09dec2002 dl Fix interference checks. +*/ + +//package EDU.oswego.cs.dl.util.concurrent; +package org.apache.xmlbeans.impl.common; + +import java.io.IOException; +import java.io.Serializable; +import java.util.AbstractCollection; +import java.util.AbstractMap; +import java.util.AbstractSet; +import java.util.Collection; +import java.util.Enumeration; +import java.util.Iterator; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.Set; + + +/** + * A version of Hashtable that supports mostly-concurrent reading, but + * exclusive writing. Because reads are not limited to periods + * without writes, a concurrent reader policy is weaker than a classic + * reader/output policy, but is generally faster and allows more + * concurrency. This class is a good choice especially for tables that + * are mainly created by one thread during the start-up phase of a + * program, and from then on, are mainly read (with perhaps occasional + * additions or removals) in many threads. If you also need concurrency + * among writes, consider instead using ConcurrentHashMap. + *

    + * + * Successful retrievals using get(key) and containsKey(key) usually + * run without locking. Unsuccessful ones (i.e., when the key is not + * present) do involve brief synchronization (locking). Also, the + * size and isEmpty methods are always synchronized. + * + *

    Because retrieval operations can ordinarily overlap with + * writing operations (i.e., put, remove, and their derivatives), + * retrievals can only be guaranteed to return the results of the most + * recently completed operations holding upon their + * onset. Retrieval operations may or may not return results + * reflecting in-progress writing operations. However, the retrieval + * operations do always return consistent results -- either those + * holding before any single modification or after it, but never a + * nonsense result. For aggregate operations such as putAll and + * clear, concurrent reads may reflect insertion or removal of only + * some entries. In those rare contexts in which you use a hash table + * to synchronize operations across threads (for example, to prevent + * reads until after clears), you should either encase operations + * in synchronized blocks, or instead use java.util.Hashtable. + * + *

    + * + * This class also supports optional guaranteed + * exclusive reads, simply by surrounding a call within a synchronized + * block, as in
    + * ConcurrentReaderHashMap t; ... Object v;
    + * synchronized(t) { v = t.get(k); }

    + * + * But this is not usually necessary in practice. For + * example, it is generally inefficient to write: + * + *

    + *   ConcurrentReaderHashMap t; ...            // Inefficient version
    + *   Object key; ...
    + *   Object value; ...
    + *   synchronized(t) { 
    + *     if (!t.containsKey(key))
    + *       t.put(key, value);
    + *       // other code if not previously present
    + *     }
    + *     else {
    + *       // other code if it was previously present
    + *     }
    + *   }
    + *
    + * Instead, if the values are intended to be the same in each case, just take advantage of the fact that put returns + * null if the key was not previously present: + *
    + *   ConcurrentReaderHashMap t; ...                // Use this instead
    + *   Object key; ...
    + *   Object value; ...
    + *   Object oldValue = t.put(key, value);
    + *   if (oldValue == null) {
    + *     // other code if not previously present
    + *   }
    + *   else {
    + *     // other code if it was previously present
    + *   }
    + *
    + *

    + * + * Iterators and Enumerations (i.e., those returned by + * keySet().iterator(), entrySet().iterator(), values().iterator(), + * keys(), and elements()) return elements reflecting the state of the + * hash table at some point at or since the creation of the + * iterator/enumeration. They will return at most one instance of + * each element (via next()/nextElement()), but might or might not + * reflect puts and removes that have been processed since they were + * created. They do not throw ConcurrentModificationException. + * However, these iterators are designed to be used by only one + * thread at a time. Sharing an iterator across multiple threads may + * lead to unpredictable results if the table is being concurrently + * modified. Again, you can ensure interference-free iteration by + * enclosing the iteration in a synchronized block.

    + * + * This class may be used as a direct replacement for any use of + * java.util.Hashtable that does not depend on readers being blocked + * during updates. Like Hashtable but unlike java.util.HashMap, + * this class does NOT allow null to be used as a key or + * value. This class is also typically faster than ConcurrentHashMap + * when there is usually only one thread updating the table, but + * possibly many retrieving values from it. + *

    + * + * Implementation note: A slightly faster implementation of + * this class will be possible once planned Java Memory Model + * revisions are in place. + * + *

    [ Introduction to this package. ] + + **/ + + +public class ConcurrentReaderHashMap + extends AbstractMap + implements Map, Cloneable, Serializable { + + + /* + The basic strategy is an optimistic-style scheme based on + the guarantee that the hash table and its lists are always + kept in a consistent enough state to be read without locking: + + * Read operations first proceed without locking, by traversing the + apparently correct list of the apparently correct bin. If an + entry is found, but not invalidated (value field null), it is + returned. If not found, operations must recheck (after a memory + barrier) to make sure they are using both the right list and + the right table (which can change under resizes). If + invalidated, reads must acquire main update lock to wait out + the update, and then re-traverse. + + * All list additions are at the front of each bin, making it easy + to check changes, and also fast to traverse. Entry next + pointers are never assigned. Remove() builds new nodes when + necessary to preserve this. + + * Remove() (also clear()) invalidates removed nodes to alert read + operations that they must wait out the full modifications. + + */ + + /** A Serializable class for barrier lock **/ + protected static class BarrierLock implements java.io.Serializable { } + + /** + * Lock used only for its memory effects. + **/ + protected final BarrierLock barrierLock = new BarrierLock(); + + /** + * field written to only to guarantee lock ordering. + **/ + + protected transient Object lastWrite; + + /** + * Force a memory synchronization that will cause + * all readers to see table. Call only when already + * holding main synch lock. + **/ + protected final void recordModification(Object x) { + synchronized(barrierLock) { + lastWrite = x; + } + } + + /** + * Get ref to table; the reference and the cells it + * accesses will be at least as fresh as from last + * use of barrierLock + **/ + protected final Entry[] getTableForReading() { + synchronized(barrierLock) { + return table; + } + } + + + /** + * The default initial number of table slots for this table (32). + * Used when not otherwise specified in constructor. + **/ + public static int DEFAULT_INITIAL_CAPACITY = 32; + + + /** + * The minimum capacity, used if a lower value is implicitly specified + * by either of the constructors with arguments. + * MUST be a power of two. + */ + private static final int MINIMUM_CAPACITY = 4; + + /** + * The maximum capacity, used if a higher value is implicitly specified + * by either of the constructors with arguments. + * MUST be a power of two <= 1<<30. + */ + private static final int MAXIMUM_CAPACITY = 1 << 30; + + /** + * The default load factor for this table (1.0). + * Used when not otherwise specified in constructor. + **/ + + public static final float DEFAULT_LOAD_FACTOR = 0.75f; + + + /** + * The hash table data. + */ + protected transient Entry[] table; + + /** + * The total number of mappings in the hash table. + */ + protected transient int count; + + /** + * The table is rehashed when its size exceeds this threshold. (The + * value of this field is always (int)(capacity * loadFactor).) + * + * @serial + */ + protected int threshold; + + /** + * The load factor for the hash table. + * + * @serial + */ + protected float loadFactor; + + /** + * Returns the appropriate capacity (power of two) for the specified + * initial capacity argument. + */ + private int p2capacity(int initialCapacity) { + int cap = initialCapacity; + + // Compute the appropriate capacity + int result; + if (cap > MAXIMUM_CAPACITY || cap < 0) { + result = MAXIMUM_CAPACITY; + } else { + result = MINIMUM_CAPACITY; + while (result < cap) + result <<= 1; + } + return result; + } + + /** + * Return hash code for Object x. Since we are using power-of-two + * tables, it is worth the effort to improve hashcode via + * the same multiplicative scheme as used in IdentityHashMap. + */ + private static int hash(Object x) { + int h = x.hashCode(); + // Multiply by 127 (quickly, via shifts), and mix in some high + // bits to help guard against bunching of codes that are + // consecutive or equally spaced. + return ((h << 7) - h + (h >>> 9) + (h >>> 17)); + } + + /** + * Check for equality of non-null references x and y. + **/ + protected boolean eq(Object x, Object y) { + return x == y || x.equals(y); + } + + /** + * Constructs a new, empty map with the specified initial + * capacity and the specified load factor. + * + * @param initialCapacity the initial capacity + * The actual initial capacity is rounded to the nearest power of two. + * @param loadFactor the load factor of the ConcurrentReaderHashMap + * @throws IllegalArgumentException if the initial maximum number + * of elements is less + * than zero, or if the load factor is nonpositive. + */ + + public ConcurrentReaderHashMap(int initialCapacity, float loadFactor) { + if (loadFactor <= 0) + throw new IllegalArgumentException("Illegal Load factor: "+ + loadFactor); + this.loadFactor = loadFactor; + + int cap = p2capacity(initialCapacity); + + table = new Entry[cap]; + threshold = (int)(cap * loadFactor); + } + + /** + * Constructs a new, empty map with the specified initial + * capacity and default load factor. + * + * @param initialCapacity the initial capacity of the + * ConcurrentReaderHashMap. + * @throws IllegalArgumentException if the initial maximum number + * of elements is less + * than zero. + */ + + public ConcurrentReaderHashMap(int initialCapacity) { + this(initialCapacity, DEFAULT_LOAD_FACTOR); + } + + /** + * Constructs a new, empty map with a default initial capacity + * and load factor. + */ + + public ConcurrentReaderHashMap() { + this(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR); + } + + /** + * Constructs a new map with the same mappings as the given map. The + * map is created with a capacity of twice the number of mappings in + * the given map or 16 (whichever is greater), and a default load factor. + */ + + public ConcurrentReaderHashMap(Map t) { + this(Math.max((int) (t.size() / DEFAULT_LOAD_FACTOR) + 1, 16), + DEFAULT_LOAD_FACTOR); + putAll(t); + } + + /** + * Returns the number of key-value mappings in this map. + * + * @return the number of key-value mappings in this map. + */ + + public synchronized int size() { + return count; + } + + /** + * Returns true if this map contains no key-value mappings. + * + * @return true if this map contains no key-value mappings. + */ + + public synchronized boolean isEmpty() { + return count == 0; + } + + + + /** + * Returns the value to which the specified key is mapped in this table. + * + * @param key a key in the table. + * @return the value to which the key is mapped in this table; + * null if the key is not mapped to any value in + * this table. + * @exception NullPointerException if the key is + * null. + * @see #put(Object, Object) + */ + + + public Object get(Object key) { + + // throw null pointer exception if key null + int hash = hash(key); + + /* + Start off at the apparently correct bin. If entry is found, we + need to check after a barrier anyway. If not found, we need a + barrier to check if we are actually in right bin. So either + way, we encounter only one barrier unless we need to retry. + And we only need to fully synchronize if there have been + concurrent modifications. + */ + + Entry[] tab = table; + int index = hash & (tab.length - 1); + Entry first = tab[index]; + Entry e = first; + + for (;;) { + if (e == null) { + + // If key apparently not there, check to + // make sure this was a valid read + + Entry[] reread = getTableForReading(); + if (tab == reread && first == tab[index]) + return null; + else { + // Wrong list -- must restart traversal at new first + tab = reread; + e = first = tab[index = hash & (tab.length-1)]; + } + + } + + else if (e.hash == hash && eq(key, e.key)) { + Object value = e.value; + if (value != null) + return value; + + // Entry was invalidated during deletion. But it could + // have been re-inserted, so we must retraverse. + // To avoid useless contention, get lock to wait out modifications + // before retraversing. + + synchronized(this) { + tab = table; + } + e = first = tab[index = hash & (tab.length-1)]; + + } + else + e = e.next; + } + } + + + /** + * Tests if the specified object is a key in this table. + * + * @param key possible key. + * @return true if and only if the specified object + * is a key in this table, as determined by the + * equals method; false otherwise. + * @exception NullPointerException if the key is + * null. + * @see #contains(Object) + */ + + + public boolean containsKey(Object key) { + return get(key) != null; + } + + /** + * Maps the specified key to the specified + * value in this table. Neither the key nor the + * value can be null.

    + * + * The value can be retrieved by calling the get method + * with a key that is equal to the original key. + * + * @param key the table key. + * @param value the value. + * @return the previous value of the specified key in this table, + * or null if it did not have one. + * @exception NullPointerException if the key or value is + * null. + * @see Object#equals(Object) + * @see #get(Object) + */ + + public Object put(Object key, Object value) { + if (value == null) + throw new NullPointerException(); + + int hash = hash(key); + Entry[] tab = table; + int index = hash & (tab.length-1); + Entry first = tab[index]; + Entry e; + + for (e = first; e != null; e = e.next) + if (e.hash == hash && eq(key, e.key)) + break; + + synchronized(this) { + if (tab == table) { + if (e == null) { + // make sure we are adding to correct list + if (first == tab[index]) { + // Add to front of list + Entry newEntry = new Entry(hash, key, value, first); + tab[index] = newEntry; + if (++count >= threshold) rehash(); + else recordModification(newEntry); + return null; + } + } + else { + Object oldValue = e.value; + if (first == tab[index] && oldValue != null) { + e.value = value; + return oldValue; + } + } + } + + // retry if wrong list or lost race against concurrent remove + return sput(key, value, hash); + } + } + + + /** + * Continuation of put(), called only when synch lock is + * held and interference has been detected. + **/ + protected Object sput(Object key, Object value, int hash) { + + Entry[] tab = table; + int index = hash & (tab.length-1); + Entry first = tab[index]; + Entry e = first; + + for (;;) { + if (e == null) { + Entry newEntry = new Entry(hash, key, value, first); + tab[index] = newEntry; + if (++count >= threshold) rehash(); + else recordModification(newEntry); + return null; + } + else if (e.hash == hash && eq(key, e.key)) { + Object oldValue = e.value; + e.value = value; + return oldValue; + } + else + e = e.next; + } + } + + + /** + * Rehashes the contents of this map into a new table + * with a larger capacity. This method is called automatically when the + * number of keys in this map exceeds its capacity and load factor. + */ + protected void rehash() { + Entry[] oldTable = table; + int oldCapacity = oldTable.length; + if (oldCapacity >= MAXIMUM_CAPACITY) { + threshold = Integer.MAX_VALUE; // avoid retriggering + return; + } + + int newCapacity = oldCapacity << 1; + int mask = newCapacity - 1; + threshold = (int)(newCapacity * loadFactor); + + Entry[] newTable = new Entry[newCapacity]; + /* + * Reclassify nodes in each list to new Map. Because we are + * using power-of-two expansion, the elements from each bin + * must either stay at same index, or move to + * oldCapacity+index. We also eliminate unnecessary node + * creation by catching cases where old nodes can be reused + * because their next fields won't change. Statistically, at + * the default threshhold, only about one-sixth of them need + * cloning. (The nodes they replace will be garbage + * collectable as soon as they are no longer referenced by any + * reader thread that may be in the midst of traversing table + * right now.) + */ + + for (int i = 0; i < oldCapacity ; i++) { + // We need to guarantee that any existing reads of old Map can + // proceed. So we cannot yet null out each bin. + Entry e = oldTable[i]; + + if (e != null) { + int idx = e.hash & mask; + Entry next = e.next; + + // Single node on list + if (next == null) + newTable[idx] = e; + + else { + // Reuse trailing consecutive sequence of all same bit + Entry lastRun = e; + int lastIdx = idx; + for (Entry last = next; last != null; last = last.next) { + int k = last.hash & mask; + if (k != lastIdx) { + lastIdx = k; + lastRun = last; + } + } + newTable[lastIdx] = lastRun; + + // Clone all remaining nodes + for (Entry p = e; p != lastRun; p = p.next) { + int k = p.hash & mask; + newTable[k] = new Entry(p.hash, p.key, + p.value, newTable[k]); + } + } + } + } + + table = newTable; + recordModification(newTable); + } + + /** + * Removes the key (and its corresponding value) from this + * table. This method does nothing if the key is not in the table. + * + * @param key the key that needs to be removed. + * @return the value to which the key had been mapped in this table, + * or null if the key did not have a mapping. + * @exception NullPointerException if the key is + * null. + */ + + public Object remove(Object key) { + /* + Find the entry, then + 1. Set value field to null, to force get() to retry + 2. Rebuild the list without this entry. + All entries following removed node can stay in list, but + all preceeding ones need to be cloned. Traversals rely + on this strategy to ensure that elements will not be + repeated during iteration. + */ + + + int hash = hash(key); + Entry[] tab = table; + int index = hash & (tab.length-1); + Entry first = tab[index]; + Entry e = first; + + for (e = first; e != null; e = e.next) + if (e.hash == hash && eq(key, e.key)) + break; + + + synchronized(this) { + if (tab == table) { + if (e == null) { + if (first == tab[index]) + return null; + } + else { + Object oldValue = e.value; + if (first == tab[index] && oldValue != null) { + e.value = null; + count--; + + Entry head = e.next; + for (Entry p = first; p != e; p = p.next) + head = new Entry(p.hash, p.key, p.value, head); + + tab[index] = head; + recordModification(head); + return oldValue; + } + } + } + + // Wrong list or interference + return sremove(key, hash); + } + } + + /** + * Continuation of remove(), called only when synch lock is + * held and interference has been detected. + **/ + + protected Object sremove(Object key, int hash) { + Entry[] tab = table; + int index = hash & (tab.length-1); + Entry first = tab[index]; + + for (Entry e = first; e != null; e = e.next) { + if (e.hash == hash && eq(key, e.key)) { + Object oldValue = e.value; + e.value = null; + count--; + Entry head = e.next; + for (Entry p = first; p != e; p = p.next) + head = new Entry(p.hash, p.key, p.value, head); + + tab[index] = head; + recordModification(head); + return oldValue; + } + } + return null; + } + + + /** + * Returns true if this map maps one or more keys to the + * specified value. Note: This method requires a full internal + * traversal of the hash table, and so is much slower than + * method containsKey. + * + * @param value value whose presence in this map is to be tested. + * @return true if this map maps one or more keys to the + * specified value. + * @exception NullPointerException if the value is null. + */ + + public boolean containsValue(Object value) { + if (value == null) throw new NullPointerException(); + + Entry tab[] = getTableForReading(); + + for (int i = 0 ; i < tab.length; ++i) { + for (Entry e = tab[i] ; e != null ; e = e.next) + if (value.equals(e.value)) + return true; + } + + return false; + } + + /** + * Tests if some key maps into the specified value in this table. + * This operation is more expensive than the containsKey + * method.

    + * + * Note that this method is identical in functionality to containsValue, + * (which is part of the Map interface in the collections framework). + * + * @param value a value to search for. + * @return true if and only if some key maps to the + * value argument in this table as + * determined by the equals method; + * false otherwise. + * @exception NullPointerException if the value is null. + * @see #containsKey(Object) + * @see #containsValue(Object) + * @see Map + */ + + public boolean contains(Object value) { + return containsValue(value); + } + + + /** + * Copies all of the mappings from the specified map to this one. + * + * These mappings replace any mappings that this map had for any of the + * keys currently in the specified Map. + * + * @param t Mappings to be stored in this map. + */ + + public synchronized void putAll(Map t) { + int n = t.size(); + if (n == 0) + return; + + // Expand enough to hold at least n elements without resizing. + // We can only resize table by factor of two at a time. + // It is faster to rehash with fewer elements, so do it now. + while (n >= threshold) + rehash(); + + for (Iterator it = t.entrySet().iterator(); it.hasNext();) { + Map.Entry entry = (Map.Entry) it.next(); + Object key = entry.getKey(); + Object value = entry.getValue(); + put(key, value); + } + } + + + /** + * Removes all mappings from this map. + */ + public synchronized void clear() { + Entry tab[] = table; + for (int i = 0; i < tab.length ; ++i) { + + // must invalidate all to force concurrent get's to wait and then retry + for (Entry e = tab[i]; e != null; e = e.next) + e.value = null; + + tab[i] = null; + } + count = 0; + recordModification(tab); + } + + /** + * Returns a shallow copy of this + * ConcurrentReaderHashMap instance: the keys and + * values themselves are not cloned. + * + * @return a shallow copy of this map. + */ + + public synchronized Object clone() { + try { + ConcurrentReaderHashMap t = (ConcurrentReaderHashMap)super.clone(); + + t.keySet = null; + t.entrySet = null; + t.values = null; + + Entry[] tab = table; + t.table = new Entry[tab.length]; + Entry[] ttab = t.table; + + for (int i = 0; i < tab.length; ++i) { + Entry first = null; + for (Entry e = tab[i]; e != null; e = e.next) + first = new Entry(e.hash, e.key, e.value, first); + ttab[i] = first; + } + + return t; + } + catch (CloneNotSupportedException e) { + // this shouldn't happen, since we are Cloneable + throw new InternalError(); + } + } + + // Views + + protected transient Set keySet = null; + protected transient Set entrySet = null; + protected transient Collection values = null; + + /** + * Returns a set view of the keys contained in this map. The set is + * backed by the map, so changes to the map are reflected in the set, and + * vice-versa. The set supports element removal, which removes the + * corresponding mapping from this map, via the Iterator.remove, + * Set.remove, removeAll, retainAll, and + * clear operations. It does not support the add or + * addAll operations. + * + * @return a set view of the keys contained in this map. + */ + + public Set keySet() { + Set ks = keySet; + return (ks != null)? ks : (keySet = new KeySet()); + } + + private class KeySet extends AbstractSet { + public Iterator iterator() { + return new KeyIterator(); + } + public int size() { + return ConcurrentReaderHashMap.this.size(); + } + public boolean contains(Object o) { + return ConcurrentReaderHashMap.this.containsKey(o); + } + public boolean remove(Object o) { + return ConcurrentReaderHashMap.this.remove(o) != null; + } + public void clear() { + ConcurrentReaderHashMap.this.clear(); + } + } + + /** + * Returns a collection view of the values contained in this map. The + * collection is backed by the map, so changes to the map are reflected in + * the collection, and vice-versa. The collection supports element + * removal, which removes the corresponding mapping from this map, via the + * Iterator.remove, Collection.remove, + * removeAll, retainAll, and clear operations. + * It does not support the add or addAll operations. + * + * @return a collection view of the values contained in this map. + */ + + public Collection values() { + Collection vs = values; + return (vs != null)? vs : (values = new Values()); + } + + private class Values extends AbstractCollection { + public Iterator iterator() { + return new ValueIterator(); + } + public int size() { + return ConcurrentReaderHashMap.this.size(); + } + public boolean contains(Object o) { + return ConcurrentReaderHashMap.this.containsValue(o); + } + public void clear() { + ConcurrentReaderHashMap.this.clear(); + } + } + + /** + * Returns a collection view of the mappings contained in this map. Each + * element in the returned collection is a Map.Entry. The + * collection is backed by the map, so changes to the map are reflected in + * the collection, and vice-versa. The collection supports element + * removal, which removes the corresponding mapping from the map, via the + * Iterator.remove, Collection.remove, + * removeAll, retainAll, and clear operations. + * It does not support the add or addAll operations. + * + * @return a collection view of the mappings contained in this map. + */ + + public Set entrySet() { + Set es = entrySet; + return (es != null) ? es : (entrySet = new EntrySet()); + } + + private class EntrySet extends AbstractSet { + public Iterator iterator() { + return new HashIterator(); + } + public boolean contains(Object o) { + if (!(o instanceof Map.Entry)) + return false; + Map.Entry entry = (Map.Entry)o; + Object v = ConcurrentReaderHashMap.this.get(entry.getKey()); + return v != null && v.equals(entry.getValue()); + } + public boolean remove(Object o) { + if (!(o instanceof Map.Entry)) + return false; + return ConcurrentReaderHashMap.this.findAndRemoveEntry((Map.Entry)o); + } + public int size() { + return ConcurrentReaderHashMap.this.size(); + } + public void clear() { + ConcurrentReaderHashMap.this.clear(); + } + } + + /** + * Helper method for entrySet.remove + **/ + protected synchronized boolean findAndRemoveEntry(Map.Entry entry) { + Object key = entry.getKey(); + Object v = get(key); + if (v != null && v.equals(entry.getValue())) { + remove(key); + return true; + } + else + return false; + } + + /** + * Returns an enumeration of the keys in this table. + * + * @return an enumeration of the keys in this table. + * @see Enumeration + * @see #elements() + * @see #keySet() + * @see Map + */ + public Enumeration keys() { + return new KeyIterator(); + } + + /** + * Returns an enumeration of the values in this table. + * Use the Enumeration methods on the returned object to fetch the elements + * sequentially. + * + * @return an enumeration of the values in this table. + * @see java.util.Enumeration + * @see #keys() + * @see #values() + * @see Map + */ + + public Enumeration elements() { + return new ValueIterator(); + } + + + /** + * ConcurrentReaderHashMap collision list entry. + */ + + protected static class Entry implements Map.Entry { + + /* + The use of volatile for value field ensures that + we can detect status changes without synchronization. + The other fields are never changed, and are + marked as final. + */ + + protected final int hash; + protected final Object key; + protected final Entry next; + protected volatile Object value; + + Entry(int hash, Object key, Object value, Entry next) { + this.hash = hash; + this.key = key; + this.next = next; + this.value = value; + } + + // Map.Entry Ops + + public Object getKey() { + return key; + } + + /** + * Get the value. Note: In an entrySet or entrySet.iterator, + * unless the set or iterator is used under synchronization of the + * table as a whole (or you can otherwise guarantee lack of + * concurrent modification), getValue might + * return null, reflecting the fact that the entry has been + * concurrently removed. However, there are no assurances that + * concurrent removals will be reflected using this method. + * + * @return the current value, or null if the entry has been + * detectably removed. + **/ + public Object getValue() { + return value; + } + + /** + * Set the value of this entry. Note: In an entrySet or + * entrySet.iterator), unless the set or iterator is used under + * synchronization of the table as a whole (or you can otherwise + * guarantee lack of concurrent modification), setValue + * is not strictly guaranteed to actually replace the value field + * obtained via the get operation of the underlying hash + * table in multithreaded applications. If iterator-wide + * synchronization is not used, and any other concurrent + * put or remove operations occur, sometimes + * even to other entries, then this change is not + * guaranteed to be reflected in the hash table. (It might, or it + * might not. There are no assurances either way.) + * + * @param value the new value. + * @return the previous value, or null if entry has been detectably + * removed. + * @exception NullPointerException if the value is null. + * + **/ + + public Object setValue(Object value) { + if (value == null) + throw new NullPointerException(); + Object oldValue = this.value; + this.value = value; + return oldValue; + } + + public boolean equals(Object o) { + if (!(o instanceof Map.Entry)) + return false; + Map.Entry e = (Map.Entry)o; + return (key.equals(e.getKey()) && value.equals(e.getValue())); + } + + public int hashCode() { + return key.hashCode() ^ value.hashCode(); + } + + public String toString() { + return key + "=" + value; + } + + } + + protected class HashIterator implements Iterator, Enumeration { + protected final Entry[] tab; // snapshot of table + protected int index; // current slot + protected Entry entry = null; // current node of slot + protected Object currentKey; // key for current node + protected Object currentValue; // value for current node + protected Entry lastReturned = null; // last node returned by next + + protected HashIterator() { + tab = ConcurrentReaderHashMap.this.getTableForReading(); + index = tab.length - 1; + } + + public boolean hasMoreElements() { return hasNext(); } + public Object nextElement() { return next(); } + + + public boolean hasNext() { + + /* + currentkey and currentValue are set here to ensure that next() + returns normally if hasNext() returns true. This avoids + surprises especially when final element is removed during + traversal -- instead, we just ignore the removal during + current traversal. + */ + + for (;;) { + if (entry != null) { + Object v = entry.value; + if (v != null) { + currentKey = entry.key; + currentValue = v; + return true; + } + else + entry = entry.next; + } + + while (entry == null && index >= 0) + entry = tab[index--]; + + if (entry == null) { + currentKey = currentValue = null; + return false; + } + } + } + + protected Object returnValueOfNext() { return entry; } + + public Object next() { + if (currentKey == null && !hasNext()) + throw new NoSuchElementException(); + + Object result = returnValueOfNext(); + lastReturned = entry; + currentKey = currentValue = null; + entry = entry.next; + return result; + } + + public void remove() { + if (lastReturned == null) + throw new IllegalStateException(); + ConcurrentReaderHashMap.this.remove(lastReturned.key); + lastReturned = null; + } + + } + + + protected class KeyIterator extends HashIterator { + protected Object returnValueOfNext() { return currentKey; } + } + + protected class ValueIterator extends HashIterator { + protected Object returnValueOfNext() { return currentValue; } + } + + + + /** + * Save the state of the ConcurrentReaderHashMap + * instance to a stream (i.e., + * serialize it). + * + * @serialData The capacity of the + * ConcurrentReaderHashMap (the length of the + * bucket array) is emitted (int), followed by the + * size of the ConcurrentReaderHashMap (the number of key-value + * mappings), followed by the key (Object) and value (Object) + * for each key-value mapping represented by the ConcurrentReaderHashMap + * The key-value mappings are emitted in no particular order. + */ + + private synchronized void writeObject(java.io.ObjectOutputStream s) + throws IOException { + // Write out the threshold, loadfactor, and any hidden stuff + s.defaultWriteObject(); + + // Write out number of buckets + s.writeInt(table.length); + + // Write out size (number of Mappings) + s.writeInt(count); + + // Write out keys and values (alternating) + for (int index = table.length-1; index >= 0; index--) { + Entry entry = table[index]; + + while (entry != null) { + s.writeObject(entry.key); + s.writeObject(entry.value); + entry = entry.next; + } + } + } + + /** + * Reconstitute the ConcurrentReaderHashMap + * instance from a stream (i.e., + * deserialize it). + */ + private synchronized void readObject(java.io.ObjectInputStream s) + throws IOException, ClassNotFoundException { + // Read in the threshold, loadfactor, and any hidden stuff + s.defaultReadObject(); + + // Read in number of buckets and allocate the bucket array; + int numBuckets = s.readInt(); + table = new Entry[numBuckets]; + + // Read in size (number of Mappings) + int size = s.readInt(); + + // Read the keys and values, and put the mappings in the table + for (int i=0; i= 0 ) + { + // KHK: cvc-identity-constraint.4.2.1 ? + // keys must have all values supplied + emitError(e, "Key " + QNameHelper.pretty(_selector._constraint.getName()) + " is missing field with xpath: '" + _selector._constraint.getFields()[_value.unfilled()] + "'"); + } + else + { + // Finished. Add these fields to the selector state + _selector.addFields(_value, e); + } + } + + } + + public class IdState extends ConstraintState + { + Set _values = new LinkedHashSet(); + + IdState() { } + + void attr(Event e, QName name, SchemaType st, String value) + { + handleValue(e, st, value); + } + + void text(Event e, SchemaType st, String value, boolean emptyContent) + { + if (emptyContent) + return; + + handleValue(e, st, value); + } + + private void handleValue(Event e, SchemaType st, String value) + { + + // Null value indicates previously reported validation problem + if (value == null) return; + + if (st == null || st.isNoType()) + { + // ignore invalid values. Assume that validation catches these + return; + } + + if (XmlID.type.isAssignableFrom(st)) + { + XmlObjectList xmlValue = new XmlObjectList(1); + XmlObject o = newValue(XmlID.type, value); + + // Ignore invalid values. Assume that validation catches these + if (o == null) return; + + xmlValue.set(o, 0); + + if (_values.contains(xmlValue)) + emitError(e, XmlErrorCodes.ID_VALID$DUPLICATE, new Object[] { value }); + else + _values.add(xmlValue); + } + } + + void element(Event e, SchemaType st) {} + void endElement(Event e){} + void remove(Event e){} + + } + + public class IdRefState extends ConstraintState + { + IdState _ids; + List _values; + + IdRefState(IdState ids) + { + _ids = ids; + _values = new ArrayList(); + } + + private void handleValue(Event e, SchemaType st, String value) + { + // Null value indicates previously reported validation problem + if (value == null) return; + + if (st == null || st.isNoType()) + { + // ignore invalid values. Assume that validation catches these + return; + } + if (XmlIDREFS.type.isAssignableFrom(st)) + { + XmlIDREFS lv = (XmlIDREFS)newValue(XmlIDREFS.type, value); + + // Ignore invalid values. Assume that validation catches these + if (lv == null) return; + + List l = lv.xgetListValue(); + + // Add one value for each idref in the list + for (int i = 0 ; i < l.size() ; i++) + { + XmlObjectList xmlValue = new XmlObjectList(1); + XmlIDREF idref = (XmlIDREF)l.get(i); + xmlValue.set(idref, 0); + _values.add(xmlValue); + } + } + else if (XmlIDREF.type.isAssignableFrom(st)) + { + XmlObjectList xmlValue = new XmlObjectList(1); + XmlIDREF idref = (XmlIDREF)st.newValue(value); + + // Ignore invalid values. Assume that validation catches these + if (idref == null) return; + + xmlValue.set(idref, 0); + _values.add(xmlValue); + } + } + + void attr(Event e, QName name, SchemaType st, String value) + { + handleValue(e, st, value); + } + void text(Event e, SchemaType st, String value, boolean emptyContent) + { + if (emptyContent) + return; + + handleValue(e, st, value); + } + void remove(Event e) + { + // Validate each ref has a corresponding ID + for (Iterator it = _values.iterator() ; it.hasNext() ; ) + { + Object o = it.next(); + if (! _ids._values.contains(o)) + { + // KHK: cvc-id.1 + emitError(e, "ID not found for IDRef value '" + o + "'"); + } + } + } + void element(Event e, SchemaType st) { } + void endElement(Event e) { } + } + + private static class ElementState { + ElementState _next; + boolean _hasConstraints; + ConstraintState _savePoint; + } +} diff --git a/xmlbeans/src/common/org/apache/xmlbeans/impl/common/InvalidLexicalValueException.java b/xmlbeans/src/common/org/apache/xmlbeans/impl/common/InvalidLexicalValueException.java new file mode 100644 index 000000000..25b9ba41a --- /dev/null +++ b/xmlbeans/src/common/org/apache/xmlbeans/impl/common/InvalidLexicalValueException.java @@ -0,0 +1,76 @@ +/* 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.common; + +import javax.xml.stream.Location; + +/** + * Author: Cezar Andrei (cezar.andrei at bea.com) + * Date: Nov 24, 2003 + */ +public class InvalidLexicalValueException + extends RuntimeException +{ + private Location _location; + + public InvalidLexicalValueException() + { + super(); + } + + public InvalidLexicalValueException(String msg) + { + super(msg); + } + + public InvalidLexicalValueException(String msg, Throwable cause) + { + super(msg, cause); + } + + public InvalidLexicalValueException(Throwable cause) + { + super(cause); + } + + public InvalidLexicalValueException(String msg, Location location) + { + super(msg); + setLocation(location); + } + + public InvalidLexicalValueException(String msg, Throwable cause, Location location) + { + super(msg, cause); + setLocation(location); + } + + public InvalidLexicalValueException(Throwable cause, Location location) + { + super(cause); + setLocation(location); + } + + public Location getLocation() + { + return _location; + } + + public void setLocation(Location location) + { + this._location = location; + } +} diff --git a/xmlbeans/src/common/org/apache/xmlbeans/impl/common/JarHelper.java b/xmlbeans/src/common/org/apache/xmlbeans/impl/common/JarHelper.java new file mode 100644 index 000000000..95c6d4293 --- /dev/null +++ b/xmlbeans/src/common/org/apache/xmlbeans/impl/common/JarHelper.java @@ -0,0 +1,194 @@ +/* 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.common; + +import java.io.*; +import java.util.jar.JarOutputStream; +import java.util.jar.JarEntry; +import java.util.jar.JarInputStream; + +/** + * Provides utility services for jarring and unjarring files and directories. + * Note that a given instance of JarHelper is not threadsafe with respect to + * multiple jar operations. + * + * @author Patrick Calahan + */ +public class JarHelper +{ + // ======================================================================== + // Constants + + private static final int BUFFER_SIZE = 2156; + + // ======================================================================== + // Variables + + private byte[] mBuffer = new byte[BUFFER_SIZE]; + private int mByteCount = 0; + private boolean mVerbose = false; + private String mDestJarName = ""; + + // ======================================================================== + // Constructor + + /** + * Instantiates a new JarHelper. + */ + public JarHelper() {} + + // ======================================================================== + // Public methods + + /** + * Jars a given directory or single file into a JarOutputStream. + */ + public void jarDir(File dirOrFile2Jar, File destJar) + throws IOException { + + if (dirOrFile2Jar == null || destJar == null) + throw new IllegalArgumentException(); + + mDestJarName = destJar.getCanonicalPath(); + FileOutputStream fout = new FileOutputStream(destJar); + JarOutputStream jout = new JarOutputStream(fout); + //jout.setLevel(0); + try { + jarDir(dirOrFile2Jar, jout, null); + } catch(IOException ioe) { + throw ioe; + } finally { + jout.close(); + fout.close(); + } + } + + /** + * Unjars a given jar file into a given directory. + */ + public void unjarDir(File jarFile, File destDir) throws IOException { + BufferedOutputStream dest = null; + FileInputStream fis = new FileInputStream(jarFile); + unjar(fis,destDir); + } + + /** + * Given an InputStream on a jar file, unjars the contents into the given + * directory. + */ + public void unjar(InputStream in, File destDir) throws IOException { + BufferedOutputStream dest = null; + JarInputStream jis = new JarInputStream(in); + JarEntry entry; + while ((entry = jis.getNextJarEntry()) != null) { + if (entry.isDirectory()) { + File dir = new File(destDir,entry.getName()); + dir.mkdir(); + if (entry.getTime() != -1) dir.setLastModified(entry.getTime()); + continue; + } + int count; + byte data[] = new byte[BUFFER_SIZE]; + File destFile = new File(destDir, entry.getName()); + if (mVerbose) + System.out.println("unjarring " + destFile + + " from " + entry.getName()); + FileOutputStream fos = new FileOutputStream(destFile); + dest = new BufferedOutputStream(fos, BUFFER_SIZE); + while ((count = jis.read(data, 0, BUFFER_SIZE)) != -1) { + dest.write(data, 0, count); + } + dest.flush(); + dest.close(); + if (entry.getTime() != -1) destFile.setLastModified(entry.getTime()); + } + jis.close(); + } + + public void setVerbose(boolean b) { + mVerbose = b; + } + + // ======================================================================== + // Private methods + + private static final char SEP = '/'; + /** + * Recursively jars up the given path under the given directory. + */ + private void jarDir(File dirOrFile2jar, JarOutputStream jos, String path) + throws IOException { + if (mVerbose) System.out.println("checking " + dirOrFile2jar); + if (dirOrFile2jar.isDirectory()) { + String[] dirList = dirOrFile2jar.list(); + String subPath = (path == null) ? "" : (path+dirOrFile2jar.getName()+SEP); + if (path != null) { + JarEntry je = new JarEntry(subPath); + je.setTime(dirOrFile2jar.lastModified()); + jos.putNextEntry(je); + jos.flush(); + jos.closeEntry(); + } + for (int i = 0; i < dirList.length; i++) { + File f = new File(dirOrFile2jar, dirList[i]); + jarDir(f,jos,subPath); + } + } else { + if (dirOrFile2jar.getCanonicalPath().equals(mDestJarName)) + { + if (mVerbose) System.out.println("skipping " + dirOrFile2jar.getPath()); + return; + } + + if (mVerbose) System.out.println("adding " + dirOrFile2jar.getPath()); + FileInputStream fis = new FileInputStream(dirOrFile2jar); + try { + JarEntry entry = new JarEntry(path+dirOrFile2jar.getName()); + entry.setTime(dirOrFile2jar.lastModified()); + jos.putNextEntry(entry); + while ((mByteCount = fis.read(mBuffer)) != -1) { + jos.write(mBuffer, 0, mByteCount); + if (mVerbose) System.out.println("wrote " + mByteCount + " bytes"); + } + jos.flush(); + jos.closeEntry(); + } catch (IOException ioe) { + throw ioe; + } finally { + fis.close(); + } + } + } + + // for debugging + public static void main(String[] args) + throws IOException + { + if (args.length < 2) + { + System.err.println("Usage: JarHelper jarname.jar directory"); + return; + } + + JarHelper jarHelper = new JarHelper(); + jarHelper.mVerbose = true; + + File destJar = new File(args[0]); + File dirOrFile2Jar = new File(args[1]); + + jarHelper.jarDir(dirOrFile2Jar, destJar); + } +} diff --git a/xmlbeans/src/common/org/apache/xmlbeans/impl/common/Levenshtein.java b/xmlbeans/src/common/org/apache/xmlbeans/impl/common/Levenshtein.java new file mode 100644 index 000000000..6360b0e8e --- /dev/null +++ b/xmlbeans/src/common/org/apache/xmlbeans/impl/common/Levenshtein.java @@ -0,0 +1,88 @@ +/* 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.common; + +public class Levenshtein +{ + //**************************** + // Get minimum of three values + //**************************** + + private static int minimum(int a, int b, int c) + { + int mi = a; + if (b < mi) + mi = b; + if (c < mi) + mi = c; + return mi; + } + + //***************************** + // Compute Levenshtein distance + //***************************** + public static int distance(String s, String t) + { + int d[][]; // matrix + int n; // length of s + int m; // length of t + int i; // iterates through s + int j; // iterates through t + char s_i; // ith character of s + char t_j; // jth character of t + int cost; // cost + + // Step 1 + n = s.length(); + m = t.length(); + if (n == 0) + return m; + if (m == 0) + return n; + d = new int[n+1][m+1]; + + // Step 2 + for (i = 0; i <= n; i++) + d[i][0] = i; + for (j = 0; j <= m; j++) + d[0][j] = j; + + // Step 3 + for (i = 1; i <= n; i++) + { + s_i = s.charAt (i - 1); + + // Step 4 + for (j = 1; j <= m; j++) + { + t_j = t.charAt(j - 1); + + // Step 5 + if (s_i == t_j) + cost = 0; + else + cost = 1; + + // Step 6 + d[i][j] = minimum(d[i-1][j]+1, d[i][j-1]+1, d[i-1][j-1] + cost); + } + } + + // Step 7 + return d[n][m]; + } + +} diff --git a/xmlbeans/src/common/org/apache/xmlbeans/impl/common/LoadSaveUtils.java b/xmlbeans/src/common/org/apache/xmlbeans/impl/common/LoadSaveUtils.java new file mode 100644 index 000000000..74b52743e --- /dev/null +++ b/xmlbeans/src/common/org/apache/xmlbeans/impl/common/LoadSaveUtils.java @@ -0,0 +1,140 @@ +/* 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. + */ + +/** + * Author: Cezar Andrei ( cezar.andrei at bea.com ) + * Date: Nov 11, 2003 + */ +package org.apache.xmlbeans.impl.common; + +import org.w3c.dom.Document; +import org.xml.sax.SAXException; + +import javax.xml.parsers.SAXParserFactory; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.stream.XMLStreamWriter; +import javax.xml.stream.XMLOutputFactory; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamException; +import java.io.File; +import java.io.IOException; +import java.io.OutputStream; +import java.io.InputStream; + + +public class LoadSaveUtils +{ + public static Document xmlText2GenericDom(InputStream is, Document emptyDoc) + throws SAXException, ParserConfigurationException, IOException + { + SAXParserFactory factory = SAXParserFactory.newInstance(); + factory.setNamespaceAware(true); + + SAXParser parser = factory.newSAXParser(); + + Sax2Dom handler = new Sax2Dom(emptyDoc); + + parser.setProperty("http://xml.org/sax/properties/lexical-handler", handler); + parser.parse(is, handler); + + return (Document) handler.getDOM(); + } + + public static void xmlStreamReader2XmlText(XMLStreamReader xsr, OutputStream os) + throws XMLStreamException + { + //REVIEW (zieg): I think we can cache this factory + XMLStreamWriter xsw = XMLOutputFactory.newInstance().createXMLStreamWriter(os); + + while (xsr.hasNext()) + { + switch( xsr.getEventType() ) + { + case XMLStreamReader.ATTRIBUTE: + xsw.writeAttribute(xsr.getPrefix(), xsr.getNamespaceURI(), xsr.getLocalName(), xsr.getText()); + break; + + case XMLStreamReader.CDATA: + xsw.writeCData(xsr.getText()); + break; + + case XMLStreamReader.CHARACTERS: + xsw.writeCharacters(xsr.getText()); + break; + + case XMLStreamReader.COMMENT: + xsw.writeComment(xsr.getText()); + break; + + case XMLStreamReader.DTD: + xsw.writeDTD(xsr.getText()); + break; + + case XMLStreamReader.END_DOCUMENT: + xsw.writeEndDocument(); + break; + + case XMLStreamReader.END_ELEMENT: + xsw.writeEndElement(); + break; + + case XMLStreamReader.ENTITY_DECLARATION: + break; + + case XMLStreamReader.ENTITY_REFERENCE: + xsw.writeEntityRef(xsr.getText()); + break; + + case XMLStreamReader.NAMESPACE: + xsw.writeNamespace(xsr.getPrefix(), xsr.getNamespaceURI()); + break; + + case XMLStreamReader.NOTATION_DECLARATION: + break; + + case XMLStreamReader.PROCESSING_INSTRUCTION: + xsw.writeProcessingInstruction(xsr.getPITarget(), xsr.getPIData()); + break; + + case XMLStreamReader.SPACE: + xsw.writeCharacters(xsr.getText()); + break; + + case XMLStreamReader.START_DOCUMENT: + xsw.writeStartDocument(); + break; + + case XMLStreamReader.START_ELEMENT: + xsw.writeStartElement(xsr.getPrefix()==null ? "" : xsr.getPrefix(), xsr.getLocalName(), xsr.getNamespaceURI()); + + int attrs = xsr.getAttributeCount(); + for ( int i = attrs-1; i>=0; i--) + { + xsw.writeAttribute(xsr.getAttributePrefix(i)==null ? "" : xsr.getAttributePrefix(i), xsr.getAttributeNamespace(i), xsr.getAttributeLocalName(i), xsr.getAttributeValue(i)); + } + + int nses = xsr.getNamespaceCount(); + for ( int i = 0; i= 'a' && ch <='z' || + ch >= 'A' && ch <='Z' || + ch >= '0' && ch <='9' || + ch == '-' || ch == '.' || ch == '+'); + } + + private static boolean isUriAlphaChar(char ch) + { + return (ch >= 'a' && ch <='z' || ch >= 'A' && ch <= 'Z'); + } + + private static int findSchemeColon(String uri) + { + int len = uri.length(); + if (len == 0) + return -1; + if (!isUriAlphaChar(uri.charAt(0))) + return -1; + int i; + for (i = 1; i < len; i++) + if (!isUriSchemeChar(uri.charAt(i))) + break; + if (i == len) + return -1; + if (uri.charAt(i) != ':') + return -1; + // consume consecutive colons + for (; i < len; i++) + if (uri.charAt(i) != ':') + break; + // for the "scheme:::" case, return len-1 + return i-1; + } + + private static String jls77String(String name) + { + StringBuffer buf = new StringBuffer(name); + for (int i = 0; i < name.length(); i++) + { + // We need to also make sure that our package names don't contain the + // "$" character in them, which, although a valid Java identifier part, + // would create confusion when trying to generate fully-qualified names + if (!Character.isJavaIdentifierPart(buf.charAt(i)) || '$' == buf.charAt(i)) + buf.setCharAt(i, '_'); + } + if (buf.length() == 0 || !Character.isJavaIdentifierStart(buf.charAt(0))) + buf.insert(0, '_'); + if (isJavaReservedWord(name)) + buf.append('_'); + return buf.toString(); + } + + private static List splitDNS(String dns) + { + // JAXB says: only split+reverse DNS if TLD matches known TLDs or ISO 3166 + // We are ignoring this now (TH) + + List result = new ArrayList(); + + int end = dns.length(); + int begin = dns.lastIndexOf('.'); + for ( ; begin != -1 ; begin--) + { + if (dns.charAt(begin) == '.') { + result.add(jls77String(dns.substring(begin + 1, end))); + end = begin; + } + } + result.add(jls77String(dns.substring(0, end))); + + // JAXB draft example implies removal of www + if (result.size() >= 3 && + ((String)result.get(result.size() - 1)).toLowerCase().equals("www")) + result.remove(result.size() - 1); + + return result; + } + + private static String processFilename(String filename) + { + // JAXB says: strip 2 or 3 letter extension or ".html" + + int i = filename.lastIndexOf('.'); + if (i > 0 && ( + i + 1 + 2 == filename.length() || + i + 1 + 3 == filename.length() || + filename.substring(i + 1).toLowerCase() == "html")) + { + return filename.substring(0, i); + } + + return filename; + } + + public static String getPackageFromNamespace(String uri) + { + return getPackageFromNamespace(uri, false); + } + + public static String getPackageFromNamespace(String uri, boolean useJaxRpcRules) + { + // special case: no namespace -> package "noNamespace" + if (uri == null || uri.length() == 0) + return "noNamespace"; + + // apply draft JAXB rules + int len = uri.length(); + int i = findSchemeColon(uri); + List result = null; + + if (i == len-1) + { + // XMLBEANS-57: colon is at end so just use scheme as the package name + result = new ArrayList(); + result.add(uri.substring(0, i)); + } + else if (i >= 0 && uri.substring(0, i).equals("java")) + { + result = Arrays.asList(uri.substring(i + 1).split("\\.")); + } + else { + result = new ArrayList(); + outer: for (i = i + 1; i < len; ) + { + while (uri.charAt(i) == '/') + if (++i >= len) break outer; + int start = i; + while (uri.charAt(i) != '/') + if (++i >= len) break; + int end = i; + result.add(uri.substring(start, end)); + } + if (result.size() > 1) + result.set(result.size() - 1, processFilename((String)result.get(result.size() - 1))); + + if (result.size() > 0) + { + List splitdns = splitDNS((String)result.get(0)); + result.remove(0); + result.addAll(0, splitdns); + } + } + + StringBuffer buf = new StringBuffer(); + for (Iterator it = result.iterator(); it.hasNext(); ) + { + String part = nonJavaKeyword(lowerCamelCase((String)it.next(), useJaxRpcRules, true)); + if (part.length() > 0) + { + buf.append(part); + buf.append('.'); + } + } + if (buf.length() == 0) + return "noNamespace"; + if (useJaxRpcRules) + return buf.substring(0, buf.length() - 1).toLowerCase(); + return buf.substring(0, buf.length() - 1); // chop off extra dot + } + + public static void main(String[] args) + { + for (int i = 0; i < args.length; i++) + System.out.println(upperCaseUnderbar(args[i])); + } + + /** + * Returns a upper-case-and-underbar string using the JAXB rules. + * Always starts with a capital letter that is a valid + * java identifier start. (If JAXB rules don't produce + * one, then "X_" is prepended.) + */ + public static String upperCaseUnderbar(String xml_name) + { + StringBuffer buf = new StringBuffer(); + List words = splitWords(xml_name, false); + + final int sz = words.size() - 1; + if (sz >= 0 && !Character.isJavaIdentifierStart(((String)words.get(0)).charAt(0))) + buf.append("X_"); + + for(int i = 0 ; i < sz ; i++) + { + buf.append((String)words.get(i)); + buf.append(USCORE); + } + + if (sz >= 0) + { + buf.append((String)words.get(sz)); + } + + //upcase entire buffer + final int len = buf.length(); + for(int j = 0 ; j < len ; j++) + { + char c = buf.charAt(j); + buf.setCharAt(j, Character.toUpperCase(c)); + } + + return buf.toString(); + } + + /** + * Returns a camel-cased string using the JAXB rules. + * Always starts with a capital letter that is a valid + * java identifier start. (If JAXB rules don't produce + * one, then "X" is prepended.) + */ + public static String upperCamelCase(String xml_name) + { + return upperCamelCase(xml_name, false); + } + + /** + * Returns a camel-cased string, but either JAXB or JAX-RPC rules + * are used + */ + public static String upperCamelCase(String xml_name, boolean useJaxRpcRules) + { + StringBuffer buf = new StringBuffer(); + List words = splitWords(xml_name, useJaxRpcRules); + + if (words.size() > 0) + { + if (!Character.isJavaIdentifierStart(((String)words.get(0)).charAt(0))) + buf.append("X"); + + Iterator itr = words.iterator(); + while(itr.hasNext()) + buf.append((String)itr.next()); + } + return buf.toString(); + } + + /** + * Returns a camel-cased string using the JAXB rules, + * where the first component is lowercased. Note that + * if the first component is an acronym, the whole + * thigns gets lowercased. + * Always starts with a lowercase letter that is a valid + * java identifier start. (If JAXB rules don't produce + * one, then "x" is prepended.) + */ + public static String lowerCamelCase(String xml_name) + { + return lowerCamelCase(xml_name, false, true); + } + + /** + * Returns a camel-cased string using the JAXB or JAX-RPC rules + */ + public static String lowerCamelCase(String xml_name, boolean useJaxRpcRules, + boolean fixGeneratedName) + { + StringBuffer buf = new StringBuffer(); + List words = splitWords(xml_name, useJaxRpcRules); + + if (words.size() > 0) + { + String first = ((String)words.get(0)).toLowerCase(); + char f = first.charAt(0); + if (!Character.isJavaIdentifierStart(f) && fixGeneratedName) + buf.append("x"); + buf.append(first); + + Iterator itr = words.iterator(); + itr.next(); // skip already-lowercased word + while(itr.hasNext()) + buf.append((String)itr.next()); + } + return buf.toString(); + } + + public static String upperCaseFirstLetter(String s) + { + if (s.length() == 0 || Character.isUpperCase(s.charAt(0))) + return s; + + StringBuffer buf = new StringBuffer(s); + buf.setCharAt(0, Character.toUpperCase(buf.charAt(0))); + return buf.toString(); + } + + + /** + split an xml name into words via JAXB approach, upcasing first + letter of each word as needed, if upcase is true + + ncname is xml ncname (i.e. no colons). + */ + private static void addCapped(List list, String str) + { + if (str.length() > 0) + list.add(upperCaseFirstLetter(str)); + } + + public static List splitWords(String name, boolean useJaxRpcRules) + { + List list = new ArrayList(); + int len = name.length(); + int start = 0; + int prefix = START; + for (int i = 0; i < len; i++) + { + int current = getCharClass(name.charAt(i), useJaxRpcRules); + if (prefix != PUNCT && current == PUNCT) + { + addCapped(list, name.substring(start, i)); + while ((current = getCharClass(name.charAt(i), useJaxRpcRules)) == PUNCT) + if (++i >= len) return list; + start = i; + } + else if ((prefix == DIGIT) != (current == DIGIT) || + (prefix == LOWER && current != LOWER) || + (isLetter(prefix) != isLetter(current))) + { + addCapped(list, name.substring(start, i)); + start = i; + } + else if (prefix == UPPER && current == LOWER && i > start + 1) + { + addCapped(list, name.substring(start, i - 1)); + start = i - 1; + } + prefix = current; + } + addCapped(list, name.substring(start)); + return list; + } + + //char classes + private final static int START = 0; + private final static int PUNCT = 1; + private final static int DIGIT = 2; + private final static int MARK = 3; + private final static int UPPER = 4; + private final static int LOWER= 5; + private final static int NOCASE= 6; + + public static int getCharClass(char c, boolean useJaxRpcRules) + { + //ordering is important here. + if (isPunctuation(c, useJaxRpcRules)) + return PUNCT; + else if (Character.isDigit(c)) + return DIGIT; + else if (Character.isUpperCase(c)) + return UPPER; + else if (Character.isLowerCase(c)) + return LOWER; + else if (Character.isLetter(c)) + return NOCASE; + else if (Character.isJavaIdentifierPart(c)) + return MARK; + else + return PUNCT; // not covered by JAXB: treat it as punctuation + } + + private static boolean isLetter(int state) + { + return (state==UPPER + || state==LOWER + || state==NOCASE); + } + + public static boolean isPunctuation(char c, boolean useJaxRpcRules) + { + return (c == HYPHEN + || c == PERIOD + || c == COLON + || c == DOT + || (c == USCORE && !useJaxRpcRules) + || c == TELEIA + || c == AYAH + || c == ELHIZB); + } + + /** + * Intended to be applied to a lowercase-starting identifier that + * may collide with a Java keyword. If it does collide, this + * prepends the letter "x". + */ + public static String nonJavaKeyword(String word) + { + if (isJavaReservedWord(word)) + return 'x' + word; + return word; + } + + /** + * Intended to be applied to a lowercase-starting identifier that + * may collide with a Java keyword. If it does collide, this + * prepends the letter "x". + */ + public static String nonExtraKeyword(String word) + { + if (isExtraReservedWord(word, true)) + return word + "Value"; + return word; + } + + /** + * Intended to be applied to an uppercase-starting identifier that + * may collide with a java.lang.* classname. If it does collide, this + * prepends the letter "X". + */ + public static String nonJavaCommonClassName(String name) + { + if (isJavaCommonClassName(name)) + return "X" + name; + return name; + } + + private static boolean isJavaReservedWord(String word) + { + return isJavaReservedWord(word, true); + } + + private static boolean isJavaReservedWord(String word, boolean ignore_case) + { + if (ignore_case) + word = word.toLowerCase(); + return javaWords.contains(word); + } + + private static boolean isExtraReservedWord(String word, boolean ignore_case) + { + if (ignore_case) + word = word.toLowerCase(); + return extraWords.contains(word); + } + + public static boolean isJavaCommonClassName(String word) + { + return javaNames.contains(word); + } +} diff --git a/xmlbeans/src/common/org/apache/xmlbeans/impl/common/PrefixResolver.java b/xmlbeans/src/common/org/apache/xmlbeans/impl/common/PrefixResolver.java new file mode 100644 index 000000000..32af527bd --- /dev/null +++ b/xmlbeans/src/common/org/apache/xmlbeans/impl/common/PrefixResolver.java @@ -0,0 +1,31 @@ +/* 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.common; + +public interface PrefixResolver +{ + /** + * Caled when the user has a prefix and needs to look up the corresponding + * namespace URI. If the prefix is not defined in this context, then this + * method may return null. The no-namespace is represented by the empty + * string return result. + * + * If the prefix is null or "", then the default namespace is being + * requested. To conform with the XML spec, the default namespace will + * return the no-namespace ("") if it is not mapped. + */ + String getNamespaceForPrefix(String prefix); +} diff --git a/xmlbeans/src/common/org/apache/xmlbeans/impl/common/PushedInputStream.java b/xmlbeans/src/common/org/apache/xmlbeans/impl/common/PushedInputStream.java new file mode 100644 index 000000000..db066777d --- /dev/null +++ b/xmlbeans/src/common/org/apache/xmlbeans/impl/common/PushedInputStream.java @@ -0,0 +1,209 @@ +/* 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.common; + +import java.io.IOException; +import java.io.OutputStream; +import java.io.InputStream; + + +public abstract class PushedInputStream extends InputStream +{ + private static int defaultBufferSize = 2048; + protected byte buf[]; + protected int writepos; + protected int readpos; + protected int markpos = -1; + protected int marklimit; + protected OutputStream outputStream = new InternalOutputStream(); + + /** + * Called when more bytes need to be written into this stream + * (as an OutputStream). + * + * This method must write at least one byte if the stream is + * not ended, and it must not write any bytes if the stream has + * already ended. + */ + protected abstract void fill(int requestedBytes) throws IOException; + + /** + * Returns the linked output stream. + * + * This is the output stream that must be written to whenever + * the fill method is called. + */ + public final OutputStream getOutputStream() + { + return outputStream; + } + + public PushedInputStream() + { + this(defaultBufferSize); + } + + public PushedInputStream(int size) + { + if (size < 0) + { + throw new IllegalArgumentException("Negative initial buffer size"); + } + buf = new byte[size]; + } + + /** + * Makes room for cb more bytes of data + */ + private void shift(int cb) + { + int savepos = readpos; + if (markpos > 0) + { + if (readpos - markpos > marklimit) + markpos = -1; + else + savepos = markpos; + } + + int size = writepos - savepos; + + if (savepos > 0 && buf.length - size >= cb && size <= cb) + { + System.arraycopy(buf, savepos, buf, 0, size); + } + else + { + int newcount = size + cb; + byte newbuf[] = new byte[Math.max(buf.length << 1, newcount)]; + System.arraycopy(buf, savepos, newbuf, 0, size); + buf = newbuf; + } + + if (savepos > 0) + { + readpos -= savepos; + if (markpos > 0) + markpos -= savepos; + writepos -= savepos; + } + } + + public synchronized int read() throws IOException + { + if (readpos >= writepos) + { + fill(1); + if (readpos >= writepos) + return -1; + } + return buf[readpos++] & 0xff; + } + + /** + * Read characters into a portion of an array, reading from the underlying + * stream at most once if necessary. + */ + public synchronized int read(byte[] b, int off, int len) throws IOException + { + int avail = writepos - readpos; + if (avail < len) + { + fill(len - avail); + avail = writepos - readpos; + if (avail <= 0) return -1; + } + int cnt = (avail < len) ? avail : len; + System.arraycopy(buf, readpos, b, off, cnt); + readpos += cnt; + return cnt; + } + + public synchronized long skip(long n) throws IOException + { + if (n <= 0) + return 0; + + long avail = writepos - readpos; + + if (avail < n) + { + // Fill in buffer to save bytes for reset + long req = n - avail; + if (req > Integer.MAX_VALUE) + req = Integer.MAX_VALUE; + fill((int)req); + avail = writepos - readpos; + if (avail <= 0) + return 0; + } + + long skipped = (avail < n) ? avail : n; + readpos += skipped; + return skipped; + } + + public synchronized int available() + { + return writepos - readpos; + } + + public synchronized void mark(int readlimit) + { + marklimit = readlimit; + markpos = readpos; + } + + public synchronized void reset() throws IOException + { + if (markpos < 0) + throw new IOException("Resetting to invalid mark"); + readpos = markpos; + } + + public boolean markSupported() + { + return true; + } + + private class InternalOutputStream extends OutputStream + { + public synchronized void write(int b) throws IOException + { + if (writepos + 1 > buf.length) + { + shift(1); + } + buf[writepos] = (byte)b; + writepos += 1; + } + + public synchronized void write(byte b[], int off, int len) + { + if ((off < 0) || (off > b.length) || (len < 0) || + ((off + len) > b.length) || ((off + len) < 0)) + throw new IndexOutOfBoundsException(); + else if (len == 0) + return; + + if (writepos + len > buf.length) + shift(len); + + System.arraycopy(b, off, buf, writepos, len); + writepos += len; + } + } +} diff --git a/xmlbeans/src/common/org/apache/xmlbeans/impl/common/QNameHelper.java b/xmlbeans/src/common/org/apache/xmlbeans/impl/common/QNameHelper.java new file mode 100644 index 000000000..b6c44588c --- /dev/null +++ b/xmlbeans/src/common/org/apache/xmlbeans/impl/common/QNameHelper.java @@ -0,0 +1,405 @@ +/* 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.common; + +import javax.xml.namespace.QName; +import org.apache.xmlbeans.xml.stream.XMLName; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.Map; +import java.util.HashMap; +import java.util.Collections; +import java.io.UnsupportedEncodingException; + +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.SchemaField; + +public class QNameHelper +{ + private static final Map WELL_KNOWN_PREFIXES = buildWKP(); + + public static XMLName getXMLName(QName qname) + { + if (qname == null) + return null; + + return XMLNameHelper.forLNS( qname.getLocalPart(), qname.getNamespaceURI() ); + } + + public static QName forLNS(String localname, String uri) + { + if (uri == null) + uri = ""; + return new QName(uri, localname); + } + + public static QName forLN(String localname) + { + return new QName("", localname); + } + + public static QName forPretty(String pretty, int offset) + { + int at = pretty.indexOf('@', offset); + if (at < 0) + return new QName("", pretty.substring(offset)); + return new QName(pretty.substring(at + 1), pretty.substring(offset, at)); + } + + public static String pretty(QName name) + { + if (name == null) + return "null"; + + if (name.getNamespaceURI() == null || name.getNamespaceURI().length() == 0) + return name.getLocalPart(); + + return name.getLocalPart() + "@" + name.getNamespaceURI(); + } + + private static final char[] hexdigits = new char[] + {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; + + private static boolean isSafe(int c) + { + if (c >= 'a' && c <= 'z') + return true; + if (c >= 'A' && c <= 'Z') + return true; + if (c >= '0' && c <= '9') + return true; + return false; + } + + // This produces a string which is a safe filename from the given string s. + // To make it a safe filename, the following two transformations are applied: + // + // 1. First all non-ascii-alphanumeric characters are escaped using + // their UTF8 byte sequence, in the form _xx_xx_xx, for example, + // "Hello_20There" for "Hello There". (Obviously, a single unicode + // character may expand into as many as three escape patterns.) + // If the resulting string is 64 characters or fewer, that's the result. + // + // 2. If the resulting string is longer than 64 characters, then it is + // discarded. Instead, the SHA1 algorithm is run on the original + // string's UTF8 representation, and then the resulting 20-byte message + // digest is turned into a 40-character hex string; then "URI_SHA_1_" is + // prepended. + // + // The reason for the "shortening" is to avoid filenames longer than about + // 256 characters, which are prohibited on Windows NT. + + public static final int MAX_NAME_LENGTH = 64; + public static final String URI_SHA1_PREFIX = "URI_SHA_1_"; + + public static String hexsafe(String s) + { + StringBuffer result = new StringBuffer(); + for (int i = 0; i < s.length(); i++) + { + char ch = s.charAt(i); + if (isSafe(ch)) + { + result.append(ch); + } + else + { + byte[] utf8 = null; + try + { + utf8 = s.substring(i, i + 1).getBytes("UTF-8"); + for (int j = 0; j < utf8.length; j++) + { + result.append('_'); + result.append(hexdigits[(utf8[j] >> 4) & 0xF]); + result.append(hexdigits[utf8[j] & 0xF]); + } + } + catch(UnsupportedEncodingException uee) + { + // should never happen - UTF-8 i always supported + result.append("_BAD_UTF8_CHAR"); + } + } + } + + // short enough? Done! + if (result.length() <= MAX_NAME_LENGTH) + return result.toString(); + + // too long? use SHA1 + try + { + MessageDigest md = MessageDigest.getInstance("SHA"); + byte[] inputBytes = null; + try + { + inputBytes = s.getBytes("UTF-8"); + } + catch(UnsupportedEncodingException uee) + { + // should never happen - UTF-8 is always supported + inputBytes = new byte[0]; + } + byte[] digest = md.digest(inputBytes); + assert(digest.length == 20); // SHA1 160 bits == 20 bytes + result = new StringBuffer(URI_SHA1_PREFIX); + for (int j = 0; j < digest.length; j++) + { + result.append(hexdigits[(digest[j] >> 4) & 0xF]); + result.append(hexdigits[digest[j] & 0xF]); + } + return result.toString(); + } + catch (NoSuchAlgorithmException e) + { + throw new IllegalStateException("Using in a JDK without an SHA implementation"); + } + } + + public static String hexsafedir(QName name) + { + if (name.getNamespaceURI() == null || name.getNamespaceURI().length() == 0) + return "_nons/" + hexsafe(name.getLocalPart()); + return hexsafe(name.getNamespaceURI()) + "/" + hexsafe(name.getLocalPart()); + } + + private static Map buildWKP() + { + Map result = new HashMap(); + result.put("http://www.w3.org/XML/1998/namespace", "xml"); + result.put("http://www.w3.org/2001/XMLSchema", "xs"); + result.put("http://www.w3.org/2001/XMLSchema-instance", "xsi"); + result.put("http://schemas.xmlsoap.org/wsdl/", "wsdl"); + result.put("http://schemas.xmlsoap.org/soap/encoding/", "soapenc"); + result.put("http://schemas.xmlsoap.org/soap/envelope/", "soapenv"); + return Collections.unmodifiableMap(result); + } + + public static String readable(SchemaType sType) + { + return readable(sType, WELL_KNOWN_PREFIXES); + } + + public static String readable(SchemaType sType, Map nsPrefix) + { + if (sType.getName() != null) + { + return readable(sType.getName(), nsPrefix); + } + + if (sType.isAttributeType()) + { + return "attribute type " + readable(sType.getAttributeTypeAttributeName(), nsPrefix); + } + + if (sType.isDocumentType()) + { + return "document type " + readable(sType.getDocumentElementName(), nsPrefix); + } + + if (sType.isNoType() || sType.getOuterType() == null) + { + return "invalid type"; + } + + SchemaType outerType = sType.getOuterType(); + SchemaField container = sType.getContainerField(); + + if (outerType.isAttributeType()) + { + return "type of attribute " + readable(container.getName(), nsPrefix); + } + else if (outerType.isDocumentType()) + { + return "type of element " + readable(container.getName(), nsPrefix); + } + + if (container != null) + { + if (container.isAttribute()) + { + return "type of " + container.getName().getLocalPart() + " attribute in " + readable(outerType, nsPrefix); + } + else + { + return "type of " + container.getName().getLocalPart() + " element in " + readable(outerType, nsPrefix); + } + } + + if (outerType.getBaseType() == sType) + return "base type of " + readable(outerType, nsPrefix); + else if (outerType.getSimpleVariety() == SchemaType.LIST) + return "item type of " + readable(outerType, nsPrefix); + else if (outerType.getSimpleVariety() == SchemaType.UNION) + return "member type " + sType.getAnonymousUnionMemberOrdinal() + " of " + readable(outerType, nsPrefix); + else + return "inner type in " + readable(outerType, nsPrefix); + } + + public static String readable(QName name) + { + return readable(name, WELL_KNOWN_PREFIXES); + } + + public static String readable(QName name, Map prefixes) + { + if (name.getNamespaceURI().length() == 0) + return name.getLocalPart(); + String prefix = (String)prefixes.get(name.getNamespaceURI()); + if (prefix != null) + return prefix + ":" + name.getLocalPart(); + return name.getLocalPart() + " in namespace " + name.getNamespaceURI(); + } + + public static String suggestPrefix(String namespace) + { + String result = (String)WELL_KNOWN_PREFIXES.get(namespace); + if (result != null) + return result; + + int len = namespace.length(); + int i = namespace.lastIndexOf('/'); + if (i > 0 && i == namespace.length() - 1) + { + len = i; + i = namespace.lastIndexOf('/', i - 1); + } + + i += 1; // skip '/', also covers -1 case. + + if (namespace.startsWith("www.", i)) + { + i += 4; // "www.".length() + } + + while (i < len) + { + if (XMLChar.isNCNameStart(namespace.charAt(i))) + break; + i += 1; + } + + for (int end = i + 1; end < len; end += 1) + { + if (!XMLChar.isNCName(namespace.charAt(end)) || !Character.isLetterOrDigit(namespace.charAt(end))) + { + len = end; + break; + } + } + + // prefixes starting with "xml" are forbidden, so change "xmls" -> "xs" + if (namespace.length() >= i + 3 && startsWithXml(namespace, i)) + { + if (namespace.length() >= i + 4) + return "x" + Character.toLowerCase(namespace.charAt(i + 3)); + return "ns"; + } + + if (len - i > 4) // four or less? leave it. + { + if (isVowel(namespace.charAt(i + 2)) && !isVowel(namespace.charAt(i + 3))) + len = i + 4; + else + len = i + 3; // more than four? truncate to 3. + } + + if (len - i == 0) + return "ns"; + + return namespace.substring(i, len).toLowerCase(); + } + + private static boolean startsWithXml(String s, int i) + { + if (s.length() < i + 3) + return false; + + if (s.charAt(i) != 'X' && s.charAt(i) != 'x') + return false; + if (s.charAt(i + 1) != 'M' && s.charAt(i + 1) != 'm') + return false; + if (s.charAt(i + 2) != 'L' && s.charAt(i + 2) != 'l') + return false; + + return true; + } + + private static boolean isVowel(char ch) + { + switch (ch) + { + case 'a': + case 'e': + case 'i': + case 'o': + case 'u': + case 'A': + case 'E': + case 'I': + case 'O': + case 'U': + return true; + default: + return false; + } + } + + public static String namespace(SchemaType sType) + { + while (sType != null) + { + if (sType.getName() != null) + return sType.getName().getNamespaceURI(); + if (sType.getContainerField() != null && sType.getContainerField().getName().getNamespaceURI().length() > 0) + return sType.getContainerField().getName().getNamespaceURI(); + sType = sType.getOuterType(); + } + return ""; + } + + /** + * Returns the local name of the given node. + * + * @param qname Input name + * + * @return Local part of the name if prefixed, or the given name if not + */ + public static String getLocalPart(String qname) + { + + int index = qname.indexOf(':'); + + return (index < 0) ? qname : qname.substring(index + 1); + } + + /** + * Returns the local name of the given node. + * + * @param qname Input name + * + * @return Prefix of name or empty string if none there + */ + public static String getPrefixPart(String qname) + { + + int index = qname.indexOf(':'); + + return (index >= 0) ? qname.substring(0, index) : ""; + } +} diff --git a/xmlbeans/src/common/org/apache/xmlbeans/impl/common/ReaderInputStream.java b/xmlbeans/src/common/org/apache/xmlbeans/impl/common/ReaderInputStream.java new file mode 100644 index 000000000..275d8d67e --- /dev/null +++ b/xmlbeans/src/common/org/apache/xmlbeans/impl/common/ReaderInputStream.java @@ -0,0 +1,59 @@ +/* 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.common; + +import java.io.Reader; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.io.UnsupportedEncodingException; +import java.io.IOException; + +public class ReaderInputStream extends PushedInputStream +{ + private Reader reader; + private Writer writer; + private char[] buf; + public static int defaultBufferSize = 2048; + + public ReaderInputStream(Reader reader, String encoding) throws UnsupportedEncodingException + { + this(reader, encoding, defaultBufferSize); + } + + public ReaderInputStream(Reader reader, String encoding, int bufferSize) throws UnsupportedEncodingException + { + if (bufferSize <= 0) + throw new IllegalArgumentException("Buffer size <= 0"); + + this.reader = reader; + this.writer = new OutputStreamWriter(getOutputStream(), encoding); + buf = new char[bufferSize]; + } + + public void fill(int requestedBytes) throws IOException + { + do + { + int chars = reader.read(buf); + if (chars < 0) + return; + + writer.write(buf, 0, chars); + writer.flush(); + } + while (available() <= 0); // loop for safety, in case encoding didn't produce any bytes yet + } +} diff --git a/xmlbeans/src/common/org/apache/xmlbeans/impl/common/ResolverUtil.java b/xmlbeans/src/common/org/apache/xmlbeans/impl/common/ResolverUtil.java new file mode 100644 index 000000000..626e48bc5 --- /dev/null +++ b/xmlbeans/src/common/org/apache/xmlbeans/impl/common/ResolverUtil.java @@ -0,0 +1,77 @@ +/* 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.common; + +import org.apache.xmlbeans.SystemProperties; + +import org.xml.sax.EntityResolver; +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; + +/** + * Author: Cezar Andrei (cezar.andrei at bea.com) + * Date: Dec 3, 2003 + */ +public class ResolverUtil +{ + private static EntityResolver _entityResolver = null; + + static + { + try + { + String erClassName = SystemProperties.getProperty("xmlbean.entityResolver"); + if (erClassName != null) { + Object o = Class.forName(erClassName).newInstance(); + _entityResolver = (EntityResolver)o; + } + } + catch (Exception e) + { + _entityResolver = null; + } + } + + public static EntityResolver getGlobalEntityResolver() + { + return _entityResolver; + } + + public static EntityResolver resolverForCatalog(String catalogFile) + { + if (catalogFile==null) + return null; + + try + { + Class cmClass = Class.forName("org.apache.xml.resolver.CatalogManager"); + Constructor cstrCm = cmClass.getConstructor(new Class[] {}); + Object cmObj = cstrCm.newInstance(new Object[] {}); + Method cmMethod = cmClass.getMethod("setCatalogFiles", new Class[] {String.class}); + cmMethod.invoke(cmObj, new String[] {catalogFile}); + + Class crClass = Class.forName("org.apache.xml.resolver.tools.CatalogResolver"); + Constructor cstrCr = crClass.getConstructor(new Class[] {cmClass}); + Object crObj = cstrCr.newInstance(new Object[] {cmObj}); + + return (EntityResolver)crObj; + } + catch( Exception e ) + { + return null; + } + } +} diff --git a/xmlbeans/src/common/org/apache/xmlbeans/impl/common/Sax2Dom.java b/xmlbeans/src/common/org/apache/xmlbeans/impl/common/Sax2Dom.java new file mode 100644 index 000000000..67294bb84 --- /dev/null +++ b/xmlbeans/src/common/org/apache/xmlbeans/impl/common/Sax2Dom.java @@ -0,0 +1,246 @@ +/* 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.common; + +import org.w3c.dom.Node; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.ProcessingInstruction; +import org.w3c.dom.Comment; +import org.xml.sax.Attributes; +import org.xml.sax.Locator; +import org.xml.sax.SAXException; +import org.xml.sax.ContentHandler; +import org.xml.sax.helpers.DefaultHandler; +import org.xml.sax.ext.LexicalHandler; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.DocumentBuilderFactory; +import java.util.Stack; +import java.util.Vector; + +public class Sax2Dom + extends DefaultHandler + implements ContentHandler, LexicalHandler +{ + public static final String EMPTYSTRING = ""; + public static final String XML_PREFIX = "xml"; + public static final String XMLNS_PREFIX = "xmlns"; + public static final String XMLNS_STRING = "xmlns:"; + public static final String XMLNS_URI = "http://www.w3.org/2000/xmlns/"; + + private Node _root = null; + private Document _document = null; + private Stack _nodeStk = new Stack(); + private Vector _namespaceDecls = null; + + public Sax2Dom() throws ParserConfigurationException + { + final DocumentBuilderFactory factory = + DocumentBuilderFactory.newInstance(); + _document = factory.newDocumentBuilder().newDocument(); + _root = _document; + } + + public Sax2Dom(Node root) throws ParserConfigurationException + { + _root = root; + if (root instanceof Document) + { + _document = (Document) root; + } + else if (root != null) + { + _document = root.getOwnerDocument(); + } + else + { + final DocumentBuilderFactory factory = + DocumentBuilderFactory.newInstance(); + _document = factory.newDocumentBuilder().newDocument(); + _root = _document; + } + } + + public Node getDOM() + { + return _root; + } + + public void characters(char[] ch, int start, int length) + { + final Node last = (Node) _nodeStk.peek(); + + // No text nodes can be children of root (DOM006 exception) + if (last != _document) + { + final String text = new String(ch, start, length); + last.appendChild(_document.createTextNode(text)); + } + } + + public void startDocument() + { + _nodeStk.push(_root); + } + + public void endDocument() + { + _nodeStk.pop(); + } + + public void startElement(String namespace, String localName, String qName, + Attributes attrs) + { + final Element tmp = (Element) _document.createElementNS(namespace, qName); + + // Add namespace declarations first + if (_namespaceDecls != null) + { + final int nDecls = _namespaceDecls.size(); + for (int i = 0; i < nDecls; i++) + { + final String prefix = (String) _namespaceDecls.elementAt(i++); + + if (prefix == null || prefix.equals(EMPTYSTRING)) + { + tmp.setAttributeNS(XMLNS_URI, XMLNS_PREFIX, + (String) _namespaceDecls.elementAt(i)); + } + else + { + tmp.setAttributeNS(XMLNS_URI, XMLNS_STRING + prefix, + (String) _namespaceDecls.elementAt(i)); + } + } + _namespaceDecls.clear(); + } + + // Add attributes to element + final int nattrs = attrs.getLength(); + for (int i = 0; i < nattrs; i++) + { + if (attrs.getLocalName(i) == null) + { + tmp.setAttribute(attrs.getQName(i), attrs.getValue(i)); + } + else + { + tmp.setAttributeNS(attrs.getURI(i), attrs.getQName(i), + attrs.getValue(i)); + } + } + + // Append this new node onto current stack node + Node last = (Node) _nodeStk.peek(); + last.appendChild(tmp); + + // Push this node onto stack + _nodeStk.push(tmp); + } + + public void endElement(String namespace, String localName, String qName) + { + _nodeStk.pop(); + } + + public void startPrefixMapping(String prefix, String uri) + { + if (_namespaceDecls == null) + { + _namespaceDecls = new Vector(2); + } + _namespaceDecls.addElement(prefix); + _namespaceDecls.addElement(uri); + } + + public void endPrefixMapping(String prefix) + { + // do nothing + } + + /** + * This class is only used internally so this method should never + * be called. + */ + public void ignorableWhitespace(char[] ch, int start, int length) + { + } + + /** + * adds processing instruction node to DOM. + */ + public void processingInstruction(String target, String data) + { + final Node last = (Node) _nodeStk.peek(); + ProcessingInstruction pi = _document.createProcessingInstruction( + target, data); + if (pi != null) last.appendChild(pi); + } + + /** + * This class is only used internally so this method should never + * be called. + */ + public void setDocumentLocator(Locator locator) + { + } + + /** + * This class is only used internally so this method should never + * be called. + */ + public void skippedEntity(String name) + { + } + + + /** + * Lexical Handler method to create comment node in DOM tree. + */ + public void comment(char[] ch, int start, int length) + { + final Node last = (Node) _nodeStk.peek(); + Comment comment = _document.createComment(new String(ch, start, length)); + if (comment != null) last.appendChild(comment); + } + + // Lexical Handler methods- not implemented + public void startCDATA() + { + } + + public void endCDATA() + { + } + + public void startEntity(java.lang.String name) + { + } + + public void endEntity(String name) + { + } + + public void startDTD(String name, String publicId, String systemId) + throws SAXException + { + } + + public void endDTD() + { + } +} diff --git a/xmlbeans/src/common/org/apache/xmlbeans/impl/common/SniffedXmlInputStream.java b/xmlbeans/src/common/org/apache/xmlbeans/impl/common/SniffedXmlInputStream.java new file mode 100644 index 000000000..611af9267 --- /dev/null +++ b/xmlbeans/src/common/org/apache/xmlbeans/impl/common/SniffedXmlInputStream.java @@ -0,0 +1,296 @@ +/* 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.common; + +import java.io.InputStream; +import java.io.BufferedInputStream; +import java.io.IOException; +import java.io.ByteArrayInputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.nio.charset.Charset; + +public class SniffedXmlInputStream extends BufferedInputStream +{ + // We don't sniff more than 192 bytes. + public static int MAX_SNIFFED_BYTES = 192; + + public SniffedXmlInputStream(InputStream stream) throws IOException + { + super(stream); + + // read byte order marks and detect EBCDIC etc + _encoding = sniffFourBytes(); + + if (_encoding != null && _encoding.equals("IBM037")) + { + // First four bytes suggest EBCDIC with + // assuming we can read it as UTF-8. + _encoding = sniffForXmlDecl("UTF-8"); + } + + if (_encoding == null) + { + // The XML spec says these two things: + + // (1) "In the absence of external character encoding information + // (such as MIME headers), parsed entities which are stored in an + // encoding other than UTF-8 or UTF-16 must begin with a text + // declaration (see 4.3.1 The Text Declaration) containing an + // encoding declaration:" + + // (2) "In the absence of information provided by an external + // transport protocol (e.g. HTTP or MIME), it is an error + // for an entity including an encoding declaration to be + // presented to the XML processor in an encoding other than + // that named in the declaration, or for an entity which begins + // with neither a Byte Order Mark nor an encoding declaration + // to use an encoding other than UTF-8." + + // Since we're using a sniffed stream, we do not have external + // character encoding information. + + // Since we're here, we also don't have a recognized byte order + // mark or an explicit encoding declaration that can be read in + // either ASCII or EBDIC style. + + // Therefore, we must use UTF-8. + + _encoding = "UTF-8"; + } + } + + private int readAsMuchAsPossible(byte[] buf, int startAt, int len) throws IOException + { + int total = 0; + while (total < len) + { + int count = read(buf, startAt + total, len - total); + if (count < 0) + break; + total += count; + } + return total; + } + + private String sniffFourBytes() throws IOException + { + mark(4); + int skip = 0; + try + { + byte[] buf = new byte[4]; + if (readAsMuchAsPossible(buf, 0, 4) < 4) + return null; + long result = 0xFF000000 & (buf[0] << 24) | 0x00FF0000 & (buf[1] << 16) | 0x0000FF00 & (buf[2] << 8) | 0x000000FF & buf[3]; + + if (result == 0x0000FEFF) + return "UCS-4"; + else if (result == 0xFFFE0000) + return "UCS-4"; + else if (result == 0x0000003C) + return "UCS-4BE"; + else if (result == 0x3C000000) + return "UCS-4LE"; + else if (result == 0x003C003F) + return "UTF-16BE"; + else if (result == 0x3C003F00) + return "UTF-16LE"; + else if (result == 0x3C3F786D) + return null; // looks like US-ASCII with = 0) + { + int i = xmlpi + 5; + ScannedAttribute attr = new ScannedAttribute(); + while (i < limit) + { + i = scanAttribute(buf, i, limit, attr); + if (i < 0) + return null; + if (attr.name.equals("encoding")) + return attr.value; + } + } + return null; + } + + private static int firstIndexOf(String s, char[] buf, int startAt, int limit) + { + assert(s.length() > 0); + char[] lookFor = s.toCharArray(); + + char firstchar = lookFor[0]; + searching: for (limit -= lookFor.length; startAt < limit; startAt++) + { + if (buf[startAt] == firstchar) + { + for (int i = 1; i < lookFor.length; i++) + { + if (buf[startAt + i] != lookFor[i]) + { + continue searching; + } + } + return startAt; + } + } + + return -1; + } + + private static int nextNonmatchingByte(char[] lookFor, char[] buf, int startAt, int limit) + { + searching: for (; startAt < limit; startAt++) + { + int thischar = buf[startAt]; + for (int i = 0; i < lookFor.length; i++) + if (thischar == lookFor[i]) + continue searching; + return startAt; + } + return -1; + } + + private static int nextMatchingByte(char[] lookFor, char[] buf, int startAt, int limit) + { + searching: for (; startAt < limit; startAt++) + { + int thischar = buf[startAt]; + for (int i = 0; i < lookFor.length; i++) + if (thischar == lookFor[i]) + return startAt; + } + return -1; + } + + private static int nextMatchingByte(char lookFor, char[] buf, int startAt, int limit) + { + searching: for (; startAt < limit; startAt++) + { + if (buf[startAt] == lookFor) + return startAt; + } + return -1; + } + private static char[] WHITESPACE = new char[] { ' ', '\r', '\t', '\n' }; + private static char[] NOTNAME = new char[] { '=', ' ', '\r', '\t', '\n', '?', '>', '<', '\'', '\"' }; + + private static class ScannedAttribute + { + public String name; + public String value; + } + + private static int scanAttribute(char[] buf, int startAt, int limit, ScannedAttribute attr) + { + int nameStart = nextNonmatchingByte(WHITESPACE, buf, startAt, limit); + if (nameStart < 0) + return -1; + int nameEnd = nextMatchingByte(NOTNAME, buf, nameStart, limit); + if (nameEnd < 0) + return -1; + int equals = nextNonmatchingByte(WHITESPACE, buf, nameEnd, limit); + if (equals < 0) + return -1; + if (buf[equals] != '=') + return -1; + int valQuote = nextNonmatchingByte(WHITESPACE, buf, equals + 1, limit); + if (buf[valQuote] != '\'' && buf[valQuote] != '\"') + return -1; + int valEndquote = nextMatchingByte(buf[valQuote], buf, valQuote + 1, limit); + if (valEndquote < 0) + return -1; + attr.name = new String(buf, nameStart, nameEnd - nameStart); + attr.value = new String(buf, valQuote + 1, valEndquote - valQuote - 1); + return valEndquote + 1; + } +} diff --git a/xmlbeans/src/common/org/apache/xmlbeans/impl/common/SniffedXmlReader.java b/xmlbeans/src/common/org/apache/xmlbeans/impl/common/SniffedXmlReader.java new file mode 100644 index 000000000..b497814ea --- /dev/null +++ b/xmlbeans/src/common/org/apache/xmlbeans/impl/common/SniffedXmlReader.java @@ -0,0 +1,80 @@ +/* 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.common; + +import java.io.IOException; +import java.io.Reader; +import java.io.BufferedReader; +import java.nio.charset.Charset; + +public class SniffedXmlReader extends BufferedReader +{ + // We don't sniff more than 192 bytes. + public static int MAX_SNIFFED_CHARS = 192; + + public SniffedXmlReader(Reader reader) throws IOException + { + super(reader); + _encoding = sniffForXmlDecl(); + } + + private int readAsMuchAsPossible(char[] buf, int startAt, int len) throws IOException + { + int total = 0; + while (total < len) + { + int count = read(buf, startAt + total, len - total); + if (count < 0) + break; + total += count; + } + return total; + } + + // BUGBUG in JDK: Charset.forName is not threadsafe, so we'll prime it + // with the common charsets. + + private static Charset dummy1 = Charset.forName("UTF-8"); + private static Charset dummy2 = Charset.forName("UTF-16"); + private static Charset dummy3 = Charset.forName("UTF-16BE"); + private static Charset dummy4 = Charset.forName("UTF-16LE"); + private static Charset dummy5 = Charset.forName("ISO-8859-1"); + private static Charset dummy6 = Charset.forName("US-ASCII"); + private static Charset dummy7 = Charset.forName("Cp1252"); + + + private String sniffForXmlDecl() throws IOException + { + mark(MAX_SNIFFED_CHARS); + try + { + char[] buf = new char[MAX_SNIFFED_CHARS]; + int limit = readAsMuchAsPossible(buf, 0, MAX_SNIFFED_CHARS); + return SniffedXmlInputStream.extractXmlDeclEncoding(buf, 0, limit); + } + finally + { + reset(); + } + } + + private String _encoding; + + public String getXmlEncoding() + { + return _encoding; + } +} diff --git a/xmlbeans/src/common/org/apache/xmlbeans/impl/common/SoftCache.java b/xmlbeans/src/common/org/apache/xmlbeans/impl/common/SoftCache.java new file mode 100644 index 000000000..e02262a22 --- /dev/null +++ b/xmlbeans/src/common/org/apache/xmlbeans/impl/common/SoftCache.java @@ -0,0 +1,63 @@ +/* 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.common; + +import java.util.HashMap; +import java.lang.ref.SoftReference; + +/** + * @author Cezar Andrei (cezar.andrei at bea.com) + * Date: Apr 26, 2005 + */ +public class SoftCache +{ + private HashMap map = new HashMap(); + + public Object get(Object key) + { + SoftReference softRef = (SoftReference)map.get(key); + + if (softRef==null) + return null; + + return softRef.get(); + } + + public Object put(Object key, Object value) + { + SoftReference softRef = (SoftReference)map.put(key, new SoftReference(value)); + + if (softRef==null) + return null; + + Object oldValue = softRef.get(); + softRef.clear(); + + return oldValue; + } + + public Object remove(Object key) + { + SoftReference softRef = (SoftReference)map.remove(key); + + if (softRef==null) + return null; + + Object oldValue = softRef.get(); + softRef.clear(); + + return oldValue; + } +} \ No newline at end of file diff --git a/xmlbeans/src/common/org/apache/xmlbeans/impl/common/SystemCache.java b/xmlbeans/src/common/org/apache/xmlbeans/impl/common/SystemCache.java new file mode 100644 index 000000000..580a1f7ae --- /dev/null +++ b/xmlbeans/src/common/org/apache/xmlbeans/impl/common/SystemCache.java @@ -0,0 +1,111 @@ +/* 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.common; + +import java.lang.ref.SoftReference; +import java.util.ArrayList; + +import org.apache.xmlbeans.SchemaTypeLoader; +import org.apache.xmlbeans.SystemProperties; + +/** + * This class encapsulates the caching strategy for XmlBeans. + * By subclassing this, a client of XmlBeans can implement caches that are + * more suitable for different applications using information that XmlBeans + * cannot know. + *

    + * This class works as a singleton and as a default implementation for the cache. + * You can set a particular implementation using the "xmlbean.systemcacheimpl" + * system property or using the static {@link set} method. + * Subclasses of this need to be thread-safe. An implementation can be replaced + * at any time, so use of static variables is discouraged to ensure proper cleanup. + */ +public class SystemCache +{ + private static SystemCache INSTANCE = new SystemCache(); + + static + { + String cacheClass = SystemProperties.getProperty("xmlbean.systemcacheimpl"); + Object impl = null; + if (cacheClass != null) + { + try + { + impl = Class.forName(cacheClass).newInstance(); + if (!(impl instanceof SystemCache)) + throw new ClassCastException("Value for system property " + + "\"xmlbean.systemcacheimpl\" points to a class (" + cacheClass + + ") which does not derive from SystemCache"); + } + catch (ClassNotFoundException cnfe) + { + throw new RuntimeException("Cache class " + cacheClass + + " specified by \"xmlbean.systemcacheimpl\" was not found.", + cnfe); + } + catch (InstantiationException ie) + { + throw new RuntimeException("Could not instantiate class " + + cacheClass + " as specified by \"xmlbean.systemcacheimpl\"." + + " An empty constructor may be missing.", ie); + } + catch (IllegalAccessException iae) + { + throw new RuntimeException("Could not instantiate class " + + cacheClass + " as specified by \"xmlbean.systemcacheimpl\"." + + " A public empty constructor may be missing.", iae); + } + } + if (impl != null) + INSTANCE = (SystemCache) impl; + } + + public static synchronized final void set(SystemCache instance) + { + INSTANCE = instance; + } + + public static final SystemCache get() + { + return INSTANCE; + } + + public SchemaTypeLoader getFromTypeLoaderCache(ClassLoader cl) + { + return null; + } + + public void addToTypeLoaderCache(SchemaTypeLoader stl, ClassLoader cl) + { + return; + } + + private ThreadLocal tl_saxLoaders = new ThreadLocal(); + + public Object getSaxLoader() + { + SoftReference s = (SoftReference) tl_saxLoaders.get(); + if (s == null) + return null; + else + return s.get(); + } + + public void setSaxLoader(Object saxLoader) + { + tl_saxLoaders.set(new SoftReference(saxLoader)); + } +} diff --git a/xmlbeans/src/common/org/apache/xmlbeans/impl/common/ValidationContext.java b/xmlbeans/src/common/org/apache/xmlbeans/impl/common/ValidationContext.java new file mode 100644 index 000000000..de6b93bc8 --- /dev/null +++ b/xmlbeans/src/common/org/apache/xmlbeans/impl/common/ValidationContext.java @@ -0,0 +1,24 @@ +/* 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.common; + +public interface ValidationContext +{ + // KHK: remove this + public void invalid ( String message ); + + public void invalid ( String code, Object[] args ); +} \ No newline at end of file diff --git a/xmlbeans/src/common/org/apache/xmlbeans/impl/common/ValidatorListener.java b/xmlbeans/src/common/org/apache/xmlbeans/impl/common/ValidatorListener.java new file mode 100644 index 000000000..229028234 --- /dev/null +++ b/xmlbeans/src/common/org/apache/xmlbeans/impl/common/ValidatorListener.java @@ -0,0 +1,60 @@ +/* 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.common; + +import org.apache.xmlbeans.XmlCursor; +import javax.xml.namespace.QName; +import javax.xml.stream.Location; + +/** + * First event must be a BEGIN with no name (to communicate any xsi + * information). BEGIN and END need to match. + */ + +public interface ValidatorListener +{ + public static final int BEGIN = 1; // Begin element + public static final int END = 2; // End element + public static final int TEXT = 3; // Text + public static final int ATTR = 4; // Attr (non-namespaces, non xsi only) + public static final int ENDATTRS = 5; // after BEGIN, after attrs + + void nextEvent ( int kind, Event event ); + + public interface Event extends PrefixResolver + { + public static final int PRESERVE = 1; + public static final int REPLACE = 2; + public static final int COLLAPSE = 3; + + XmlCursor getLocationAsCursor ( ); + Location getLocation(); + + String getXsiType ( ); // BEGIN xsi:type + String getXsiNil ( ); // BEGIN xsi:nil + String getXsiLoc ( ); // BEGIN xsi:schemaLocation + String getXsiNoLoc ( ); // BEGIN xsi:noNamespaceSchemaLocation + + // On START and ATTR + QName getName ( ); + + // On TEXT and ATTR + String getText ( ); + String getText (int wsr ); + + boolean textIsWhitespace ( ); + } +} \ No newline at end of file diff --git a/xmlbeans/src/common/org/apache/xmlbeans/impl/common/XBeanDebug.java b/xmlbeans/src/common/org/apache/xmlbeans/impl/common/XBeanDebug.java new file mode 100644 index 000000000..19f2c4a78 --- /dev/null +++ b/xmlbeans/src/common/org/apache/xmlbeans/impl/common/XBeanDebug.java @@ -0,0 +1,119 @@ +/* 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.common; + +import org.apache.xmlbeans.SystemProperties; + +import java.io.File; +import java.io.PrintStream; +import java.io.FileOutputStream; +import java.io.IOException; + +public class XBeanDebug +{ + public static final int TRACE_SCHEMA_LOADING = 0x0001; + public static final String traceProp = "org.apache.xmlbeans.impl.debug"; + public static final String defaultProp = ""; // "TRACE_SCHEMA_LOADING"; + + private static int _enabled = initializeBitsFromProperty(); + private static int _indent = 0; + private static String _indentspace = " "; + + private static int initializeBitsFromProperty() + { + int bits = 0; + String prop = SystemProperties.getProperty(traceProp, defaultProp); + if (prop.indexOf("TRACE_SCHEMA_LOADING") >= 0) + bits |= TRACE_SCHEMA_LOADING; + return bits; + } + public static void enable(int bits) + { + _enabled = _enabled | bits; + } + + public static void disable(int bits) + { + _enabled = _enabled & ~bits; + } + + public static void trace(int bits, String message, int indent) + { + if (test(bits)) + { + synchronized (XBeanDebug.class) + { + if (indent < 0) + _indent += indent; + + String spaces = _indent < 0 ? "" : _indent > _indentspace.length() ? _indentspace : _indentspace.substring(0, _indent); + String logmessage = Thread.currentThread().getName() + ": " + spaces + message + "\n"; + System.err.print(logmessage); + + if (indent > 0) + _indent += indent; + } + } + } + + public static boolean test(int bits) + { + return (_enabled & bits) != 0; + } + + static PrintStream _err; + + public static String log(String message) + { + log(message, null); + return message; + } + + public static String logStackTrace(String message) + { + log(message, new Throwable()); + return message; + } + + private synchronized static String log(String message, Throwable stackTrace) + { + if (_err == null) + { + try + { + File diagnosticFile = File.createTempFile("xmlbeandebug", ".log"); + _err = new PrintStream(new FileOutputStream(diagnosticFile)); + System.err.println("Diagnostic XML Bean debug log file created: " + diagnosticFile); + } + catch (IOException e) + { + _err = System.err; + } + } + _err.println(message); + if (stackTrace != null) + { + stackTrace.printStackTrace(_err); + } + return message; + } + + public static Throwable logException(Throwable t) + { + log(t.getMessage(), t); + return t; + } +} diff --git a/xmlbeans/src/common/org/apache/xmlbeans/impl/common/XMLChar.java b/xmlbeans/src/common/org/apache/xmlbeans/impl/common/XMLChar.java new file mode 100644 index 000000000..0ae77cabe --- /dev/null +++ b/xmlbeans/src/common/org/apache/xmlbeans/impl/common/XMLChar.java @@ -0,0 +1,650 @@ +/* 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.common; + +/** + * This class defines the basic XML character properties. The data + * in this class can be used to verify that a character is a valid + * XML character or if the character is a space, name start, or name + * character. + *

    + * A series of convenience methods are supplied to ease the burden + * of the developer. Because inlining the checks can improve per + * character performance, the tables of character properties are + * public. Using the character as an index into the CHARS + * array and applying the appropriate mask flag (e.g. + * MASK_VALID), yields the same results as calling the + * convenience methods. There is one exception: check the comments + * for the isValid method for details. + * + * @author Glenn Marcy, IBM + * @author Andy Clark, IBM + * @author Eric Ye, IBM + * @author Arnaud Le Hors, IBM + * @author Rahul Srivastava, Sun Microsystems Inc. + * + * @version $Id$ + */ +public class XMLChar { + + // + // Constants + // + + /** Character flags. */ + private static final byte[] CHARS = new byte[1 << 16]; + + /** Valid character mask. */ + public static final int MASK_VALID = 0x01; + + /** Space character mask. */ + public static final int MASK_SPACE = 0x02; + + /** Name start character mask. */ + public static final int MASK_NAME_START = 0x04; + + /** Name character mask. */ + public static final int MASK_NAME = 0x08; + + /** Pubid character mask. */ + public static final int MASK_PUBID = 0x10; + + /** + * Content character mask. Special characters are those that can + * be considered the start of markup, such as '<' and '&'. + * The various newline characters are considered special as well. + * All other valid XML characters can be considered content. + *

    + * This is an optimization for the inner loop of character scanning. + */ + public static final int MASK_CONTENT = 0x20; + + /** NCName start character mask. */ + public static final int MASK_NCNAME_START = 0x40; + + /** NCName character mask. */ + public static final int MASK_NCNAME = 0x80; + + // + // Static initialization + // + + static { + + // + // [2] Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | + // [#xE000-#xFFFD] | [#x10000-#x10FFFF] + // + + int charRange[] = { + 0x0009, 0x000A, 0x000D, 0x000D, 0x0020, 0xD7FF, 0xE000, 0xFFFD, + }; + + // + // [3] S ::= (#x20 | #x9 | #xD | #xA)+ + // + + int spaceChar[] = { + 0x0020, 0x0009, 0x000D, 0x000A, + }; + + // + // [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' | + // CombiningChar | Extender + // + + int nameChar[] = { + 0x002D, 0x002E, // '-' and '.' + }; + + // + // [5] Name ::= (Letter | '_' | ':') (NameChar)* + // + + int nameStartChar[] = { + 0x003A, 0x005F, // ':' and '_' + }; + + // + // [13] PubidChar ::= #x20 | 0xD | 0xA | [a-zA-Z0-9] | [-'()+,./:=?;!*#@$_%] + // + + int pubidChar[] = { + 0x000A, 0x000D, 0x0020, 0x0021, 0x0023, 0x0024, 0x0025, 0x003D, + 0x005F + }; + + int pubidRange[] = { + 0x0027, 0x003B, 0x003F, 0x005A, 0x0061, 0x007A + }; + + // + // [84] Letter ::= BaseChar | Ideographic + // + + int letterRange[] = { + // BaseChar + 0x0041, 0x005A, 0x0061, 0x007A, 0x00C0, 0x00D6, 0x00D8, 0x00F6, + 0x00F8, 0x0131, 0x0134, 0x013E, 0x0141, 0x0148, 0x014A, 0x017E, + 0x0180, 0x01C3, 0x01CD, 0x01F0, 0x01F4, 0x01F5, 0x01FA, 0x0217, + 0x0250, 0x02A8, 0x02BB, 0x02C1, 0x0388, 0x038A, 0x038E, 0x03A1, + 0x03A3, 0x03CE, 0x03D0, 0x03D6, 0x03E2, 0x03F3, 0x0401, 0x040C, + 0x040E, 0x044F, 0x0451, 0x045C, 0x045E, 0x0481, 0x0490, 0x04C4, + 0x04C7, 0x04C8, 0x04CB, 0x04CC, 0x04D0, 0x04EB, 0x04EE, 0x04F5, + 0x04F8, 0x04F9, 0x0531, 0x0556, 0x0561, 0x0586, 0x05D0, 0x05EA, + 0x05F0, 0x05F2, 0x0621, 0x063A, 0x0641, 0x064A, 0x0671, 0x06B7, + 0x06BA, 0x06BE, 0x06C0, 0x06CE, 0x06D0, 0x06D3, 0x06E5, 0x06E6, + 0x0905, 0x0939, 0x0958, 0x0961, 0x0985, 0x098C, 0x098F, 0x0990, + 0x0993, 0x09A8, 0x09AA, 0x09B0, 0x09B6, 0x09B9, 0x09DC, 0x09DD, + 0x09DF, 0x09E1, 0x09F0, 0x09F1, 0x0A05, 0x0A0A, 0x0A0F, 0x0A10, + 0x0A13, 0x0A28, 0x0A2A, 0x0A30, 0x0A32, 0x0A33, 0x0A35, 0x0A36, + 0x0A38, 0x0A39, 0x0A59, 0x0A5C, 0x0A72, 0x0A74, 0x0A85, 0x0A8B, + 0x0A8F, 0x0A91, 0x0A93, 0x0AA8, 0x0AAA, 0x0AB0, 0x0AB2, 0x0AB3, + 0x0AB5, 0x0AB9, 0x0B05, 0x0B0C, 0x0B0F, 0x0B10, 0x0B13, 0x0B28, + 0x0B2A, 0x0B30, 0x0B32, 0x0B33, 0x0B36, 0x0B39, 0x0B5C, 0x0B5D, + 0x0B5F, 0x0B61, 0x0B85, 0x0B8A, 0x0B8E, 0x0B90, 0x0B92, 0x0B95, + 0x0B99, 0x0B9A, 0x0B9E, 0x0B9F, 0x0BA3, 0x0BA4, 0x0BA8, 0x0BAA, + 0x0BAE, 0x0BB5, 0x0BB7, 0x0BB9, 0x0C05, 0x0C0C, 0x0C0E, 0x0C10, + 0x0C12, 0x0C28, 0x0C2A, 0x0C33, 0x0C35, 0x0C39, 0x0C60, 0x0C61, + 0x0C85, 0x0C8C, 0x0C8E, 0x0C90, 0x0C92, 0x0CA8, 0x0CAA, 0x0CB3, + 0x0CB5, 0x0CB9, 0x0CE0, 0x0CE1, 0x0D05, 0x0D0C, 0x0D0E, 0x0D10, + 0x0D12, 0x0D28, 0x0D2A, 0x0D39, 0x0D60, 0x0D61, 0x0E01, 0x0E2E, + 0x0E32, 0x0E33, 0x0E40, 0x0E45, 0x0E81, 0x0E82, 0x0E87, 0x0E88, + 0x0E94, 0x0E97, 0x0E99, 0x0E9F, 0x0EA1, 0x0EA3, 0x0EAA, 0x0EAB, + 0x0EAD, 0x0EAE, 0x0EB2, 0x0EB3, 0x0EC0, 0x0EC4, 0x0F40, 0x0F47, + 0x0F49, 0x0F69, 0x10A0, 0x10C5, 0x10D0, 0x10F6, 0x1102, 0x1103, + 0x1105, 0x1107, 0x110B, 0x110C, 0x110E, 0x1112, 0x1154, 0x1155, + 0x115F, 0x1161, 0x116D, 0x116E, 0x1172, 0x1173, 0x11AE, 0x11AF, + 0x11B7, 0x11B8, 0x11BC, 0x11C2, 0x1E00, 0x1E9B, 0x1EA0, 0x1EF9, + 0x1F00, 0x1F15, 0x1F18, 0x1F1D, 0x1F20, 0x1F45, 0x1F48, 0x1F4D, + 0x1F50, 0x1F57, 0x1F5F, 0x1F7D, 0x1F80, 0x1FB4, 0x1FB6, 0x1FBC, + 0x1FC2, 0x1FC4, 0x1FC6, 0x1FCC, 0x1FD0, 0x1FD3, 0x1FD6, 0x1FDB, + 0x1FE0, 0x1FEC, 0x1FF2, 0x1FF4, 0x1FF6, 0x1FFC, 0x212A, 0x212B, + 0x2180, 0x2182, 0x3041, 0x3094, 0x30A1, 0x30FA, 0x3105, 0x312C, + 0xAC00, 0xD7A3, + // Ideographic + 0x3021, 0x3029, 0x4E00, 0x9FA5, + }; + int letterChar[] = { + // BaseChar + 0x0386, 0x038C, 0x03DA, 0x03DC, 0x03DE, 0x03E0, 0x0559, 0x06D5, + 0x093D, 0x09B2, 0x0A5E, 0x0A8D, 0x0ABD, 0x0AE0, 0x0B3D, 0x0B9C, + 0x0CDE, 0x0E30, 0x0E84, 0x0E8A, 0x0E8D, 0x0EA5, 0x0EA7, 0x0EB0, + 0x0EBD, 0x1100, 0x1109, 0x113C, 0x113E, 0x1140, 0x114C, 0x114E, + 0x1150, 0x1159, 0x1163, 0x1165, 0x1167, 0x1169, 0x1175, 0x119E, + 0x11A8, 0x11AB, 0x11BA, 0x11EB, 0x11F0, 0x11F9, 0x1F59, 0x1F5B, + 0x1F5D, 0x1FBE, 0x2126, 0x212E, + // Ideographic + 0x3007, + }; + + // + // [87] CombiningChar ::= ... + // + + int combiningCharRange[] = { + 0x0300, 0x0345, 0x0360, 0x0361, 0x0483, 0x0486, 0x0591, 0x05A1, + 0x05A3, 0x05B9, 0x05BB, 0x05BD, 0x05C1, 0x05C2, 0x064B, 0x0652, + 0x06D6, 0x06DC, 0x06DD, 0x06DF, 0x06E0, 0x06E4, 0x06E7, 0x06E8, + 0x06EA, 0x06ED, 0x0901, 0x0903, 0x093E, 0x094C, 0x0951, 0x0954, + 0x0962, 0x0963, 0x0981, 0x0983, 0x09C0, 0x09C4, 0x09C7, 0x09C8, + 0x09CB, 0x09CD, 0x09E2, 0x09E3, 0x0A40, 0x0A42, 0x0A47, 0x0A48, + 0x0A4B, 0x0A4D, 0x0A70, 0x0A71, 0x0A81, 0x0A83, 0x0ABE, 0x0AC5, + 0x0AC7, 0x0AC9, 0x0ACB, 0x0ACD, 0x0B01, 0x0B03, 0x0B3E, 0x0B43, + 0x0B47, 0x0B48, 0x0B4B, 0x0B4D, 0x0B56, 0x0B57, 0x0B82, 0x0B83, + 0x0BBE, 0x0BC2, 0x0BC6, 0x0BC8, 0x0BCA, 0x0BCD, 0x0C01, 0x0C03, + 0x0C3E, 0x0C44, 0x0C46, 0x0C48, 0x0C4A, 0x0C4D, 0x0C55, 0x0C56, + 0x0C82, 0x0C83, 0x0CBE, 0x0CC4, 0x0CC6, 0x0CC8, 0x0CCA, 0x0CCD, + 0x0CD5, 0x0CD6, 0x0D02, 0x0D03, 0x0D3E, 0x0D43, 0x0D46, 0x0D48, + 0x0D4A, 0x0D4D, 0x0E34, 0x0E3A, 0x0E47, 0x0E4E, 0x0EB4, 0x0EB9, + 0x0EBB, 0x0EBC, 0x0EC8, 0x0ECD, 0x0F18, 0x0F19, 0x0F71, 0x0F84, + 0x0F86, 0x0F8B, 0x0F90, 0x0F95, 0x0F99, 0x0FAD, 0x0FB1, 0x0FB7, + 0x20D0, 0x20DC, 0x302A, 0x302F, + }; + + int combiningCharChar[] = { + 0x05BF, 0x05C4, 0x0670, 0x093C, 0x094D, 0x09BC, 0x09BE, 0x09BF, + 0x09D7, 0x0A02, 0x0A3C, 0x0A3E, 0x0A3F, 0x0ABC, 0x0B3C, 0x0BD7, + 0x0D57, 0x0E31, 0x0EB1, 0x0F35, 0x0F37, 0x0F39, 0x0F3E, 0x0F3F, + 0x0F97, 0x0FB9, 0x20E1, 0x3099, 0x309A, + }; + + // + // [88] Digit ::= ... + // + + int digitRange[] = { + 0x0030, 0x0039, 0x0660, 0x0669, 0x06F0, 0x06F9, 0x0966, 0x096F, + 0x09E6, 0x09EF, 0x0A66, 0x0A6F, 0x0AE6, 0x0AEF, 0x0B66, 0x0B6F, + 0x0BE7, 0x0BEF, 0x0C66, 0x0C6F, 0x0CE6, 0x0CEF, 0x0D66, 0x0D6F, + 0x0E50, 0x0E59, 0x0ED0, 0x0ED9, 0x0F20, 0x0F29, + }; + + // + // [89] Extender ::= ... + // + + int extenderRange[] = { + 0x3031, 0x3035, 0x309D, 0x309E, 0x30FC, 0x30FE, + }; + + int extenderChar[] = { + 0x00B7, 0x02D0, 0x02D1, 0x0387, 0x0640, 0x0E46, 0x0EC6, 0x3005, + }; + + // + // SpecialChar ::= '<', '&', '\n', '\r', ']' + // + + int specialChar[] = { + '<', '&', '\n', '\r', ']', + }; + + // + // Initialize + // + + // set valid characters + for (int i = 0; i < charRange.length; i += 2) { + for (int j = charRange[i]; j <= charRange[i + 1]; j++) { + CHARS[j] |= MASK_VALID | MASK_CONTENT; + } + } + + // remove special characters + for (int i = 0; i < specialChar.length; i++) { + CHARS[specialChar[i]] = (byte)(CHARS[specialChar[i]] & ~MASK_CONTENT); + } + + // set space characters + for (int i = 0; i < spaceChar.length; i++) { + CHARS[spaceChar[i]] |= MASK_SPACE; + } + + // set name start characters + for (int i = 0; i < nameStartChar.length; i++) { + CHARS[nameStartChar[i]] |= MASK_NAME_START | MASK_NAME | + MASK_NCNAME_START | MASK_NCNAME; + } + for (int i = 0; i < letterRange.length; i += 2) { + for (int j = letterRange[i]; j <= letterRange[i + 1]; j++) { + CHARS[j] |= MASK_NAME_START | MASK_NAME | + MASK_NCNAME_START | MASK_NCNAME; + } + } + for (int i = 0; i < letterChar.length; i++) { + CHARS[letterChar[i]] |= MASK_NAME_START | MASK_NAME | + MASK_NCNAME_START | MASK_NCNAME; + } + + // set name characters + for (int i = 0; i < nameChar.length; i++) { + CHARS[nameChar[i]] |= MASK_NAME | MASK_NCNAME; + } + for (int i = 0; i < digitRange.length; i += 2) { + for (int j = digitRange[i]; j <= digitRange[i + 1]; j++) { + CHARS[j] |= MASK_NAME | MASK_NCNAME; + } + } + for (int i = 0; i < combiningCharRange.length; i += 2) { + for (int j = combiningCharRange[i]; j <= combiningCharRange[i + 1]; j++) { + CHARS[j] |= MASK_NAME | MASK_NCNAME; + } + } + for (int i = 0; i < combiningCharChar.length; i++) { + CHARS[combiningCharChar[i]] |= MASK_NAME | MASK_NCNAME; + } + for (int i = 0; i < extenderRange.length; i += 2) { + for (int j = extenderRange[i]; j <= extenderRange[i + 1]; j++) { + CHARS[j] |= MASK_NAME | MASK_NCNAME; + } + } + for (int i = 0; i < extenderChar.length; i++) { + CHARS[extenderChar[i]] |= MASK_NAME | MASK_NCNAME; + } + + // remove ':' from allowable MASK_NCNAME_START and MASK_NCNAME chars + CHARS[':'] &= ~(MASK_NCNAME_START | MASK_NCNAME); + + // set Pubid characters + for (int i = 0; i < pubidChar.length; i++) { + CHARS[pubidChar[i]] |= MASK_PUBID; + } + for (int i = 0; i < pubidRange.length; i += 2) { + for (int j = pubidRange[i]; j <= pubidRange[i + 1]; j++) { + CHARS[j] |= MASK_PUBID; + } + } + + } // () + + // + // Public static methods + // + + /** + * Returns true if the specified character is a supplemental character. + * + * @param c The character to check. + */ + public static boolean isSupplemental(int c) { + return (c >= 0x10000 && c <= 0x10FFFF); + } + + /** + * Returns true the supplemental character corresponding to the given + * surrogates. + * + * @param h The high surrogate. + * @param l The low surrogate. + */ + public static int supplemental(char h, char l) { + return (h - 0xD800) * 0x400 + (l - 0xDC00) + 0x10000; + } + + /** + * Returns the high surrogate of a supplemental character + * + * @param c The supplemental character to "split". + */ + public static char highSurrogate(int c) { + return (char) (((c - 0x00010000) >> 10) + 0xD800); + } + + /** + * Returns the low surrogate of a supplemental character + * + * @param c The supplemental character to "split". + */ + public static char lowSurrogate(int c) { + return (char) (((c - 0x00010000) & 0x3FF) + 0xDC00); + } + + /** + * Returns whether the given character is a high surrogate + * + * @param c The character to check. + */ + public static boolean isHighSurrogate(int c) { + return (0xD800 <= c && c <= 0xDBFF); + } + + /** + * Returns whether the given character is a low surrogate + * + * @param c The character to check. + */ + public static boolean isLowSurrogate(int c) { + return (0xDC00 <= c && c <= 0xDFFF); + } + + + /** + * Returns true if the specified character is valid. This method + * also checks the surrogate character range from 0x10000 to 0x10FFFF. + *

    + * If the program chooses to apply the mask directly to the + * CHARS array, then they are responsible for checking + * the surrogate character range. + * + * @param c The character to check. + */ + public static boolean isValid(int c) { + return (c < 0x10000 && (CHARS[c] & MASK_VALID) != 0) || + (0x10000 <= c && c <= 0x10FFFF); + } // isValid(int):boolean + + /** + * Returns true if the specified character is invalid. + * + * @param c The character to check. + */ + public static boolean isInvalid(int c) { + return !isValid(c); + } // isInvalid(int):boolean + + /** + * Returns true if the specified character can be considered content. + * + * @param c The character to check. + */ + public static boolean isContent(int c) { + return (c < 0x10000 && (CHARS[c] & MASK_CONTENT) != 0) || + (0x10000 <= c && c <= 0x10FFFF); + } // isContent(int):boolean + + /** + * Returns true if the specified character can be considered markup. + * Markup characters include '<', '&', and '%'. + * + * @param c The character to check. + */ + public static boolean isMarkup(int c) { + return c == '<' || c == '&' || c == '%'; + } // isMarkup(int):boolean + + /** + * Returns true if the specified character is a space character + * as defined by production [3] in the XML 1.0 specification. + * + * @param c The character to check. + */ + public static boolean isSpace(int c) { + return c < 0x10000 && (CHARS[c] & MASK_SPACE) != 0; + } // isSpace(int):boolean + + /** + * Returns true if the specified character is a space character + * as amdended in the XML 1.1 specification. + * + * @param c The character to check. + */ + public static boolean isXML11Space(int c) { + return (c < 0x10000 && (CHARS[c] & MASK_SPACE) != 0) || + c == 0x85 || c == 0x2028; + } // isXML11Space(int):boolean + + /** + * Returns true if the specified character is a valid name start + * character as defined by production [5] in the XML 1.0 + * specification. + * + * @param c The character to check. + */ + public static boolean isNameStart(int c) { + return c < 0x10000 && (CHARS[c] & MASK_NAME_START) != 0; + } // isNameStart(int):boolean + + /** + * Returns true if the specified character is a valid name + * character as defined by production [4] in the XML 1.0 + * specification. + * + * @param c The character to check. + */ + public static boolean isName(int c) { + return c < 0x10000 && (CHARS[c] & MASK_NAME) != 0; + } // isName(int):boolean + + /** + * Returns true if the specified character is a valid NCName start + * character as defined by production [4] in Namespaces in XML + * recommendation. + * + * @param c The character to check. + */ + public static boolean isNCNameStart(int c) { + return c < 0x10000 && (CHARS[c] & MASK_NCNAME_START) != 0; + } // isNCNameStart(int):boolean + + /** + * Returns true if the specified character is a valid NCName + * character as defined by production [5] in Namespaces in XML + * recommendation. + * + * @param c The character to check. + */ + public static boolean isNCName(int c) { + return c < 0x10000 && (CHARS[c] & MASK_NCNAME) != 0; + } // isNCName(int):boolean + + /** + * Returns true if the specified character is a valid Pubid + * character as defined by production [13] in the XML 1.0 + * specification. + * + * @param c The character to check. + */ + public static boolean isPubid(int c) { + return c < 0x10000 && (CHARS[c] & MASK_PUBID) != 0; + } // isPubid(int):boolean + + /* + * [5] Name ::= (Letter | '_' | ':') (NameChar)* + */ + /** + * Check to see if a string is a valid Name according to [5] + * in the XML 1.0 Recommendation + * + * @param name string to check + * @return true if name is a valid Name + */ + public static boolean isValidName(String name) { + if (name.length() == 0) + return false; + char ch = name.charAt(0); + if( isNameStart(ch) == false) + return false; + for (int i = 1; i < name.length(); i++ ) { + ch = name.charAt(i); + if( isName( ch ) == false ){ + return false; + } + } + return true; + } // isValidName(String):boolean + + + /* + * from the namespace rec + * [4] NCName ::= (Letter | '_') (NCNameChar)* + */ + /** + * Check to see if a string is a valid NCName according to [4] + * from the XML Namespaces 1.0 Recommendation + * + * @param ncName string to check + * @return true if name is a valid NCName + */ + public static boolean isValidNCName(String ncName) { + if (ncName.length() == 0) + return false; + char ch = ncName.charAt(0); + if( isNCNameStart(ch) == false) + return false; + for (int i = 1; i < ncName.length(); i++ ) { + ch = ncName.charAt(i); + if( isNCName( ch ) == false ){ + return false; + } + } + return true; + } // isValidNCName(String):boolean + + /* + * [7] Nmtoken ::= (NameChar)+ + */ + /** + * Check to see if a string is a valid Nmtoken according to [7] + * in the XML 1.0 Recommendation + * + * @param nmtoken string to check + * @return true if nmtoken is a valid Nmtoken + */ + public static boolean isValidNmtoken(String nmtoken) { + if (nmtoken.length() == 0) + return false; + for (int i = 0; i < nmtoken.length(); i++ ) { + char ch = nmtoken.charAt(i); + if( ! isName( ch ) ){ + return false; + } + } + return true; + } // isValidName(String):boolean + + + + + + // encodings + + /** + * Returns true if the encoding name is a valid IANA encoding. + * This method does not verify that there is a decoder available + * for this encoding, only that the characters are valid for an + * IANA encoding name. + * + * @param ianaEncoding The IANA encoding name. + */ + public static boolean isValidIANAEncoding(String ianaEncoding) { + if (ianaEncoding != null) { + int length = ianaEncoding.length(); + if (length > 0) { + char c = ianaEncoding.charAt(0); + if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) { + for (int i = 1; i < length; i++) { + c = ianaEncoding.charAt(i); + if ((c < 'A' || c > 'Z') && (c < 'a' || c > 'z') && + (c < '0' || c > '9') && c != '.' && c != '_' && + c != '-') { + return false; + } + } + return true; + } + } + } + return false; + } // isValidIANAEncoding(String):boolean + + /** + * Returns true if the encoding name is a valid Java encoding. + * This method does not verify that there is a decoder available + * for this encoding, only that the characters are valid for an + * Java encoding name. + * + * @param javaEncoding The Java encoding name. + */ + public static boolean isValidJavaEncoding(String javaEncoding) { + if (javaEncoding != null) { + int length = javaEncoding.length(); + if (length > 0) { + for (int i = 1; i < length; i++) { + char c = javaEncoding.charAt(i); + if ((c < 'A' || c > 'Z') && (c < 'a' || c > 'z') && + (c < '0' || c > '9') && c != '.' && c != '_' && + c != '-') { + return false; + } + } + return true; + } + } + return false; + } // isValidIANAEncoding(String):boolean + +} // class XMLChar diff --git a/xmlbeans/src/common/org/apache/xmlbeans/impl/common/XMLNameHelper.java b/xmlbeans/src/common/org/apache/xmlbeans/impl/common/XMLNameHelper.java new file mode 100644 index 000000000..505c76c21 --- /dev/null +++ b/xmlbeans/src/common/org/apache/xmlbeans/impl/common/XMLNameHelper.java @@ -0,0 +1,116 @@ +/* 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.common; + +import org.apache.xmlbeans.xml.stream.XMLName; +import javax.xml.namespace.QName; +import java.io.UnsupportedEncodingException; + +public class XMLNameHelper +{ + public static QName getQName(XMLName xmlName) + { + if (xmlName == null) + return null; + + return QNameHelper.forLNS( xmlName.getLocalName(), xmlName.getNamespaceUri() ); + } + + public static XMLName forLNS(String localname, String uri) + { + if (uri == null) + uri = ""; + return new XmlNameImpl(uri, localname); + } + + public static XMLName forLN(String localname) + { + return new XmlNameImpl("", localname); + } + + public static XMLName forPretty(String pretty, int offset) + { + int at = pretty.indexOf('@', offset); + if (at < 0) + return new XmlNameImpl("", pretty.substring(offset)); + return new XmlNameImpl(pretty.substring(at + 1), pretty.substring(offset, at)); + } + + public static String pretty(XMLName name) + { + if (name == null) + return "null"; + + if (name.getNamespaceUri() == null || name.getNamespaceUri().length() == 0) + return name.getLocalName(); + + return name.getLocalName() + "@" + name.getNamespaceUri(); + } + + private static final char[] hexdigits = new char[] + {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; + + private static boolean isSafe(int c) + { + if (c >= 'a' && c <= 'z') + return true; + if (c >= 'A' && c <= 'Z') + return true; + if (c >= '0' && c <= '9') + return true; + return false; + } + + public static String hexsafe(String s) + { + StringBuffer result = new StringBuffer(); + for (int i = 0; i < s.length(); i++) + { + char ch = s.charAt(i); + if (isSafe(ch)) + { + result.append(ch); + } + else + { + byte[] utf8 = null; + try + { + utf8 = s.substring(i, i + 1).getBytes("UTF-8"); + for (int j = 0; j < utf8.length; j++) + { + result.append('_'); + result.append(hexdigits[(utf8[j] >> 4) & 0xF]); + result.append(hexdigits[utf8[j] & 0xF]); + } + } + catch(UnsupportedEncodingException uee) + { + // should never happen - UTF-8 is always supported + result.append("_BAD_UTF8_CHAR"); + } + } + } + return result.toString(); + } + + public static String hexsafedir(XMLName name) + { + if (name.getNamespaceUri() == null || name.getNamespaceUri().length() == 0) + return "_nons/" + hexsafe(name.getLocalName()); + return hexsafe(name.getNamespaceUri()) + "/" + hexsafe(name.getLocalName()); + } +} diff --git a/xmlbeans/src/common/org/apache/xmlbeans/impl/common/XPath.java b/xmlbeans/src/common/org/apache/xmlbeans/impl/common/XPath.java new file mode 100644 index 000000000..e3edd925d --- /dev/null +++ b/xmlbeans/src/common/org/apache/xmlbeans/impl/common/XPath.java @@ -0,0 +1,1119 @@ +/* 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.common; + +import javax.xml.namespace.QName; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.HashMap; +import org.apache.xmlbeans.XmlError; +import org.apache.xmlbeans.XmlException; +import org.apache.xmlbeans.impl.common.XMLChar; + + +public class XPath +{ + public static class XPathCompileException extends XmlException + { + XPathCompileException ( XmlError err ) + { + super( err.toString(), null, err ); + } + } + + // + // + // + + public static class ExecutionContext + { + public ExecutionContext ( ) + { + _stack = new ArrayList(); + } + + public static final int HIT = 0x1; + public static final int DESCEND = 0x2; + public static final int ATTRS = 0x4; + + public final void init ( XPath xpath ) + { + if (_xpath != xpath) + { + _xpath = xpath; + + _paths = new PathContext [ xpath._selector._paths.length ]; + + for ( int i = 0 ; i < _paths.length ; i++ ) + _paths[ i ] = new PathContext(); + } + + _stack.clear(); + + for ( int i = 0 ; i < _paths.length ; i++ ) + _paths[ i ].init( xpath._selector._paths[ i ] ); + } + + public final int start ( ) + { + int result = 0; + + for ( int i = 0 ; i < _paths.length ; i++ ) + result |= _paths[ i ].start(); + + return result; + } + + public final int element ( QName name ) + { + assert name != null; + + _stack.add( name ); + + int result = 0; + + for ( int i = 0 ; i < _paths.length ; i++ ) + result |= _paths[ i ].element( name ); + + return result; + } + + public final boolean attr ( QName name ) + { + boolean hit = false; + + for ( int i = 0 ; i < _paths.length ; i++ ) + hit = hit | _paths[ i ].attr( name ); + + return hit; + } + + public final void end ( ) + { + _stack.remove( _stack.size() - 1 ); + + for ( int i = 0 ; i < _paths.length ; i++ ) + _paths[ i ].end(); + } + + private final class PathContext + { + PathContext ( ) + { + _prev = new ArrayList(); + } + + void init ( Step steps ) + { + _curr = steps; + _prev.clear(); + } + + private QName top ( int i ) + { + return (QName) ExecutionContext.this._stack.get( _stack.size() - 1 - i ); + } + + // goes back to the begining of the sequence since last // wildcard + private void backtrack ( ) + { + assert _curr != null; + + if (_curr._hasBacktrack) + { // _backtrack seems to be a pointer to the step that follows a // wildcard + // ex: for .//b/c/d steps c and d should backtrack to b in case there isn't a match + _curr = _curr._backtrack; + return; + } + + assert !_curr._deep; + + _curr = _curr._prev; + + search: for ( ; !_curr._deep ; _curr = _curr._prev ) + { + int t = 0; + + for ( Step s = _curr ; !s._deep ; s = s._prev ) + { + if (!s.match( top( t++ ))) + continue search; + } + + break; + } + } + + int start ( ) + { + assert _curr != null; + assert _curr._prev == null; + + if (_curr._name != null) + return _curr._flags; + + // If the steps consist on only a terminator, then the path can + // only be '.'. In this case, we get a hit, but there is + // nothing else to match. No need to backtrack. + + _curr = null; + + return HIT; + } + + int element ( QName name ) + { + //System.out.println(" Path.element: " + name); + _prev.add( _curr ); + + if (_curr == null) + return 0; + + assert _curr._name != null; + + if (!_curr._attr && _curr.match( name )) + { + if ((_curr = _curr._next)._name != null) + return _curr._flags; + + backtrack(); + + //System.out.println(" element - HIT " + _curr._flags); + return _curr == null ? HIT : HIT | _curr._flags; + } + + for ( ; ; ) + { + backtrack(); + + if (_curr == null) + return 0; + + if (_curr.match( name )) + { + _curr = _curr._next; + break; + } + + if (_curr._deep) + break; + } + + return _curr._flags; + } + + boolean attr ( QName name ) + { + return _curr != null && _curr._attr && _curr.match( name ); + } + + void end ( ) + { + //System.out.println(" Path.end "); + _curr = (Step) _prev.remove( _prev.size() - 1 ); + } + + private Step _curr; + private List _prev; + } + + private XPath _xpath; + private ArrayList _stack; + private PathContext[] _paths; + } + + // + // + // + + public static XPath compileXPath ( String xpath ) + throws XPathCompileException + { + return compileXPath( xpath, "$this", null ); + } + + public static XPath compileXPath ( String xpath, String currentNodeVar ) + throws XPathCompileException + { + return compileXPath( xpath, currentNodeVar, null ); + } + + public static XPath compileXPath ( String xpath, Map namespaces ) + throws XPathCompileException + { + return compileXPath( xpath, "$this", namespaces ); + } + + public static XPath compileXPath ( + String xpath, String currentNodeVar, Map namespaces ) + throws XPathCompileException + { + return + new CompilationContext( namespaces, currentNodeVar ). + compile( xpath ); + } + + private static class CompilationContext + { + CompilationContext ( Map namespaces, String currentNodeVar ) + { + assert + _currentNodeVar == null || + _currentNodeVar.startsWith( "$" ); + + if (currentNodeVar == null) + _currentNodeVar = "$this"; + else + _currentNodeVar = currentNodeVar; + + _namespaces = new HashMap(); + + _externalNamespaces = + namespaces == null ? new HashMap() : namespaces; + } + + XPath compile ( String expr ) throws XPathCompileException + { + _offset = 0; + _line = 1; + _column = 1; + _expr = expr; + + return tokenizeXPath(); + } + + int currChar ( ) + { + return currChar( 0 ); + } + + int currChar ( int offset ) + { + return + _offset + offset >= _expr.length() + ? -1 + : _expr.charAt( _offset + offset ); + } + + void advance ( ) + { + if (_offset < _expr.length()) + { + char ch = _expr.charAt( _offset ); + + _offset++; + _column++; + + if (ch == '\r' || ch == '\n') + { + _line++; + _column = 1; + + if (_offset + 1 < _expr.length()) + { + char nextCh = _expr.charAt( _offset + 1 ); + + if ((nextCh == '\r' || nextCh == '\n') && ch != nextCh) + _offset++; + } + } + } + } + + void advance ( int count ) + { + assert count >= 0; + + while ( count-- > 0 ) + advance(); + } + + boolean isWhitespace ( ) + { + return isWhitespace( 0 ); + } + + boolean isWhitespace ( int offset ) + { + int ch = currChar( offset ); + return ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r'; + } + + boolean isNCNameStart ( ) + { + return + currChar() == -1 + ? false : + XMLChar.isNCNameStart( currChar() ); + } + + boolean isNCName ( ) + { + return + currChar() == -1 + ? false : + XMLChar.isNCName( currChar() ); + } + + boolean startsWith ( String s ) + { + return startsWith( s, 0 ); + } + + boolean startsWith ( String s, int offset ) + { + if (_offset + offset >= _expr.length()) + return false; + + return _expr.startsWith( s, _offset + offset ); + } + + private XPathCompileException newError ( String msg ) + { + XmlError err = + XmlError.forLocation( + msg, XmlError.SEVERITY_ERROR, null, + _line, _column, _offset ); + + return new XPathCompileException( err ); + } + + String lookupPrefix ( String prefix ) throws XPathCompileException + { + if (_namespaces.containsKey( prefix )) + return (String) _namespaces.get( prefix ); + + if (_externalNamespaces.containsKey( prefix )) + return (String) _externalNamespaces.get( prefix ); + + if (prefix.equals( "xml" )) + return "http://www.w3.org/XML/1998/namespace"; + + if (prefix.equals( "xs" )) + return "http://www.w3.org/2001/XMLSchema"; + + if (prefix.equals( "xsi" )) + return "http://www.w3.org/2001/XMLSchema-instance"; + + if (prefix.equals( "fn" )) + return "http://www.w3.org/2002/11/xquery-functions"; + + if (prefix.equals( "xdt" )) + return "http://www.w3.org/2003/11/xpath-datatypes"; + + if (prefix.equals( "local" )) + return "http://www.w3.org/2003/11/xquery-local-functions"; + + throw newError( "Undefined prefix: " + prefix ); + } + + private boolean parseWhitespace ( ) throws XPathCompileException + { + boolean sawSpace = false; + + while ( isWhitespace() ) + { + advance(); + sawSpace = true; + } + + return sawSpace; + } + + // + // Tokenizing will consume whitespace followed by the tokens, separated + // by whitespace. The whitespace following the last token is not + // consumed. + // + + private boolean tokenize ( String s ) + { + assert s.length() > 0; + + int offset = 0; + + while ( isWhitespace( offset ) ) + offset++; + + if (!startsWith( s, offset )) + return false; + + offset += s.length(); + + advance( offset ); + + return true; + } + + private boolean tokenize ( String s1, String s2 ) + { + assert s1.length() > 0; + assert s2.length() > 0; + + int offset = 0; + + while ( isWhitespace( offset ) ) + offset++; + + if (!startsWith( s1, offset )) + return false; + + offset += s1.length(); + + while ( isWhitespace( offset ) ) + offset++; + + if (!startsWith( s2, offset )) + return false; + + offset += s2.length(); + + advance( offset ); + + return true; + } + + private boolean tokenize ( String s1, String s2, String s3) + { + assert s1.length() > 0; + assert s2.length() > 0; + assert s3.length() > 0; + + int offset = 0; + + while ( isWhitespace( offset ) ) + offset++; + + if (!startsWith( s1, offset )) + return false; + + offset += s1.length(); + + while ( isWhitespace( offset ) ) + offset++; + + if (!startsWith( s2, offset )) + return false; + + offset += s2.length(); + + while ( isWhitespace( offset ) ) + offset++; + + if (!startsWith( s3, offset )) + return false; + + offset += s3.length(); + + while ( isWhitespace( offset ) ) + offset++; + + advance( offset ); + + return true; + } + private boolean tokenize ( String s1, String s2, String s3,String s4) { + assert s1.length() > 0; + assert s2.length() > 0; + assert s3.length() > 0; + assert s4.length() > 0; + + int offset = 0; + + while ( isWhitespace( offset ) ) + offset++; + + if (!startsWith( s1, offset )) + return false; + + offset += s1.length(); + + while ( isWhitespace( offset ) ) + offset++; + + if (!startsWith( s2, offset )) + return false; + + offset += s2.length(); + + while ( isWhitespace( offset ) ) + offset++; + + if (!startsWith( s3, offset )) + return false; + + offset += s3.length(); + + while ( isWhitespace( offset ) ) + offset++; + + if (!startsWith( s4, offset )) + return false; + + offset += s4.length(); + + advance( offset ); + + return true; + } + + + private String tokenizeNCName ( ) throws XPathCompileException + { + parseWhitespace(); + + if (!isNCNameStart()) + throw newError( "Expected non-colonized name" ); + + StringBuffer sb = new StringBuffer(); + + sb.append( (char) currChar() ); + + for ( advance() ; isNCName() ; advance() ) + sb.append( (char) currChar() ); + + return sb.toString(); + } + + private QName getAnyQName ( ) + { + return new QName( "", "" ); + } + + private QName tokenizeQName ( ) throws XPathCompileException + { + if (tokenize( "*" )) + return getAnyQName(); + + String ncName = tokenizeNCName(); + + if (!tokenize( ":" )) + return new QName( lookupPrefix( "" ), ncName ); + + return + new QName( + lookupPrefix( ncName ), + tokenize( "*" ) ? "" : tokenizeNCName() ); + } + + private String tokenizeQuotedUri ( ) throws XPathCompileException + { + char quote; + + if (tokenize( "\"" )) + quote = '"'; + else if (tokenize( "'" )) + quote = '\''; + else + throw newError( "Expected quote (\" or ')" ); + + StringBuffer sb = new StringBuffer(); + + for ( ; ; ) + { + if (currChar() == -1) + throw newError( "Path terminated in URI literal" ); + + if (currChar() == quote) + { + advance(); + + if (currChar() != quote) + break; + } + + sb.append( (char) currChar() ); + + advance(); + } + + return sb.toString(); + } + + private Step addStep ( boolean deep, boolean attr, QName name, Step steps ) + { + Step step = new Step( deep, attr, name ); + + if (steps == null) + return step; + + Step s = steps; + + while ( steps._next != null ) + steps = steps._next; + + steps._next = step; + step._prev = steps; + + return s; + } + + private Step tokenizeSteps ( ) throws XPathCompileException + { + if (tokenize( "/" )) + throw newError( "Absolute paths unsupported" ); + + boolean deep; + + if (tokenize( "$", _currentNodeVar, "//" ) || tokenize( ".", "//" )) + deep = true; + else if (tokenize( "$", _currentNodeVar, "/" ) || tokenize( ".", "/" )) + deep = false; + else if (tokenize( "$", _currentNodeVar ) || tokenize( "." )) + return addStep( false, false, null, null ); + else + deep = false; + + Step steps = null; + + // Compile the steps removing /. and mergind //. with the next step + + boolean deepDot = false; + + for ( ; ; ) + { + if (tokenize( "attribute", "::" ) || tokenize( "@" )) + { + steps = addStep( deep, true, tokenizeQName(), steps ); + break; + } + + QName name; + + if (tokenize( "." )) + deepDot = deepDot || deep; + else + { + tokenize( "child", "::" ); + if ((name = tokenizeQName()) != null) + { + steps = addStep( deep, false, name, steps ); + deep = false; // only this step needs to be deep + // other folowing steps will be deep only if they are preceded by // wildcard + } + } + + if (tokenize( "//" )) + { + deep = true; + deepDot = false; + } + else if (tokenize( "/" )) + { + if (deepDot) + deep = true; + } + else + break; + } + + // If there was a //. at the end of th path, then we need to make + // two paths, one with * at the end and another with @* at the end. + + if ((_lastDeepDot = deepDot)) + { + _lastDeepDot = true; + steps = addStep( true, false, getAnyQName(), steps ); + } + + // Add sentinal step (_name == null) + + return addStep( false, false, null, steps ); + } + + private void computeBacktrack ( Step steps ) + throws XPathCompileException + { + // + // Compute static backtrack information + // + // Note that I use the fact that _hasBacktrack is initialized to + // false and _backtrack to null in the following code. + // + + Step s, t; + + for ( s = steps ; s != null ; s = t ) + { + // Compute the segment from [ s, t ) + + for ( t = s._next ; t != null && !t._deep ; ) + t = t._next; + + // If the segment is NOT rooted at //, then the backtrack is + // null for the entire segment, including possible attr and/or + // sentinal + + if (!s._deep) + { + for ( Step u = s ; u != t ; u = u._next ) + u._hasBacktrack = true; + + continue; + } + + // Compute the sequence [ s, u ) of length n which contain no + // wild steps. + + int n = 0; + Step u = s; + + while ( u != t && u._name != null && !u.isWild() && !u._attr ) + { + n++; + u = u._next; + } + + // Now, apply KMP to [ s, u ) for fast backtracking + + QName [] pattern = new QName [ n + 1 ]; + int [] kmp = new int [ n + 1 ]; + + Step v = s; + + for ( int i = 0 ; i < n ; i++ ) + { + pattern[ i ] = v._name; + v = v._next; + } + + pattern[ n ] = getAnyQName(); + + int i = 0; + int j = kmp[ 0 ] = -1; + + while ( i < n ) + { + while ( j > -1 && !pattern[ i ].equals( pattern[ j ] ) ) + j = kmp[ j ]; + + if (pattern[ ++i ].equals( pattern[ ++j ] )) + kmp[ i ] = kmp[ j ]; + else + kmp[ i ] = j; + } + + i = 0; + + for ( v = s ; v != u ; v = v._next ) + { + v._hasBacktrack = true; + v._backtrack = s; + + for ( j = kmp[ i ] ; j > 0 ; j-- ) + v._backtrack = v._backtrack._next; + + i++; + } + + // Compute the success backtrack and stuff it into an attr and + // sentinal if they exist for this segment + + v = s; + + if (n > 1) + { + for ( j = kmp[ n - 1 ] ; j > 0 ; j-- ) + v = v._next; + } + + if (u != t && u._attr) + { + u._hasBacktrack = true; + u._backtrack = v; + u = u._next; + } + + if (u != t && u._name == null) + { + u._hasBacktrack = true; + u._backtrack = v; + } + + // The first part of a deep segment always backtracks to itself + + assert s._deep; + + s._hasBacktrack = true; + s._backtrack = s; + } + } + + private void tokenizePath ( ArrayList paths ) + throws XPathCompileException + { + _lastDeepDot = false; + + Step steps = tokenizeSteps(); + + computeBacktrack( steps ); + + paths.add( steps ); + + // If the last path ended in //., that path will match all + // elements, here I make a path which matches all attributes. + + if (_lastDeepDot) + { + _sawDeepDot = true; + + Step s = null; + + for ( Step t = steps ; t != null ; t = t._next ) + { + if (t._next != null && t._next._next == null) + s = addStep( t._deep, true, t._name, s ); + else + s = addStep( t._deep, t._attr, t._name, s ); + } + + computeBacktrack( s ); + + paths.add( s ); + } + } + + private Selector tokenizeSelector ( ) throws XPathCompileException + { + ArrayList paths = new ArrayList(); + + tokenizePath( paths ); + + while ( tokenize( "|" ) ) + tokenizePath( paths ); + + return new Selector( (Step[]) paths.toArray( new Step [ 0 ] ) ); + } + + private XPath tokenizeXPath ( ) throws XPathCompileException + { + for ( ; ; ) + { + if (tokenize( "declare", "namespace" )) + { + if (!parseWhitespace()) + throw newError( "Expected prefix after 'declare namespace'" ); + + String prefix = tokenizeNCName(); + + if (!tokenize( "=" )) + throw newError( "Expected '='" ); + + String uri = tokenizeQuotedUri(); + + if (_namespaces.containsKey( prefix )) + { + throw newError( + "Redefinition of namespace prefix: " + prefix ); + } + + _namespaces.put( prefix, uri ); + + //return these to saxon:? Is it an error to pass external NS + //that conflicts? or should we just override it? + if (_externalNamespaces.containsKey( prefix )) + { + throw newError( + "Redefinition of namespace prefix: " + prefix ); + } + _externalNamespaces.put( prefix, uri ); + + if (! tokenize( ";" )) + { +// throw newError( +// "Namespace declaration must end with ;" ); + } + + _externalNamespaces.put(_NS_BOUNDARY,new Integer(_offset)); + + continue; + } + + if (tokenize( "declare","default", "element", "namespace" )) + { + String uri = tokenizeQuotedUri(); + + if (_namespaces.containsKey( "" )) + { + throw newError( + "Redefinition of default element namespace" ); + } + + _namespaces.put( "", uri ); + + //return these to saxon:? Is it an error to pass external NS + //that conflicts? or should we just override it? + if (_externalNamespaces.containsKey( XPath._DEFAULT_ELT_NS )) + { + throw newError("Redefinition of default element namespace : "); + } + _externalNamespaces.put( XPath._DEFAULT_ELT_NS, uri ); + + if (! tokenize( ";" )) + throw newError("Default Namespace declaration must end with ;" ); + //the boundary is the last ; in the prolog... + _externalNamespaces.put(_NS_BOUNDARY,new Integer(_offset)); + + continue; + } + + break; + } + + // Add the default prefix mapping if it has not been redefined + + if (!_namespaces.containsKey( "" )) + _namespaces.put( "", "" ); + + Selector selector = tokenizeSelector(); + + parseWhitespace(); + + if (currChar() != -1) + { + throw newError( + "Unexpected char '" + (char) currChar() + "'" ); + } + + return new XPath( selector, _sawDeepDot ); + } + + //split of prolog decls that are not standard XPath syntax + //but work in v1 + private void processNonXpathDecls(){ + + } + + private String _expr; + + private boolean _sawDeepDot; // Saw one overall + private boolean _lastDeepDot; + + private String _currentNodeVar; + + // private Map _namespaces; + protected Map _namespaces; + private Map _externalNamespaces; + + private int _offset; + private int _line; + private int _column; + } + + private static final class Step + { + Step ( boolean deep, boolean attr, QName name ) + { + _name = name; + + _deep = deep; + _attr = attr; + + int flags = 0; + + if (_deep || !_attr) + flags |= ExecutionContext.DESCEND; + + if (_attr) + flags |= ExecutionContext.ATTRS; + + _flags = flags; + } + + boolean isWild ( ) + { + return _name.getLocalPart().length() == 0; + } + + boolean match ( QName name ) + { + String local = _name.getLocalPart(); + String nameLocal = name.getLocalPart(); + String uri; + String nameUri; + + int localLength = local.length(); + int uriLength; + + // match any name to _name when _name is empty ""@"" + if (localLength==0) + { + uri = _name.getNamespaceURI(); + uriLength = uri.length(); + + if (uriLength==0) + return true; + + return uri.equals(name.getNamespaceURI()); + } + + if (localLength!=nameLocal.length()) + return false; + + uri = _name.getNamespaceURI(); + nameUri = name.getNamespaceURI(); + + if (uri.length()!=nameUri.length()) + return false; + + return local.equals(nameLocal) && uri.equals(nameUri); + } + + final boolean _attr; + final boolean _deep; + + int _flags; + + final QName _name; + + Step _next, _prev; + + boolean _hasBacktrack; + Step _backtrack; + } + + private static final class Selector + { + Selector ( Step[] paths ) + { + _paths = paths; + } + + final Step[] _paths; + } + + // + // + // + + private XPath ( Selector selector, boolean sawDeepDot ) + { + _selector = selector; + _sawDeepDot = sawDeepDot; + } + + public boolean sawDeepDot ( ) + { + return _sawDeepDot; + } + + public static final String _NS_BOUNDARY = "$xmlbeans!ns_boundary"; + public static final String _DEFAULT_ELT_NS = "$xmlbeans!default_uri"; + private final Selector _selector; + private final boolean _sawDeepDot; +} \ No newline at end of file diff --git a/xmlbeans/src/common/org/apache/xmlbeans/impl/common/XmlEncodingSniffer.java b/xmlbeans/src/common/org/apache/xmlbeans/impl/common/XmlEncodingSniffer.java new file mode 100644 index 000000000..614bbfe15 --- /dev/null +++ b/xmlbeans/src/common/org/apache/xmlbeans/impl/common/XmlEncodingSniffer.java @@ -0,0 +1,164 @@ +/* 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.common; + +import java.io.Reader; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.UnsupportedEncodingException; +import java.io.IOException; + +public class XmlEncodingSniffer +{ + private String _xmlencoding; + private String _javaencoding; + private InputStream _stream; + private Reader _reader; + + /** + * Sniffs the given XML stream for encoding information. + * + * After a sniffer is constructed, it can return either a stream + * (which is a buffered stream wrapper of the original) or a reader + * (which applies the proper encoding). + * + * @param stream The stream to sniff + * @param encodingOverride The XML (IANA) name for the overriding encoding + * @throws IOException + * @throws UnsupportedEncodingException + */ + public XmlEncodingSniffer(InputStream stream, String encodingOverride) + throws IOException, UnsupportedEncodingException + { + _stream = stream; + + if (encodingOverride != null) + _xmlencoding = EncodingMap.getJava2IANAMapping(encodingOverride); + + if (_xmlencoding == null) + _xmlencoding = encodingOverride; + + if (_xmlencoding == null) + { + SniffedXmlInputStream sniffed = new SniffedXmlInputStream(_stream); + _xmlencoding = sniffed.getXmlEncoding(); + assert(_xmlencoding != null); + _stream = sniffed; + } + + _javaencoding = EncodingMap.getIANA2JavaMapping(_xmlencoding); + + // we allow you to use Java's encoding names in XML even though you're + // not supposed to. + + if (_javaencoding == null) + _javaencoding = _xmlencoding; + } + + /** + * Sniffs the given XML stream for encoding information. + * + * After a sniffer is constructed, it can return either a reader + * (which is a buffered stream wrapper of the original) or a stream + * (which applies the proper encoding). + * + * @param reader The reader to sniff + * @param encodingDefault The Java name for the default encoding to apply, UTF-8 if null. + * @throws IOException + * @throws UnsupportedEncodingException + */ + public XmlEncodingSniffer(Reader reader, String encodingDefault) + throws IOException, UnsupportedEncodingException + { + if (encodingDefault == null) + encodingDefault = "UTF-8"; + + SniffedXmlReader sniffedReader = new SniffedXmlReader(reader); + _reader = sniffedReader; + _xmlencoding = sniffedReader.getXmlEncoding(); + + if (_xmlencoding == null) + { + _xmlencoding = EncodingMap.getJava2IANAMapping(encodingDefault); + if (_xmlencoding != null) + _javaencoding = encodingDefault; + else + _xmlencoding = encodingDefault; + } + + if (_xmlencoding == null) + _xmlencoding = "UTF-8"; + + // we allow you to use Java's encoding names in XML even though you're + // not supposed to. + + _javaencoding = EncodingMap.getIANA2JavaMapping(_xmlencoding); + + if (_javaencoding == null) + _javaencoding = _xmlencoding; + } + + public String getXmlEncoding() + { + return _xmlencoding; + } + + public String getJavaEncoding() + { + return _javaencoding; + } + + public InputStream getStream() + throws UnsupportedEncodingException + { + if (_stream != null) + { + InputStream is = _stream; + _stream = null; + return is; + } + + if (_reader != null) + { + InputStream is = new ReaderInputStream( _reader, _javaencoding ); + _reader = null; + return is; + } + + return null; + } + + + public Reader getReader ( ) + throws UnsupportedEncodingException + { + if (_reader != null) + { + Reader reader = _reader; + _reader = null; + return reader; + } + + if (_stream != null) + { + Reader reader = new InputStreamReader( _stream, _javaencoding ); + _stream = null; + return reader; + } + + return null; + } +} diff --git a/xmlbeans/src/common/org/apache/xmlbeans/impl/common/XmlErrorPrinter.java b/xmlbeans/src/common/org/apache/xmlbeans/impl/common/XmlErrorPrinter.java new file mode 100644 index 000000000..eae88ac21 --- /dev/null +++ b/xmlbeans/src/common/org/apache/xmlbeans/impl/common/XmlErrorPrinter.java @@ -0,0 +1,60 @@ +/* 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.common; + +import org.apache.xmlbeans.XmlError; + +import java.util.AbstractCollection; +import java.util.Iterator; +import java.util.Collections; +import java.net.URI; + +public class XmlErrorPrinter extends AbstractCollection +{ + private boolean _noisy; + private URI _baseURI; + + public XmlErrorPrinter(boolean noisy, URI baseURI) + { + _noisy = noisy; + _baseURI = baseURI; + } + + public boolean add(Object o) + { + if (o instanceof XmlError) + { + XmlError err = (XmlError)o; + if (err.getSeverity() == XmlError.SEVERITY_ERROR || + err.getSeverity() == XmlError.SEVERITY_WARNING) + System.err.println(err.toString(_baseURI)); + else if (_noisy) + System.out.println(err.toString(_baseURI)); + } + return false; + } + + public Iterator iterator() + { + return Collections.EMPTY_LIST.iterator(); + } + + public int size() + { + return 0; + } +} + diff --git a/xmlbeans/src/common/org/apache/xmlbeans/impl/common/XmlErrorWatcher.java b/xmlbeans/src/common/org/apache/xmlbeans/impl/common/XmlErrorWatcher.java new file mode 100644 index 000000000..d80259044 --- /dev/null +++ b/xmlbeans/src/common/org/apache/xmlbeans/impl/common/XmlErrorWatcher.java @@ -0,0 +1,69 @@ +/* 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.common; + +import org.apache.xmlbeans.XmlError; + +import java.util.AbstractCollection; +import java.util.Collection; +import java.util.Iterator; +import java.util.Collections; + +public class XmlErrorWatcher extends AbstractCollection +{ + private Collection _underlying; + private XmlError _firstError; + + public XmlErrorWatcher(Collection underlying) + { + _underlying = underlying; + } + + public boolean add(Object o) + { + if (_firstError == null && o instanceof XmlError && ((XmlError)o).getSeverity() == XmlError.SEVERITY_ERROR) + _firstError = (XmlError)o; + if (_underlying == null) + return false; + return _underlying.add(o); + } + + public Iterator iterator() + { + if (_underlying == null) + return Collections.EMPTY_LIST.iterator(); + + return _underlying.iterator(); + } + + public int size() + { + if (_underlying == null) + return 0; + + return _underlying.size(); + } + + public boolean hasError() + { + return _firstError != null; + } + + public XmlError firstError() + { + return _firstError; + } +} diff --git a/xmlbeans/src/common/org/apache/xmlbeans/impl/common/XmlEventBase.java b/xmlbeans/src/common/org/apache/xmlbeans/impl/common/XmlEventBase.java new file mode 100644 index 000000000..9a771d283 --- /dev/null +++ b/xmlbeans/src/common/org/apache/xmlbeans/impl/common/XmlEventBase.java @@ -0,0 +1,112 @@ +/* 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.common; + +import org.apache.xmlbeans.xml.stream.XMLEvent; +import org.apache.xmlbeans.xml.stream.events.ElementTypeNames; + +/** + * Abstract base class which implements the type part XMLEvent. + */ + +public abstract class XmlEventBase implements XMLEvent +{ + public XmlEventBase ( ) + { + } + + public XmlEventBase ( int type ) + { + _type = type; + } + + public void setType ( int type ) + { + _type = type; + } + + public int getType ( ) + { + return _type; + } + + public String getTypeAsString ( ) + { + return ElementTypeNames.getName( _type ); + } + + public boolean isStartElement ( ) + { + return _type == XMLEvent.START_ELEMENT; + } + + public boolean isEndElement ( ) + { + return _type == XMLEvent.END_ELEMENT; + } + + public boolean isEntityReference ( ) + { + return _type == XMLEvent.ENTITY_REFERENCE; + } + + public boolean isStartPrefixMapping ( ) + { + return _type == XMLEvent.START_PREFIX_MAPPING; + } + + public boolean isEndPrefixMapping ( ) + { + return _type == XMLEvent.END_PREFIX_MAPPING; + } + + public boolean isChangePrefixMapping ( ) + { + return _type == XMLEvent.CHANGE_PREFIX_MAPPING; + } + + public boolean isProcessingInstruction ( ) + { + return _type == XMLEvent.PROCESSING_INSTRUCTION; + } + + public boolean isCharacterData ( ) + { + return _type == XMLEvent.CHARACTER_DATA; + } + + public boolean isSpace ( ) + { + return _type == XMLEvent.SPACE; + } + + public boolean isNull ( ) + { + return _type == XMLEvent.NULL_ELEMENT; + } + + public boolean isStartDocument ( ) + { + return _type == XMLEvent.START_DOCUMENT; + } + + public boolean isEndDocument ( ) + { + return _type == XMLEvent.END_DOCUMENT; + } + + private int _type; +} diff --git a/xmlbeans/src/common/org/apache/xmlbeans/impl/common/XmlLocale.java b/xmlbeans/src/common/org/apache/xmlbeans/impl/common/XmlLocale.java new file mode 100755 index 000000000..5f47a9f4b --- /dev/null +++ b/xmlbeans/src/common/org/apache/xmlbeans/impl/common/XmlLocale.java @@ -0,0 +1,27 @@ +/* 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. + */ + +// TODO - consider moving this to public .... + +package org.apache.xmlbeans.impl.common; + +public interface XmlLocale +{ + boolean sync ( ); + boolean noSync ( ); + + void enter ( ); + void exit ( ); +} \ No newline at end of file diff --git a/xmlbeans/src/common/org/apache/xmlbeans/impl/common/XmlNameImpl.java b/xmlbeans/src/common/org/apache/xmlbeans/impl/common/XmlNameImpl.java new file mode 100644 index 000000000..13970cc02 --- /dev/null +++ b/xmlbeans/src/common/org/apache/xmlbeans/impl/common/XmlNameImpl.java @@ -0,0 +1,107 @@ +/* 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.common; + +import org.apache.xmlbeans.xml.stream.XMLName; + +public class XmlNameImpl implements XMLName { + + private String namespaceUri=null; + private String localName=null; + private String prefix=null; + private int hash = 0; + + public XmlNameImpl () {} + public XmlNameImpl (String localName) { + this.localName = localName; + } + public XmlNameImpl (String namespaceUri,String localName) { + setNamespaceUri(namespaceUri); + this.localName = localName; + } + public XmlNameImpl (String namespaceUri, + String localName, + String prefix) { + setNamespaceUri(namespaceUri); + this.localName = localName; + this.prefix = prefix; + } + + public String getNamespaceUri() { return namespaceUri; } + public String getLocalName() { return localName; } + public String getPrefix() { return prefix; } + + public void setNamespaceUri(String namespaceUri) { + hash = 0; + if (namespaceUri != null && namespaceUri.equals("")) return; + this.namespaceUri = namespaceUri; + } + public void setLocalName(String localName) { + this.localName = localName; + hash = 0; + } + public void setPrefix(String prefix) { this.prefix = prefix; } + + public String getQualifiedName() { + if (prefix != null && prefix.length() > 0) + return prefix + ":" + localName; + else + return localName; + } + public String toString() { + if (getNamespaceUri() != null) + return "['"+getNamespaceUri()+"']:"+getQualifiedName(); + else + return getQualifiedName(); + } + + public final int hashCode() { + int tmp_hash = hash; + if (tmp_hash == 0) { + tmp_hash = 17; + if (namespaceUri != null) { + tmp_hash = 37*tmp_hash + namespaceUri.hashCode(); + } + if (localName != null) { + tmp_hash = 37*tmp_hash + localName.hashCode(); + } + hash = tmp_hash; + } + return tmp_hash; + } + + public final boolean equals(Object obj) { + if (obj == this) return true; + + if (obj instanceof XMLName) { + final XMLName name= (XMLName) obj; + + final String lname = localName; + if (!(lname==null ? name.getLocalName()==null : + lname.equals(name.getLocalName()))) + return false; + + final String uri = namespaceUri; + return (uri==null ? name.getNamespaceUri()==null : + uri.equals(name.getNamespaceUri())); + + } + return false; + } + + + +} diff --git a/xmlbeans/src/common/org/apache/xmlbeans/impl/common/XmlObjectList.java b/xmlbeans/src/common/org/apache/xmlbeans/impl/common/XmlObjectList.java new file mode 100644 index 000000000..ca8970e89 --- /dev/null +++ b/xmlbeans/src/common/org/apache/xmlbeans/impl/common/XmlObjectList.java @@ -0,0 +1,133 @@ +/* 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.common; + +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.SimpleValue; + +/** + * A class to hold and compare a list of XmlObjects for use by keys + * keyrefs during validation. + */ +public class XmlObjectList +{ + private final XmlObject[] _objects; + + /** + * Construct a new empty object list of the given fixed size. + */ + public XmlObjectList(int objectCount) { + _objects = new XmlObject[objectCount]; + } + + /** + * Set an object by index unless a value has been previously + * set at that location. + * + * @return true if the value was set, false if the value has + * already been set + */ + public boolean set(XmlObject o, int index) + { + if (_objects[index] != null) + return false; + + _objects[index] = o; + return true; + } + + /** + * Tests that all values have been set. Needed for keys. + */ + public boolean filled() { + for (int i = 0 ; i < _objects.length ; i++) + if (_objects[i] == null) return false; + + return true; + } + + /** + * Tests that all values have been set. Needed for keys. + */ + public int unfilled() + { + for (int i = 0 ; i < _objects.length ; i++) + if (_objects[i] == null) return i; + + return -1; + } + + public boolean equals(Object o) { + if (!( o instanceof XmlObjectList)) + return false; + + XmlObjectList other = (XmlObjectList)o; + + if (other._objects.length != this._objects.length) + return false; + + for (int i = 0 ; i < _objects.length ; i++) { + // Ignore missing values + if (_objects[i] == null || other._objects[i] == null) + return false; + + if (! _objects[i].valueEquals(other._objects[i])) + return false; + } + + return true; + } + + public int hashCode() + { + int h = 0; + + for (int i = 0 ; i < _objects.length ; i++) + if (_objects[i] != null) + h = 31 * h + _objects[i].valueHashCode(); + + return h; + } + + private static String prettytrim(String s) + { + int end; + for (end = s.length(); end > 0; end -= 1) + { + if (!XMLChar.isSpace(s.charAt(end - 1))) + break; + } + int start; + for (start = 0; start < end; start += 1) + { + if (!XMLChar.isSpace(s.charAt(start))) + break; + } + return s.substring(start, end); + } + + public String toString() { + StringBuffer b = new StringBuffer(); + + for (int i = 0 ; i < _objects.length ; i++) + { + if (i != 0) b.append(" "); + b.append(prettytrim(((SimpleValue)_objects[i]).getStringValue())); + } + + return b.toString(); + } +} diff --git a/xmlbeans/src/common/org/apache/xmlbeans/impl/common/XmlReaderToWriter.java b/xmlbeans/src/common/org/apache/xmlbeans/impl/common/XmlReaderToWriter.java new file mode 100644 index 000000000..567de58c4 --- /dev/null +++ b/xmlbeans/src/common/org/apache/xmlbeans/impl/common/XmlReaderToWriter.java @@ -0,0 +1,116 @@ +/* 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.common; + +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamWriter; +import javax.xml.stream.events.XMLEvent; + + +public final class XmlReaderToWriter +{ + private XmlReaderToWriter() + { + } + + public static void writeAll(XMLStreamReader xmlr, XMLStreamWriter writer) + throws XMLStreamException + { + while (xmlr.hasNext()) { + write(xmlr, writer); + xmlr.next(); + } + write(xmlr, writer); // write the last element + writer.flush(); + } + + public static void write(XMLStreamReader xmlr, XMLStreamWriter writer) + throws XMLStreamException + { + switch (xmlr.getEventType()) { + case XMLEvent.START_ELEMENT: + final String localName = xmlr.getLocalName(); + final String namespaceURI = xmlr.getNamespaceURI(); + if (namespaceURI != null && namespaceURI.length() > 0) { + final String prefix = xmlr.getPrefix(); + if (prefix != null) + writer.writeStartElement(prefix, localName, + namespaceURI); + else + writer.writeStartElement(namespaceURI, localName); + } else { + writer.writeStartElement(localName); + } + + for (int i = 0, len = xmlr.getNamespaceCount(); i < len; i++) { + writer.writeNamespace(xmlr.getNamespacePrefix(i), + xmlr.getNamespaceURI(i)); + } + + for (int i = 0, len = xmlr.getAttributeCount(); i < len; i++) { + String attUri = xmlr.getAttributeNamespace(i); + if (attUri != null) + writer.writeAttribute(attUri, + xmlr.getAttributeLocalName(i), + xmlr.getAttributeValue(i)); + else + writer.writeAttribute(xmlr.getAttributeLocalName(i), + xmlr.getAttributeValue(i)); + } + break; + case XMLEvent.END_ELEMENT: + writer.writeEndElement(); + break; + case XMLEvent.SPACE: + case XMLEvent.CHARACTERS: + writer.writeCharacters(xmlr.getTextCharacters(), + xmlr.getTextStart(), + xmlr.getTextLength()); + break; + case XMLEvent.PROCESSING_INSTRUCTION: + writer.writeProcessingInstruction(xmlr.getPITarget(), + xmlr.getPIData()); + break; + case XMLEvent.CDATA: + writer.writeCData(xmlr.getText()); + break; + + case XMLEvent.COMMENT: + writer.writeComment(xmlr.getText()); + break; + case XMLEvent.ENTITY_REFERENCE: + writer.writeEntityRef(xmlr.getLocalName()); + break; + case XMLEvent.START_DOCUMENT: + String encoding = xmlr.getCharacterEncodingScheme(); + String version = xmlr.getVersion(); + + if (encoding != null && version != null) + writer.writeStartDocument(encoding, + version); + else if (version != null) + writer.writeStartDocument(xmlr.getVersion()); + break; + case XMLEvent.END_DOCUMENT: + writer.writeEndDocument(); + break; + case XMLEvent.DTD: + writer.writeDTD(xmlr.getText()); + break; + } + } +} diff --git a/xmlbeans/src/common/org/apache/xmlbeans/impl/common/XmlStreamUtils.java b/xmlbeans/src/common/org/apache/xmlbeans/impl/common/XmlStreamUtils.java new file mode 100644 index 000000000..664730558 --- /dev/null +++ b/xmlbeans/src/common/org/apache/xmlbeans/impl/common/XmlStreamUtils.java @@ -0,0 +1,215 @@ +/* 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.common; + +import javax.xml.stream.XMLStreamReader; + +/** + * debugging utilities for XmlStreamReader + */ +public final class XmlStreamUtils +{ + public static String printEvent(XMLStreamReader xmlr) + { + StringBuffer b = new StringBuffer(); + b.append("EVENT:[" + xmlr.getLocation().getLineNumber() + "][" + + xmlr.getLocation().getColumnNumber() + "] "); + b.append(getName(xmlr.getEventType())); + b.append(" ["); + switch (xmlr.getEventType()) { + case XMLStreamReader.START_ELEMENT: + b.append("<"); + printName(xmlr, b); + for (int i = 0; i < xmlr.getNamespaceCount(); i++) { + b.append(" "); + String n = xmlr.getNamespacePrefix(i); + if ("xmlns".equals(n)) { + b.append("xmlns=\"" + xmlr.getNamespaceURI(i) + "\""); + } else { + b.append("xmlns:" + n); + b.append("=\""); + b.append(xmlr.getNamespaceURI(i)); + b.append("\""); + } + } + + for (int i = 0; i < xmlr.getAttributeCount(); i++) { + b.append(" "); + printName(xmlr.getAttributePrefix(i), + xmlr.getAttributeNamespace(i), + xmlr.getAttributeLocalName(i), + b); + b.append("=\""); + b.append(xmlr.getAttributeValue(i)); + b.append("\""); + } + + b.append(">"); + break; + case XMLStreamReader.END_ELEMENT: + b.append(""); + break; + case XMLStreamReader.SPACE: + case XMLStreamReader.CHARACTERS: + //b.append(xmlr.getText()); + int start = xmlr.getTextStart(); + int length = xmlr.getTextLength(); + b.append(new String(xmlr.getTextCharacters(), + start, + length)); + break; + case XMLStreamReader.PROCESSING_INSTRUCTION: + String target = xmlr.getPITarget(); + if (target == null) target = ""; + String data = xmlr.getPIData(); + if (data == null) data = ""; + b.append(""); + break; + case XMLStreamReader.CDATA: + b.append(""); + break; + + case XMLStreamReader.COMMENT: + b.append(""); + break; + case XMLStreamReader.ENTITY_REFERENCE: + b.append(xmlr.getLocalName() + "="); + if (xmlr.hasText()) + b.append("[" + xmlr.getText() + "]"); + break; + case XMLStreamReader.START_DOCUMENT: + b.append(""); + break; + + } + b.append("]"); + return b.toString(); + } + + + private static void printName(String prefix, + String uri, + String localName, + StringBuffer b) + { + if (uri != null && !("".equals(uri))) b.append("['" + uri + "']:"); + if (prefix != null && !("".equals(prefix))) b.append(prefix + ":"); + if (localName != null) b.append(localName); + } + + private static void printName(XMLStreamReader xmlr, StringBuffer b) + { + if (xmlr.hasName()) { + String prefix = xmlr.getPrefix(); + String uri = xmlr.getNamespaceURI(); + String localName = xmlr.getLocalName(); + printName(prefix, uri, localName, b); + } + } + + public static String getName(int eventType) + { + switch (eventType) { + case XMLStreamReader.START_ELEMENT: + return "START_ELEMENT"; + case XMLStreamReader.END_ELEMENT: + return "END_ELEMENT"; + case XMLStreamReader.PROCESSING_INSTRUCTION: + return "PROCESSING_INSTRUCTION"; + case XMLStreamReader.CHARACTERS: + return "CHARACTERS"; + case XMLStreamReader.SPACE: + return "SPACE"; + case XMLStreamReader.COMMENT: + return "COMMENT"; + case XMLStreamReader.START_DOCUMENT: + return "START_DOCUMENT"; + case XMLStreamReader.END_DOCUMENT: + return "END_DOCUMENT"; + case XMLStreamReader.ENTITY_REFERENCE: + return "ENTITY_REFERENCE"; + case XMLStreamReader.ATTRIBUTE: + return "ATTRIBUTE"; + case XMLStreamReader.DTD: + return "DTD"; + case XMLStreamReader.CDATA: + return "CDATA"; + case XMLStreamReader.NAMESPACE: + return "NAMESPACE"; + } + return "UNKNOWN_EVENT_TYPE"; + } + + public static int getType(String val) + { + if (val.equals("START_ELEMENT")) + return XMLStreamReader.START_ELEMENT; + if (val.equals("SPACE")) + return XMLStreamReader.SPACE; + if (val.equals("END_ELEMENT")) + return XMLStreamReader.END_ELEMENT; + if (val.equals("PROCESSING_INSTRUCTION")) + return XMLStreamReader.PROCESSING_INSTRUCTION; + if (val.equals("CHARACTERS")) + return XMLStreamReader.CHARACTERS; + if (val.equals("COMMENT")) + return XMLStreamReader.COMMENT; + if (val.equals("START_DOCUMENT")) + return XMLStreamReader.START_DOCUMENT; + if (val.equals("END_DOCUMENT")) + return XMLStreamReader.END_DOCUMENT; + if (val.equals("ATTRIBUTE")) + return XMLStreamReader.ATTRIBUTE; + if (val.equals("DTD")) + return XMLStreamReader.DTD; + if (val.equals("CDATA")) + return XMLStreamReader.CDATA; + if (val.equals("NAMESPACE")) + return XMLStreamReader.NAMESPACE; + return -1; + } + + +} diff --git a/xmlbeans/src/common/org/apache/xmlbeans/impl/common/XmlWhitespace.java b/xmlbeans/src/common/org/apache/xmlbeans/impl/common/XmlWhitespace.java new file mode 100644 index 000000000..7baec33c9 --- /dev/null +++ b/xmlbeans/src/common/org/apache/xmlbeans/impl/common/XmlWhitespace.java @@ -0,0 +1,157 @@ +/* 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.common; + +import org.apache.xmlbeans.SchemaType; + +public class XmlWhitespace +{ + public static final int WS_UNSPECIFIED = SchemaType.WS_UNSPECIFIED; + public static final int WS_PRESERVE = SchemaType.WS_PRESERVE; + public static final int WS_REPLACE = SchemaType.WS_REPLACE; + public static final int WS_COLLAPSE = SchemaType.WS_COLLAPSE; + + + public static boolean isSpace(char ch) + { + switch (ch) + { + case ' ': + case '\n': + case '\r': + case '\t': + return true; + } + return false; + } + + public static boolean isAllSpace(String v) + { + for (int i = 0, len = v.length(); i < len; i++) + { + if (!isSpace(v.charAt(i))) + return false; + } + return true; + } + + public static boolean isAllSpace(CharSequence v) + { + for (int i = 0, len = v.length(); i < len; i++) + { + if (!isSpace(v.charAt(i))) + return false; + } + return true; + } + + public static String collapse(String v) + { + return collapse(v, XmlWhitespace.WS_COLLAPSE); + } + + /** + * The algorithm used by apply_wscanon: sometimes used in impls. + */ + public static String collapse(String v, int wsr) + { + if (wsr == SchemaType.WS_PRESERVE || wsr == SchemaType.WS_UNSPECIFIED) + return v; + + if (v.indexOf('\n') >= 0) + v = v.replace('\n', ' '); + if (v.indexOf('\t') >= 0) + v = v.replace('\t', ' '); + if (v.indexOf('\r') >= 0) + v = v.replace('\r', ' '); + + if (wsr == SchemaType.WS_REPLACE) + return v; + + int j = 0; + int len = v.length(); + if (len == 0) + return v; + + int i; + + /* a trick: examine every other character looking for pairs of spaces */ + if (v.charAt(0) != ' ') + { + examine: { + for (j = 2; j < len; j += 2) + { + if (v.charAt(j) == ' ') + { + if (v.charAt(j - 1) == ' ') + break examine; + if (j == len - 1) + break examine; + j++; + if (v.charAt(j) == ' ') + break examine; + } + } + if (j == len && v.charAt(j - 1) == ' ') + break examine; + return v; + } + /* j is pointing at the first ws to be removed, or past end */ + i = j; + } + else + { + /** + * j is pointing at the last whitespace in the initial run + */ + while (j + 1 < v.length() && v.charAt(j + 1) == ' ') + j += 1; + i = 0; + } + + char[] ch = v.toCharArray(); + + shifter: for (;;) + { + for (;;) + { + /* j was ws or past end */ + j++; + if (j >= len) + break shifter; + if (v.charAt(j) != ' ') + break; + } + for (;;) + { + /* j was nonws */ + ch[i++] = ch[j++]; + if (j >= len) + break shifter; + if (ch[j] == ' ') + { + ch[i++] = ch[j++]; + if (j >= len) + break shifter; + if (ch[j] == ' ') + break; + } + } + } + + return new String(ch, 0, (i == 0 || ch[i - 1] != ' ') ? i : i - 1); + } +} diff --git a/xmlbeans/src/common/org/apache/xmlbeans/impl/common/readme.txt b/xmlbeans/src/common/org/apache/xmlbeans/impl/common/readme.txt new file mode 100644 index 000000000..ea25143d4 --- /dev/null +++ b/xmlbeans/src/common/org/apache/xmlbeans/impl/common/readme.txt @@ -0,0 +1,5 @@ +There are isolated files in this directory taken from the Apache +Xerces-J 2.0 project + +It contains very minor modifications including a change in namespace. + diff --git a/xmlbeans/src/configschema/schema/xmlconfig.xsd b/xmlbeans/src/configschema/schema/xmlconfig.xsd new file mode 100644 index 000000000..409486e0d --- /dev/null +++ b/xmlbeans/src/configschema/schema/xmlconfig.xsd @@ -0,0 +1,316 @@ + + + + + + + + + The config element is the top-level element for an .xsdconfig file. + It contains configuration information that guides the xsd compiler + when it generates Java classes. You can specify package names to + be used for whole xml namespaces; you can specify class names + to use for individual schema types; and you can supply extension + interfaces and implementations to be extended by the generated + Java classes. + + + + + + + + + Specifies configuration for a namespace. + + + + + + + + Specifies java mapping for a qname. + + + + + + + + Specifies extensions for the generated types in the 'for' attribute. + + + + + + + + Specifies a custom java type mapping for a derived simple type. + A static handler must be specified that converts between the + custom java type and the built-in simple type it derives from. + + + + + + + + + + + + + + + The package name to be used for types generated in this + namespace. + + + + + + + + A prefix to be used to prepend to top-level Java type names + generated in this namespace. (The prefix is not used for + inner Java type definitions.) + + + + + + + + A suffix to be used to append to top-level Java type names + generated in this namespace. (The suffix is not used for + inner Java type definitions.) + + + + + + + + + + A list of any number of namespace URIs or ##local for the no-namespace, + or ##any for all namespaces. + + + + + + + + A list of any number of namespace URIs. + + + + + + + + + + + + + + Specified on what type of Schema component does the qname mapping apply: + - type - on global types with that QName and "local" types contained within attributes/elements + with the specified name + - document-type - on "document" types generated from global elements/attributes with + the specified name + - accessor-element - on getters/setters generated from elements with the specified name + - accessor-attribute - on getters/setters generated from attributes with the specified name + + + + + + + + + A list of namespace URIs. + + + + + + + + + A list of namespace URIs, with ##local for no-uri; or ##any for all URIs. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + The name of the handler class for this user type. + The handler must contain public static methods for + translating the user type to and from the derived simple type. + Example: + - qname example:uuid restricts xs:string + - javaname is java.util.UUID + - handler interface must have signatures: + public void encodeUuid(UUID obj, SimpleValue target) + public UUID decodeUuid(SimpleValue obj) + + + + + + + + + + + + + + + The extension interface (it has to be on the classpath). + All the generated types in this domain will implement this interface, + the calls will be redirected to the handler. + + + + + + + + The name of the handler class for this extension interface. + The handler must contain public static methods for each method + in the interface, and they have to have the following signature. + Example: + - method in the extension interface: + public String foo(String s) + - method in the handler: + public static String foo(XmlObject xo, String s) + + + + + + + + + The extension interface name (it has to be on the classpath). + + + + + + + + + preSet and postSet calls will get generated in the implementation classes. (Only for setter methods). + + + + + + + + The name of the handler class for preSet and postSet methods. + The handler must contain the following public static methods. + public static boolean preSet(int opType, XmlObject xo, QName prop, boolean isAttr, int index) + { + ... + return true; // true to execute store implementation code, false to skip it + } + + public static void postSet(int opType, XmlObject xo, QName prop, boolean isAttr, int index) + {...} + + + + + + + + + + + '*' or a list of generated java types (interfaces) that reprezents this extension domain. + + + + + + + + + A list of generated java interface names or '*' for all interfaces. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/xmlbeans/src/configschema/schema/xmlconfig.xsdconfig b/xmlbeans/src/configschema/schema/xmlconfig.xsdconfig new file mode 100644 index 000000000..e3ab6e4ed --- /dev/null +++ b/xmlbeans/src/configschema/schema/xmlconfig.xsdconfig @@ -0,0 +1,17 @@ + + + + + org.apache.xmlbeans.impl.xb.xmlconfig + + + diff --git a/xmlbeans/src/jamsupport/org/apache/xmlbeans/impl/jam/internal/javadoc/JavadocTigerDelegateImpl_150.java b/xmlbeans/src/jamsupport/org/apache/xmlbeans/impl/jam/internal/javadoc/JavadocTigerDelegateImpl_150.java new file mode 100644 index 000000000..a5583f49c --- /dev/null +++ b/xmlbeans/src/jamsupport/org/apache/xmlbeans/impl/jam/internal/javadoc/JavadocTigerDelegateImpl_150.java @@ -0,0 +1,65 @@ +/* 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.jam.internal.javadoc; + +import com.sun.javadoc.ClassDoc; +import com.sun.javadoc.ExecutableMemberDoc; +import com.sun.javadoc.Parameter; +import com.sun.javadoc.ProgramElementDoc; +import org.apache.xmlbeans.impl.jam.internal.elements.ElementContext; +import org.apache.xmlbeans.impl.jam.provider.JamLogger; +import org.apache.xmlbeans.impl.jam.mutable.MAnnotatedElement; +import org.apache.xmlbeans.impl.jam.mutable.MClass; + + +/** + * This class is required by JAM so it runs under JDK1.5 + * Since XmlBeans doesn't require 1.5 in order to run + * this stub replaces the real impl. + */ +public final class JavadocTigerDelegateImpl_150 extends JavadocTigerDelegate +{ + public void init(ElementContext ctx) + {} + + public void init(JamLogger logger) + {} + + public void populateAnnotationTypeIfNecessary(ClassDoc cd, + MClass clazz, + JavadocClassBuilder builder) + { + } + + + // ======================================================================== + // OLD STUFF remove someday + + + public void extractAnnotations(MAnnotatedElement dest, ProgramElementDoc src) + { + } + + public void extractAnnotations(MAnnotatedElement dest, + ExecutableMemberDoc method, + Parameter src) + { + } + + public boolean isEnum(ClassDoc cd) + { + return false; // under 1.4, nothing is enum + } +} diff --git a/xmlbeans/src/jamsupport/org/apache/xmlbeans/impl/jam/internal/reflect/ReflectTigerDelegateImpl_150.java b/xmlbeans/src/jamsupport/org/apache/xmlbeans/impl/jam/internal/reflect/ReflectTigerDelegateImpl_150.java new file mode 100644 index 000000000..0fe8a42f1 --- /dev/null +++ b/xmlbeans/src/jamsupport/org/apache/xmlbeans/impl/jam/internal/reflect/ReflectTigerDelegateImpl_150.java @@ -0,0 +1,87 @@ +/* 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.jam.internal.reflect; + +import org.apache.xmlbeans.impl.jam.JClass; +import org.apache.xmlbeans.impl.jam.mutable.MAnnotatedElement; +import org.apache.xmlbeans.impl.jam.mutable.MAnnotation; +import org.apache.xmlbeans.impl.jam.mutable.MClass; +import org.apache.xmlbeans.impl.jam.mutable.MConstructor; +import org.apache.xmlbeans.impl.jam.mutable.MField; +import org.apache.xmlbeans.impl.jam.mutable.MMember; +import org.apache.xmlbeans.impl.jam.mutable.MParameter; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; + + +/** + * This class is required by JAM so it runs under JDK1.5 + * Since XmlBeans doesn't require 1.5 in order to run + * this stub replaces the real impl. + */ +public final class ReflectTigerDelegateImpl_150 extends ReflectTigerDelegate +{ + // ======================================================================== + // Reflect15Delegate implementation + + public void populateAnnotationTypeIfNecessary(Class cd, + MClass clazz, + ReflectClassBuilder builder) + { + } + + public void extractAnnotations(MMember dest, Method src) + { + } + + public void extractAnnotations(MConstructor dest, Constructor src) + { + } + + public void extractAnnotations(MField dest, Field src) + { + } + + public void extractAnnotations(MClass dest, Class src) + { + } + + public void extractAnnotations(MParameter dest, Method src, + int paramNum) + { + } + + public void extractAnnotations(MParameter dest, Constructor src, + int paramNum) + { + } + + public boolean isEnum(Class clazz) + { return false; } + + public Constructor getEnclosingConstructor(Class clazz) + { + return null; // JDK1.4 doesn't support this + } + + public Method getEnclosingMethod(Class clazz) + { + return null; // JDK1.4 doesn't support this + } +} diff --git a/xmlbeans/src/marshal/org/apache/xmlbeans/impl/richParser/XMLStreamReaderExt.java b/xmlbeans/src/marshal/org/apache/xmlbeans/impl/richParser/XMLStreamReaderExt.java new file mode 100644 index 000000000..058b5280e --- /dev/null +++ b/xmlbeans/src/marshal/org/apache/xmlbeans/impl/richParser/XMLStreamReaderExt.java @@ -0,0 +1,224 @@ +/* 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.richParser; + +import org.apache.xmlbeans.GDate; +import org.apache.xmlbeans.GDuration; +import org.apache.xmlbeans.XmlCalendar; +import org.apache.xmlbeans.impl.common.XmlWhitespace; + +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamException; +import javax.xml.namespace.QName; +import java.math.BigInteger; +import java.math.BigDecimal; +import java.util.Date; +import java.io.InputStream; + +/** + * This interface extends the simple XMLStreamReader interface adding + * methods to get java objects asociated with schemas simple types like: + * ints, long, BigIntegers, Dates etc + * + * Note: Given the fact that an implemetation of this interface will not + * run validation in the stream, we will not include support for lists, + * enumeration and unions. They might be possible to introduce but the + * user has to push the corect schema type. Because usualy the backends + * are not list/union aware, there would be not performance win from this. + * If interest rises for this, support should be added. + * + * Author: Cezar Andrei (cezar.andrei at bea.com) + * Date: Nov 14, 2003 + */ +public interface XMLStreamReaderExt + extends XMLStreamReader +{ + public static final int WS_PRESERVE = XmlWhitespace.WS_PRESERVE; + public static final int WS_REPLACE = XmlWhitespace.WS_REPLACE; + public static final int WS_COLLAPSE = XmlWhitespace.WS_COLLAPSE; + + /** Returns the value as a {@link String}. */ + public String getStringValue() throws XMLStreamException; + + /** Returns the value as a {@link String}, with wsStyle applied. */ + public String getStringValue(int wsStyle) throws XMLStreamException; + + /** Returns the value as a boolean. */ + public boolean getBooleanValue() throws XMLStreamException; + + /** Returns the value as a byte. */ + public byte getByteValue() throws XMLStreamException; + + /** Returns the value as a short. */ + public short getShortValue() throws XMLStreamException; + + /** Returns the value as an int. */ + public int getIntValue() throws XMLStreamException; + + /** Returns the value as a long. */ + public long getLongValue() throws XMLStreamException; + + /** Returns the value as a {@link java.math.BigInteger}. */ + public BigInteger getBigIntegerValue() throws XMLStreamException; + + /** Returns the value as a {@link java.math.BigDecimal}. */ + public BigDecimal getBigDecimalValue() throws XMLStreamException; + + /** Returns the value as a float. */ + public float getFloatValue() throws XMLStreamException; + + /** Returns the value as a double. */ + public double getDoubleValue() throws XMLStreamException; + + /** Returns the decoded hexbinary value as an InputStream. */ + public InputStream getHexBinaryValue() throws XMLStreamException; + + /** Returns the decoded base64 value as anInputStream. */ + public InputStream getBase64Value() throws XMLStreamException; + + /** Returns the value as an XmlCalendar which extends {@link java.util.Calendar}. */ + public XmlCalendar getCalendarValue() throws XMLStreamException; + + /** Returns the value as a {@link java.util.Date}. */ + public Date getDateValue() throws XMLStreamException; + + /** Returns the value as a {@link org.apache.xmlbeans.GDate}. */ + public GDate getGDateValue() throws XMLStreamException; + + /** Returns the value as a {@link org.apache.xmlbeans.GDuration}. */ + public GDuration getGDurationValue() throws XMLStreamException; + + /** Returns the value as a {@link javax.xml.namespace.QName}. */ + public QName getQNameValue() throws XMLStreamException; + + /** Returns the value as a {@link String}. */ + public String getAttributeStringValue(int index) throws XMLStreamException; + + /** Returns the value as a {@link String}, with wsStyle applied. */ + public String getAttributeStringValue(int index, int wsStyle) throws XMLStreamException; + + /** Returns the value as a boolean. */ + public boolean getAttributeBooleanValue(int index) throws XMLStreamException; + + /** Returns the value as a byte. */ + public byte getAttributeByteValue(int index) throws XMLStreamException; + + /** Returns the value as a short. */ + public short getAttributeShortValue(int index) throws XMLStreamException; + + /** Returns the value as an int. */ + public int getAttributeIntValue(int index) throws XMLStreamException; + + /** Returns the value as a long. */ + public long getAttributeLongValue(int index) throws XMLStreamException; + + /** Returns the value as a {@link java.math.BigInteger}. */ + public BigInteger getAttributeBigIntegerValue(int index) throws XMLStreamException; + + /** Returns the value as a {@link java.math.BigDecimal}. */ + public BigDecimal getAttributeBigDecimalValue(int index) throws XMLStreamException; + + /** Returns the value as a float. */ + public float getAttributeFloatValue(int index) throws XMLStreamException; + + /** Returns the value as a double. */ + public double getAttributeDoubleValue(int index) throws XMLStreamException; + + /** Returns the decoded hexbinary value as an InputStream. */ + public InputStream getAttributeHexBinaryValue(int index) throws XMLStreamException; + + /** Returns the decoded base64 value as anInputStream. */ + public InputStream getAttributeBase64Value(int index) throws XMLStreamException; + + /** Returns the value as an XmlCalendar which extends {@link java.util.Calendar}. */ + public XmlCalendar getAttributeCalendarValue(int index) throws XMLStreamException; + + /** Returns the value as a {@link java.util.Date}. */ + public Date getAttributeDateValue(int index) throws XMLStreamException; + + /** Returns the value as a {@link org.apache.xmlbeans.GDate}. */ + public GDate getAttributeGDateValue(int index) throws XMLStreamException; + + /** Returns the value as a {@link org.apache.xmlbeans.GDuration}. */ + public GDuration getAttributeGDurationValue(int index) throws XMLStreamException; + + /** Returns the value as a {@link javax.xml.namespace.QName}. */ + public QName getAttributeQNameValue(int index) throws XMLStreamException; + + /** Returns the value as a {@link String}. */ + public String getAttributeStringValue(String uri, String local) throws XMLStreamException; + + /** Returns the value as a {@link String}, with wsStyle applied. */ + public String getAttributeStringValue(String uri, String local, int wsStyle) throws XMLStreamException; + + /** Returns the value as a boolean. */ + public boolean getAttributeBooleanValue(String uri, String local) throws XMLStreamException; + + /** Returns the value as a byte. */ + public byte getAttributeByteValue(String uri, String local) throws XMLStreamException; + + /** Returns the value as a short. */ + public short getAttributeShortValue(String uri, String local) throws XMLStreamException; + + /** Returns the value as an int. */ + public int getAttributeIntValue(String uri, String local) throws XMLStreamException; + + /** Returns the value as a long. */ + public long getAttributeLongValue(String uri, String local) throws XMLStreamException; + + /** Returns the value as a {@link java.math.BigInteger}. */ + public BigInteger getAttributeBigIntegerValue(String uri, String local) throws XMLStreamException; + + /** Returns the value as a {@link java.math.BigDecimal}. */ + public BigDecimal getAttributeBigDecimalValue(String uri, String local) throws XMLStreamException; + + /** Returns the value as a float. */ + public float getAttributeFloatValue(String uri, String local) throws XMLStreamException; + + /** Returns the value as a double. */ + public double getAttributeDoubleValue(String uri, String local) throws XMLStreamException; + + /** Returns the decoded hexbinary value as an InputStream. */ + public InputStream getAttributeHexBinaryValue(String uri, String local) throws XMLStreamException; + + /** Returns the decoded base64 value as anInputStream. */ + public InputStream getAttributeBase64Value(String uri, String local) throws XMLStreamException; + + /** Returns the value as an XmlCalendar which extends {@link java.util.Calendar}. */ + public XmlCalendar getAttributeCalendarValue(String uri, String local) throws XMLStreamException; + + /** Returns the value as a {@link java.util.Date}. */ + public Date getAttributeDateValue(String uri, String local) throws XMLStreamException; + + /** Returns the value as a {@link org.apache.xmlbeans.GDate}. */ + public GDate getAttributeGDateValue(String uri, String local) throws XMLStreamException; + + /** Returns the value as a {@link org.apache.xmlbeans.GDuration}. */ + public GDuration getAttributeGDurationValue(String uri, String local) throws XMLStreamException; + + /** Returns the value as a {@link javax.xml.namespace.QName}. */ + public QName getAttributeQNameValue(String uri, String local) throws XMLStreamException; + + /** Sets the default value for the next getXXXValue() call. + * For example: + * setDefaultValue("7"); + * //the xml looks like: + * int i = getIntValue(); // returns 7 + * // from now on the default value will not apply anymore + * Note: Works for getAttributeXXXValue(...) too. + */ + public void setDefaultValue(String defaultValue) throws XMLStreamException; +} diff --git a/xmlbeans/src/marshal/org/apache/xmlbeans/impl/richParser/XMLStreamReaderExtImpl.java b/xmlbeans/src/marshal/org/apache/xmlbeans/impl/richParser/XMLStreamReaderExtImpl.java new file mode 100644 index 000000000..831ec0199 --- /dev/null +++ b/xmlbeans/src/marshal/org/apache/xmlbeans/impl/richParser/XMLStreamReaderExtImpl.java @@ -0,0 +1,1341 @@ +/* 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.richParser; + +import org.apache.xmlbeans.GDate; +import org.apache.xmlbeans.GDateBuilder; +import org.apache.xmlbeans.GDuration; +import org.apache.xmlbeans.XmlCalendar; +import org.apache.xmlbeans.impl.common.XMLChar; +import org.apache.xmlbeans.impl.util.XsTypeConverter; +import org.apache.xmlbeans.impl.util.Base64; +import org.apache.xmlbeans.impl.util.HexBin; +import org.apache.xmlbeans.impl.common.InvalidLexicalValueException; +import org.apache.xmlbeans.impl.common.XmlWhitespace; + +import javax.xml.namespace.NamespaceContext; +import javax.xml.namespace.QName; +import javax.xml.stream.Location; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.Date; + +/** + * Author: Cezar Andrei (cezar.andrei at bea.com) + * Date: Nov 17, 2003 + */ +public class XMLStreamReaderExtImpl + implements XMLStreamReaderExt +{ + private final XMLStreamReader _xmlStream; + private final CharSeqTrimWS _charSeq; + private String _defaultValue; + + public XMLStreamReaderExtImpl(XMLStreamReader xmlStream) + { + if (xmlStream==null) + throw new IllegalArgumentException(); + + _xmlStream = xmlStream; + _charSeq = new CharSeqTrimWS(this); + } + + public XMLStreamReader getUnderlyingXmlStream() + { + return _xmlStream; + } + + // XMLStreamReaderExt methods + public String getStringValue() + throws XMLStreamException + { + _charSeq.reload(CharSeqTrimWS.XMLWHITESPACE_PRESERVE); + return _charSeq.toString(); + } + + public String getStringValue(int wsStyle) + throws XMLStreamException + { + _charSeq.reload(CharSeqTrimWS.XMLWHITESPACE_PRESERVE); + //REVIEW zieg 2004-01-11 - we should write a collapse method + //that takes a CharSequence to void creating this extra String object + return XmlWhitespace.collapse(_charSeq.toString(), wsStyle); + } + + public boolean getBooleanValue() + throws XMLStreamException, InvalidLexicalValueException + { + _charSeq.reload(CharSeqTrimWS.XMLWHITESPACE_TRIM); + try + { + return XsTypeConverter.lexBoolean(_charSeq); + } + catch(InvalidLexicalValueException e) + { + throw new InvalidLexicalValueException(e, _charSeq.getLocation()); + } + } + + public byte getByteValue() + throws XMLStreamException, InvalidLexicalValueException + { + _charSeq.reload(CharSeqTrimWS.XMLWHITESPACE_TRIM); + try + { + return XsTypeConverter.lexByte(_charSeq); + } + catch(NumberFormatException e) + { + throw new InvalidLexicalValueException(e, _charSeq.getLocation()); + } + } + + public short getShortValue() + throws XMLStreamException, InvalidLexicalValueException + { + _charSeq.reload(CharSeqTrimWS.XMLWHITESPACE_TRIM); + try + { + return XsTypeConverter.lexShort(_charSeq); + } + catch(NumberFormatException e) + { + throw new InvalidLexicalValueException(e, _charSeq.getLocation()); + } + } + + public int getIntValue() + throws XMLStreamException, InvalidLexicalValueException + { + _charSeq.reload(CharSeqTrimWS.XMLWHITESPACE_TRIM); + try + { + return XsTypeConverter.lexInt(_charSeq); + } + catch(NumberFormatException e) + { + throw new InvalidLexicalValueException(e, _charSeq.getLocation()); + } + } + + public long getLongValue() + throws XMLStreamException, InvalidLexicalValueException + { + _charSeq.reload(CharSeqTrimWS.XMLWHITESPACE_TRIM); + try + { + return XsTypeConverter.lexLong(_charSeq); + } + catch(NumberFormatException e) + { + throw new InvalidLexicalValueException(e, _charSeq.getLocation()); + } + } + + public BigInteger getBigIntegerValue() + throws XMLStreamException, InvalidLexicalValueException + { + _charSeq.reload(CharSeqTrimWS.XMLWHITESPACE_TRIM); + try + { + return XsTypeConverter.lexInteger(_charSeq); + } + catch(NumberFormatException e) + { + throw new InvalidLexicalValueException(e, _charSeq.getLocation()); + } + } + + public BigDecimal getBigDecimalValue() + throws XMLStreamException, InvalidLexicalValueException + { + _charSeq.reload(CharSeqTrimWS.XMLWHITESPACE_TRIM); + try + { + return XsTypeConverter.lexDecimal(_charSeq); + } + catch(NumberFormatException e) + { + throw new InvalidLexicalValueException(e, _charSeq.getLocation()); + } + } + + public float getFloatValue() + throws XMLStreamException, InvalidLexicalValueException + { + _charSeq.reload(CharSeqTrimWS.XMLWHITESPACE_TRIM); + try + { + return XsTypeConverter.lexFloat(_charSeq); + } + catch(NumberFormatException e) + { + throw new InvalidLexicalValueException(e, _charSeq.getLocation()); + } + } + + public double getDoubleValue() + throws XMLStreamException, InvalidLexicalValueException + { + _charSeq.reload(CharSeqTrimWS.XMLWHITESPACE_TRIM); + try + { + return XsTypeConverter.lexDouble(_charSeq); + } + catch(NumberFormatException e) + { + throw new InvalidLexicalValueException(e, _charSeq.getLocation()); + } + } + + public InputStream getHexBinaryValue() + throws XMLStreamException, InvalidLexicalValueException + { + _charSeq.reload(CharSeqTrimWS.XMLWHITESPACE_TRIM); + String text = _charSeq.toString(); + byte[] buf = HexBin.decode(text.getBytes()); + if (buf!=null) + return new ByteArrayInputStream(buf); + else + throw new InvalidLexicalValueException("invalid hexBinary value", _charSeq.getLocation()); + } + + public InputStream getBase64Value() + throws XMLStreamException, InvalidLexicalValueException + { + _charSeq.reload(CharSeqTrimWS.XMLWHITESPACE_TRIM); + String text = _charSeq.toString(); + byte[] buf = Base64.decode(text.getBytes()); + if (buf!=null) + return new ByteArrayInputStream(buf); + else + throw new InvalidLexicalValueException("invalid base64Binary value", _charSeq.getLocation()); + } + + public XmlCalendar getCalendarValue() + throws XMLStreamException, InvalidLexicalValueException + { + _charSeq.reload(CharSeqTrimWS.XMLWHITESPACE_TRIM); + try + { + return new GDateBuilder(_charSeq).getCalendar(); + } + catch( IllegalArgumentException e) + { + throw new InvalidLexicalValueException(e, _charSeq.getLocation()); + } + } + + public Date getDateValue() + throws XMLStreamException, InvalidLexicalValueException + { + _charSeq.reload(CharSeqTrimWS.XMLWHITESPACE_TRIM); + try + { + return new GDateBuilder(_charSeq).getDate(); + } + catch(IllegalArgumentException e) + { + throw new InvalidLexicalValueException(e, _charSeq.getLocation()); + } + } + + public GDate getGDateValue() + throws XMLStreamException, InvalidLexicalValueException + { + _charSeq.reload(CharSeqTrimWS.XMLWHITESPACE_TRIM); + try + { + return XsTypeConverter.lexGDate(_charSeq); + } + catch(IllegalArgumentException e) + { + throw new InvalidLexicalValueException(e, _charSeq.getLocation()); + } + } + + public GDuration getGDurationValue() + throws XMLStreamException, InvalidLexicalValueException + { + _charSeq.reload(CharSeqTrimWS.XMLWHITESPACE_TRIM); + try + { + return new GDuration(_charSeq); + } + catch(IllegalArgumentException e) + { + throw new InvalidLexicalValueException(e, _charSeq.getLocation()); + } + } + + public QName getQNameValue() + throws XMLStreamException, InvalidLexicalValueException + { + _charSeq.reload(CharSeqTrimWS.XMLWHITESPACE_TRIM); + try + { + return XsTypeConverter.lexQName(_charSeq, _xmlStream.getNamespaceContext()); + } + catch(InvalidLexicalValueException e) + { + throw new InvalidLexicalValueException(e.getMessage(), _charSeq.getLocation()); + } + } + + public String getAttributeStringValue(int index) throws XMLStreamException + { + return _xmlStream.getAttributeValue(index); + } + + public String getAttributeStringValue(int index, int wsStyle) throws XMLStreamException + { + return XmlWhitespace.collapse(_xmlStream.getAttributeValue(index), wsStyle); + } + + public boolean getAttributeBooleanValue(int index) throws XMLStreamException + { + try + { + return XsTypeConverter.lexBoolean(_charSeq.reloadAtt(index, CharSeqTrimWS.XMLWHITESPACE_TRIM)); + } + catch(InvalidLexicalValueException e) + { + throw new InvalidLexicalValueException(e, _charSeq.getLocation()); + } + } + + public byte getAttributeByteValue(int index) throws XMLStreamException + { + try + { + return XsTypeConverter.lexByte(_charSeq.reloadAtt(index, CharSeqTrimWS.XMLWHITESPACE_TRIM)); + } + catch(NumberFormatException e) + { + throw new InvalidLexicalValueException(e, _charSeq.getLocation()); + } + } + + public short getAttributeShortValue(int index) throws XMLStreamException + { + try + { + return XsTypeConverter.lexShort(_charSeq.reloadAtt(index, CharSeqTrimWS.XMLWHITESPACE_TRIM)); + } + catch(NumberFormatException e) + { + throw new InvalidLexicalValueException(e, _charSeq.getLocation()); + } + } + + public int getAttributeIntValue(int index) throws XMLStreamException + { + try + { + return XsTypeConverter.lexInt(_charSeq.reloadAtt(index, CharSeqTrimWS.XMLWHITESPACE_TRIM)); + } + catch(NumberFormatException e) + { + throw new InvalidLexicalValueException(e, _charSeq.getLocation()); + } + } + + public long getAttributeLongValue(int index) throws XMLStreamException + { + try + { + return XsTypeConverter.lexLong(_charSeq.reloadAtt(index, CharSeqTrimWS.XMLWHITESPACE_TRIM)); + } + catch(NumberFormatException e) + { + throw new InvalidLexicalValueException(e, _charSeq.getLocation()); + } + } + + public BigInteger getAttributeBigIntegerValue(int index) throws XMLStreamException + { + try + { + return XsTypeConverter.lexInteger(_charSeq.reloadAtt(index, CharSeqTrimWS.XMLWHITESPACE_TRIM)); + } + catch(NumberFormatException e) + { + throw new InvalidLexicalValueException(e, _charSeq.getLocation()); + } + } + + public BigDecimal getAttributeBigDecimalValue(int index) throws XMLStreamException + { + try + { + return XsTypeConverter.lexDecimal(_charSeq.reloadAtt(index, CharSeqTrimWS.XMLWHITESPACE_TRIM)); + } + catch(NumberFormatException e) + { + throw new InvalidLexicalValueException(e, _charSeq.getLocation()); + } + } + + public float getAttributeFloatValue(int index) throws XMLStreamException + { + try + { + return XsTypeConverter.lexFloat(_charSeq.reloadAtt(index, CharSeqTrimWS.XMLWHITESPACE_TRIM)); + } + catch(NumberFormatException e) + { + throw new InvalidLexicalValueException(e, _charSeq.getLocation()); + } + } + + public double getAttributeDoubleValue(int index) throws XMLStreamException + { + try + { + return XsTypeConverter.lexDouble(_charSeq.reloadAtt(index, CharSeqTrimWS.XMLWHITESPACE_TRIM)); + } + catch(NumberFormatException e) + { + throw new InvalidLexicalValueException(e, _charSeq.getLocation()); + } + } + + public InputStream getAttributeHexBinaryValue(int index) throws XMLStreamException + { + String text = _charSeq.reloadAtt(index, CharSeqTrimWS.XMLWHITESPACE_TRIM).toString(); + byte[] buf = HexBin.decode(text.getBytes()); + if (buf!=null) + return new ByteArrayInputStream(buf); + else + throw new InvalidLexicalValueException("invalid hexBinary value", _charSeq.getLocation()); + } + + public InputStream getAttributeBase64Value(int index) throws XMLStreamException + { + String text = _charSeq.reloadAtt(index, CharSeqTrimWS.XMLWHITESPACE_TRIM).toString(); + byte[] buf = Base64.decode(text.getBytes()); + if (buf!=null) + return new ByteArrayInputStream(buf); + else + throw new InvalidLexicalValueException("invalid base64Binary value", _charSeq.getLocation()); + } + + public XmlCalendar getAttributeCalendarValue(int index) throws XMLStreamException + { + try + { + return new GDateBuilder(_charSeq.reloadAtt(index, CharSeqTrimWS.XMLWHITESPACE_TRIM)). + getCalendar(); + } + catch(IllegalArgumentException e) + { + throw new InvalidLexicalValueException(e, _charSeq.getLocation()); + } + } + + public Date getAttributeDateValue(int index) throws XMLStreamException + { + try + { + return new GDateBuilder(_charSeq.reloadAtt(index, CharSeqTrimWS.XMLWHITESPACE_TRIM)) + .getDate(); + } + catch(IllegalArgumentException e) + { + throw new InvalidLexicalValueException(e, _charSeq.getLocation()); + } + } + + public GDate getAttributeGDateValue(int index) throws XMLStreamException + { + try + { + return new GDate(_charSeq.reloadAtt(index, CharSeqTrimWS.XMLWHITESPACE_TRIM)); + } + catch(IllegalArgumentException e) + { + throw new InvalidLexicalValueException(e, _charSeq.getLocation()); + } + } + + public GDuration getAttributeGDurationValue(int index) throws XMLStreamException + { + try + { + return new GDuration(_charSeq.reloadAtt(index, CharSeqTrimWS.XMLWHITESPACE_TRIM)); + } + catch(IllegalArgumentException e) + { + throw new InvalidLexicalValueException(e, _charSeq.getLocation()); + } + } + + public QName getAttributeQNameValue(int index) throws XMLStreamException + { + try + { + return XsTypeConverter.lexQName(_charSeq.reloadAtt(index, CharSeqTrimWS.XMLWHITESPACE_TRIM), + _xmlStream.getNamespaceContext()); + } + catch(InvalidLexicalValueException e) + { + throw new InvalidLexicalValueException(e.getMessage(), _charSeq.getLocation()); + } + } + + public String getAttributeStringValue(String uri, String local) throws XMLStreamException + { + return _charSeq.reloadAtt(uri, local, CharSeqTrimWS.XMLWHITESPACE_PRESERVE).toString(); + } + + public String getAttributeStringValue(String uri, String local, int wsStyle) throws XMLStreamException + { + return XmlWhitespace.collapse(_xmlStream.getAttributeValue(uri, local), wsStyle); + } + + public boolean getAttributeBooleanValue(String uri, String local) throws XMLStreamException + { + CharSequence cs = _charSeq.reloadAtt(uri, local, CharSeqTrimWS.XMLWHITESPACE_TRIM); + try + { + return XsTypeConverter.lexBoolean(cs); + } + catch(InvalidLexicalValueException e) + { + throw new InvalidLexicalValueException(e, _charSeq.getLocation()); + } + } + + public byte getAttributeByteValue(String uri, String local) throws XMLStreamException + { + CharSequence cs = _charSeq.reloadAtt(uri, local, CharSeqTrimWS.XMLWHITESPACE_TRIM); + try + { + return XsTypeConverter.lexByte(cs); + } + catch(NumberFormatException e) + { + throw new InvalidLexicalValueException(e, _charSeq.getLocation()); + } + } + + public short getAttributeShortValue(String uri, String local) throws XMLStreamException + { + CharSequence cs = _charSeq.reloadAtt(uri, local, CharSeqTrimWS.XMLWHITESPACE_TRIM); + try + { + return XsTypeConverter.lexShort(cs); + } + catch(NumberFormatException e) + { + throw new InvalidLexicalValueException(e, _charSeq.getLocation()); + } + } + + public int getAttributeIntValue(String uri, String local) throws XMLStreamException + { + CharSequence cs = _charSeq.reloadAtt(uri, local, CharSeqTrimWS.XMLWHITESPACE_TRIM); + try + { + return XsTypeConverter.lexInt(cs); + } + catch(NumberFormatException e) + { + throw new InvalidLexicalValueException(e, _charSeq.getLocation()); + } + } + + public long getAttributeLongValue(String uri, String local) throws XMLStreamException + { + CharSequence cs = _charSeq.reloadAtt(uri, local, CharSeqTrimWS.XMLWHITESPACE_TRIM); + try + { + return XsTypeConverter.lexLong(cs); + } + catch(NumberFormatException e) + { + throw new InvalidLexicalValueException(e, _charSeq.getLocation()); + } + } + + public BigInteger getAttributeBigIntegerValue(String uri, String local) throws XMLStreamException + { + CharSequence cs = _charSeq.reloadAtt(uri, local, CharSeqTrimWS.XMLWHITESPACE_TRIM); + try + { + return XsTypeConverter.lexInteger(cs); + } + catch(NumberFormatException e) + { + throw new InvalidLexicalValueException(e, _charSeq.getLocation()); + } + } + + public BigDecimal getAttributeBigDecimalValue(String uri, String local) throws XMLStreamException + { + CharSequence cs = _charSeq.reloadAtt(uri, local, CharSeqTrimWS.XMLWHITESPACE_TRIM); + try + { + return XsTypeConverter.lexDecimal(cs); + } + catch(NumberFormatException e) + { + throw new InvalidLexicalValueException(e, _charSeq.getLocation()); + } + } + + public float getAttributeFloatValue(String uri, String local) throws XMLStreamException + { + CharSequence cs = _charSeq.reloadAtt(uri, local, CharSeqTrimWS.XMLWHITESPACE_TRIM); + try + { + return XsTypeConverter.lexFloat(cs); + } + catch(NumberFormatException e) + { + throw new InvalidLexicalValueException(e, _charSeq.getLocation()); + } + } + + public double getAttributeDoubleValue(String uri, String local) throws XMLStreamException + { + CharSequence cs = _charSeq.reloadAtt(uri, local, CharSeqTrimWS.XMLWHITESPACE_TRIM); + try + { + return XsTypeConverter.lexDouble(cs); + } + catch(NumberFormatException e) + { + throw new InvalidLexicalValueException(e, _charSeq.getLocation()); + } + } + + public InputStream getAttributeHexBinaryValue(String uri, String local) throws XMLStreamException + { + CharSequence cs = _charSeq.reloadAtt(uri, local, CharSeqTrimWS.XMLWHITESPACE_TRIM); + String text = cs.toString(); + byte[] buf = HexBin.decode(text.getBytes()); + if (buf!=null) + return new ByteArrayInputStream(buf); + else + throw new InvalidLexicalValueException("invalid hexBinary value", _charSeq.getLocation()); + } + + public InputStream getAttributeBase64Value(String uri, String local) throws XMLStreamException + { + CharSequence cs = _charSeq.reloadAtt(uri, local, CharSeqTrimWS.XMLWHITESPACE_TRIM); + String text = cs.toString(); + byte[] buf = Base64.decode(text.getBytes()); + if (buf!=null) + return new ByteArrayInputStream(buf); + else + throw new InvalidLexicalValueException("invalid base64Binary value", _charSeq.getLocation()); + } + + public XmlCalendar getAttributeCalendarValue(String uri, String local) throws XMLStreamException + { + CharSequence cs = _charSeq.reloadAtt(uri, local, CharSeqTrimWS.XMLWHITESPACE_TRIM); + try + { + return new GDateBuilder(cs).getCalendar(); + } + catch(IllegalArgumentException e) + { + throw new InvalidLexicalValueException(e, _charSeq.getLocation()); + } + } + + public Date getAttributeDateValue(String uri, String local) throws XMLStreamException + { + try + { + CharSequence cs = _charSeq.reloadAtt(uri, local, CharSeqTrimWS.XMLWHITESPACE_TRIM); + return new GDateBuilder(cs).getDate(); + } + catch(IllegalArgumentException e) + { + throw new InvalidLexicalValueException(e, _charSeq.getLocation()); + } + } + + public GDate getAttributeGDateValue(String uri, String local) throws XMLStreamException + { + try + { + CharSequence cs = _charSeq.reloadAtt(uri, local, CharSeqTrimWS.XMLWHITESPACE_TRIM); + return new GDate(cs); + } + catch(IllegalArgumentException e) + { + throw new InvalidLexicalValueException(e, _charSeq.getLocation()); + } + } + + public GDuration getAttributeGDurationValue(String uri, String local) throws XMLStreamException + { + try + { + return new GDuration(_charSeq.reloadAtt(uri, local, CharSeqTrimWS.XMLWHITESPACE_TRIM)); + } + catch(IllegalArgumentException e) + { + throw new InvalidLexicalValueException(e, _charSeq.getLocation()); + } + } + + public QName getAttributeQNameValue(String uri, String local) throws XMLStreamException + { + CharSequence cs = _charSeq.reloadAtt(uri, local, CharSeqTrimWS.XMLWHITESPACE_TRIM); + try + { + return XsTypeConverter.lexQName(cs, _xmlStream.getNamespaceContext()); + } + catch (InvalidLexicalValueException e) + { + throw new InvalidLexicalValueException(e.getMessage(), _charSeq.getLocation()); + } + } + + public void setDefaultValue(String defaultValue) throws XMLStreamException + { + _defaultValue = defaultValue; + } + + /** + * Only trims the XML whaitspace at edges, it should not be used for WS collapse + * Used for int, short, byte + */ + private static class CharSeqTrimWS + implements CharSequence + { + final static int XMLWHITESPACE_PRESERVE = 1; + final static int XMLWHITESPACE_TRIM = 2; + + private static int INITIAL_SIZE = 100; + private char[] _buf = new char[INITIAL_SIZE]; + private int _start, _length = 0; + private int _nonWSStart = 0; + private int _nonWSEnd = 0; + private String _toStringValue; + private XMLStreamReaderExtImpl _xmlSteam; + //private boolean _supportForGetTextCharacters = true; + private final ExtLocation _location; + private boolean _hasText; + + CharSeqTrimWS(XMLStreamReaderExtImpl xmlSteam) + { + _xmlSteam = xmlSteam; + _location = new ExtLocation(); + } + + void reload(int style) + throws XMLStreamException + { + _toStringValue = null; + _location.reset(); + _hasText = false; + + fillBuffer(); + + if (style==XMLWHITESPACE_PRESERVE) + { + _nonWSStart = 0; + _nonWSEnd = _length; + + // takes defaultValue only if there wasn't any text + if (!_hasText && _xmlSteam._defaultValue!=null) + { + _length = 0; + fillBufferFromString(_xmlSteam._defaultValue); + } + } + else if (style==XMLWHITESPACE_TRIM) + { + for (_nonWSStart=0; _nonWSStart<_length; _nonWSStart++) + if (!XMLChar.isSpace(_buf[_nonWSStart])) + break; + for (_nonWSEnd=_length; _nonWSEnd>_nonWSStart; _nonWSEnd--) + if (!XMLChar.isSpace(_buf[_nonWSEnd-1])) + break; + + // takes defaultValue if length after triming is 0 + if (length()==0 && _xmlSteam._defaultValue!=null) + { + _length = 0; + fillBufferFromString(_xmlSteam._defaultValue); + + //apply whispace rule on the default value + for (_nonWSStart=0; _nonWSStart<_length; _nonWSStart++) + if (!XMLChar.isSpace(_buf[_nonWSStart])) + break; + for (_nonWSEnd=_length; _nonWSEnd>_nonWSStart; _nonWSEnd--) + if (!XMLChar.isSpace(_buf[_nonWSEnd-1])) + break; + } + } + _xmlSteam._defaultValue = null; + } + + private void fillBuffer() + throws XMLStreamException + { + _length = 0; + + if (_xmlSteam.getEventType() == XMLStreamReader.START_DOCUMENT) + _xmlSteam.next(); + if (_xmlSteam.isStartElement()) + _xmlSteam.next(); + + int depth = 0; + String error = null; + int eventType = _xmlSteam.getEventType(); + + loop: + while(true) + { + switch(eventType) + { + case XMLStreamReader.CDATA: + case XMLStreamReader.CHARACTERS: + case XMLStreamReader.SPACE: + _location.set(_xmlSteam.getLocation()); + + if (depth==0) + addTextToBuffer(); + + break; + + case XMLStreamReader.ATTRIBUTE: + case XMLStreamReader.COMMENT: + case XMLStreamReader.DTD: + case XMLStreamReader.ENTITY_DECLARATION: + case XMLStreamReader.NAMESPACE: + case XMLStreamReader.NOTATION_DECLARATION: + case XMLStreamReader.PROCESSING_INSTRUCTION: + case XMLStreamReader.START_DOCUMENT: + // ignore + break; + + case XMLStreamReader.END_DOCUMENT: + _location.set(_xmlSteam.getLocation()); + + break loop; + + case XMLStreamReader.END_ELEMENT: + _location.set(_xmlSteam.getLocation()); + depth--; + if (depth<0) + break loop; + break; + + case XMLStreamReader.ENTITY_REFERENCE: + _location.set(_xmlSteam.getLocation()); + + addEntityToBuffer(); + break; + + case XMLStreamReader.START_ELEMENT: + depth++; + error = "Unexpected element '" + _xmlSteam.getName() + "' in text content."; + _location.set(_xmlSteam.getLocation()); + + break; + } + eventType = _xmlSteam.next(); + } + if (error!=null) + throw new XMLStreamException(error); + } + + private void ensureBufferLength(int lengthToAdd) + { + if (_length + lengthToAdd>_buf.length) + { + char[] newBuf = new char[_length + lengthToAdd]; + if (_length>0) + System.arraycopy(_buf, 0, newBuf, 0, _length); + _buf = newBuf; + } + } + + private void fillBufferFromString(CharSequence value) + { + int textLength = value.length(); + ensureBufferLength(textLength); + + for (int i=0; inonWSStart; nonWSEnd--) + if (!XMLChar.isSpace(value.charAt(nonWSEnd-1))) + break; + if (nonWSStart==0 && nonWSEnd==length) + return value; + else + return value.subSequence(nonWSStart, nonWSEnd); + } + + throw new IllegalStateException("unknown style"); + } + + CharSequence reloadAtt(String uri, String local, int style) + throws XMLStreamException + { + _location.reset(); + _location.set(_xmlSteam.getLocation()); + String value = _xmlSteam.getAttributeValue(uri, local); + + if (value==null && _xmlSteam._defaultValue!=null) + value = _xmlSteam._defaultValue; + + _xmlSteam._defaultValue = null; + + int length = value.length(); + + if (style==XMLWHITESPACE_PRESERVE) + { + return value; + } + else if (style==XMLWHITESPACE_TRIM) + { + for (_nonWSStart=0; _nonWSStart_nonWSStart; _nonWSEnd--) + if (!XMLChar.isSpace(value.charAt(_nonWSEnd-1))) + break; + if (_nonWSStart==0 && _nonWSEnd==length) + return value; + else + return value.subSequence(_nonWSStart, _nonWSEnd); + } + throw new IllegalStateException("unknown style"); + } + + Location getLocation() + { + ExtLocation loc = new ExtLocation(); + loc.set(_location); + return loc; + } + + public int length() + { + return _nonWSEnd - _nonWSStart; + } + + public char charAt(int index) + { + // for each char, this has to be fast, using assert instead of if throw + assert (index<_nonWSEnd-_nonWSStart && -1-1 and <" + (_nonWSEnd - _nonWSStart); + + return _buf[_nonWSStart + index]; + } + + public CharSequence subSequence(int start, int end) + { + return new String(_buf, _nonWSStart + start, end - start); + } + + public String toString() + { + if (_toStringValue!=null) + return _toStringValue; + + _toStringValue = new String(_buf, _nonWSStart, _nonWSEnd - _nonWSStart); + return _toStringValue; + } + + private static class ExtLocation implements Location + { + private int _line; + private int _col; + private int _off; + private String _pid; + private String _sid; + private boolean _isSet; + + ExtLocation() + { + _isSet = false; + } + + public int getLineNumber() + { + if (_isSet) + return _line; + else + throw new IllegalStateException(); + } + + public int getColumnNumber() + { + if (_isSet) + return _col; + else + throw new IllegalStateException(); + } + + public int getCharacterOffset() + { + if (_isSet) + return _off; + else + throw new IllegalStateException(); + } + + public String getPublicId() + { + if (_isSet) + return _pid; + else + throw new IllegalStateException(); + } + + public String getSystemId() + { + if (_isSet) + return _sid; + else + throw new IllegalStateException(); + } + + void set(Location loc) + { + if (_isSet) + return; + + _isSet = true; + _line = loc.getLineNumber(); + _col = loc.getColumnNumber(); + _off = loc.getCharacterOffset(); + _pid = loc.getPublicId(); + _sid = loc.getSystemId(); + } + + void reset() + { + _isSet = false; + } + } + } + + // XMLStreamReader methods + public Object getProperty(String s) + throws IllegalArgumentException + { + return _xmlStream.getProperty(s); + } + + public int next() + throws XMLStreamException + { + return _xmlStream.next(); + } + + public void require(int i, String s, String s1) + throws XMLStreamException + { + _xmlStream.require(i, s, s1); + } + + public String getElementText() throws XMLStreamException + { + return _xmlStream.getElementText(); + } + + public int nextTag() throws XMLStreamException + { + return _xmlStream.nextTag(); + } + + public boolean hasNext() throws XMLStreamException + { + return _xmlStream.hasNext(); + } + + public void close() throws XMLStreamException + { + _xmlStream.close(); + } + + public String getNamespaceURI(String s) + { + return _xmlStream.getNamespaceURI(s); + } + + public boolean isStartElement() + { + return _xmlStream.isStartElement(); + } + + public boolean isEndElement() + { + return _xmlStream.isEndElement(); + } + + public boolean isCharacters() + { + return _xmlStream.isCharacters(); + } + + public boolean isWhiteSpace() + { + return _xmlStream.isWhiteSpace(); + } + + public String getAttributeValue(String s, String s1) + { + return _xmlStream.getAttributeValue(s, s1); + } + + public int getAttributeCount() + { + return _xmlStream.getAttributeCount(); + } + + public QName getAttributeName(int i) + { + return _xmlStream.getAttributeName(i); + } + + public String getAttributeNamespace(int i) + { + return _xmlStream.getAttributeNamespace(i); + } + + public String getAttributeLocalName(int i) + { + return _xmlStream.getAttributeLocalName(i); + } + + public String getAttributePrefix(int i) + { + return _xmlStream.getAttributePrefix(i); + } + + public String getAttributeType(int i) + { + return _xmlStream.getAttributeType(i); + } + + public String getAttributeValue(int i) + { + return _xmlStream.getAttributeValue(i); + } + + public boolean isAttributeSpecified(int i) + { + return _xmlStream.isAttributeSpecified(i); + } + + public int getNamespaceCount() + { + return _xmlStream.getNamespaceCount(); + } + + public String getNamespacePrefix(int i) + { + return _xmlStream.getNamespacePrefix(i); + } + + public String getNamespaceURI(int i) + { + return _xmlStream.getNamespaceURI(i); + } + + public NamespaceContext getNamespaceContext() + { + return _xmlStream.getNamespaceContext(); + } + + public int getEventType() + { + return _xmlStream.getEventType(); + } + + public String getText() + { + return _xmlStream.getText(); + } + + public char[] getTextCharacters() + { + return _xmlStream.getTextCharacters(); + } + + public int getTextCharacters(int i, char[] chars, int i1, int i2) + throws XMLStreamException + { + return _xmlStream.getTextCharacters(i, chars, i1, i2); + } + + public int getTextStart() + { + return _xmlStream.getTextStart(); + } + + public int getTextLength() + { + return _xmlStream.getTextLength(); + } + + public String getEncoding() + { + return _xmlStream.getEncoding(); + } + + public boolean hasText() + { + return _xmlStream.hasText(); + } + + public Location getLocation() + { + return _xmlStream.getLocation(); + } + + public QName getName() + { + return _xmlStream.getName(); + } + + public String getLocalName() + { + return _xmlStream.getLocalName(); + } + + public boolean hasName() + { + return _xmlStream.hasName(); + } + + public String getNamespaceURI() + { + return _xmlStream.getNamespaceURI(); + } + + public String getPrefix() + { + return _xmlStream.getPrefix(); + } + + public String getVersion() + { + return _xmlStream.getVersion(); + } + + public boolean isStandalone() + { + return _xmlStream.isStandalone(); + } + + public boolean standaloneSet() + { + return _xmlStream.standaloneSet(); + } + + public String getCharacterEncodingScheme() + { + return _xmlStream.getCharacterEncodingScheme(); + } + + public String getPITarget() + { + return _xmlStream.getPITarget(); + } + + public String getPIData() + { + return _xmlStream.getPIData(); + } +} diff --git a/xmlbeans/src/repackage/repackage/EditBuildScript.java b/xmlbeans/src/repackage/repackage/EditBuildScript.java new file mode 100644 index 000000000..6df16e8ab --- /dev/null +++ b/xmlbeans/src/repackage/repackage/EditBuildScript.java @@ -0,0 +1,99 @@ +/* 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 repackage; + +import java.io.*; + +public class EditBuildScript +{ + // + // usgae: edit buildfile token new-value + // + + public static void main ( String[] args ) + throws Exception + { + if (args.length != 3) + throw new IllegalArgumentException( "Wrong number of arguments" ); + + args[ 0 ] = args[ 0 ].replace( '/', File.separatorChar ); + + File buildFile = new File( args[ 0 ] ); + + StringBuffer sb = readFile( buildFile ); + + String tokenStr = " 0) + System.out.println("Skipped " + _skippedFiles + " unmodified files."); + } + + private boolean fileIsUnchanged(String name) + { + File sourceFile = new File( _sourceBase, name ); + File targetFile = new File( _targetBase, name ); + return (sourceFile.lastModified() < targetFile.lastModified()); + } + + public void repackageFile ( String name ) + throws IOException + { + if (name.endsWith( ".java" )) + repackageJavaFile( name ); + else if (name.endsWith( ".xsdconfig" ) || + name.endsWith( ".xml" ) || + name.endsWith( ".g" ) ) + repackageNonJavaFile( name ); + else if (name.startsWith( "bin" + File.separatorChar )) + repackageNonJavaFile( name ); + else + moveAlongWithJavaFiles( name ); + } + + public void moveAlongWithJavaFiles( String name ) + { + _moveAlongFiles.add(name); + } + + public void finishMovingFiles ( ) + throws IOException + { + for ( Iterator i = _moveAlongFiles.iterator(); i.hasNext(); ) + { + String name = (String) i.next(); + String toName = name; + + String srcDir = Repackager.dirForPath( name ); + String toDir = (String) _movedDirs.get( srcDir ); + + if (toDir != null) + toName = new File( toDir, new File( name ).getName() ).toString(); + + if (name.endsWith( ".html" )) + repackageNonJavaFile(name, toName); + else + justMoveNonJavaFile(name, toName); + } + } + + public void repackageNonJavaFile(String name) + throws IOException + { + File sourceFile = new File( _sourceBase, name ); + File targetFile = new File( _targetBase, name ); + + if (sourceFile.lastModified() < targetFile.lastModified()) + _skippedFiles += 1; + else + writeFile( targetFile, _repackager.repackage( readFile( sourceFile ) ) ); + } + + public void repackageNonJavaFile ( String sourceName, String targetName ) + throws IOException + { + File sourceFile = new File( _sourceBase, sourceName ); + File targetFile = new File( _targetBase, targetName ); + + if (sourceFile.lastModified() < targetFile.lastModified()) + _skippedFiles += 1; + else + writeFile( targetFile, _repackager.repackage( readFile( sourceFile ) ) ); + } + + public void justMoveNonJavaFile ( String sourceName, String targetName ) + throws IOException + { + File sourceFile = new File( _sourceBase, sourceName ); + File targetFile = new File( _targetBase, targetName ); + + if (sourceFile.lastModified() < targetFile.lastModified()) + _skippedFiles += 1; + else + copyFile( sourceFile, targetFile ); + } + + public void repackageJavaFile ( String name ) + throws IOException + { + File sourceFile = new File(_sourceBase, name); + StringBuffer sb = readFile(sourceFile); + + Matcher packageMatcher = _packagePattern.matcher( sb ); + + if (packageMatcher.find()) + { + String pkg = packageMatcher.group( 1 ); + int pkgStart = packageMatcher.start( 1 ); + int pkgEnd = packageMatcher.end( 1 ); + + if (packageMatcher.find()) + throw new RuntimeException( "Two package specifications found: " + name ); + + List filePath = Repackager.splitPath( name, File.separatorChar ); + String srcDir = Repackager.dirForPath( name ); + + // Sort the repackage spec so that longer from's are first to match + // longest package first + + for ( ; ; ) + { + boolean swapped = false; + + for ( int i = 1 ; i < filePath.size() ; i++ ) + { + String spec1 = (String) filePath.get( i - 1 ); + String spec2 = (String) filePath.get( i ); + + if (spec1.indexOf( ':' ) < spec2.indexOf( ':' )) + { + filePath.set( i - 1, spec2 ); + filePath.set( i, spec1 ); + + swapped = true; + } + } + + if (!swapped) + break; + } + + List pkgPath = Repackager.splitPath( pkg, '.' ); + + int f = filePath.size() - 2; + + if (f<0 || (filePath.size()-1)< pkgPath.size()) + throw new RuntimeException("Package spec differs from file path: " + name); + + for ( int i = pkgPath.size() - 1 ; i >= 0 ; i-- ) + { + if (!pkgPath.get( i ).equals( filePath.get( f ) )) + throw new RuntimeException( "Package spec differs from file path: " + name ); + f--; + } + + List changeTo = null; + List changeFrom = null; + + from: + for ( int i = 0 ; i < _fromPackages.size() ; i ++ ) + { + List from = (List) _fromPackages.get( i ); + + if (from.size() <= pkgPath.size()) + { + for ( int j = 0 ; j < from.size() ; j++ ) + if (!from.get( j ).equals( pkgPath.get( j ))) + continue from; + + changeFrom = from; + changeTo = (List) _toPackages.get( i ); + + break; + } + } + + if (changeTo != null) + { + String newPkg = ""; + String newName = ""; + + for ( int i = 0 ; i < changeTo.size() ; i++ ) + { + if (i > 0) + { + newPkg += "."; + newName += File.separatorChar; + } + + newPkg += changeTo.get( i ); + newName += changeTo.get( i ); + } + + for ( int i = filePath.size() - pkgPath.size() - 2 ; i >= 0 ; i-- ) + newName = (String) filePath.get( i ) + File.separatorChar + newName; + + for ( int i = changeFrom.size() ; i < pkgPath.size() ; i++ ) + { + newName += File.separatorChar + (String) pkgPath.get( i ); + newPkg += '.' + (String) pkgPath.get( i ); + } + + newName += File.separatorChar + (String) filePath.get( filePath.size() - 1 ); + + sb.replace( pkgStart, pkgEnd, newPkg ); + + name = newName; + String newDir = Repackager.dirForPath( name ); + + if (!srcDir.equals(newDir)) + { + _movedDirs.put(srcDir, newDir); + } + } + } + + File targetFile = new File(_targetBase, name); // new name + + if (sourceFile.lastModified() < targetFile.lastModified()) + { + _skippedFiles += 1; + return; + } + + writeFile( new File( _targetBase, name ), _repackager.repackage( sb ) ); + } + + void writeFile ( File f, StringBuffer chars ) + throws IOException + { + f.getParentFile().mkdirs(); + + OutputStream out = new FileOutputStream( f ); + Writer w = new OutputStreamWriter( out ); + Reader r = new StringReader( chars.toString() ); + + copy( r, w ); + + r.close(); + w.close(); + out.close(); + } + + StringBuffer readFile ( File f ) + throws IOException + { + InputStream in = new FileInputStream( f ); + Reader r = new InputStreamReader( in ); + StringWriter w = new StringWriter(); + + copy( r, w ); + + w.close(); + r.close(); + in.close(); + + return w.getBuffer(); + } + + StringBuffer readInputStream ( InputStream is ) + throws IOException + { + Reader r = new InputStreamReader( is ); + StringWriter w = new StringWriter(); + + copy( r, w ); + + w.close(); + r.close(); + + return w.getBuffer(); + } + + public static void copyFile ( File from, File to ) throws IOException + { + to.getParentFile().mkdirs(); + + FileInputStream in = new FileInputStream( from ); + FileOutputStream out = new FileOutputStream( to ); + + copy( in, out ); + + out.close(); + in.close(); + } + + public static void copy ( InputStream in, OutputStream out ) throws IOException + { + byte[] buffer = new byte [ 1024 * 16 ]; + + for ( ; ; ) + { + int n = in.read( buffer, 0, buffer.length ); + + if (n < 0) + break; + + out.write( buffer, 0, n ); + } + } + + public static void copy ( Reader r, Writer w ) throws IOException + { + char[] buffer = new char [ 1024 * 16 ]; + + for ( ; ; ) + { + int n = r.read( buffer, 0, buffer.length ); + + if (n < 0) + break; + + w.write( buffer, 0, n ); + } + } + + public void fillFiles ( ArrayList files, File file ) throws IOException + { + if (!file.isDirectory()) + { + files.add( file ); + return; + } + + // Exclude the build directory + + if (file.getName().equals( "build" )) + return; + + // Exclude CVS directories + if (file.getName().equals( "CVS" )) + return; + + String[] entries = file.list(); + + for ( int i = 0 ; i < entries.length ; i++ ) + fillFiles( files, new File( file, entries[ i ] ) ); + } + + public void recursiveDelete ( File file ) throws IOException + { + if (!file.exists()) + return; + + if (file.isDirectory()) + { + String[] entries = file.list(); + + for ( int i = 0 ; i < entries.length ; i++ ) + recursiveDelete( new File( file, entries[ i ] ) ); + } + + file.delete(); + } + + private File _sourceBase; + private File _targetBase; + + private List _fromPackages; + private List _toPackages; + + private Pattern _packagePattern; + + private Repackager _repackager; + + private Map _movedDirs; + private List _moveAlongFiles; + private int _skippedFiles; +} diff --git a/xmlbeans/src/repackage/repackage/Repackager.java b/xmlbeans/src/repackage/repackage/Repackager.java new file mode 100644 index 000000000..d1a815d0f --- /dev/null +++ b/xmlbeans/src/repackage/repackage/Repackager.java @@ -0,0 +1,184 @@ +/* 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 repackage; + +import java.util.List; +import java.util.ArrayList; +import java.util.regex.Pattern; +import java.util.regex.Matcher; +import java.io.File; + +public class Repackager +{ + public Repackager ( String repackageSpecs ) + { + _fromPackages = new ArrayList(); + _toPackages = new ArrayList(); + + List repackages = splitPath( repackageSpecs, ';' ); + + // Sort the repackage spec so that longer from's are first to match + // longest package first + + for ( ; ; ) + { + boolean swapped = false; + + for ( int i = 1 ; i < repackages.size() ; i++ ) + { + String spec1 = (String) repackages.get( i - 1 ); + String spec2 = (String) repackages.get( i ); + + if (spec1.indexOf( ':' ) < spec2.indexOf( ':' )) + { + repackages.set( i - 1, spec2 ); + repackages.set( i, spec1 ); + + swapped = true; + } + } + + if (!swapped) + break; + } + + for ( int i = 0 ; i < repackages.size() ; i++ ) + { + String spec = (String) repackages.get( i ); + + int j = spec.indexOf( ':' ); + + if (j < 0 || spec.indexOf( ':', j + 1 ) >= 0) + throw new RuntimeException( "Illegal repackage specification: " + spec ); + + String from = spec.substring( 0, j ); + String to = spec.substring( j + 1 ); + + _fromPackages.add( Repackager.splitPath( from, '.' ) ); + _toPackages.add( Repackager.splitPath( to, '.' ) ); + } + + _fromMatchers = new Matcher [ _fromPackages.size() * 2 ]; + _toPackageNames = new String [ _fromPackages.size() * 2 ]; + + addPatterns( '.', 0 ); + addPatterns( '/', _fromPackages.size() ); + } + + void addPatterns ( char sep, int off ) + { + for ( int i = 0 ; i < _fromPackages.size() ; i++ ) + { + List from = (List) _fromPackages.get( i ); + List to = (List) _toPackages.get( i ); + + String pattern = ""; + + for ( int j = 0 ; j < from.size() ; j++ ) + { + if (j > 0) + pattern += "\\" + sep; + + pattern += from.get( j ); + } + + String toPackage = ""; + + for ( int j = 0 ; j < to.size() ; j++ ) + { + if (j > 0) + toPackage += sep; + + toPackage += to.get( j ); + } + + _fromMatchers[ off + i ] = Pattern.compile( pattern ).matcher( "" ); + _toPackageNames[ off + i ] = toPackage; + } + } + + public StringBuffer repackage ( StringBuffer sb ) + { + StringBuffer result = null; + + for ( int i = 0 ; i < _fromMatchers.length ; i++ ) + { + Matcher m = (Matcher) _fromMatchers[ i ]; + + m.reset( sb ); + + for ( boolean found = m.find() ; found ; found = m.find() ) + { + if (result == null) + result = new StringBuffer(); + + m.appendReplacement( result, _toPackageNames[ i ] ); + } + + if (result != null) + { + m.appendTail( result ); + sb = result; + result = null; + } + } + + return sb; + } + + public List getFromPackages ( ) + { + return _fromPackages; + } + + public List getToPackages ( ) + { + return _toPackages; + } + + public static ArrayList splitPath ( String path, char separator ) + { + ArrayList components = new ArrayList(); + + for ( ; ; ) + { + int i = path.indexOf( separator ); + + if (i < 0) + break; + + components.add( path.substring( 0, i ) ); + + path = path.substring( i + 1 ); + } + + if (path.length() > 0) + components.add( path ); + + return components; + } + + public static String dirForPath ( String path ) + { + return new File(path).getParent(); + } + + private List _fromPackages; + private List _toPackages; + + private Matcher[] _fromMatchers; + private String[] _toPackageNames; +} \ No newline at end of file diff --git a/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/AttachmentPart.java b/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/AttachmentPart.java new file mode 100644 index 000000000..5e7f797e2 --- /dev/null +++ b/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/AttachmentPart.java @@ -0,0 +1,410 @@ +/* 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.soap; + +// ericvas +//import javax.activation.DataHandler; +import java.util.Iterator; + +/** + *

    A single attachment to a SOAPMessage object. A + * SOAPMessage object may contain zero, one, or many + * AttachmentPart objects. Each + * AttachmentPart object consists of two parts, + * application-specific content and associated MIME headers. The + * MIME headers consists of name/value pairs that can be used to + * identify and describe the content.

    + * + *

    An AttachmentPart object must conform to + * certain standards.

    + * + *
      + *
    1. It must conform to MIME [RFC2045] + * standards
    2. + * + *
    3. It MUST contain content
    4. + * + *
    5. + * The header portion MUST include the following header: + * + *
        + *
      • + * Content-Type
        + * This header identifies the type of data in the content + * of an AttachmentPart object and MUST + * conform to [RFC2045]. The following is an example of a + * Content-Type header: + *
        + *      Content-Type:  application/xml
        + *
        + * 
        + * The following line of code, in which ap is + * an AttachmentPart object, sets the header + * shown in the previous example. + *
        + *      ap.setMimeHeader("Content-Type", "application/xml");
        + *
        + * 
        + * + *

        + *
      • + *
      + *
    6. + *
    + * + *

    There are no restrictions on the content portion of an + * AttachmentPart object. The content may be anything + * from a simple plain text object to a complex XML document or + * image file.

    + * + *

    An AttachmentPart object is created with the + * method SOAPMessage.createAttachmentPart. After + * setting its MIME headers, the AttachmentPart + * object is added to the message that created it with the method + * SOAPMessage.addAttachmentPart.

    + * + *

    The following code fragment, in which m is a + * SOAPMessage object and contentStringl + * is a String, creates an instance of + * AttachmentPart, sets the AttachmentPart + * object with some content and header information, and adds the + * AttachmentPart object to the + * SOAPMessage object.

    + *
    + *    AttachmentPart ap1 = m.createAttachmentPart();
    + *    ap1.setContent(contentString1, "text/plain");
    + *    m.addAttachmentPart(ap1);
    + * 
    + * + *

    The following code fragment creates and adds a second + * AttachmentPart instance to the same message. + * jpegData is a binary byte buffer representing the jpeg + * file.

    + *
    + *    AttachmentPart ap2 = m.createAttachmentPart();
    + *    byte[] jpegData =  ...;
    + *    ap2.setContent(new ByteArrayInputStream(jpegData), "image/jpeg");
    + *    m.addAttachmentPart(ap2);
    + * 
    + * + *

    The getContent method retrieves the contents + * and header from an AttachmentPart object. + * Depending on the DataContentHandler objects + * present, the returned Object can either be a typed + * Java object corresponding to the MIME type or an + * InputStream object that contains the content as + * bytes.

    + *
    + *    String content1 = ap1.getContent();
    + *    java.io.InputStream content2 = ap2.getContent();
    + * 
    + * The method clearContent removes all the content + * from an AttachmentPart object but does not affect + * its header information. + *
    + *    ap1.clearContent();
    + * 
    + */ +public abstract class AttachmentPart { + + // fixme: should this constructor be protected? + /** Create a new AttachmentPart. */ + public AttachmentPart() {} + + /** + * Returns the number of bytes in this + * AttachmentPart object. + * @return the size of this AttachmentPart object + * in bytes or -1 if the size cannot be determined + * @throws SOAPException if the content of this + * attachment is corrupted of if there was an exception + * while trying to determine the size. + */ + public abstract int getSize() throws SOAPException; + + /** + * Clears out the content of this + * AttachmentPart object. The MIME header portion is left + * untouched. + */ + public abstract void clearContent(); + + /** + * Gets the content of this AttachmentPart object as a Java + * object. The type of the returned Java object depends on (1) the + * DataContentHandler object that is used to interpret the bytes + * and (2) the Content-Type given in the header. + *

    + * For the MIME content types "text/plain", "text/html" and "text/xml", the + * DataContentHandler object does the conversions to and + * from the Java types corresponding to the MIME types. + * For other MIME types,the DataContentHandler object + * can return an InputStream object that contains the content data + * as raw bytes. + *

    + * A JAXM-compliant implementation must, as a minimum, return a + * java.lang.String object corresponding to any content + * stream with a Content-Type value of + * text/plain, a + * javax.xml.transform.StreamSource object corresponding to a + * content stream with a Content-Type value of + * text/xml, a java.awt.Image object + * corresponding to a content stream with a + * Content-Type value of image/gif or + * image/jpeg. For those content types that an + * installed DataContentHandler object does not understand, the + * DataContentHandler object is required to return a + * java.io.InputStream object with the raw bytes. + * + * @return a Java object with the content of this + * AttachmentPart object + * @throws SOAPException if there is no content set + * into this AttachmentPart object or if there + * was a data transformation error + */ + public abstract Object getContent() throws SOAPException; + + /** + * Sets the content of this attachment part to that of the + * given Object and sets the value of the + * Content-Type header to the given type. The type of the + * Object should correspond to the value given for + * the Content-Type. This depends on the particular + * set of DataContentHandler objects in use. + * @param object the Java object that makes up + * the content for this attachment part + * @param contentType the MIME string that + * specifies the type of the content + * @throws java.lang.IllegalArgumentException if + * the contentType does not match the type of the content + * object, or if there was no + * DataContentHandler object for this content + * object + * @see #getContent() getContent() + */ + public abstract void setContent(Object object, String contentType); + + /** + * Gets the DataHandler object for this + * AttachmentPart object. + * @return the DataHandler object associated with + * this AttachmentPart object + * @throws SOAPException if there is + * no data in this AttachmentPart object + */ +// ericvas +// public abstract DataHandler getDataHandler() throws SOAPException; + + /** + * Sets the given DataHandler object as the + * data handler for this AttachmentPart object. + * Typically, on an incoming message, the data handler is + * automatically set. When a message is being created and + * populated with content, the setDataHandler + * method can be used to get data from various data sources into + * the message. + * @param datahandler DataHandler object to + * be set + * @throws java.lang.IllegalArgumentException if + * there was a problem with the specified + * DataHandler object + */ +// ericvas +// public abstract void setDataHandler(DataHandler datahandler); + + /** + * Gets the value of the MIME header whose name is + * "Content-Id". + * @return a String giving the value of the + * "Content-Id" header or null if there is + * none + * @see #setContentId(java.lang.String) setContentId(java.lang.String) + */ + public String getContentId() { + + String as[] = getMimeHeader("Content-Id"); + + if (as != null && as.length > 0) { + return as[0]; + } else { + return null; + } + } + + /** + * Gets the value of the MIME header + * "Content-Location". + * @return a String giving the value of the + * "Content-Location" header or null if there + * is none + */ + public String getContentLocation() { + + String as[] = getMimeHeader("Content-Location"); + + if (as != null && as.length > 0) { + return as[0]; + } else { + return null; + } + } + + /** + * Gets the value of the MIME header "Content-Type". + * @return a String giving the value of the + * "Content-Type" header or null if there is + * none + */ + public String getContentType() { + + String as[] = getMimeHeader("Content-Type"); + + if (as != null && as.length > 0) { + return as[0]; + } else { + return null; + } + } + + /** + * Sets the MIME header "Content-Id" with the given + * value. + * @param contentId a String giving + * the value of the "Content-Id" header + * @throws java.lang.IllegalArgumentException if + * there was a problem with the specified + * contentId value + * @see #getContentId() getContentId() + */ + public void setContentId(String contentId) { + setMimeHeader("Content-Id", contentId); + } + + /** + * Sets the MIME header "Content-Location" with the given + * value. + * @param contentLocation a String + * giving the value of the "Content-Location" header + * @throws java.lang.IllegalArgumentException if + * there was a problem with the specified content + * location + */ + public void setContentLocation(String contentLocation) { + setMimeHeader("Content-Location", contentLocation); + } + + /** + * Sets the MIME header "Content-Type" with the given + * value. + * @param contentType a String + * giving the value of the "Content-Type" header + * @throws java.lang.IllegalArgumentException if + * there was a problem with the specified content type + */ + public void setContentType(String contentType) { + setMimeHeader("Content-Type", contentType); + } + + /** + * Removes all MIME headers that match the given name. + * @param header - the string name of the MIME + * header/s to be removed + */ + public abstract void removeMimeHeader(String header); + + /** Removes all the MIME header entries. */ + public abstract void removeAllMimeHeaders(); + + /** + * Gets all the values of the header identified by the given + * String. + * @param name the name of the header; example: + * "Content-Type" + * @return a String array giving the value for the + * specified header + * @see #setMimeHeader(java.lang.String, java.lang.String) setMimeHeader(java.lang.String, java.lang.String) + */ + public abstract String[] getMimeHeader(String name); + + /** + * Changes the first header entry that matches the given name + * to the given value, adding a new header if no existing + * header matches. This method also removes all matching + * headers but the first. + * + *

    Note that RFC822 headers can only contain US-ASCII + * characters.

    + * @param name a String giving the + * name of the header for which to search + * @param value a String giving the + * value to be set for the header whose name matches the + * given name + * @throws java.lang.IllegalArgumentException if + * there was a problem with the specified mime header name + * or value + */ + public abstract void setMimeHeader(String name, String value); + + /** + * Adds a MIME header with the specified name and value to + * this AttachmentPart object. + * + *

    Note that RFC822 headers can contain only US-ASCII + * characters.

    + * @param name a String giving the + * name of the header to be added + * @param value a String giving the + * value of the header to be added + * @throws java.lang.IllegalArgumentException if + * there was a problem with the specified mime header name + * or value + */ + public abstract void addMimeHeader(String name, String value); + + /** + * Retrieves all the headers for this + * AttachmentPart object as an iterator over the + * MimeHeader objects. + * @return an Iterator object with all of the Mime + * headers for this AttachmentPart object + */ + public abstract Iterator getAllMimeHeaders(); + + /** + * Retrieves all MimeHeader objects that match + * a name in the given array. + * @param names a String array with + * the name(s) of the MIME headers to be returned + * @return all of the MIME headers that match one of the names + * in the given array as an Iterator + * object + */ + public abstract Iterator getMatchingMimeHeaders(String names[]); + + /** + * Retrieves all MimeHeader objects whose name + * does not match a name in the given array. + * @param names a String array with + * the name(s) of the MIME headers not to be returned + * @return all of the MIME headers in this + * AttachmentPart object except those that match one + * of the names in the given array. The nonmatching MIME + * headers are returned as an Iterator + * object. + */ + public abstract Iterator getNonMatchingMimeHeaders(String names[]); +} diff --git a/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/Detail.java b/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/Detail.java new file mode 100644 index 000000000..0ac4dbe5f --- /dev/null +++ b/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/Detail.java @@ -0,0 +1,65 @@ +/* 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.soap; + +import java.util.Iterator; + +/** + * A container for DetailEntry objects. DetailEntry + * objects give detailed error information that is application-specific and + * related to the SOAPBody object that contains it. + *

    + * A Detail object, which is part of a SOAPFault + * object, can be retrieved using the method SOAPFault.getDetail. + * The Detail interface provides two methods. One creates a new + * DetailEntry object and also automatically adds it to + * the Detail object. The second method gets a list of the + * DetailEntry objects contained in a Detail + * object. + *

    + * The following code fragment, in which sf is a SOAPFault + * object, gets its Detail object (d), adds a new + * DetailEntry object to d, and then gets a list of all the + * DetailEntry objects in d. The code also creates a + * Name object to pass to the method addDetailEntry. + * The variable se, used to create the Name object, + * is a SOAPEnvelope object. + *

    + *    Detail d = sf.getDetail();
    + *    Name name = se.createName("GetLastTradePrice", "WOMBAT",
    + *                                "http://www.wombat.org/trader");
    + *    d.addDetailEntry(name);
    + *    Iterator it = d.getDetailEntries();
    + * 
    + */ +public interface Detail extends SOAPFaultElement { + + /** + * Creates a new DetailEntry object with the given + * name and adds it to this Detail object. + * @param name a Name object identifying the new DetailEntry object + * @return DetailEntry. + * @throws SOAPException thrown when there is a problem in adding a DetailEntry object to this Detail object. + */ + public abstract DetailEntry addDetailEntry(Name name) throws SOAPException; + + /** + * Gets a list of the detail entries in this Detail object. + * @return an Iterator object over the DetailEntry + * objects in this Detail object + */ + public abstract Iterator getDetailEntries(); +} diff --git a/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/DetailEntry.java b/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/DetailEntry.java new file mode 100644 index 000000000..464e80ced --- /dev/null +++ b/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/DetailEntry.java @@ -0,0 +1,25 @@ +/* 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.soap; + +/** + * The content for a Detail object, giving details for + * a SOAPFault object. A DetailEntry object, + * which carries information about errors related to the SOAPBody + * object that contains it, is application-specific. + *

    + */ +public interface DetailEntry extends SOAPElement {} diff --git a/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/FactoryFinder.java b/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/FactoryFinder.java new file mode 100644 index 000000000..9b73b6dca --- /dev/null +++ b/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/FactoryFinder.java @@ -0,0 +1,154 @@ +/* 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.soap; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.InputStream; +import java.io.InputStreamReader; + +import java.util.Properties; +import org.apache.xmlbeans.SystemProperties; + +/** + * This class is used to locate factory classes for javax.xml.soap. + * It has package scope since it is not part of JAXM and should not + * be accessed from other packages. + */ +class FactoryFinder { + /** + * instantiates an object go the given classname. + * + * @param factoryClassName + * @return a factory object + * @throws SOAPException + */ + private static Object newInstance(String factoryClassName) throws SOAPException { + ClassLoader classloader = null; + try { + classloader = Thread.currentThread().getContextClassLoader(); + } catch (Exception exception) { + throw new SOAPException(exception.toString(), exception); + } + + try { + Class factory = null; + if (classloader == null) { + factory = Class.forName(factoryClassName); + } else { + try { + factory = classloader.loadClass(factoryClassName); + } catch (ClassNotFoundException cnfe) {} + } + if (factory == null) { + classloader = FactoryFinder.class.getClassLoader(); + factory = classloader.loadClass(factoryClassName); + } + return factory.newInstance(); + } catch (ClassNotFoundException classnotfoundexception) { + throw new SOAPException("Provider " + factoryClassName + " not found", classnotfoundexception); + } catch (Exception exception) { + throw new SOAPException("Provider " + factoryClassName + " could not be instantiated: " + exception, exception); + } + } + + /** + * Instantiates a factory object given the factory's property name and the + * default class name. + * + * @param factoryPropertyName + * @param defaultFactoryClassName + * @return a factory object + * @throws SOAPException + */ + static Object find(String factoryPropertyName, String defaultFactoryClassName) throws SOAPException { + try { + String factoryClassName = SystemProperties.getProperty(factoryPropertyName); + if (factoryClassName != null) { + return newInstance(factoryClassName); + } + } catch (SecurityException securityexception) {} + + try { + String propertiesFileName = SystemProperties.getProperty("java.home") + + File.separator + "lib" + + File.separator + "jaxm.properties"; + File file = new File(propertiesFileName); + if (file.exists()) { + FileInputStream fileInput = new FileInputStream(file); + Properties properties = new Properties(); + properties.load(fileInput); + fileInput.close(); + String factoryClassName = properties.getProperty(factoryPropertyName); + return newInstance(factoryClassName); + } + } catch (Exception exception1) {} + + String factoryResource = "META-INF/services/" + factoryPropertyName; + + try { + InputStream inputstream = getResource(factoryResource); + if (inputstream != null) { + BufferedReader bufferedreader = new BufferedReader(new InputStreamReader(inputstream, "UTF-8")); + String factoryClassName = bufferedreader.readLine(); + bufferedreader.close(); + if ((factoryClassName != null) && !"".equals(factoryClassName)) { + return newInstance(factoryClassName); + } + } + } catch (Exception exception2) {} + + if (defaultFactoryClassName == null) { + throw new SOAPException("Provider for " + factoryPropertyName + " cannot be found", null); + } else { + return newInstance(defaultFactoryClassName); + } + } + + /** + * Returns an input stream for the specified resource. + * + *

    This method will firstly try + * ClassLoader.getSystemResourceAsStream() then + * the class loader of the current thread with + * getResourceAsStream() and finally attempt + * getResourceAsStream() on + * FactoryFinder.class.getClassLoader(). + * + * @param factoryResource the resource name + * @return an InputStream that can be used to read that resource, or + * null if the resource could not be resolved + */ + private static InputStream getResource(String factoryResource) { + ClassLoader classloader = null; + try { + classloader = Thread.currentThread().getContextClassLoader(); + } catch (SecurityException securityexception) {} + + InputStream inputstream; + if (classloader == null) { + inputstream = ClassLoader.getSystemResourceAsStream(factoryResource); + } else { + inputstream = classloader.getResourceAsStream(factoryResource); + } + + if (inputstream == null) { + inputstream = FactoryFinder.class.getClassLoader().getResourceAsStream(factoryResource); + } + return inputstream; + } +} diff --git a/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/MessageFactory.java b/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/MessageFactory.java new file mode 100644 index 000000000..cb37d0603 --- /dev/null +++ b/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/MessageFactory.java @@ -0,0 +1,169 @@ +/* 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.soap; + +import java.io.IOException; +import java.io.InputStream; + +/** + *

    A factory for creating SOAPMessage objects.

    + * + *

    A JAXM client performs the following steps to create a + * message.

    + * + *
      + *
    • + * Creates a MessageFactory object from a + * ProviderConnection object (con in the + * following line of code). The String passed to + * the createMessageFactory method is the name of + * of a messaging profile, which must be the URL for the + * schema. + *
      + *      MessageFactory mf = con.createMessageFactory(schemaURL);
      + * 
      + *
    • + * + *
    • + * Calls the method createMessage on the + * MessageFactory object. All messages produced by this + * MessageFactory object will have the header + * information appropriate for the messaging profile that was + * specified when the MessageFactory object was + * created. + *
      + *      SOAPMessage m = mf.createMessage();
      + * 
      + *
    • + *
    + * It is also possible to create a MessageFactory + * object using the method newInstance, as shown in + * the following line of code. + *
    + *      MessageFactory mf = MessageFactory.newInstance();
    + * 
    + * A standalone client (a client that is not running in a + * container) can use the newInstance method to + * create a MessageFactory object. + * + *

    All MessageFactory objects, regardless of how + * they are created, will produce SOAPMessage objects + * that have the following elements by default:

    + * + *
      + *
    • A SOAPPart object
    • + * + *
    • A SOAPEnvelope object
    • + * + *
    • A SOAPBody object
    • + * + *
    • A SOAPHeader object
    • + *
    + * If a MessageFactory object was created using a + * ProviderConnection object, which means that it was + * initialized with a specified profile, it will produce messages + * that also come prepopulated with additional entries in the + * SOAPHeader object and the SOAPBody + * object. The content of a new SOAPMessage object + * depends on which of the two MessageFactory methods + * is used to create it. + * + *
      + *
    • createMessage() -- message has no + * content
      + * This is the method clients would normally use to create a + * request message.
    • + * + *
    • createMessage(MimeHeaders, + * java.io.InputStream) -- message has content from the + * InputStream object and headers from the + * MimeHeaders object
      + * This method can be used internally by a service + * implementation to create a message that is a response to a + * request.
    • + *
    + */ +public abstract class MessageFactory { + + // fixme: this should be protected as the class is abstract. + /** Create a new MessageFactory. */ + public MessageFactory() {} + + /** + * Creates a new MessageFactory object that is + * an instance of the default implementation. + * @return a new MessageFactory object + * @throws SOAPException if there was an error in + * creating the default implementation of the + * MessageFactory + */ + public static MessageFactory newInstance() throws SOAPException { + + try { + return (MessageFactory) FactoryFinder.find(MESSAGE_FACTORY_PROPERTY, + DEFAULT_MESSAGE_FACTORY); + } catch (Exception exception) { + throw new SOAPException( + "Unable to create message factory for SOAP: " + + exception.getMessage()); + } + } + + /** + * Creates a new SOAPMessage object with the + * default SOAPPart, SOAPEnvelope, + * SOAPBody, and SOAPHeader objects. + * Profile-specific message factories can choose to + * prepopulate the SOAPMessage object with + * profile-specific headers. + * + *

    Content can be added to this message's + * SOAPPart object, and the message can be sent "as is" + * when a message containing only a SOAP part is sufficient. + * Otherwise, the SOAPMessage object needs to + * create one or more AttachmentPart objects and + * add them to itself. Any content that is not in XML format + * must be in an AttachmentPart object.

    + * @return a new SOAPMessage object + * @throws SOAPException if a SOAP error occurs + */ + public abstract SOAPMessage createMessage() throws SOAPException; + + /** + * Internalizes the contents of the given + * InputStream object into a new SOAPMessage + * object and returns the SOAPMessage object. + * @param mimeheaders the transport-specific headers + * passed to the message in a transport-independent fashion + * for creation of the message + * @param inputstream the InputStream object + * that contains the data for a message + * @return a new SOAPMessage object containing the + * data from the given InputStream object + * @throws IOException if there is a + * problem in reading data from the input stream + * @throws SOAPException if the message is invalid + */ + public abstract SOAPMessage createMessage( + MimeHeaders mimeheaders, InputStream inputstream) + throws IOException, SOAPException; + + private static final String DEFAULT_MESSAGE_FACTORY = + "org.apache.axis.soap.MessageFactoryImpl"; + + private static final String MESSAGE_FACTORY_PROPERTY = + "javax.xml.soap.MessageFactory"; +} diff --git a/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/MimeHeader.java b/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/MimeHeader.java new file mode 100644 index 000000000..4bd092d43 --- /dev/null +++ b/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/MimeHeader.java @@ -0,0 +1,60 @@ +/* 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.soap; + +/** + * An object that stores a MIME header name and its value. One + * or more MimeHeader objects may be contained in a + * MimeHeaders object. + * @see MimeHeaders MimeHeaders + */ +public class MimeHeader { + + /** + * Constructs a MimeHeader object initialized + * with the given name and value. + * @param name a String giving the + * name of the header + * @param value a String giving the + * value of the header + */ + public MimeHeader(String name, String value) { + this.name = name; + this.value = value; + } + + /** + * Returns the name of this MimeHeader + * object. + * @return the name of the header as a String + */ + public String getName() { + return name; + } + + /** + * Returns the value of this MimeHeader + * object. + * @return the value of the header as a String + */ + public String getValue() { + return value; + } + + private String name; + + private String value; +} diff --git a/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/MimeHeaders.java b/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/MimeHeaders.java new file mode 100644 index 000000000..ccf288770 --- /dev/null +++ b/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/MimeHeaders.java @@ -0,0 +1,310 @@ +/* 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.soap; + +import java.util.Iterator; +import java.util.Vector; + +/** + * A container for MimeHeader objects, which + * represent the MIME headers present in a MIME part of a + * message.

    + * + *

    This class is used primarily when an application wants to + * retrieve specific attachments based on certain MIME headers and + * values. This class will most likely be used by implementations + * of AttachmentPart and other MIME dependent parts + * of the JAXM API. + * @see SOAPMessage#getAttachments() SOAPMessage.getAttachments() + * @see AttachmentPart AttachmentPart + */ +public class MimeHeaders { + + class MatchingIterator implements Iterator { + + private Object nextMatch() { + + label0: + while (iterator.hasNext()) { + MimeHeader mimeheader = (MimeHeader) iterator.next(); + + if (names == null) { + return match + ? null + : mimeheader; + } + + for (int i = 0; i < names.length; i++) { + if (!mimeheader.getName().equalsIgnoreCase(names[i])) { + continue; + } + + if (match) { + return mimeheader; + } + + continue label0; + } + + if (!match) { + return mimeheader; + } + } + + return null; + } + + public boolean hasNext() { + + if (nextHeader == null) { + nextHeader = nextMatch(); + } + + return nextHeader != null; + } + + public Object next() { + + if (nextHeader != null) { + Object obj = nextHeader; + + nextHeader = null; + + return obj; + } + + if (hasNext()) { + return nextHeader; + } else { + return null; + } + } + + public void remove() { + iterator.remove(); + } + + private boolean match; + + private Iterator iterator; + + private String names[]; + + private Object nextHeader; + + MatchingIterator(String as[], boolean flag) { + + match = flag; + names = as; + iterator = headers.iterator(); + } + } + + /** + * Constructs + * a default MimeHeaders object initialized with + * an empty Vector object. + */ + public MimeHeaders() { + headers = new Vector(); + } + + /** + * Returns all of the values for the specified header as an + * array of String objects. + * @param name the name of the header for which + * values will be returned + * @return a String array with all of the values + * for the specified header + * @see #setHeader(java.lang.String, java.lang.String) setHeader(java.lang.String, java.lang.String) + */ + public String[] getHeader(String name) { + + Vector vector = new Vector(); + + for (int i = 0; i < headers.size(); i++) { + MimeHeader mimeheader = (MimeHeader) headers.elementAt(i); + + if (mimeheader.getName().equalsIgnoreCase(name) + && (mimeheader.getValue() != null)) { + vector.addElement(mimeheader.getValue()); + } + } + + if (vector.size() == 0) { + return null; + } else { + String as[] = new String[vector.size()]; + + vector.copyInto(as); + + return as; + } + } + + /** + * Replaces the current value of the first header entry whose + * name matches the given name with the given value, adding a + * new header if no existing header name matches. This method + * also removes all matching headers after the first one. + * + *

    Note that RFC822 headers can contain only US-ASCII + * characters.

    + * @param name a String with the + * name of the header for which to search + * @param value a String with the + * value that will replace the current value of the + * specified header + * @throws java.lang.IllegalArgumentException if there was a + * problem in the mime header name or the value being set + * @see #getHeader(java.lang.String) getHeader(java.lang.String) + */ + public void setHeader(String name, String value) { + + boolean flag = false; + + if ((name == null) || name.equals("")) { + throw new IllegalArgumentException( + "Illegal MimeHeader name"); + } + + for (int i = 0; i < headers.size(); i++) { + MimeHeader mimeheader = (MimeHeader) headers.elementAt(i); + + if (mimeheader.getName().equalsIgnoreCase(name)) { + if (!flag) { + headers.setElementAt(new MimeHeader(mimeheader + .getName(), value), i); + + flag = true; + } else { + headers.removeElementAt(i--); + } + } + } + + if (!flag) { + addHeader(name, value); + } + } + + /** + * Adds a MimeHeader object with the specified + * name and value to this MimeHeaders object's + * list of headers. + * + *

    Note that RFC822 headers can contain only US-ASCII + * characters.

    + * @param name a String with the + * name of the header to be added + * @param value a String with the + * value of the header to be added + * @throws java.lang.IllegalArgumentException if + * there was a problem in the mime header name or value + * being added + */ + public void addHeader(String name, String value) { + + if ((name == null) || name.equals("")) { + throw new IllegalArgumentException( + "Illegal MimeHeader name"); + } + + int i = headers.size(); + + for (int j = i - 1; j >= 0; j--) { + MimeHeader mimeheader = (MimeHeader) headers.elementAt(j); + + if (mimeheader.getName().equalsIgnoreCase(name)) { + headers.insertElementAt(new MimeHeader(name, value), j + 1); + + return; + } + } + + headers.addElement(new MimeHeader(name, value)); + } + + /** + * Remove all MimeHeader objects whose name + * matches the the given name. + * @param name a String with the + * name of the header for which to search + */ + public void removeHeader(String name) { + + for (int i = 0; i < headers.size(); i++) { + MimeHeader mimeheader = (MimeHeader) headers.elementAt(i); + + if (mimeheader.getName().equalsIgnoreCase(name)) { + headers.removeElementAt(i--); + } + } + } + + /** + * Removes all the header entries from this + * MimeHeaders object. + */ + public void removeAllHeaders() { + headers.removeAllElements(); + } + + /** + * Returns all the headers in this MimeHeaders + * object. + * @return an Iterator object over this + * MimeHeaders object's list of + * MimeHeader objects + */ + public Iterator getAllHeaders() { + return headers.iterator(); + } + + /** + * Returns all the MimeHeader objects whose + * name matches a name in the given array of names. + * @param names an array of String + * objects with the names for which to search + * @return an Iterator object over the + * MimeHeader objects whose name matches one of the + * names in the given list + */ + public Iterator getMatchingHeaders(String names[]) { + return new MatchingIterator(names, true); + } + + /** + * Returns all of the MimeHeader objects whose + * name does not match a name in the given array of names. + * @param names an array of String + * objects with the names for which to search + * @return an Iterator object over the + * MimeHeader objects whose name does not match one + * of the names in the given list + */ + public Iterator getNonMatchingHeaders(String names[]) { + return new MatchingIterator(names, false); + } + + // fixme: does this need to be a Vector? Will a non-synchronized impl of + // List do? + /** + * A Vector containing the headers as MimeHeader + * instances. + */ + protected Vector headers; +} diff --git a/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/Name.java b/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/Name.java new file mode 100644 index 000000000..10b836297 --- /dev/null +++ b/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/Name.java @@ -0,0 +1,91 @@ +/* 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.soap; + +/** + * A representation of an XML name. This interface provides methods for + * getting the local and namespace-qualified names and also for getting the + * prefix associated with the namespace for the name. It is also possible + * to get the URI of the namespace. + *

    + * The following is an example of a namespace declaration in an element. + *

    + *  <wombat:GetLastTradePrice xmlns:wombat="http://www.wombat.org/trader">
    + * 
    + * ("xmlns" stands for "XML namespace".) + * The following + * shows what the methods in the Name interface will return. + *
      + *
    • getQualifiedName will return "prefix:LocalName" = + * "WOMBAT:GetLastTradePrice" + *
    • getURI will return "http://www.wombat.org/trader" + *
    • getLocalName will return "GetLastTracePrice" + *
    • getPrefix will return "WOMBAT" + *
    + *

    + * XML namespaces are used to disambiguate SOAP identifiers from + * application-specific identifiers. + *

    + * Name objects are created using the method + * SOAPEnvelope.createName, which has two versions. + * One method creates Name objects with + * a local name, a namespace prefix, and a namespace URI. + * and the second creates Name objects with just a local name. + * The following line of + * code, in which se is a SOAPEnvelope object, creates a new + * Name object with all three. + *

    + *    Name name = se.createName("GetLastTradePrice", "WOMBAT",
    + *                               "http://www.wombat.org/trader");
    + * 
    + * The following line of code gives an example of how a Name object + * can be used. The variable element is a SOAPElement object. + * This code creates a new SOAPElement object with the given name and + * adds it to element. + *
    + *    element.addChildElement(name);
    + * 
    + */ +public interface Name { + + /** + * Gets the local name part of the XML name that this Name + * object represents. + * @return a string giving the local name + */ + public abstract String getLocalName(); + + /** + * Gets the namespace-qualified name of the XML name that this + * Name object represents. + * @return the namespace-qualified name as a string + */ + public abstract String getQualifiedName(); + + /** + * Returns the prefix associated with the namespace for the XML + * name that this Name object represents. + * @return the prefix as a string + */ + public abstract String getPrefix(); + + /** + * Returns the URI of the namespace for the XML + * name that this Name object represents. + * @return the URI as a string + */ + public abstract String getURI(); +} diff --git a/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/Node.java b/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/Node.java new file mode 100644 index 000000000..29b6a830f --- /dev/null +++ b/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/Node.java @@ -0,0 +1,92 @@ +/* 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.soap; + +/** + * A representation of a node (element) in a DOM representation of an XML document + * that provides some tree manipulation methods. + * This interface provides methods for getting the value of a node, for + * getting and setting the parent of a node, and for removing a node. + */ +public interface Node extends org.w3c.dom.Node { + + /** + * Returns the the value of the immediate child of this Node + * object if a child exists and its value is text. + * @return a String with the text of the immediate child of + * this Node object if (1) there is a child and + * (2) the child is a Text object; + * null otherwise + */ + public abstract String getValue(); + + /** + * Sets the parent of this Node object to the given + * SOAPElement object. + * @param parent the SOAPElement object to be set as + * the parent of this Node object + * @throws SOAPException if there is a problem in setting the + * parent to the given element + * @see #getParentElement() getParentElement() + */ + public abstract void setParentElement(SOAPElement parent) + throws SOAPException; + + /** + * Returns the parent element of this Node object. + * This method can throw an UnsupportedOperationException + * if the tree is not kept in memory. + * @return the SOAPElement object that is the parent of + * this Node object or null if this + * Node object is root + * @throws java.lang.UnsupportedOperationException if the whole tree is not kept in memory + * @see #setParentElement(javax.xml.soap.SOAPElement) setParentElement(javax.xml.soap.SOAPElement) + */ + public abstract SOAPElement getParentElement(); + + /** + * Removes this Node object from the tree. Once + * removed, this node can be garbage collected if there are no + * application references to it. + */ + public abstract void detachNode(); + + /** + * Notifies the implementation that this Node + * object is no longer being used by the application and that the + * implementation is free to reuse this object for nodes that may + * be created later. + *

    + * Calling the method recycleNode implies that the method + * detachNode has been called previously. + */ + public abstract void recycleNode(); + + /** + * If this is a Text node then this method will set its value, otherwise it + * sets the value of the immediate (Text) child of this node. The value of + * the immediate child of this node can be set only if, there is one child + * node and that node is a Text node, or if there are no children in which + * case a child Text node will be created. + * + * @param value the text to set + * @throws IllegalStateException if the node is not a Text node and + * either has more than one child node or has a child node that + * is not a Text node + */ + + public abstract void setValue(String value); +} diff --git a/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/SOAPBody.java b/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/SOAPBody.java new file mode 100644 index 000000000..e4003c185 --- /dev/null +++ b/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/SOAPBody.java @@ -0,0 +1,125 @@ +/* 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.soap; + +import org.w3c.dom.Document; + +import java.util.Locale; + +/** + * An object that represents the contents of the SOAP body + * element in a SOAP message. A SOAP body element consists of XML data + * that affects the way the application-specific content is processed. + *

    + * A SOAPBody object contains SOAPBodyElement + * objects, which have the content for the SOAP body. + * A SOAPFault object, which carries status and/or + * error information, is an example of a SOAPBodyElement object. + * @see SOAPFault SOAPFault + */ +public interface SOAPBody extends SOAPElement { + + /** + * Creates a new SOAPFault object and adds it to + * this SOAPBody object. + * @return the new SOAPFault object + * @throws SOAPException if there is a SOAP error + */ + public abstract SOAPFault addFault() throws SOAPException; + + /** + * Indicates whether a SOAPFault object exists in + * this SOAPBody object. + * @return true if a SOAPFault object exists in + * this SOAPBody object; false + * otherwise + */ + public abstract boolean hasFault(); + + /** + * Returns the SOAPFault object in this SOAPBody + * object. + * @return the SOAPFault object in this SOAPBody + * object + */ + public abstract SOAPFault getFault(); + + /** + * Creates a new SOAPBodyElement object with the + * specified name and adds it to this SOAPBody object. + * @param name a Name object with the name for the new + * SOAPBodyElement object + * @return the new SOAPBodyElement object + * @throws SOAPException if a SOAP error occurs + */ + public abstract SOAPBodyElement addBodyElement(Name name) + throws SOAPException; + + /** + * Creates a new SOAPFault object and adds it to this + * SOAPBody object. The new SOAPFault will have a + * faultcode element that is set to the faultCode + * parameter and a faultstring set to faultstring + * and localized to locale. + * + * @param faultCode a Name object giving the fault code to be + * set; must be one of the fault codes defined in the SOAP 1.1 + * specification and of type QName + * @param faultString a String giving an explanation of the + * fault + * @param locale a Locale object indicating the native language + * of the faultString + * @return the new SOAPFault object + * @throws SOAPException if there is a SOAP error + */ + public abstract SOAPFault addFault(Name faultCode, + String faultString, + Locale locale) throws SOAPException; + + /** + * Creates a new SOAPFault object and adds it to this + * SOAPBody object. The new SOAPFault will have a + * faultcode element that is set to the faultCode + * parameter and a faultstring set to faultstring. + * + * @param faultCode a Name object giving the fault code to be + * set; must be one of the fault codes defined in the SOAP 1.1 + * specification and of type QName + * @param faultString a String giving an explanation of the + * fault + * @return the new SOAPFault object + * @throws SOAPException if there is a SOAP error + */ + public abstract SOAPFault addFault(Name faultCode, String faultString) throws SOAPException; + + /** + * Adds the root node of the DOM Document to this + * SOAPBody object. + *

    + * Calling this method invalidates the document parameter. The + * client application should discard all references to this + * Document and its contents upon calling + * addDocument. The behavior of an application that continues + * to use such references is undefined. + * + * @param document the Document object whose root node will be + * added to this SOAPBody + * @return the SOAPBodyElement that represents the root node + * that was added + * @throws SOAPException if the Document cannot be added + */ + public abstract SOAPBodyElement addDocument(Document document) throws SOAPException; + } diff --git a/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/SOAPBodyElement.java b/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/SOAPBodyElement.java new file mode 100644 index 000000000..d13400cdb --- /dev/null +++ b/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/SOAPBodyElement.java @@ -0,0 +1,32 @@ +/* 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.soap; + +/** + * A SOAPBodyElement object represents the contents in + * a SOAPBody object. The SOAPFault interface + * is a SOAPBodyElement object that has been defined. + *

    + * A new SOAPBodyElement object can be created and added + * to a SOAPBody object with the SOAPBody + * method addBodyElement. In the following line of code, + * sb is a SOAPBody object, and + * myName is a Name object. + *

    + *   SOAPBodyElement sbe = sb.addBodyElement(myName);
    + * 
    + */ +public interface SOAPBodyElement extends SOAPElement {} diff --git a/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/SOAPConnection.java b/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/SOAPConnection.java new file mode 100644 index 000000000..b7785fd06 --- /dev/null +++ b/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/SOAPConnection.java @@ -0,0 +1,60 @@ +/* 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.soap; + +/** + * A point-to-point connection that a client can use for sending messages + * directly to a remote party (represented by a URL, for instance). + *

    + * A client can obtain a SOAPConnection object simply by + * calling the following static method. + *

    + *
    + *      SOAPConnection con = SOAPConnection.newInstance();
    + * 
    + * A SOAPConnection object can be used to send messages + * directly to a URL following the request/response paradigm. That is, + * messages are sent using the method call, which sends the + * message and then waits until it gets a reply. + */ +public abstract class SOAPConnection { + + public SOAPConnection() {} + + /** + * Sends the given message to the specified endpoint and + * blocks until it has returned the response. + * @param request the SOAPMessage + * object to be sent + * @param endpoint an Object that identifies + * where the message should be sent. It is required to + * support Objects of type + * java.lang.String, + * java.net.URL, and when JAXM is present + * javax.xml.messaging.URLEndpoint + * @return the SOAPMessage object that is the + * response to the message that was sent + * @throws SOAPException if there is a SOAP error + */ + public abstract SOAPMessage call(SOAPMessage request, Object endpoint) + throws SOAPException; + + /** + * Closes this SOAPConnection object. + * @throws SOAPException if there is a SOAP error + */ + public abstract void close() throws SOAPException; +} diff --git a/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/SOAPConnectionFactory.java b/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/SOAPConnectionFactory.java new file mode 100644 index 000000000..94d85c687 --- /dev/null +++ b/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/SOAPConnectionFactory.java @@ -0,0 +1,65 @@ +/* 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.soap; + +/** + * A factory for creating SOAPConnection objects. Implementation of + * this class is optional. If SOAPConnectionFactory.newInstance() + * throws an UnsupportedOperationException then the implementation + * does not support the SAAJ communication infrastructure. Otherwise + * SOAPConnection objects can be created by calling + * createConnection() on the newly created + * SOAPConnectionFactory object. + */ +public abstract class SOAPConnectionFactory { + + public SOAPConnectionFactory() {} + + /** + * Creates an instance of the default + * SOAPConnectionFactory object. + * @return a new instance of a default + * SOAPConnectionFactory object + * @throws SOAPException if there was an error creating + * the SOAPConnectionFactory + * @throws UnsupportedOperationException if newInstance is not supported. + */ + public static SOAPConnectionFactory newInstance() + throws SOAPException, UnsupportedOperationException { + + try { + return (SOAPConnectionFactory) FactoryFinder.find(SF_PROPERTY, + DEFAULT_SOAP_CONNECTION_FACTORY); + } catch (Exception exception) { + throw new SOAPException("Unable to create SOAP connection factory: " + + exception.getMessage()); + } + } + + /** + * Create a new SOAPConnection. + * @return the new SOAPConnection object. + * @throws SOAPException if there was an exception + * creating the SOAPConnection object. + */ + public abstract SOAPConnection createConnection() throws SOAPException; + + private static final String DEFAULT_SOAP_CONNECTION_FACTORY = + "org.apache.axis.soap.SOAPConnectionFactoryImpl"; + + private static final String SF_PROPERTY = + "javax.xml.soap.SOAPConnectionFactory"; +} diff --git a/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/SOAPConstants.java b/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/SOAPConstants.java new file mode 100644 index 000000000..87ae50278 --- /dev/null +++ b/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/SOAPConstants.java @@ -0,0 +1,38 @@ +/* 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.soap; + +/** The definition of constants pertaining to the SOAP 1.1 protocol. */ +public interface SOAPConstants { + + /** The namespace identifier for the SOAP envelope. */ + public static final String URI_NS_SOAP_ENVELOPE = + "http://schemas.xmlsoap.org/soap/envelope/"; + + /** + * The namespace identifier for the SOAP encoding (see section 5 of + * the SOAP 1.1 specification). + */ + public static final String URI_NS_SOAP_ENCODING = + "http://schemas.xmlsoap.org/soap/encoding/"; + + /** + * The URI identifying the first application processing a SOAP request as the intended + * actor for a SOAP header entry (see section 4.2.2 of the SOAP 1.1 specification). + */ + public static final String URI_SOAP_ACTOR_NEXT = + "http://schemas.xmlsoap.org/soap/actor/next"; +} diff --git a/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/SOAPElement.java b/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/SOAPElement.java new file mode 100644 index 000000000..d0e52a378 --- /dev/null +++ b/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/SOAPElement.java @@ -0,0 +1,288 @@ +/* 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.soap; + +import java.util.Iterator; + +/** + * An object representing the contents in a + * SOAPBody object, the contents in a SOAPHeader + * object, the content that can follow the SOAPBody object in a + * SOAPEnvelope object, or what can follow the detail element + * in a SOAPFault object. It is + * the base class for all of the classes that represent the SOAP objects as + * defined in the SOAP specification. + */ +public interface SOAPElement extends Node, org.w3c.dom.Element { + + /** + * Creates a new SOAPElement object initialized with the + * given Name object and adds the new element to this + * SOAPElement object. + * @param name a Name object with the XML name for the + * new element + * @return the new SOAPElement object that was created + * @throws SOAPException if there is an error in creating the + * SOAPElement object + */ + public abstract SOAPElement addChildElement(Name name) throws SOAPException; + + /** + * Creates a new SOAPElement object initialized with the + * given String object and adds the new element to this + * SOAPElement object. + * @param localName a String giving the local name for + * the element + * @return the new SOAPElement object that was created + * @throws SOAPException if there is an error in creating the + * SOAPElement object + */ + public abstract SOAPElement addChildElement(String localName) + throws SOAPException; + + /** + * Creates a new SOAPElement object initialized with the + * specified local name and prefix and adds the new element to this + * SOAPElement object. + * @param localName a String giving the local name for + * the new element + * @param prefix a String giving the namespace prefix for + * the new element + * @return the new SOAPElement object that was created + * @throws SOAPException if there is an error in creating the + * SOAPElement object + */ + public abstract SOAPElement addChildElement(String localName, String prefix) + throws SOAPException; + + /** + * Creates a new SOAPElement object initialized with the + * specified local name, prefix, and URI and adds the new element to this + * SOAPElement object. + * @param localName a String giving the local name for + * the new element + * @param prefix a String giving the namespace prefix for + * the new element + * @param uri a String giving the URI of the namespace + * to which the new element belongs + * @return the new SOAPElement object that was created + * @throws SOAPException if there is an error in creating the + * SOAPElement object + */ + public abstract SOAPElement addChildElement( + String localName, String prefix, String uri) throws SOAPException; + + /** + * Add a SOAPElement as a child of this + * SOAPElement instance. The SOAPElement + * is expected to be created by a + * SOAPElementFactory. Callers should not rely on the + * element instance being added as is into the XML + * tree. Implementations could end up copying the content + * of the SOAPElement passed into an instance of + * a different SOAPElement implementation. For + * instance if addChildElement() is called on a + * SOAPHeader, element will be copied + * into an instance of a SOAPHeaderElement. + * + *

    The fragment rooted in element is either added + * as a whole or not at all, if there was an error. + * + *

    The fragment rooted in element cannot contain + * elements named "Envelope", "Header" or "Body" and in the SOAP + * namespace. Any namespace prefixes present in the fragment + * should be fully resolved using appropriate namespace + * declarations within the fragment itself. + * @param element the SOAPElement to be added as a + * new child + * @return an instance representing the new SOAP element that was + * actually added to the tree. + * @throws SOAPException if there was an error in adding this + * element as a child + */ + public abstract SOAPElement addChildElement(SOAPElement element) + throws SOAPException; + + /** + * Creates a new Text object initialized with the given + * String and adds it to this SOAPElement object. + * @param text a String object with the textual content to be added + * @return the SOAPElement object into which + * the new Text object was inserted + * @throws SOAPException if there is an error in creating the + * new Text object + */ + public abstract SOAPElement addTextNode(String text) throws SOAPException; + + /** + * Adds an attribute with the specified name and value to this + * SOAPElement object. + *

    + * @param name a Name object with the name of the attribute + * @param value a String giving the value of the attribute + * @return the SOAPElement object into which the attribute was + * inserted + * @throws SOAPException if there is an error in creating the + * Attribute + */ + public abstract SOAPElement addAttribute(Name name, String value) + throws SOAPException; + + /** + * Adds a namespace declaration with the specified prefix and URI to this + * SOAPElement object. + *

    + * @param prefix a String giving the prefix of the namespace + * @param uri a String giving + * the prefix of the namespace + * @return the SOAPElement object into which this + * namespace declaration was inserted. + * @throws SOAPException if there is an error in creating the + * namespace + */ + public abstract SOAPElement addNamespaceDeclaration( + String prefix, String uri) throws SOAPException; + + /** + * Returns the value of the attribute with the specified + * name. + * @param name a Name object with + * the name of the attribute + * @return a String giving the value of the + * specified attribute + */ + public abstract String getAttributeValue(Name name); + + /** + * Returns an iterator over all of the attribute names in + * this SOAPElement object. The iterator can be + * used to get the attribute names, which can then be passed to + * the method getAttributeValue to retrieve the + * value of each attribute. + * @return an iterator over the names of the attributes + */ + public abstract Iterator getAllAttributes(); + + /** + * Returns the URI of the namespace that has the given + * prefix. + * + * @param prefix a String giving + * the prefix of the namespace for which to search + * @return a String with the uri of the namespace + * that has the given prefix + */ + public abstract String getNamespaceURI(String prefix); + + /** + * Returns an iterator of namespace prefixes. The iterator + * can be used to get the namespace prefixes, which can then be + * passed to the method getNamespaceURI to retrieve + * the URI of each namespace. + * @return an iterator over the namespace prefixes in this + * SOAPElement object + */ + public abstract Iterator getNamespacePrefixes(); + + /** + * Returns the name of this SOAPElement + * object. + * @return a Name object with the name of this + * SOAPElement object + */ + public abstract Name getElementName(); + + /** + * Removes the attribute with the specified name. + * @param name the Name object with + * the name of the attribute to be removed + * @return true if the attribute was removed + * successfully; false if it was not + */ + public abstract boolean removeAttribute(Name name); + + /** + * Removes the namespace declaration corresponding to the + * given prefix. + * @param prefix a String giving + * the prefix for which to search + * @return true if the namespace declaration was + * removed successfully; false if it was + * not + */ + public abstract boolean removeNamespaceDeclaration(String prefix); + + /** + * Returns an iterator over all the immediate content of + * this element. This includes Text objects as well + * as SOAPElement objects. + * @return an iterator with the content of this + * SOAPElement object + */ + public abstract Iterator getChildElements(); + + /** + * Returns an iterator over all the child elements with the + * specified name. + * @param name a Name object with + * the name of the child elements to be returned + * @return an Iterator object over all the elements + * in this SOAPElement object with the + * specified name + */ + public abstract Iterator getChildElements(Name name); + + /** + * Sets the encoding style for this SOAPElement + * object to one specified. + * @param encodingStyle a String + * giving the encoding style + * @throws java.lang.IllegalArgumentException if + * there was a problem in the encoding style being set. + * @see #getEncodingStyle() getEncodingStyle() + */ + public abstract void setEncodingStyle(String encodingStyle) + throws SOAPException; + + /** + * Returns the encoding style for this + * SOAPElement object. + * @return a String giving the encoding style + * @see #setEncodingStyle(java.lang.String) setEncodingStyle(java.lang.String) + */ + public abstract String getEncodingStyle(); + + /** + * Detaches all children of this SOAPElement. + *

    + * This method is useful for rolling back the construction of partially + * completed SOAPHeaders and SOAPBodys in + * reparation for sending a fault when an error condition is detected. It is + * also useful for recycling portions of a document within a SOAP message. + */ + public abstract void removeContents(); + + /** + * Returns an Iterator over the namespace prefix + * Strings visible to this element. The prefixes returned by + * this iterator can be passed to the method getNamespaceURI() + * to retrieve the URI of each namespace. + * + * @return an iterator over the namespace prefixes are within scope of this + * SOAPElement object + */ + public abstract Iterator getVisibleNamespacePrefixes(); +} diff --git a/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/SOAPElementFactory.java b/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/SOAPElementFactory.java new file mode 100644 index 000000000..492da548c --- /dev/null +++ b/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/SOAPElementFactory.java @@ -0,0 +1,117 @@ +/* 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.soap; + +/** + *

    SOAPElementFactory is a factory for XML + * fragments that will eventually end up in the SOAP part. These + * fragments can be inserted as children of the + * SOAPHeader or SOAPBody or + * SOAPEnvelope.

    + * + *

    Elements created using this factory do not have the + * properties of an element that lives inside a SOAP header + * document. These elements are copied into the XML document tree + * when they are inserted.

    + * @deprecated - Use javax.xml.soap.SOAPFactory for creating SOAPElements. + * @see SOAPFactory SOAPFactory + */ +public class SOAPElementFactory { + + /** + * Create a new SOAPElementFactory from a SOAPFactory. + * + * @param soapfactory the SOAPFactory to use + */ + private SOAPElementFactory(SOAPFactory soapfactory) { + sf = soapfactory; + } + + /** + * Create a SOAPElement object initialized with + * the given Name object. + * @param name a Name object with + * the XML name for the new element + * @return the new SOAPElement object that was + * created + * @throws SOAPException if there is an error in + * creating the SOAPElement object + * @deprecated Use javax.xml.soap.SOAPFactory.createElement(javax.xml.soap.Name) instead + * @see SOAPFactory#createElement(javax.xml.soap.Name) SOAPFactory.createElement(javax.xml.soap.Name) + */ + public SOAPElement create(Name name) throws SOAPException { + return sf.createElement(name); + } + + /** + * Create a SOAPElement object initialized with + * the given local name. + * @param localName a String giving + * the local name for the new element + * @return the new SOAPElement object that was + * created + * @throws SOAPException if there is an error in + * creating the SOAPElement object + * @deprecated Use javax.xml.soap.SOAPFactory.createElement(String localName) instead + * @see SOAPFactory#createElement(java.lang.String) SOAPFactory.createElement(java.lang.String) + */ + public SOAPElement create(String localName) throws SOAPException { + return sf.createElement(localName); + } + + /** + * Create a new SOAPElement object with the + * given local name, prefix and uri. + * @param localName a String giving + * the local name for the new element + * @param prefix the prefix for this + * SOAPElement + * @param uri a String giving the + * URI of the namespace to which the new element + * belongs + * @return the new SOAPElement object that was + * created + * @throws SOAPException if there is an error in + * creating the SOAPElement object + * @deprecated Use javax.xml.soap.SOAPFactory.createElement(String localName, String prefix, String uri) instead + * @see SOAPFactory#createElement(java.lang.String, java.lang.String, java.lang.String) SOAPFactory.createElement(java.lang.String, java.lang.String, java.lang.String) + */ + public SOAPElement create(String localName, String prefix, String uri) + throws SOAPException { + return sf.createElement(localName, prefix, uri); + } + + /** + * Creates a new instance of SOAPElementFactory. + * + * @return a new instance of a + * SOAPElementFactory + * @throws SOAPException if there was an error creating + * the default SOAPElementFactory + * @deprecated + */ + public static SOAPElementFactory newInstance() throws SOAPException { + + try { + return new SOAPElementFactory(SOAPFactory.newInstance()); + } catch (Exception exception) { + throw new SOAPException("Unable to create SOAP Element Factory: " + + exception.getMessage()); + } + } + + private SOAPFactory sf; +} diff --git a/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/SOAPEnvelope.java b/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/SOAPEnvelope.java new file mode 100644 index 000000000..660900fd3 --- /dev/null +++ b/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/SOAPEnvelope.java @@ -0,0 +1,191 @@ +/* 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.soap; + +/** + * The container for the SOAPHeader and SOAPBody portions of a + * SOAPPart object. By default, a + * SOAPMessage object is created with a + * SOAPPart object that has a SOAPEnvelope + * object. The SOAPEnvelope object by default has an + * empty SOAPBody object and an empty + * SOAPHeader object. The SOAPBody object is + * required, and the SOAPHeader object, though + * optional, is used in the majority of cases. If the + * SOAPHeader object is not needed, it can be deleted, + * which is shown later.

    + * + *

    A client can access the SOAPHeader and + * SOAPBody objects by calling the methods + * SOAPEnvelope.getHeader and + * SOAPEnvelope.getBody. The following lines of code use + * these two methods after starting with the + * SOAPMessage object message to get the + * SOAPPart object sp, which is then used to get the + * SOAPEnvelope object se.

    + *
    + *    SOAPPart sp = message.getSOAPPart();
    + *    SOAPEnvelope se = sp.getEnvelope();
    + *    SOAPHeader sh = se.getHeader();
    + *    SOAPBody sb = se.getBody();
    + * 
    + * + *

    It is possible to change the body or header of a + * SOAPEnvelope object by retrieving the current one, + * deleting it, and then adding a new body or header. The + * javax.xml.soap.Node method detachNode + * detaches the XML element (node) on which it is called. For + * example, the following line of code deletes the + * SOAPBody object that is retrieved by the method + * getBody.

    + *
    + *     se.getBody().detachNode();
    + * 
    + * To create a SOAPHeader object to replace the one + * that was removed, a client uses the method + * SOAPEnvelope.addHeader, which creates a new header and + * adds it to the SOAPEnvelope object. Similarly, the + * method addBody creates a new SOAPBody + * object and adds it to the SOAPEnvelope object. The + * following code fragment retrieves the current header, removes + * it, and adds a new one. Then it retrieves the current body, + * removes it, and adds a new one. + *
    + *    SOAPPart sp = message.getSOAPPart();
    + *    SOAPEnvelope se = sp.getEnvelope();
    + *    se.getHeader().detachNode();
    + *    SOAPHeader sh = se.addHeader();
    + *    se.getBody().detachNode();
    + *    SOAPBody sb = se.addBody();
    + * 
    + * It is an error to add a SOAPBody or + * SOAPHeader object if one already exists. + * + *

    The SOAPEnvelope interface provides three + * methods for creating Name objects. One method + * creates Name objects with a local name, a + * namespace prefix, and a namesapce URI. The second method + * creates Name objects with a local name and a + * namespace prefix, and the third creates Name + * objects with just a local name. The following line of code, in + * which se is a SOAPEnvelope object, creates + * a new Name object with all three.

    + *
    + *    Name name = se.createName("GetLastTradePrice", "WOMBAT",
    + *                               "http://www.wombat.org/trader");
    + * 
    + */ +public interface SOAPEnvelope extends SOAPElement { + + /** + * Creates a new Name object initialized with the + * given local name, namespace prefix, and namespace URI. + * + *

    This factory method creates Name objects + * for use in the SOAP/XML document. + * @param localName a String giving + * the local name + * @param prefix a String giving + * the prefix of the namespace + * @param uri a String giving the + * URI of the namespace + * @return a Name object initialized with the given + * local name, namespace prefix, and namespace URI + * @throws SOAPException if there is a SOAP error + */ + public abstract Name createName(String localName, String prefix, String uri) + throws SOAPException; + + /** + * Creates a new Name object initialized with the + * given local name. + * + *

    This factory method creates Name objects + * for use in the SOAP/XML document. + * + * @param localName a String giving + * the local name + * @return a Name object initialized with the given + * local name + * @throws SOAPException if there is a SOAP error + */ + public abstract Name createName(String localName) throws SOAPException; + + /** + * Returns the SOAPHeader object for this + * SOAPEnvelope object. + * + *

    A new SOAPMessage object is by default + * created with a SOAPEnvelope object that + * contains an empty SOAPHeader object. As a + * result, the method getHeader will always + * return a SOAPHeader object unless the header + * has been removed and a new one has not been added. + * @return the SOAPHeader object or + * null if there is none + * @throws SOAPException if there is a problem + * obtaining the SOAPHeader object + */ + public abstract SOAPHeader getHeader() throws SOAPException; + + /** + * Returns the SOAPBody object associated with + * this SOAPEnvelope object. + * + *

    A new SOAPMessage object is by default + * created with a SOAPEnvelope object that + * contains an empty SOAPBody object. As a + * result, the method getBody will always return + * a SOAPBody object unless the body has been + * removed and a new one has not been added. + * @return the SOAPBody object for this + * SOAPEnvelope object or null if there + * is none + * @throws SOAPException if there is a problem + * obtaining the SOAPBody object + */ + public abstract SOAPBody getBody() throws SOAPException; + + /** + * Creates a SOAPHeader object and sets it as the + * SOAPHeader object for this + * SOAPEnvelope object. + * + *

    It is illegal to add a header when the envelope already + * contains a header. Therefore, this method should be called + * only after the existing header has been removed. + * @return the new SOAPHeader object + * @throws SOAPException if this + * SOAPEnvelope object already contains a valid + * SOAPHeader object + */ + public abstract SOAPHeader addHeader() throws SOAPException; + + /** + * Creates a SOAPBody object and sets it as the + * SOAPBody object for this + * SOAPEnvelope object. + * + *

    It is illegal to add a body when the envelope already + * contains a body. Therefore, this method should be called + * only after the existing body has been removed. + * @return the new SOAPBody object + * @throws SOAPException if this + * SOAPEnvelope object already contains a valid + * SOAPBody object + */ + public abstract SOAPBody addBody() throws SOAPException; +} diff --git a/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/SOAPException.java b/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/SOAPException.java new file mode 100644 index 000000000..97b2f9f64 --- /dev/null +++ b/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/SOAPException.java @@ -0,0 +1,177 @@ +/* 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.soap; + +/** + * An exception that signals that a SOAP exception has + * occurred. A SOAPException object may contain a + * String that gives the reason for the exception, an + * embedded Throwable object, or both. This class + * provides methods for retrieving reason messages and for + * retrieving the embedded Throwable object.

    + * + *

    Typical reasons for throwing a SOAPException + * object are problems such as difficulty setting a header, not + * being able to send a message, and not being able to get a + * connection with the provider. Reasons for embedding a + * Throwable object include problems such as input/output + * errors or a parsing problem, such as an error in parsing a + * header. + */ +public class SOAPException extends Exception { + + /** + * Constructs a SOAPException object with no + * reason or embedded Throwable object. + */ + public SOAPException() { + cause = null; + } + + /** + * Constructs a SOAPException object with the + * given String as the reason for the exception + * being thrown. + * @param reason a description of what caused + * the exception + */ + public SOAPException(String reason) { + + super(reason); + + cause = null; + } + + /** + * Constructs a SOAPException object with the + * given String as the reason for the exception + * being thrown and the given Throwable object as + * an embedded exception. + * @param reason a description of what caused + * the exception + * @param cause a Throwable object + * that is to be embedded in this SOAPException + * object + */ + public SOAPException(String reason, Throwable cause) { + + super(reason); + + initCause(cause); + } + + /** + * Constructs a SOAPException object + * initialized with the given Throwable + * object. + * @param cause a Throwable object + * that is to be embedded in this SOAPException + * object + */ + public SOAPException(Throwable cause) { + + super(cause.toString()); + + initCause(cause); + } + + /** + * Returns the detail message for this + * SOAPException object. + * + *

    If there is an embedded Throwable object, + * and if the SOAPException object has no detail + * message of its own, this method will return the detail + * message from the embedded Throwable + * object.

    + * @return the error or warning message for this + * SOAPException or, if it has none, the message of + * the embedded Throwable object, if there is + * one + */ + public String getMessage() { + + String s = super.getMessage(); + + if ((s == null) && (cause != null)) { + return cause.getMessage(); + } else { + return s; + } + } + + /** + * Returns the Throwable object embedded in + * this SOAPException if there is one. Otherwise, + * this method returns null. + * @return the embedded Throwable object or + * null if there is none + */ + public Throwable getCause() { + return cause; + } + + /** + * Initializes the cause field of this + * SOAPException object with the given + * Throwable object. + * + *

    This method can be called at most once. It is generally + * called from within the constructor or immediately after the + * constructor has returned a new SOAPException + * object. If this SOAPException object was + * created with the constructor {@link #SOAPException(java.lang.Throwable) SOAPException(java.lang.Throwable)} + * or {@link #SOAPException(java.lang.String, java.lang.Throwable) SOAPException(java.lang.String, java.lang.Throwable)}, meaning + * that its cause field already has a value, this + * method cannot be called even once. + * + * @param cause the Throwable + * object that caused this SOAPException object + * to be thrown. The value of this parameter is saved for + * later retrieval by the + * getCause() method. A null value + * is permitted and indicates that the cause is nonexistent + * or unknown. + * @return a reference to this SOAPException + * instance + * @throws java.lang.IllegalArgumentException if + * cause is this Throwable object. + * (A Throwable object cannot be its own + * cause.) + * @throws java.lang.IllegalStateException if this + * SOAPException object was created with {@link #SOAPException(java.lang.Throwable) SOAPException(java.lang.Throwable)} + * or {@link #SOAPException(java.lang.String, java.lang.Throwable) SOAPException(java.lang.String, java.lang.Throwable)}, or this + * method has already been called on this + * SOAPException object + */ + public synchronized Throwable initCause(Throwable cause) { + + if (this.cause != null) { + throw new IllegalStateException("Can't override cause"); + } + + if (cause == this) { + throw new IllegalArgumentException("Self-causation not permitted"); + } else { + this.cause = cause; + + return this; + } + } + + private Throwable cause; +} diff --git a/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/SOAPFactory.java b/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/SOAPFactory.java new file mode 100644 index 000000000..044648cd1 --- /dev/null +++ b/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/SOAPFactory.java @@ -0,0 +1,147 @@ +/* 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.soap; + +/** + * SOAPFactory is a factory for creating various objects + * that exist in the SOAP XML tree. + * + * SOAPFactory can be + * used to create XML fragments that will eventually end up in the + * SOAP part. These fragments can be inserted as children of the + * SOAPHeaderElement or SOAPBodyElement or + * SOAPEnvelope. + * + * SOAPFactory also has methods to create + * javax.xml.soap.Detail objects as well as + * java.xml.soap.Name objects. + * + */ +public abstract class SOAPFactory { + + public SOAPFactory() {} + + /** + * Create a SOAPElement object initialized with the + * given Name object. + * + * @param name a Name object with the XML name for + * the new element + * @return the new SOAPElement object that was + * created + * @throws SOAPException if there is an error in creating the + * SOAPElement object + */ + public abstract SOAPElement createElement(Name name) throws SOAPException; + + /** + * Create a SOAPElement object initialized with the + * given local name. + * + * @param localName a String giving the local name for + * the new element + * @return the new SOAPElement object that was + * created + * @throws SOAPException if there is an error in creating the + * SOAPElement object + */ + public abstract SOAPElement createElement(String localName) throws SOAPException; + + /** + * Create a new SOAPElement object with the given + * local name, prefix and uri. + * + * @param localName a String giving the local name + * for the new element + * @param prefix the prefix for this SOAPElement + * @param uri a String giving the URI of the + * namespace to which the new element belongs + * @return the new SOAPElement object that was + * created + * @throws SOAPException if there is an error in creating the + * SOAPElement object + */ + public abstract SOAPElement createElement(String localName, String prefix, String uri) + throws SOAPException; + + /** + * Creates a new Detail object which serves as a container + * for DetailEntry objects. + *

    + * This factory method creates Detail objects for use in + * situations where it is not practical to use the SOAPFault + * abstraction. + * + * @return a Detail object + * @throws SOAPException if there is a SOAP error + */ + public abstract Detail createDetail() throws SOAPException; + + /** + * Creates a new Name object initialized with the + * given local name, namespace prefix, and namespace URI. + *

    + * This factory method creates Name objects for use in + * situations where it is not practical to use the SOAPEnvelope + * abstraction. + * + * @param localName a String giving the local name + * @param prefix a String giving the prefix of the namespace + * @param uri a String giving the URI of the namespace + * @return a Name object initialized with the given + * local name, namespace prefix, and namespace URI + * @throws SOAPException if there is a SOAP error + */ + public abstract Name createName(String localName, String prefix, String uri) + throws SOAPException; + + /** + * Creates a new Name object initialized with the + * given local name. + *

    + * This factory method creates Name objects for use in + * situations where it is not practical to use the SOAPEnvelope + * abstraction. + * + * @param localName a String giving the local name + * @return a Name object initialized with the given + * local name + * @throws SOAPException if there is a SOAP error + */ + public abstract Name createName(String localName) throws SOAPException; + + /** + * Creates a new instance of SOAPFactory. + * + * @return a new instance of a SOAPFactory + * @throws SOAPException if there was an error creating the + * default SOAPFactory + */ + public static SOAPFactory newInstance() throws SOAPException { + + try { + return (SOAPFactory) FactoryFinder.find(SF_PROPERTY, DEFAULT_SF); + } catch (Exception exception) { + throw new SOAPException("Unable to create SOAP Factory: " + + exception.getMessage()); + } + } + + private static final String SF_PROPERTY = "javax.xml.soap.SOAPFactory"; + + private static final String DEFAULT_SF = + "org.apache.axis.soap.SOAPFactoryImpl"; +} diff --git a/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/SOAPFault.java b/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/SOAPFault.java new file mode 100644 index 000000000..b2eb59eea --- /dev/null +++ b/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/SOAPFault.java @@ -0,0 +1,203 @@ +/* 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.soap; + +import java.util.Locale; + +/** + * An element in the SOAPBody object that contains + * error and/or status information. This information may relate to + * errors in the SOAPMessage object or to problems + * that are not related to the content in the message itself. + * Problems not related to the message itself are generally errors + * in processing, such as the inability to communicate with an + * upstream server. + *

    + * The SOAPFault interface provides methods for + * retrieving the information contained in a + * SOAPFault object and for setting the fault code, the + * fault actor, and a string describing the fault. A fault code is + * one of the codes defined in the SOAP 1.1 specification that + * describe the fault. An actor is an intermediate recipient to + * whom a message was routed. The message path may include one or + * more actors, or, if no actors are specified, the message goes + * only to the default actor, which is the final intended + * recipient. + */ +public interface SOAPFault extends SOAPBodyElement { + + /** + * Sets this SOAPFault object with the given + * fault code. + * + *

    Fault codes, which given information about the fault, + * are defined in the SOAP 1.1 specification.

    + * @param faultCode a String giving + * the fault code to be set; must be one of the fault codes + * defined in the SOAP 1.1 specification + * @throws SOAPException if there was an error in + * adding the faultCode to the underlying XML + * tree. + * @see #getFaultCode() getFaultCode() + */ + public abstract void setFaultCode(String faultCode) throws SOAPException; + + /** + * Gets the fault code for this SOAPFault + * object. + * @return a String with the fault code + * @see #setFaultCode(java.lang.String) setFaultCode(java.lang.String) + */ + public abstract String getFaultCode(); + + /** + * Sets this SOAPFault object with the given + * fault actor. + * + *

    The fault actor is the recipient in the message path who + * caused the fault to happen.

    + * @param faultActor a String + * identifying the actor that caused this + * SOAPFault object + * @throws SOAPException if there was an error in + * adding the faultActor to the underlying XML + * tree. + * @see #getFaultActor() getFaultActor() + */ + public abstract void setFaultActor(String faultActor) throws SOAPException; + + /** + * Gets the fault actor for this SOAPFault + * object. + * @return a String giving the actor in the message + * path that caused this SOAPFault object + * @see #setFaultActor(java.lang.String) setFaultActor(java.lang.String) + */ + public abstract String getFaultActor(); + + /** + * Sets the fault string for this SOAPFault + * object to the given string. + * + * @param faultString a String + * giving an explanation of the fault + * @throws SOAPException if there was an error in + * adding the faultString to the underlying XML + * tree. + * @see #getFaultString() getFaultString() + */ + public abstract void setFaultString(String faultString) + throws SOAPException; + + /** + * Gets the fault string for this SOAPFault + * object. + * @return a String giving an explanation of the + * fault + */ + public abstract String getFaultString(); + + /** + * Returns the detail element for this SOAPFault + * object. + * + *

    A Detail object carries + * application-specific error information related to + * SOAPBodyElement objects.

    + * @return a Detail object with + * application-specific error information + */ + public abstract Detail getDetail(); + + /** + * Creates a Detail object and sets it as the + * Detail object for this SOAPFault + * object. + * + *

    It is illegal to add a detail when the fault already + * contains a detail. Therefore, this method should be called + * only after the existing detail has been removed.

    + * @return the new Detail object + * @throws SOAPException if this + * SOAPFault object already contains a valid + * Detail object + */ + public abstract Detail addDetail() throws SOAPException; + + /** + * Sets this SOAPFault object with the given fault code. + * + * Fault codes, which give information about the fault, are defined in the + * SOAP 1.1 specification. A fault code is mandatory and must be of type + * QName. This method provides a convenient way to set a fault + * code. For example, + * + *
    +     SOAPEnvelope se = ...;
    +     // Create a qualified name in the SOAP namespace with a localName
    +     // of "Client".  Note that prefix parameter is optional and is null
    +     // here which causes the implementation to use an appropriate prefix.
    +     Name qname = se.createName("Client", null,
    +     SOAPConstants.URI_NS_SOAP_ENVELOPE);
    +     SOAPFault fault = ...;
    +     fault.setFaultCode(qname);
    +     *
    +     * It is preferable to use this method over setFaultCode(String).
    +     *
    +     * @param name a Name object giving the fault code to be set.
    +     *              It must be namespace qualified.
    +     * @throws SOAPException if there was an error in adding the
    +     *              faultcode element to the underlying XML tree
    +     */
    +    public abstract void setFaultCode(Name name) throws SOAPException;
    +
    +    /**
    +     * Gets the mandatory SOAP 1.1 fault code for this SOAPFault
    +     * object as a SAAJ Name object. The SOAP 1.1 specification
    +     * requires the value of the "faultcode" element to be of type QName. This
    +     * method returns the content of the element as a QName in the form of a
    +     * SAAJ Name object. This method should be used instead of the
    +     * getFaultCode() method since it allows applications to easily
    +     * access the namespace name without additional parsing.
    +     * 

    + * In the future, a QName object version of this method may also be added. + * @return a Name representing the faultcode + */ + public abstract Name getFaultCodeAsName(); + + /** + * Sets the fault string for this SOAPFault object to the given + * string and localized to the given locale. + * + * @param faultString a String giving an explanation of + * the fault + * @param locale a Locale object indicating the + * native language of the faultString + * @throws SOAPException if there was an error in adding the + * faultString to the underlying XML tree + */ + public abstract void setFaultString(String faultString, Locale locale) throws SOAPException; + + /** + * Returns the optional detail element for this SOAPFault + * object. + * + * @return a Locale object indicating the native language of + * the fault string or null if no locale was + * specified + */ + public abstract Locale getFaultStringLocale(); +} diff --git a/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/SOAPFaultElement.java b/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/SOAPFaultElement.java new file mode 100644 index 000000000..056849d8a --- /dev/null +++ b/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/SOAPFaultElement.java @@ -0,0 +1,26 @@ +/* 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.soap; + +/** + * A representation of the contents in + * a SOAPFault object. The Detail interface + * is a SOAPFaultElement object that has been defined. + *

    + * Content is added to a SOAPFaultElement using the + * SOAPElement method addTextNode. + */ +public interface SOAPFaultElement extends SOAPElement {} diff --git a/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/SOAPHeader.java b/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/SOAPHeader.java new file mode 100644 index 000000000..0765208b5 --- /dev/null +++ b/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/SOAPHeader.java @@ -0,0 +1,149 @@ +/* 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.soap; + +import java.util.Iterator; + +/** + *

    A representation of the SOAP header element. A SOAP header + * element consists of XML data that affects the way the + * application-specific content is processed by the message + * provider. For example, transaction semantics, authentication + * information, and so on, can be specified as the content of a + * SOAPHeader object.

    + * + *

    A SOAPEnvelope object contains an empty + * SOAPHeader object by default. If the + * SOAPHeader object, which is optional, is not needed, it + * can be retrieved and deleted with the following line of code. + * The variable se is a SOAPEnvelope + * object.

    + *
    + *     se.getHeader().detachNode();
    + * 
    + * A SOAPHeader object is created with the + * SOAPEnvelope method addHeader. This method, + * which creates a new header and adds it to the envelope, may be + * called only after the existing header has been removed. + *
    + *     se.getHeader().detachNode();
    + *     SOAPHeader sh = se.addHeader();
    + * 
    + * + *

    A SOAPHeader object can have only + * SOAPHeaderElement objects as its immediate children. The + * method addHeaderElement creates a new + * HeaderElement object and adds it to the + * SOAPHeader object. In the following line of code, the + * argument to the method addHeaderElement is a + * Name object that is the name for the new + * HeaderElement object.

    + *
    + *     SOAPHeaderElement shElement = sh.addHeaderElement(name);
    + * 
    + * @see SOAPHeaderElement SOAPHeaderElement + */ +public interface SOAPHeader extends SOAPElement { + + /** + * Creates a new SOAPHeaderElement object + * initialized with the specified name and adds it to this + * SOAPHeader object. + * @param name a Name object with + * the name of the new SOAPHeaderElement + * object + * @return the new SOAPHeaderElement object that + * was inserted into this SOAPHeader + * object + * @throws SOAPException if a SOAP error occurs + */ + public abstract SOAPHeaderElement addHeaderElement(Name name) + throws SOAPException; + + /** + * Returns a list of all the SOAPHeaderElement + * objects in this SOAPHeader object that have the + * the specified actor. An actor is a global attribute that + * indicates the intermediate parties to whom the message should + * be sent. An actor receives the message and then sends it to + * the next actor. The default actor is the ultimate intended + * recipient for the message, so if no actor attribute is + * included in a SOAPHeader object, the message is + * sent to its ultimate destination. + * @param actor a String giving the + * URI of the actor for which to search + * @return an Iterator object over all the + * SOAPHeaderElement objects that contain the + * specified actor + * @see #extractHeaderElements(java.lang.String) extractHeaderElements(java.lang.String) + */ + public abstract Iterator examineHeaderElements(String actor); + + /** + * Returns a list of all the SOAPHeaderElement + * objects in this SOAPHeader object that have + * the the specified actor and detaches them from this + * SOAPHeader object. + * + *

    This method allows an actor to process only the parts of + * the SOAPHeader object that apply to it and to + * remove them before passing the message on to the next + * actor. + * @param actor a String giving the + * URI of the actor for which to search + * @return an Iterator object over all the + * SOAPHeaderElement objects that contain the + * specified actor + * @see #examineHeaderElements(java.lang.String) examineHeaderElements(java.lang.String) + */ + public abstract Iterator extractHeaderElements(String actor); + + /** + * Returns an Iterator over all the + * SOAPHeaderElement objects in this SOAPHeader + * object that have the specified actor and that have a MustUnderstand + * attribute whose value is equivalent to true. + * + * @param actor a String giving the URI of the actor for which + * to search + * @return an Iterator object over all the + * SOAPHeaderElement objects that contain the + * specified actor and are marked as MustUnderstand + */ + public abstract Iterator examineMustUnderstandHeaderElements(String actor); + + /** + * Returns an Iterator over all the + * SOAPHeaderElement objects in this SOAPHeader + * object. + * + * @return an Iterator object over all the + * SOAPHeaderElement objects contained by this + * SOAPHeader + */ + public abstract Iterator examineAllHeaderElements(); + + /** + * Returns an Iterator over all the + * SOAPHeaderElement objects in this SOAPHeader + * object and detaches them from this SOAPHeader object. + * + * @return an Iterator object over all the + * SOAPHeaderElement objects contained by this + * SOAPHeader + */ + public abstract Iterator extractAllHeaderElements(); +} diff --git a/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/SOAPHeaderElement.java b/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/SOAPHeaderElement.java new file mode 100644 index 000000000..4fcb0cc0a --- /dev/null +++ b/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/SOAPHeaderElement.java @@ -0,0 +1,77 @@ +/* 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.soap; + +/** + *

    An object representing the contents in the SOAP header part + * of the SOAP envelope. The immediate children of a + * SOAPHeader object can be represented only as + * SOAPHeaderElement objects.

    + * + *

    A SOAPHeaderElement object can have other + * SOAPElement objects as its children.

    + */ +public interface SOAPHeaderElement extends SOAPElement { + + /** + * Sets the actor associated with this + * SOAPHeaderElement object to the specified actor. The + * default value of an actor is: + * SOAPConstants.URI_SOAP_ACTOR_NEXT + * @param actorURI a String giving + * the URI of the actor to set + * @see #getActor() getActor() + * @throws java.lang.IllegalArgumentException if + * there is a problem in setting the actor. + */ + public abstract void setActor(String actorURI); + + /** + * Returns the uri of the actor associated with this + * SOAPHeaderElement object. + * @return a String giving the URI of the + * actor + * @see #setActor(java.lang.String) setActor(java.lang.String) + */ + public abstract String getActor(); + + /** + * Sets the mustUnderstand attribute for this + * SOAPHeaderElement object to be on or off. + * + *

    If the mustUnderstand attribute is on, the actor who + * receives the SOAPHeaderElement must process it + * correctly. This ensures, for example, that if the + * SOAPHeaderElement object modifies the message, that + * the message is being modified correctly.

    + * @param mustUnderstand true to + * set the mustUnderstand attribute on; false + * to turn if off + * @throws java.lang.IllegalArgumentException if + * there is a problem in setting the actor. + * @see #getMustUnderstand() getMustUnderstand() + */ + public abstract void setMustUnderstand(boolean mustUnderstand); + + /** + * Returns whether the mustUnderstand attribute for this + * SOAPHeaderElement object is turned on. + * @return true if the mustUnderstand attribute of + * this SOAPHeaderElement object is turned on; + * false otherwise + */ + public abstract boolean getMustUnderstand(); +} diff --git a/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/SOAPMessage.java b/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/SOAPMessage.java new file mode 100644 index 000000000..722de6773 --- /dev/null +++ b/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/SOAPMessage.java @@ -0,0 +1,372 @@ +/* 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.soap; + +// ericvas +//import javax.activation.DataHandler; +import java.io.IOException; +import java.io.OutputStream; +import java.util.Iterator; + +/** + *

    The root class for all SOAP messages. As transmitted on the + * "wire", a SOAP message is an XML document or a MIME message + * whose first body part is an XML/SOAP document.

    + * + *

    A SOAPMessage object consists of a SOAP part + * and optionally one or more attachment parts. The SOAP part for + * a SOAPMessage object is a SOAPPart + * object, which contains information used for message routing and + * identification, and which can contain application-specific + * content. All data in the SOAP Part of a message must be in XML + * format.

    + * + *

    A new SOAPMessage object contains the following + * by default:

    + * + *
      + *
    • A SOAPPart object
    • + * + *
    • A SOAPEnvelope object
    • + * + *
    • A SOAPBody object
    • + * + *
    • A SOAPHeader object
    • + *
    + * The SOAP part of a message can be retrieved by calling the + * method SOAPMessage.getSOAPPart(). The + * SOAPEnvelope object is retrieved from the + * SOAPPart object, and the SOAPEnvelope + * object is used to retrieve the SOAPBody and + * SOAPHeader objects. + *
    + * SOAPPart sp = message.getSOAPPart();
    + * SOAPEnvelope se = sp.getEnvelope();
    + * SOAPBody sb = se.getBody();
    + * SOAPHeader sh = se.getHeader();
    + * 
    + * + *

    In addition to the mandatory SOAPPart object, a + * SOAPMessage object may contain zero or more + * AttachmentPart objects, each of which contains + * application-specific data. The SOAPMessage + * interface provides methods for creating + * AttachmentPart objects and also for adding them to a + * SOAPMessage object. A party that has received a + * SOAPMessage object can examine its contents by + * retrieving individual attachment parts.

    + * + *

    Unlike the rest of a SOAP message, an attachment is not + * required to be in XML format and can therefore be anything from + * simple text to an image file. Consequently, any message content + * that is not in XML format must be in an + * AttachmentPart object.

    + * + *

    A MessageFactory object creates new + * SOAPMessage objects. If the MessageFactory + * object was initialized with a messaging Profile, it produces + * SOAPMessage objects that conform to that Profile. + * For example, a SOAPMessage object created by a + * MessageFactory object initialized with the ebXML + * Profile will have the appropriate ebXML headers.

    + * @see MessageFactory MessageFactory + * @see AttachmentPart AttachmentPart + */ +public abstract class SOAPMessage { + + public SOAPMessage() {} + + /** + * Retrieves a description of this SOAPMessage + * object's content. + * @return a String describing the content of this + * message or null if no description has been + * set + * @see #setContentDescription(java.lang.String) setContentDescription(java.lang.String) + */ + public abstract String getContentDescription(); + + /** + * Sets the description of this SOAPMessage + * object's content with the given description. + * @param description a String + * describing the content of this message + * @see #getContentDescription() getContentDescription() + */ + public abstract void setContentDescription(String description); + + /** + * Gets the SOAP part of this SOAPMessage object. + * + * + *

    If a SOAPMessage object contains one or + * more attachments, the SOAP Part must be the first MIME body + * part in the message.

    + * @return the SOAPPart object for this + * SOAPMessage object + */ + public abstract SOAPPart getSOAPPart(); + + /** + * Removes all AttachmentPart objects that have + * been added to this SOAPMessage object. + * + *

    This method does not touch the SOAP part.

    + */ + public abstract void removeAllAttachments(); + + /** + * Gets a count of the number of attachments in this + * message. This count does not include the SOAP part. + * @return the number of AttachmentPart objects + * that are part of this SOAPMessage + * object + */ + public abstract int countAttachments(); + + /** + * Retrieves all the AttachmentPart objects + * that are part of this SOAPMessage object. + * @return an iterator over all the attachments in this + * message + */ + public abstract Iterator getAttachments(); + + /** + * Retrieves all the AttachmentPart objects + * that have header entries that match the specified headers. + * Note that a returned attachment could have headers in + * addition to those specified. + * @param headers a MimeHeaders + * object containing the MIME headers for which to + * search + * @return an iterator over all attachments that have a header + * that matches one of the given headers + */ + public abstract Iterator getAttachments(MimeHeaders headers); + + /** + * Adds the given AttachmentPart object to this + * SOAPMessage object. An + * AttachmentPart object must be created before it can be + * added to a message. + * @param attachmentpart an + * AttachmentPart object that is to become part of + * this SOAPMessage object + * @throws java.lang.IllegalArgumentException + */ + public abstract void addAttachmentPart(AttachmentPart attachmentpart); + + /** + * Creates a new empty AttachmentPart object. + * Note that the method addAttachmentPart must be + * called with this new AttachmentPart object as + * the parameter in order for it to become an attachment to this + * SOAPMessage object. + * @return a new AttachmentPart object that can be + * populated and added to this SOAPMessage + * object + */ + public abstract AttachmentPart createAttachmentPart(); + + /** + * Creates an AttachmentPart object and + * populates it using the given DataHandler + * object. + * @param datahandler the + * javax.activation.DataHandler object that will + * generate the content for this SOAPMessage + * object + * @return a new AttachmentPart object that + * contains data generated by the given + * DataHandler object + * @throws java.lang.IllegalArgumentException if + * there was a problem with the specified + * DataHandler object + * @see DataHandler DataHandler + * @see javax.activation.DataContentHandler DataContentHandler + */ +// ericvas +// public AttachmentPart createAttachmentPart(DataHandler datahandler) { +// +// AttachmentPart attachmentpart = createAttachmentPart(); +// +// attachmentpart.setDataHandler(datahandler); +// +// return attachmentpart; +// } + + /** + * Returns all the transport-specific MIME headers for this + * SOAPMessage object in a transport-independent + * fashion. + * @return a MimeHeaders object containing the + * MimeHeader objects + */ + public abstract MimeHeaders getMimeHeaders(); + + /** + * Creates an AttachmentPart object and + * populates it with the specified data of the specified content + * type. + * @param content an Object + * containing the content for this SOAPMessage + * object + * @param contentType a String + * object giving the type of content; examples are + * "text/xml", "text/plain", and "image/jpeg" + * @return a new AttachmentPart object that + * contains the given data + * @throws java.lang.IllegalArgumentException if the contentType does not match the type of the content + * object, or if there was no + * DataContentHandler object for the given content + * object + * @see DataHandler DataHandler + * @see javax.activation.DataContentHandler DataContentHandler + */ + public AttachmentPart createAttachmentPart(Object content, + String contentType) { + + AttachmentPart attachmentpart = createAttachmentPart(); + + attachmentpart.setContent(content, contentType); + + return attachmentpart; + } + + /** + * Updates this SOAPMessage object with all the + * changes that have been made to it. This method is called + * automatically when a message is sent or written to by the + * methods ProviderConnection.send, + * SOAPConnection.call, or + * SOAPMessage.writeTo. However, if changes are made to + * a message that was received or to one that has already been + * sent, the method saveChanges needs to be + * called explicitly in order to save the changes. The method + * saveChanges also generates any changes that + * can be read back (for example, a MessageId in profiles that + * support a message id). All MIME headers in a message that + * is created for sending purposes are guaranteed to have + * valid values only after saveChanges has been + * called. + * + *

    In addition, this method marks the point at which the + * data from all constituent AttachmentPart + * objects are pulled into the message.

    + * @throws SOAPException if there + * was a problem saving changes to this message. + */ + public abstract void saveChanges() throws SOAPException; + + /** + * Indicates whether this SOAPMessage object + * has had the method saveChanges called on + * it. + * @return true if saveChanges has + * been called on this message at least once; + * false otherwise. + */ + public abstract boolean saveRequired(); + + /** + * Writes this SOAPMessage object to the given + * output stream. The externalization format is as defined by + * the SOAP 1.1 with Attachments specification. + * + *

    If there are no attachments, just an XML stream is + * written out. For those messages that have attachments, + * writeTo writes a MIME-encoded byte stream.

    + * @param out the OutputStream + * object to which this SOAPMessage object will + * be written + * @throws SOAPException if there was a problem in + * externalizing this SOAP message + * @throws IOException if an I/O error + * occurs + */ + public abstract void writeTo(OutputStream out) + throws SOAPException, IOException; + + /** + * Gets the SOAP Body contained in this SOAPMessage object. + * + * @return the SOAPBody object contained by this + * SOAPMessage object + * @throws SOAPException if the SOAP Body does not exist or cannot be + * retrieved + */ + public abstract SOAPBody getSOAPBody() throws SOAPException; + + /** + * Gets the SOAP Header contained in this SOAPMessage object. + * + * @return the SOAPHeader object contained by this + * SOAPMessage object + * @throws SOAPException if the SOAP Header does not exist or cannot be + * retrieved + */ + public abstract SOAPHeader getSOAPHeader() throws SOAPException; + + /** + * Associates the specified value with the specified property. If there was + * already a value associated with this property, the old value is replaced. + *

    + * The valid property names include WRITE_XML_DECLARATION and + * CHARACTER_SET_ENCODING. All of these standard SAAJ + * properties are prefixed by "javax.xml.soap". Vendors may also add + * implementation specific properties. These properties must be prefixed + * with package names that are unique to the vendor. + *

    + * Setting the property WRITE_XML_DECLARATION to + * "true" will cause an XML Declaration to be written out at + * the start of the SOAP message. The default value of "false" suppresses + * this declaration. + *

    + * The property CHARACTER_SET_ENCODING defaults to the value + * "utf-8" which causes the SOAP message to be encoded using + * UTF-8. Setting CHARACTER_SET_ENCODING to + * "utf-16" causes the SOAP message to be encoded using UTF-16. + *

    + * Some implementations may allow encodings in addition to UTF-8 and UTF-16. + * Refer to your vendor's documentation for details. + * + * @param property the property with which the specified value is to be + * associated + * @param value the value to be associated with the specified property + * @throws SOAPException if the property name is not recognized + */ + public abstract void setProperty(String property, Object value) + throws SOAPException; + + /** + * Retrieves value of the specified property. + * + * @param property the name of the property to retrieve + * @return the value of the property or null if no such + * property exists + * @throws SOAPException if the property name is not recognized + */ + public abstract Object getProperty(String property) throws SOAPException; + + /** Specifies the character type encoding for the SOAP Message. */ + public static final String CHARACTER_SET_ENCODING + = "javax.xml.soap.character-set-encoding"; + + /** Specifies whether the SOAP Message should contain an XML declaration. */ + public static final String WRITE_XML_DECLARATION + = "javax.xml.soap.write-xml-declaration"; +} diff --git a/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/SOAPPart.java b/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/SOAPPart.java new file mode 100644 index 000000000..23696b485 --- /dev/null +++ b/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/SOAPPart.java @@ -0,0 +1,261 @@ +/* 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.soap; + +import javax.xml.transform.Source; +import java.util.Iterator; + +/** + *

    The container for the SOAP-specific portion of a + * SOAPMessage object. All messages are required to have a + * SOAP part, so when a SOAPMessage object is + * created, it will automatically have a SOAPPart + * object.

    + * + *

    A SOAPPart object is a MIME part and has the + * MIME headers Content-Id, Content-Location, and Content-Type. + * Because the value of Content-Type must be "text/xml", a + * SOAPPart object automatically has a MIME header of + * Content-Type with its value set to "text/xml". The value must + * be "text/xml" because content in the SOAP part of a message + * must be in XML format. Content that is not of type "text/xml" + * must be in an AttachmentPart object rather than in + * the SOAPPart object.

    + * + *

    When a message is sent, its SOAP part must have the MIME + * header Content-Type set to "text/xml". Or, from the other + * perspective, the SOAP part of any message that is received must + * have the MIME header Content-Type with a value of + * "text/xml".

    + * + *

    A client can access the SOAPPart object of a + * SOAPMessage object by calling the method + * SOAPMessage.getSOAPPart. The following line of code, in + * which message is a SOAPMessage + * object, retrieves the SOAP part of a message.

    + *
    + * SOAPPart soapPart = message.getSOAPPart();
    + * 
    + * + *

    A SOAPPart object contains a + * SOAPEnvelope object, which in turn contains a + * SOAPBody object and a SOAPHeader object. + * The SOAPPart method getEnvelope can + * be used to retrieve the SOAPEnvelope object.

    + */ +public abstract class SOAPPart implements org.w3c.dom.Document { + + public SOAPPart() {} + + /** + * Gets the SOAPEnvelope object associated with + * this SOAPPart object. Once the SOAP envelope is + * obtained, it can be used to get its contents. + * @return the SOAPEnvelope object for this + * SOAPPart object + * @throws SOAPException if there is a SOAP error + */ + public abstract SOAPEnvelope getEnvelope() throws SOAPException; + + /** + * Retrieves the value of the MIME header whose name is + * "Content-Id". + * @return a String giving the value of the MIME + * header named "Content-Id" + * @see #setContentId(java.lang.String) setContentId(java.lang.String) + */ + public String getContentId() { + + String as[] = getMimeHeader("Content-Id"); + + if (as != null && as.length > 0) { + return as[0]; + } else { + return null; + } + } + + /** + * Retrieves the value of the MIME header whose name is + * "Content-Location". + * @return a String giving the value of the MIME + * header whose name is "Content-Location" + * @see #setContentLocation(java.lang.String) setContentLocation(java.lang.String) + */ + public String getContentLocation() { + + String as[] = getMimeHeader("Content-Location"); + + if (as != null && as.length > 0) { + return as[0]; + } else { + return null; + } + } + + /** + * Sets the value of the MIME header named "Content-Id" to + * the given String. + * @param contentId a String giving + * the value of the MIME header "Content-Id" + * @throws java.lang.IllegalArgumentException if + * there is a problem in setting the content id + * @see #getContentId() getContentId() + */ + public void setContentId(String contentId) { + setMimeHeader("Content-Id", contentId); + } + + /** + * Sets the value of the MIME header "Content-Location" to + * the given String. + * @param contentLocation a String + * giving the value of the MIME header + * "Content-Location" + * @throws java.lang.IllegalArgumentException if + * there is a problem in setting the content location. + * @see #getContentLocation() getContentLocation() + */ + public void setContentLocation(String contentLocation) { + setMimeHeader("Content-Location", contentLocation); + } + + /** + * Removes all MIME headers that match the given name. + * @param header a String giving + * the name of the MIME header(s) to be removed + */ + public abstract void removeMimeHeader(String header); + + /** + * Removes all the MimeHeader objects for this + * SOAPEnvelope object. + */ + public abstract void removeAllMimeHeaders(); + + /** + * Gets all the values of the MimeHeader object + * in this SOAPPart object that is identified by + * the given String. + * @param name the name of the header; example: + * "Content-Type" + * @return a String array giving all the values for + * the specified header + * @see #setMimeHeader(java.lang.String, java.lang.String) setMimeHeader(java.lang.String, java.lang.String) + */ + public abstract String[] getMimeHeader(String name); + + /** + * Changes the first header entry that matches the given + * header name so that its value is the given value, adding a + * new header with the given name and value if no existing + * header is a match. If there is a match, this method clears + * all existing values for the first header that matches and + * sets the given value instead. If more than one header has + * the given name, this method removes all of the matching + * headers after the first one. + * + *

    Note that RFC822 headers can contain only US-ASCII + * characters.

    + * @param name a String giving the + * header name for which to search + * @param value a String giving the + * value to be set. This value will be substituted for the + * current value(s) of the first header that is a match if + * there is one. If there is no match, this value will be + * the value for a new MimeHeader object. + * @throws java.lang.IllegalArgumentException if + * there was a problem with the specified mime header name + * or value + * @throws java.lang.IllegalArgumentException if there was a problem with the specified mime header name or value + * @see #getMimeHeader(java.lang.String) getMimeHeader(java.lang.String) + */ + public abstract void setMimeHeader(String name, String value); + + /** + * Creates a MimeHeader object with the specified + * name and value and adds it to this SOAPPart + * object. If a MimeHeader with the specified + * name already exists, this method adds the specified value + * to the already existing value(s). + * + *

    Note that RFC822 headers can contain only US-ASCII + * characters.

    + * + * @param name a String giving the + * header name + * @param value a String giving the + * value to be set or added + * @throws java.lang.IllegalArgumentException if + * there was a problem with the specified mime header name + * or value + */ + public abstract void addMimeHeader(String name, String value); + + /** + * Retrieves all the headers for this SOAPPart + * object as an iterator over the MimeHeader + * objects. + * @return an Iterator object with all of the Mime + * headers for this SOAPPart object + */ + public abstract Iterator getAllMimeHeaders(); + + /** + * Retrieves all MimeHeader objects that match + * a name in the given array. + * @param names a String array with + * the name(s) of the MIME headers to be returned + * @return all of the MIME headers that match one of the names + * in the given array, returned as an Iterator + * object + */ + public abstract Iterator getMatchingMimeHeaders(String names[]); + + /** + * Retrieves all MimeHeader objects whose name + * does not match a name in the given array. + * @param names a String array with + * the name(s) of the MIME headers not to be returned + * @return all of the MIME headers in this SOAPPart + * object except those that match one of the names in the + * given array. The nonmatching MIME headers are returned as + * an Iterator object. + */ + public abstract Iterator getNonMatchingMimeHeaders(String names[]); + + /** + * Sets the content of the SOAPEnvelope object + * with the data from the given Source object. + * @param source javax.xml.transform.Source
    object with the data to + * be set + * @throws SOAPException if there is a problem in + * setting the source + * @see #getContent() getContent() + */ + public abstract void setContent(Source source) throws SOAPException; + + /** + * Returns the content of the SOAPEnvelope as a JAXP + * Source object. + * @return the content as a + * javax.xml.transform.Source object + * @throws SOAPException if the implementation cannot + * convert the specified Source object + * @see #setContent(javax.xml.transform.Source) setContent(javax.xml.transform.Source) + */ + public abstract Source getContent() throws SOAPException; +} diff --git a/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/Text.java b/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/Text.java new file mode 100644 index 000000000..5e88e8470 --- /dev/null +++ b/xmlbeans/src/saaj_api/org/apache/xmlbeans/impl/soap/Text.java @@ -0,0 +1,32 @@ +/* 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.soap; + +/** + * A representation of a node whose value is text. A + * Text object may represent text that is content or text + * that is a comment. + */ +public interface Text extends Node, org.w3c.dom.Text { + + /** + * Retrieves whether this Text object + * represents a comment. + * @return true if this Text object is + * a comment; false otherwise + */ + public abstract boolean isComment(); +} diff --git a/xmlbeans/src/store/org/apache/xmlbeans/impl/store/CharUtil.java b/xmlbeans/src/store/org/apache/xmlbeans/impl/store/CharUtil.java new file mode 100755 index 000000000..c3b8fa0dd --- /dev/null +++ b/xmlbeans/src/store/org/apache/xmlbeans/impl/store/CharUtil.java @@ -0,0 +1,930 @@ +/* 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.store; + +import java.io.PrintStream; +import java.lang.ref.SoftReference; + +public final class CharUtil +{ + public CharUtil ( int charBufSize ) + { + _charBufSize = charBufSize; + } + + public CharIterator getCharIterator ( Object src, int off, int cch ) + { + _charIter.init( src, off, cch ); + return _charIter; + } + + public CharIterator getCharIterator ( Object src, int off, int cch, int start ) + { + _charIter.init( src, off, cch, start ); + return _charIter; + } + + public static CharUtil getThreadLocalCharUtil ( ) + { + SoftReference softRef = (SoftReference)tl_charUtil.get(); + CharUtil charUtil = (CharUtil) softRef.get(); + if (charUtil==null) + { + charUtil = new CharUtil( CHARUTIL_INITIAL_BUFSIZE ); + tl_charUtil.set(new SoftReference(charUtil)); + } + return charUtil; + } + + public static void getString ( StringBuffer sb, Object src, int off, int cch ) + { + assert isValid( src, off, cch ); + + if (cch == 0) + return; + + if (src instanceof char[]) + sb.append( (char[]) src, off, cch ); + else if (src instanceof String) + { + String s = (String) src; + + if (off == 0 && cch == s.length()) + sb.append( (String) src ); + else + sb.append( s.substring( off, off + cch ) ); + } + else + ((CharJoin) src).getString( sb, off, cch ); + } + + public static void getChars ( char[] chars, int start, Object src, int off, int cch ) + { + assert isValid( src, off, cch ); + assert chars != null && start >= 0 && start <= chars.length; + + if (cch == 0) + return; + + if (src instanceof char[]) + System.arraycopy( (char[]) src, off, chars, start, cch ); + else if (src instanceof String) + ((String) src).getChars( off, off + cch, chars, start ); + else + ((CharJoin) src).getChars( chars, start, off, cch ); + } + + public static String getString ( Object src, int off, int cch ) + { + assert isValid( src, off, cch ); + + if (cch == 0) + return ""; + + if (src instanceof char[]) + return new String( (char[]) src, off, cch ); + + if (src instanceof String) + { + String s = (String) src; + + if (off == 0 && cch == s.length()) + return s; + + return s.substring( off, off + cch ); + } + + StringBuffer sb = new StringBuffer(); + + ((CharJoin) src).getString( sb, off, cch ); + + return sb.toString(); + } + + public static final boolean isWhiteSpace ( char ch ) + { + switch ( ch ) + { + case ' ': case '\t': case '\n': case '\r': return true; + default : return false; + } + } + + public final boolean isWhiteSpace ( Object src, int off, int cch ) + { + assert isValid( src, off, cch ); + + if (cch <= 0) + return true; + + if (src instanceof char[]) + { + for ( char[] chars = (char[]) src ; cch > 0 ; cch-- ) + if (!isWhiteSpace( chars[ off++ ] )) + return false; + + return true; + } + + if (src instanceof String) + { + for ( String s = (String) src ; cch > 0 ; cch-- ) + if (!isWhiteSpace( s.charAt( off++ ) )) + return false; + + return true; + } + + boolean isWhite = true; + + for ( _charIter.init( src, off, cch ) ; _charIter.hasNext() ; ) + { + if (!isWhiteSpace( _charIter.next() )) + { + isWhite = false; + break; + } + } + + _charIter.release(); + + return isWhite; + } + + public Object stripLeft ( Object src, int off, int cch ) + { + assert isValid( src, off, cch ); + + if (cch > 0) + { + if (src instanceof char[]) + { + char[] chars = (char[]) src; + + while ( cch > 0 && isWhiteSpace( chars[ off ] ) ) + { cch--; off++; } + } + else if (src instanceof String) + { + String s = (String) src; + + while ( cch > 0 && isWhiteSpace( s.charAt( off ) ) ) + { cch--; off++; } + } + else + { + int count = 0; + + for ( _charIter.init( src, off, cch ) ; _charIter.hasNext() ; count++ ) + if (!isWhiteSpace( _charIter.next() )) + break; + + _charIter.release(); + + off += count; + } + } + + if (cch == 0) + { + _offSrc = 0; + _cchSrc = 0; + + return null; + } + + _offSrc = off; + _cchSrc = cch; + + return src; + } + + public Object stripRight ( Object src, int off, int cch ) + { + assert isValid( src, off, cch ); + + if (cch > 0) + { + for ( _charIter.init( src, off, cch, cch ) ; _charIter.hasPrev() ; cch-- ) + if (!isWhiteSpace( _charIter.prev() )) + break; + + _charIter.release(); + } + + if (cch == 0) + { + _offSrc = 0; + _cchSrc = 0; + + return null; + } + + _offSrc = off; + _cchSrc = cch; + + return src; + } + + public Object insertChars ( + int posInsert, + Object src, int off, int cch, + Object srcInsert, int offInsert, int cchInsert ) + { + assert isValid( src, off, cch ); + assert isValid( srcInsert, offInsert, cchInsert ); + assert posInsert >= 0 && posInsert <= cch; + + // TODO - at some point, instead of creating joins, I should + // normalize all the text into a single buffer to stop large + // tree's from being built when many modifications happen... + + // TODO - actually, I should see if the size of the new char + // sequence is small enough to simply allocate a new contigous + // sequence, either in a common char[] managed by the master, + // or just create a new string ... this goes for remove chars + // as well. + + if (cchInsert == 0) + { + _cchSrc = cch; + _offSrc = off; + return src; + } + + if (cch == 0) + { + _cchSrc = cchInsert; + _offSrc = offInsert; + return srcInsert; + } + + _cchSrc = cch + cchInsert; + + Object newSrc; + + if (_cchSrc <= MAX_COPY && canAllocate( _cchSrc )) + { + char[] c = allocate( _cchSrc ); + + getChars( c, _offSrc, src, off, posInsert ); + getChars( c, _offSrc + posInsert, srcInsert, offInsert, cchInsert ); + getChars( c, _offSrc + posInsert + cchInsert, src, off + posInsert, cch - posInsert ); + + newSrc = c; + } + else + { + _offSrc = 0; + + CharJoin newJoin; + + if (posInsert == 0) + newJoin = new CharJoin( srcInsert, offInsert, cchInsert, src, off ); + else if (posInsert == cch) + newJoin = new CharJoin( src, off, cch, srcInsert, offInsert ); + else + { + CharJoin j = new CharJoin( src, off, posInsert, srcInsert, offInsert ); + newJoin = new CharJoin( j, 0, posInsert + cchInsert, src, off + posInsert ); + } + + if (newJoin._depth > CharJoin.MAX_DEPTH) + newSrc = saveChars( newJoin, _offSrc, _cchSrc ); + else + newSrc = newJoin; + } + + assert isValid( newSrc, _offSrc, _cchSrc ); + + return newSrc; + } + + public Object removeChars ( int posRemove, int cchRemove, Object src, int off, int cch ) + { + assert isValid( src, off, cch ); + assert posRemove >= 0 && posRemove <= cch; + assert cchRemove >= 0 && posRemove + cchRemove <= cch; + + Object newSrc; + + _cchSrc = cch - cchRemove; + + if (_cchSrc == 0) + { + newSrc = null; + _offSrc = 0; + } + else if (posRemove == 0) + { + newSrc = src; + _offSrc = off + cchRemove; + } + else if (posRemove + cchRemove == cch) + { + newSrc = src; + _offSrc = off; + } + else + { + int cchAfter = cch - cchRemove; + + if (cchAfter <= MAX_COPY && canAllocate( cchAfter )) + { + char[] chars = allocate( cchAfter ); + + getChars( chars, _offSrc, src, off, posRemove ); + + getChars( + chars, _offSrc + posRemove, + src, off + posRemove + cchRemove, cch - posRemove - cchRemove ); + + newSrc = chars; + _offSrc = _offSrc; + } + else + { + CharJoin j = new CharJoin( src, off, posRemove, src, off + posRemove + cchRemove ); + + if (j._depth > CharJoin.MAX_DEPTH) + newSrc = saveChars( j, 0, _cchSrc ); + else + { + newSrc = j; + _offSrc = 0; + } + } + } + + assert isValid( newSrc, _offSrc, _cchSrc ); + + return newSrc; + } + + private static int sizeof ( Object src ) + { + assert src == null || src instanceof String || src instanceof char[]; + + if (src instanceof char[]) + return ((char[]) src).length; + + return src == null ? 0 : ((String) src).length(); + } + + private boolean canAllocate ( int cch ) + { + return _currentBuffer == null || _currentBuffer.length - _currentOffset >= cch; + } + + private char[] allocate ( int cch ) + { + assert _currentBuffer == null || _currentBuffer.length - _currentOffset > 0; + + if (_currentBuffer == null) + { + _currentBuffer = new char [ Math.max( cch, _charBufSize ) ]; + _currentOffset = 0; + } + + _offSrc = _currentOffset; + _cchSrc = Math.min( _currentBuffer.length - _currentOffset, cch ); + + char[] retBuf = _currentBuffer; + + assert _currentOffset + _cchSrc <= _currentBuffer.length; + + if ((_currentOffset += _cchSrc) == _currentBuffer.length) + { + _currentBuffer = null; + _currentOffset = 0; + } + + return retBuf; + } + + public Object saveChars ( Object srcSave, int offSave, int cchSave ) + { + return saveChars( srcSave, offSave, cchSave, null, 0, 0 ); + } + + public Object saveChars ( + Object srcSave, int offSave, int cchSave, + Object srcPrev, int offPrev, int cchPrev ) + { + // BUGBUG (ericvas) + // + // There is a severe degenerate situation which can deveol here. The cases is where + // there is a long strings of calls to saveChars, where the caller passes in prev text + // to be prepended. In this cases, the buffer breaks and a join is made, but because the + // join is created, subsequent calls willproduce additional joins. I need to figure + // out a way that a whole bunch of joins are not created. I really only want to create + // joins in situations where large amount of text is manipulated. + + assert isValid( srcSave, offSave, cchSave ); + assert isValid( srcPrev, offPrev, cchPrev ); + + // Allocate some space to save the text and copy it there. This may not allocate all + // the space I need. This happens when I run out of buffer space. Deal with this later. + + char[] srcAlloc = allocate( cchSave ); + int offAlloc = _offSrc; + int cchAlloc = _cchSrc; + + assert cchAlloc <= cchSave; + + getChars( srcAlloc, offAlloc, srcSave, offSave, cchAlloc ); + + Object srcNew; + int offNew; + + int cchNew = cchAlloc + cchPrev; + + // The prev arguments specify a chunk of text which the caller wants prepended to the + // text to be saved. The optimization here is to detect the case where the prev text + // and the newly allcoated and saved text are adjacent, so that I can avoid copying + // or joining the two pieces. The situation where this happens most is when a parser + // reports a big piece of text in chunks, perhaps because there are entities in the + // big chunk of text. + + CharJoin j; + + if (cchPrev == 0) + { + srcNew = srcAlloc; + offNew = offAlloc; + } + else if (srcPrev == srcAlloc && offPrev + cchPrev == offAlloc) + { + assert srcPrev instanceof char[]; + + srcNew = srcPrev; + offNew = offPrev; + } + else if (srcPrev instanceof CharJoin && (j = (CharJoin) srcPrev)._srcRight == srcAlloc && + offPrev + cchPrev - j._cchLeft + j._offRight == offAlloc) + { + assert j._srcRight instanceof char[]; + + srcNew = srcPrev; + offNew = offPrev; + } + else + { + j = new CharJoin( srcPrev, offPrev, cchPrev, srcAlloc, offAlloc ); + + srcNew = j; + offNew = 0; + srcNew = j._depth > CharJoin.MAX_DEPTH ? saveChars( j, 0, cchNew ) : j; + } + + // Now, srcNew and offNew specify the two parts of the triple which has the prev text and + // part of the text to save (if not all of it). Here I compute cchMore which is any + // remaining text which was not allocated for earlier. Effectively, this code deals with + // the case where the text to save was greater than the remaining space in the buffer and + // I need to allocate another buffer to save away the second part and then join the two. + + int cchMore = cchSave - cchAlloc; + + if (cchMore > 0) + { + // If we're here the the buffer got consumed. So, this time it must allocate a new + // buffer capable of containing all of the remaining text (no matter how large) and + // return the beginning part of it. + + srcAlloc = allocate( cchMore ); + offAlloc = _offSrc; + cchAlloc = _cchSrc; + + assert cchAlloc == cchMore; + assert offAlloc == 0; + + getChars( srcAlloc, offAlloc, srcSave, offSave + (cchSave - cchMore), cchMore ); + + j = new CharJoin( srcNew, offNew, cchNew, srcAlloc, offAlloc ); + + offNew = 0; + cchNew += cchMore; + srcNew = j._depth > CharJoin.MAX_DEPTH ? saveChars( j, 0, cchNew ) : j; + } + + _offSrc = offNew; + _cchSrc = cchNew; + + assert isValid( srcNew, _offSrc, _cchSrc ); + + return srcNew; + } + + private static void dumpText ( PrintStream o, String s ) + { + o.print( "\"" ); + + for ( int i = 0 ; i < s.length() ; i++ ) + { + char ch = s.charAt( i ); + + if (i == 36) + { + o.print( "..." ); + break; + } + + if (ch == '\n') o.print( "\\n" ); + else if (ch == '\r') o.print( "\\r" ); + else if (ch == '\t') o.print( "\\t" ); + else if (ch == '\f') o.print( "\\f" ); + else if (ch == '\f') o.print( "\\f" ); + else if (ch == '"' ) o.print( "\\\"" ); + else o.print( ch ); + } + + o.print( "\"" ); + } + + public static void dump ( Object src, int off, int cch ) + { + dumpChars( System.out, src, off, cch ); + System.out.println(); + } + + public static void dumpChars ( PrintStream p, Object src, int off, int cch ) + { + p.print( "off=" + off + ", cch=" + cch + ", " ); + + if (src == null) + p.print( "" ); + else if (src instanceof String) + { + String s = (String) src; + + p.print( "String" ); + + if (off != 0 || cch != s.length()) + { + if (off < 0 || off > s.length() || off + cch < 0 || off + cch > s.length()) + { + p.print( " (Error)" ); + return; + } + } + + //p.print( ": " ); + dumpText( p, s.substring( off, off + cch ) ); + } + else if (src instanceof char[]) + { + char[] chars = (char[]) src; + + p.print( "char[]" ); + + if (off != 0 || cch != chars.length) + { + if (off < 0 || off > chars.length || off + cch < 0 || off + cch > chars.length) + { + p.print( " (Error)" ); + return; + } + } + + //p.print( ": " ); + dumpText( p, new String( chars, off, cch ) ); + } + else if (src instanceof CharJoin) + { + p.print( "CharJoin" ); + + ((CharJoin) src).dumpChars( p, off, cch ); + } + else + { + p.print( "Unknown text source" ); + } + } + + public static boolean isValid ( Object src, int off, int cch ) + { + if (cch < 0 || off < 0) + return false; + + if (src == null) + return off == 0 && cch == 0; + + if (src instanceof char[]) + { + char[] c = (char[]) src; + return off <= c.length && off + cch <= c.length; + } + + if (src instanceof String) + { + String s = (String) src; + return off <= s.length() && off + cch <= s.length(); + } + + if (src instanceof CharJoin) + return ((CharJoin) src).isValid( off, cch ); + + return false; + } + + // + // Private stuff + // + + public static final class CharJoin + { + public CharJoin ( + Object srcLeft, int offLeft, int cchLeft, Object srcRight, int offRight ) + { + _srcLeft = srcLeft; _offLeft = offLeft; _cchLeft = cchLeft; + _srcRight = srcRight; _offRight = offRight; + + int depth = 0; + + if (srcLeft instanceof CharJoin) + depth = ((CharJoin) srcLeft)._depth; + + if (srcRight instanceof CharJoin) + { + int rightDepth = ((CharJoin) srcRight)._depth; + + if (rightDepth > depth) + depth = rightDepth; + } + + _depth = depth + 1; + + assert _depth <= MAX_DEPTH + 2; + } + + private int cchRight ( int off, int cch ) + { + return Math.max( 0, cch - _cchLeft - off ); + } + + public int depth ( ) + { + int depth = 0; + + if (_srcLeft instanceof CharJoin) + depth = ((CharJoin) _srcLeft).depth(); + + if (_srcRight instanceof CharJoin) + depth = Math.max( ((CharJoin)_srcRight).depth(), depth ); + + return depth + 1; + } + + public boolean isValid ( int off, int cch ) + { + // Deep trees cause this to take forever + + if (_depth > 2) + return true; + + assert _depth == depth(); + + if (off < 0 || cch < 0) + return false; + + if (!CharUtil.isValid( _srcLeft, _offLeft, _cchLeft )) + return false; + + if (!CharUtil.isValid( _srcRight, _offRight, cchRight( off, cch ) )) + return false; + + return true; + } + + private void getString ( StringBuffer sb, int off, int cch ) + { + assert cch > 0; + + if (off < _cchLeft) + { + int cchL = Math.min( _cchLeft - off, cch ); + + CharUtil.getString( sb, _srcLeft, _offLeft + off, cchL ); + + if (cch > cchL) + CharUtil.getString( sb, _srcRight, _offRight, cch - cchL ); + } + else + CharUtil.getString( sb, _srcRight, _offRight + off - _cchLeft, cch ); + } + + private void getChars ( char[] chars, int start, int off, int cch ) + { + assert cch > 0; + + if (off < _cchLeft) + { + int cchL = Math.min( _cchLeft - off, cch ); + + CharUtil.getChars( chars, start, _srcLeft, _offLeft + off, cchL ); + + if (cch > cchL) + CharUtil.getChars( chars, start + cchL, _srcRight, _offRight, cch - cchL ); + } + else + CharUtil.getChars( chars, start, _srcRight, _offRight + off - _cchLeft, cch ); + } + + private void dumpChars( int off, int cch ) + { + dumpChars( System.out, off, cch ); + } + + private void dumpChars( PrintStream p, int off, int cch ) + { + p.print( "( " ); + CharUtil.dumpChars( p, _srcLeft, _offLeft, _cchLeft ); + p.print( ", " ); + CharUtil.dumpChars( p, _srcRight, _offRight, cchRight( off, cch ) ); + p.print( " )" ); + } + + // + // + // + + public final Object _srcLeft; + public final int _offLeft; + public final int _cchLeft; + + public final Object _srcRight; + public final int _offRight; + + public final int _depth; + + static final int MAX_DEPTH = 64; + } + + // + // + // + + public final static class CharIterator + { + public void init ( Object src, int off, int cch ) + { + init( src, off, cch, 0 ); + } + + public void init ( Object src, int off, int cch, int startPos ) + { + assert isValid( src, off, cch ); + + release(); + + _srcRoot = src; + _offRoot = off; + _cchRoot = cch; + + _minPos = _maxPos = -1; + + movePos( startPos ); + } + + public void release ( ) + { + _srcRoot = null; + _srcLeafString = null; + _srcLeafChars = null; + } + + public boolean hasNext ( ) { return _pos < _cchRoot; } + public boolean hasPrev ( ) { return _pos > 0; } + + public char next ( ) + { + assert hasNext() ; + + char ch = currentChar(); + + movePos( _pos + 1 ); + + return ch; + } + + public char prev ( ) + { + assert hasPrev() ; + + movePos( _pos - 1 ); + + return currentChar(); + } + + public void movePos ( int newPos ) + { + assert newPos >= 0 && newPos <= _cchRoot; + + if (newPos < _minPos || newPos > _maxPos) + { + // if newPos out of cached leaf, recache new leaf + Object src = _srcRoot; + int off = _offRoot + newPos; + int cch = _cchRoot; + + for ( _offLeaf = _offRoot ; src instanceof CharJoin ; ) + { + CharJoin j = (CharJoin) src; + + if (off < j._cchLeft) + { + src = j._srcLeft; + _offLeaf = j._offLeft; + off = off + j._offLeft; + cch = j._cchLeft; + } + else + { + src = j._srcRight; + _offLeaf = j._offRight; + off = off - (j._cchLeft - j._offRight); + cch = cch - j._cchLeft; + } + } + +// _offLeaf = off - Math.min( off - _offLeaf, newPos ); + _minPos = newPos - (off - _offLeaf); +// _maxPos = newPos + Math.min( _cchRoot - newPos, sizeof( src ) - off ); + _maxPos = _minPos + cch; + + if (newPos < _cchRoot) + _maxPos--; + + // Cache the leaf src to avoid instanceof for every char + + _srcLeafChars = null; + _srcLeafString = null; + + if (src instanceof char[]) + _srcLeafChars = (char[]) src; + else + _srcLeafString = (String) src; + + assert newPos >= _minPos && newPos <= _maxPos; + } + + _pos = newPos; + } + + private char currentChar ( ) + { + int i = _offLeaf + _pos - _minPos; + + return _srcLeafChars == null ? _srcLeafString.charAt( i ) : _srcLeafChars[ i ]; + } + + private Object _srcRoot; // Original triple + private int _offRoot; + private int _cchRoot; + + private int _pos; // Current position + + private int _minPos; // Min/max poses for current cached leaf + private int _maxPos; + + private int _offLeaf; + + private String _srcLeafString; // Cached leaf - either a char[] or a string + private char[] _srcLeafChars; + } + + private static int CHARUTIL_INITIAL_BUFSIZE = 1024 * 32; + private static ThreadLocal tl_charUtil = + new ThreadLocal() { protected Object initialValue() { return new SoftReference(new CharUtil( CHARUTIL_INITIAL_BUFSIZE )); } }; + + private CharIterator _charIter = new CharIterator(); + + // TODO - 64 is kinda arbitrary. Perhaps it should be configurable. + private static final int MAX_COPY = 64; + + // Current char buffer we're allcoating new chars to + + private int _charBufSize; + private int _currentOffset; + private char[] _currentBuffer; + + // These members are used to communicate offset and character count + // information back to a caller of various methods on CharUtil. + // Usually, the methods returns the src Object, and these two hold + // the offset and the char count. + + public int _offSrc; + public int _cchSrc; +} \ No newline at end of file diff --git a/xmlbeans/src/store/org/apache/xmlbeans/impl/store/Cur.java b/xmlbeans/src/store/org/apache/xmlbeans/impl/store/Cur.java new file mode 100755 index 000000000..2a865d31d --- /dev/null +++ b/xmlbeans/src/store/org/apache/xmlbeans/impl/store/Cur.java @@ -0,0 +1,3611 @@ +/* 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.store; + +import org.w3c.dom.Attr; +import org.w3c.dom.CDATASection; +import org.w3c.dom.CharacterData; +import org.w3c.dom.Comment; +import org.w3c.dom.Document; +import org.w3c.dom.DocumentFragment; +import org.w3c.dom.DocumentType; +import org.w3c.dom.DOMException; +import org.w3c.dom.DOMImplementation; +import org.w3c.dom.Element; +import org.w3c.dom.EntityReference; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.w3c.dom.ProcessingInstruction; +import org.w3c.dom.Text; +import org.w3c.dom.DOMImplementation; + +// DOM Level 3 +import org.w3c.dom.UserDataHandler; +import org.w3c.dom.DOMConfiguration; +import org.w3c.dom.TypeInfo; + + +import javax.xml.transform.Source; + +import java.io.PrintStream; + +import java.util.Iterator; +import java.util.Map; +import java.util.ArrayList; +import java.util.List; + +import org.apache.xmlbeans.impl.soap.Detail; +import org.apache.xmlbeans.impl.soap.DetailEntry; +import org.apache.xmlbeans.impl.soap.MimeHeaders; +import org.apache.xmlbeans.impl.soap.Name; +import org.apache.xmlbeans.impl.soap.SOAPBody; +import org.apache.xmlbeans.impl.soap.SOAPBodyElement; +import org.apache.xmlbeans.impl.soap.SOAPElement; +import org.apache.xmlbeans.impl.soap.SOAPEnvelope; +import org.apache.xmlbeans.impl.soap.SOAPException; +import org.apache.xmlbeans.impl.soap.SOAPFactory; +import org.apache.xmlbeans.impl.soap.SOAPFault; +import org.apache.xmlbeans.impl.soap.SOAPFaultElement; +import org.apache.xmlbeans.impl.soap.SOAPHeader; +import org.apache.xmlbeans.impl.soap.SOAPHeaderElement; +import org.apache.xmlbeans.impl.soap.SOAPPart; +import org.apache.xmlbeans.impl.store.Xobj.Bookmark; + +import org.apache.xmlbeans.impl.store.Locale.LoadContext; + +import org.apache.xmlbeans.impl.store.DomImpl.Dom; +import org.apache.xmlbeans.impl.store.DomImpl.CharNode; +import org.apache.xmlbeans.impl.store.DomImpl.TextNode; +import org.apache.xmlbeans.impl.store.DomImpl.CdataNode; +import org.apache.xmlbeans.impl.store.DomImpl.SaajTextNode; +import org.apache.xmlbeans.impl.store.DomImpl.SaajCdataNode; + +import org.apache.xmlbeans.CDataBookmark; +import org.apache.xmlbeans.XmlBeans; +import org.apache.xmlbeans.XmlLineNumber; +import org.apache.xmlbeans.SchemaField; +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.SchemaTypeLoader; +import org.apache.xmlbeans.XmlCursor; +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.XmlOptions; +import org.apache.xmlbeans.XmlException; +import org.apache.xmlbeans.QNameSet; +import org.apache.xmlbeans.XmlDocumentProperties; +import org.apache.xmlbeans.XmlCursor.XmlBookmark; + +import org.apache.xmlbeans.impl.values.TypeStore; +import org.apache.xmlbeans.impl.values.TypeStoreUser; +import org.apache.xmlbeans.impl.values.TypeStoreVisitor; +import org.apache.xmlbeans.impl.values.TypeStoreUserFactory; + +import javax.xml.namespace.QName; + +import org.apache.xmlbeans.impl.common.ValidatorListener; +import org.apache.xmlbeans.impl.common.XmlLocale; +import org.apache.xmlbeans.impl.common.QNameHelper; + + +final class Cur +{ + static final int TEXT = 0; // Must be 0 + static final int ROOT = 1; + static final int ELEM = 2; + static final int ATTR = 3; + static final int COMMENT = 4; + static final int PROCINST = 5; + + static final int POOLED = 0; + static final int REGISTERED = 1; + static final int EMBEDDED = 2; + static final int DISPOSED = 3; + + static final int END_POS = -1; + static final int NO_POS = -2; + + Cur ( Locale l ) + { + _locale = l; + _pos = NO_POS; + + _tempFrame = -1; + + _state = POOLED; + + _stackTop = Locations.NULL; + _selectionFirst = -1; + _selectionN = -1; + _selectionLoc = Locations.NULL; + _selectionCount = 0; + } + + boolean isPositioned ( ) { assert isNormal(); return _xobj != null; } + + static boolean kindIsContainer ( int k ) { return k == ELEM || k == ROOT; } + static boolean kindIsFinish ( int k ) { return k == -ELEM || k == -ROOT; } + + int kind ( ) + { + assert isPositioned(); + int kind = _xobj.kind(); + return _pos == 0 ? kind : (_pos == END_POS ? - kind : TEXT); + } + + boolean isRoot ( ) { assert isPositioned(); return _pos == 0 && _xobj.kind() == ROOT; } + boolean isElem ( ) { assert isPositioned(); return _pos == 0 && _xobj.kind() == ELEM; } + boolean isAttr ( ) { assert isPositioned(); return _pos == 0 && _xobj.kind() == ATTR; } + boolean isComment ( ) { assert isPositioned(); return _pos == 0 && _xobj.kind() == COMMENT; } + boolean isProcinst ( ) { assert isPositioned(); return _pos == 0 && _xobj.kind() == PROCINST; } + boolean isText ( ) { assert isPositioned(); return _pos > 0; } + boolean isEnd ( ) { assert isPositioned(); return _pos == END_POS && _xobj.kind() ==ELEM;} + boolean isEndRoot ( ) { assert isPositioned(); return _pos == END_POS && _xobj.kind() ==ROOT;} + boolean isNode ( ) { assert isPositioned(); return _pos == 0; } + boolean isContainer ( ) { assert isPositioned(); return _pos == 0 && kindIsContainer( _xobj.kind() ); } + boolean isFinish ( ) { assert isPositioned(); return _pos == END_POS && kindIsContainer( _xobj.kind() ); } + boolean isUserNode ( ) { assert isPositioned(); int k = kind(); return k == ELEM || k == ROOT || (k == ATTR && !isXmlns()); } + + boolean isContainerOrFinish ( ) + { + assert isPositioned(); + + if (_pos!=0 && _pos!= END_POS) + return false; + + int kind = _xobj.kind(); + return kind == ELEM || kind == -ELEM || kind == ROOT || kind == -ROOT; + } + + boolean isNormalAttr ( ) { return isNode() && _xobj.isNormalAttr(); } + boolean isXmlns ( ) { return isNode() && _xobj.isXmlns(); } + + boolean isTextCData ( ) { return _xobj.hasBookmark(CDataBookmark.class, _pos); } + + QName getName ( ) { assert isNode() || isEnd(); return _xobj._name; } + String getLocal ( ) { return getName().getLocalPart(); } + String getUri ( ) { return getName().getNamespaceURI(); } + + String getXmlnsPrefix ( ) { assert isXmlns(); return _xobj.getXmlnsPrefix(); } + String getXmlnsUri ( ) { assert isXmlns(); return _xobj.getXmlnsUri(); } + + boolean isDomDocRoot ( ) { return isRoot() && _xobj.getDom() instanceof Document; } + boolean isDomFragRoot ( ) { return isRoot() && _xobj.getDom() instanceof DocumentFragment; } + + int cchRight ( ) { assert isPositioned(); return _xobj.cchRight( _pos ); } + int cchLeft ( ) { assert isPositioned(); return _xobj.cchLeft ( _pos ); } + + // + // Creation methods + // + + void createRoot ( ) + { + createDomDocFragRoot(); + } + + void createDomDocFragRoot ( ) + { + moveTo( new Xobj.DocumentFragXobj( _locale ) ); + } + + void createDomDocumentRoot ( ) + { + moveTo( createDomDocumentRootXobj( _locale ) ); + } + + void createAttr ( QName name ) + { + createHelper( new Xobj.AttrXobj( _locale, name ) ); + } + + void createComment ( ) + { + createHelper( new Xobj.CommentXobj( _locale ) ); + } + + void createProcinst ( String target ) + { + createHelper( new Xobj.ProcInstXobj( _locale, target ) ); + } + + void createElement ( QName name ) + { + createElement( name, null ); + } + + void createElement ( QName name, QName parentName ) + { + createHelper( createElementXobj( _locale, name, parentName ) ); + } + + static Xobj createDomDocumentRootXobj ( Locale l ) + { + return createDomDocumentRootXobj(l, false); + } + + static Xobj createDomDocumentRootXobj ( Locale l , boolean fragment) + { + Xobj xo; + + if (l._saaj == null) + if (fragment) + xo = new Xobj.DocumentFragXobj( l ); + else + xo = new Xobj.DocumentXobj( l ); + else + xo = new Xobj.SoapPartDocXobj( l ); + + if (l._ownerDoc == null) + l._ownerDoc = xo.getDom(); + + return xo; + } + + static Xobj createElementXobj ( Locale l, QName name, QName parentName ) + { + if (l._saaj == null) + return new Xobj.ElementXobj( l, name ); + + Class c = l._saaj.identifyElement( name, parentName ); + + if (c == SOAPElement.class) return new Xobj.SoapElementXobj ( l, name ); + if (c == SOAPBody.class) return new Xobj.SoapBodyXobj ( l, name ); + if (c == SOAPBodyElement.class) return new Xobj.SoapBodyElementXobj ( l, name ); + if (c == SOAPEnvelope.class) return new Xobj.SoapEnvelopeXobj ( l, name ); + if (c == SOAPHeader.class) return new Xobj.SoapHeaderXobj ( l, name ); + if (c == SOAPHeaderElement.class) return new Xobj.SoapHeaderElementXobj ( l, name ); + if (c == SOAPFaultElement.class) return new Xobj.SoapFaultElementXobj ( l, name ); + if (c == Detail.class) return new Xobj.DetailXobj ( l, name ); + if (c == DetailEntry.class) return new Xobj.DetailEntryXobj ( l, name ); + if (c == SOAPFault.class) return new Xobj.SoapFaultXobj ( l, name ); + + throw new IllegalStateException( "Unknown SAAJ element class: " + c ); + } + + private void createHelper ( Xobj x ) + { + assert x._locale == _locale; + + // insert the new Xobj into an exisiting tree. + + if (isPositioned()) + { + Cur from = tempCur( x, 0 ); + from.moveNode( this ); + from.release(); + } + + moveTo( x ); + } + + // + // General operations + // + + boolean isSamePos ( Cur that ) + { + assert isNormal() && (that == null || that.isNormal()); + + return _xobj == that._xobj && _pos == that._pos; + } + + // is this just after the end of that (that must be the start of a node) + + boolean isJustAfterEnd ( Cur that ) + { + assert isNormal() && that != null && that.isNormal() && that.isNode(); + + return that._xobj.isJustAfterEnd( _xobj, _pos ); + } + + boolean isJustAfterEnd ( Xobj x ) + { + return x.isJustAfterEnd( _xobj, _pos ); + } + + boolean isAtEndOf ( Cur that ) + { + assert that != null && that.isNormal() && that.isNode(); + + return _xobj == that._xobj && _pos == END_POS; + } + + boolean isInSameTree ( Cur that ) + { + assert isPositioned() && that.isPositioned(); + + return _xobj.isInSameTree( that._xobj ); + } + + // Retunr -1, 0 or 1 for relative cursor positions. Return 2 is not in sames trees. + + int comparePosition ( Cur that ) + { + assert isPositioned() && that.isPositioned(); + + // If in differnet locales, then can't comapre + + if (_locale != that._locale) + return 2; + + // No need to denormalize, but I want positions which I can compare (no END_POS) + + Xobj xThis = _xobj; + int pThis = _pos == END_POS ? xThis.posAfter() - 1 : _pos; + + Xobj xThat = that._xobj; + int pThat = that._pos == END_POS ? xThat.posAfter() - 1 : that._pos; + + // There are several cases: + // + // 1. Cursors are on the same xobj + // 2. One cursor is a child of the other + // 3. Cursors share a common parent + // 4. Cursors are not in the same trees + // + // Check for the first, trivial, case. Then, compute the depths of the nodes the + // cursors are on, checkin for case 2 + // + + if (xThis == xThat) + return pThis < pThat ? -1 : pThis == pThat ? 0 : 1; + + // Compute the depth of xThis. See if I hit xThat (case 2) + + int dThis = 0; + + for ( Xobj x = xThis._parent ; x != null ; x = x._parent ) + { + dThis++; + + if (x == xThat) + return pThat < xThat.posAfter() - 1 ? 1 : -1; + } + + // Compute the depth of xThat. See if I hit xThis (case 2) + + int dThat = 0; + + for ( Xobj x = xThat._parent ; x != null ; x = x._parent ) + { + dThat++; + + if (x == xThis) + return pThis < xThis.posAfter() - 1 ? -1 : 1; + } + + // Must be case 3 or 4 now. Find a common parent. If none, then it's case 4 + + while ( dThis > dThat ) { dThis--; xThis = xThis._parent; } + while ( dThat > dThis ) { dThat--; xThat = xThat._parent; } + + assert dThat == dThis; + + if (dThat == 0) + return 2; + + assert xThis._parent != null && xThat._parent != null; + + while ( xThis._parent != xThat._parent ) + { + if ((xThis = xThis._parent) == null) + return 2; + + xThat = xThat._parent; + } + + // Now, see where xThis and XThat are relative to eachother in the childlist. Apply + // some quick common checks before iterating. + + if (xThis._prevSibling == null || xThat._nextSibling == null) + return -1; + + if (xThis._nextSibling == null || xThat._prevSibling == null) + return 1; + + while ( xThis != null ) + if ((xThis = xThis._prevSibling) == xThat) + return 1; + + return -1; + } + + void setName ( QName newName ) + { + assert isNode() && newName != null; + + _xobj.setName( newName ); + } + + void moveTo ( Xobj x ) + { + moveTo( x, 0 ); + } + + void moveTo ( Xobj x, int p ) + { + // This cursor may not be normalized upon entry, don't assert isNormal() here + + assert x == null || _locale == x._locale; + assert x != null || p == NO_POS; + assert x == null || x.isNormal( p ) || ( x.isVacant() && x._cchValue==0 && x._user == null ); + assert _state == REGISTERED || _state == EMBEDDED; + assert _state == EMBEDDED || (_xobj == null || !isOnList( _xobj._embedded )); + assert _state == REGISTERED || (_xobj != null && isOnList( _xobj._embedded )); + + moveToNoCheck( x, p ); + + assert isNormal() || ( _xobj.isVacant() && _xobj._cchValue==0 && _xobj._user == null ); + } + + void moveToNoCheck ( Xobj x, int p ) + { + if (_state == EMBEDDED && x != _xobj) + { + _xobj._embedded = listRemove( _xobj._embedded ); + _locale._registered = listInsert( _locale._registered ); + _state = REGISTERED; + } + + _xobj = x; + _pos = p; + } + + void moveToCur ( Cur to ) + { + assert isNormal() && (to == null || to.isNormal()); + + if (to == null) + moveTo( null, NO_POS ); + else + moveTo( to._xobj, to._pos ); + } + + void moveToDom ( Dom d ) + { + assert _locale == d.locale(); + assert d instanceof Xobj || d instanceof Xobj.SoapPartDom; + + moveTo( d instanceof Xobj ? (Xobj) d : ((Xobj.SoapPartDom) d)._docXobj ); + } + + static final class Locations + { + private static final int NULL = -1; + + Locations ( Locale l ) + { + _locale = l; + + _xobjs = new Xobj [ _initialSize ]; + _poses = new int [ _initialSize ]; + _curs = new Cur [ _initialSize ]; + _next = new int [ _initialSize ]; + _prev = new int [ _initialSize ]; + _nextN = new int [ _initialSize ]; + _prevN = new int [ _initialSize ]; + + for ( int i = _initialSize - 1 ; i >= 0 ; i-- ) + { + assert _xobjs[ i ] == null; + _poses [ i ] = NO_POS; + _next [ i ] = i + 1; + _prev [ i ] = NULL; + _nextN [ i ] = NULL; + _prevN [ i ] = NULL; + } + + _next [ _initialSize - 1 ] = NULL; + + _free = 0; + _naked = NULL; + } + + boolean isSamePos ( int i, Cur c ) + { + if (_curs[ i ] == null) + return c._xobj == _xobjs[ i ] && c._pos == _poses[ i ]; + else + return c.isSamePos( _curs[ i ] ); + } + + boolean isAtEndOf ( int i, Cur c ) + { + assert _curs[ i ] != null || _poses[ i ] == 0; + assert _curs[ i ] == null || _curs[ i ].isNode(); + + if (_curs[ i ] == null) + return c._xobj == _xobjs[ i ] && c._pos == END_POS; + else + return c.isAtEndOf( _curs[ i ] ); + } + + void moveTo ( int i, Cur c ) + { + if (_curs[ i ] == null) + c.moveTo( _xobjs[ i ], _poses[ i ] ); + else + c.moveToCur( _curs[ i ] ); + } + + int insert ( int head, int before, int i ) + { + return insert( head, before, i, _next, _prev ); + } + + int remove ( int head, int i ) + { + Cur c = _curs[ i ]; + + assert c != null || _xobjs[ i ] != null; + assert c != null || _xobjs[ i ] != null; + + if (c != null) + { + _curs[ i ].release(); + _curs[ i ] = null; + + assert _xobjs[ i ] == null; + assert _poses [ i ] == NO_POS; + } + else + { + assert _xobjs[ i ] != null && _poses[ i ] != NO_POS; + + _xobjs[ i ] = null; + _poses[ i ] = NO_POS; + + _naked = remove( _naked, i, _nextN, _prevN ); + } + + head = remove( head, i, _next, _prev ); + + _next[ i ] = _free; + _free = i; + + return head; + } + + int allocate ( Cur addThis ) + { + assert addThis.isPositioned(); + + if (_free == NULL) + makeRoom(); + + int i = _free; + + _free = _next [ i ]; + + _next [ i ] = NULL; + assert _prev [ i ] == NULL; + + assert _curs [ i ] == null; + assert _xobjs[ i ] == null; + assert _poses[ i ] == NO_POS; + + _xobjs [ i ] = addThis._xobj; + _poses [ i ] = addThis._pos; + + _naked = insert( _naked, NULL, i, _nextN, _prevN ); + + return i; + } + + private static int insert ( int head, int before, int i, int[] next, int[] prev ) + { + if (head == NULL) + { + assert before == NULL; + prev[ i ] = i; + head = i; + } + else if (before != NULL) + { + prev[ i ] = prev[ before ]; + next[ i ] = before; + prev[ before ] = i; + + if (head == before) + head = i; + } + else + { + prev[ i ] = prev[ head ]; + assert next[ i ] == NULL; + next[ prev[ head ] ] = i; + prev[ head ] = i; + } + + return head; + } + + private static int remove ( int head, int i, int[] next, int[] prev ) + { + if (prev[ i ] == i) + { + assert head == i; + head = NULL; + } + else + { + if (head == i) + head = next[ i ]; + else + next[ prev [ i ] ] = next[ i ]; + + if (next[ i ] == NULL) + prev[ head ] = prev[ i ]; + else + { + prev[ next[ i ] ] = prev[ i ]; + next[ i ] = NULL; + } + } + + prev[ i ] = NULL; + assert next[ i ] == NULL; + + return head; + } + + void notifyChange ( ) + { + for ( int i ; (i = _naked) != NULL ; ) + { + assert _curs[ i ] == null && _xobjs[ i ] != null && _poses[ i ] != NO_POS; + + _naked = remove( _naked, i, _nextN, _prevN ); + + _curs[ i ] = _locale.getCur(); + _curs[ i ].moveTo( _xobjs[ i ], _poses[ i ] ); + + _xobjs[ i ] = null; + _poses[ i ] = NO_POS; + } + } + + int next ( int i ) { return _next[ i ]; } + int prev ( int i ) { return _prev[ i ]; } + + private void makeRoom ( ) + { + assert _free == NULL; + + int l = _xobjs.length; + + Xobj [] oldXobjs = _xobjs; + int [] oldPoses = _poses; + Cur [] oldCurs = _curs; + int [] oldNext = _next; + int [] oldPrev = _prev; + int [] oldNextN = _nextN; + int [] oldPrevN = _prevN; + + _xobjs = new Xobj [ l * 2 ]; + _poses = new int [ l * 2 ]; + _curs = new Cur [ l * 2 ]; + _next = new int [ l * 2 ]; + _prev = new int [ l * 2 ]; + _nextN = new int [ l * 2 ]; + _prevN = new int [ l * 2 ]; + + System.arraycopy( oldXobjs, 0, _xobjs, 0, l ); + System.arraycopy( oldPoses, 0, _poses, 0, l ); + System.arraycopy( oldCurs, 0, _curs, 0, l ); + System.arraycopy( oldNext, 0, _next, 0, l ); + System.arraycopy( oldPrev, 0, _prev, 0, l ); + System.arraycopy( oldNextN, 0, _nextN, 0, l ); + System.arraycopy( oldPrevN, 0, _prevN, 0, l ); + + for ( int i = l * 2 - 1 ; i >= l ; i-- ) + { + _next [ i ] = i + 1; + _prev [ i ] = NULL; + _nextN [ i ] = NULL; + _prevN [ i ] = NULL; + _poses [ i ] = NO_POS; + } + + _next [ l * 2 - 1 ] = NULL; + + _free = l; + } + + private static final int _initialSize = 32; + + private Locale _locale; + + private Xobj [] _xobjs; + private int [] _poses; + private Cur [] _curs; + private int [] _next; + private int [] _prev; + private int [] _nextN; + private int [] _prevN; + + private int _free; // Unused entries + private int _naked; // Entries without Curs + } + + void push ( ) + { + assert isPositioned(); + + int i = _locale._locations.allocate( this ); + _stackTop = _locale._locations.insert( _stackTop, _stackTop, i ); + } + + void pop ( boolean stay ) + { + if (stay) + popButStay(); + else + pop(); + } + + void popButStay ( ) + { + if (_stackTop != Locations.NULL) + _stackTop = _locale._locations.remove( _stackTop, _stackTop ); + } + + boolean pop ( ) + { + if (_stackTop == Locations.NULL) + return false; + + _locale._locations.moveTo( _stackTop, this ); + _stackTop = _locale._locations.remove( _stackTop, _stackTop ); + + return true; + } + + boolean isAtLastPush ( ) + { + assert _stackTop != Locations.NULL; + + return _locale._locations.isSamePos( _stackTop, this ); + } + + boolean isAtEndOfLastPush ( ) + { + assert _stackTop != Locations.NULL; + + return _locale._locations.isAtEndOf( _stackTop, this ); + } + + void addToSelection ( Cur that ) + { + assert that != null && that.isNormal(); + assert isPositioned() && that.isPositioned(); + + int i = _locale._locations.allocate( that ); + _selectionFirst = _locale._locations.insert( _selectionFirst, Locations.NULL, i ); + + _selectionCount++; + } + + void addToSelection ( ) + { + assert isPositioned(); + + int i = _locale._locations.allocate( this ); + _selectionFirst = _locale._locations.insert( _selectionFirst, Locations.NULL, i ); + + _selectionCount++; + } + + private int selectionIndex ( int i ) + { + assert _selectionN >= -1 && i >= 0 && i < _selectionCount; + + if (_selectionN == -1) + { + _selectionN = 0; + _selectionLoc = _selectionFirst; + } + + while ( _selectionN < i ) + { + _selectionLoc = _locale._locations.next( _selectionLoc ); + _selectionN++; + } + + while ( _selectionN > i ) + { + _selectionLoc = _locale._locations.prev( _selectionLoc ); + _selectionN--; + } + + return _selectionLoc; + } + + void removeSelection ( int i ) + { + assert i >= 0 && i < _selectionCount; + + int j = selectionIndex( i ); + + // Update the nth selection indices to accomodate the deletion + + if (i < _selectionN) + _selectionN--; + else if (i == _selectionN) + { + _selectionN--; + + if (i == 0) + _selectionLoc = Locations.NULL; + else + _selectionLoc = _locale._locations.prev( _selectionLoc ); + } + + _selectionFirst = _locale._locations.remove( _selectionFirst, j ); + + _selectionCount--; + } + + int selectionCount ( ) + { + return _selectionCount; + } + + void moveToSelection ( int i ) + { + assert i >= 0 && i < _selectionCount; + + _locale._locations.moveTo( selectionIndex( i ), this ); + } + + void clearSelection ( ) + { + assert _selectionCount >= 0; + + while ( _selectionCount > 0 ) + removeSelection( 0 ); + } + + boolean toParent ( ) { return toParent( false ); } + boolean toParentRaw ( ) { return toParent( true ); } + + Xobj getParent ( ) { return getParent( false ); } + Xobj getParentRaw ( ) { return getParent( true ); } + + boolean hasParent ( ) + { + assert isPositioned(); + + if (_pos == END_POS || (_pos >= 1 && _pos < _xobj.posAfter())) + return true; + + assert _pos == 0 || _xobj._parent != null; + + return _xobj._parent != null; + } + + Xobj getParentNoRoot() + { + assert isPositioned(); + + if (_pos == END_POS || (_pos >= 1 && _pos < _xobj.posAfter())) + return _xobj; + + assert _pos == 0 || _xobj._parent != null; + + if (_xobj._parent != null) + return _xobj._parent; + + return null; + } + + Xobj getParent ( boolean raw ) + { + assert isPositioned(); + + if (_pos == END_POS || (_pos >= 1 && _pos < _xobj.posAfter())) + return _xobj; + + assert _pos == 0 || _xobj._parent != null; + + if (_xobj._parent != null) + return _xobj._parent; + + if (raw || _xobj.isRoot()) + return null; + + Cur r = _locale.tempCur(); + + r.createRoot(); + + Xobj root = r._xobj; + + r.next(); + moveNode( r ); + r.release(); + + return root; + } + + boolean toParent ( boolean raw ) + { + Xobj parent = getParent( raw ); + + if (parent == null) + return false; + + moveTo( parent ); + + return true; + } + + void toRoot () + { + Xobj xobj = _xobj; + while (!xobj.isRoot()) + { + if (xobj._parent==null) + { + Cur r = _locale.tempCur(); + + r.createRoot(); + + Xobj root = r._xobj; + + r.next(); + moveNode( r ); + r.release(); + + xobj = root; + break; + } + xobj = xobj._parent; + } + moveTo(xobj); + } + + boolean hasText ( ) + { + assert isNode(); + + return _xobj.hasTextEnsureOccupancy(); + } + + boolean hasAttrs ( ) + { + assert isNode(); + + return _xobj.hasAttrs(); + } + + boolean hasChildren ( ) + { + assert isNode(); + + return _xobj.hasChildren(); + } + + boolean toFirstChild ( ) + { + assert isNode(); + + if (!_xobj.hasChildren()) + return false; + + for ( Xobj x = _xobj._firstChild ; ; x = x._nextSibling ) + { + if (!x.isAttr()) + { + moveTo( x ); + return true; + } + } + } + + protected boolean toLastChild ( ) + { + assert isNode(); + + if (!_xobj.hasChildren()) + return false; + + moveTo( _xobj._lastChild ); + + return true; + } + + boolean toNextSibling ( ) + { + assert isNode(); + + if (_xobj.isAttr()) + { + if (_xobj._nextSibling != null && _xobj._nextSibling.isAttr()) + { + moveTo( _xobj._nextSibling ); + return true; + } + } + else if (_xobj._nextSibling != null) + { + moveTo( _xobj._nextSibling ); + return true; + } + + return false; + } + + void setValueAsQName ( QName qname ) + { + assert isNode(); + + String value = qname.getLocalPart(); + String ns = qname.getNamespaceURI(); + + String prefix = + prefixForNamespace( + ns, qname.getPrefix().length() > 0 ? qname.getPrefix() : null, true ); + + if (prefix.length() > 0) + value = prefix + ":" + value; + + setValue( value ); + } + + void setValue ( String value ) + { + assert isNode(); + + moveNodeContents( null, false ); + + next(); + + insertString( value ); + + toParent(); + } + + void removeFollowingAttrs ( ) + { + assert isAttr(); + + QName attrName = getName(); + + push(); + + if (toNextAttr()) + { + while ( isAttr() ) + { + if (getName().equals( attrName )) + moveNode( null ); + else if (!toNextAttr()) + break; + } + } + + pop(); + } + + String getAttrValue ( QName name ) + { + String s = null; + + push(); + + if (toAttr( name )) + s = getValueAsString(); + + pop(); + + return s; + } + + void setAttrValueAsQName ( QName name, QName value ) + { + assert isContainer(); + + if (value == null) + { + _xobj.removeAttr( name ); + } + else + { + if (toAttr( name )) + { + removeFollowingAttrs(); + } + else + { + next(); + createAttr( name ); + } + + setValueAsQName( value ); + + toParent(); + } + } + + boolean removeAttr ( QName name ) + { + assert isContainer(); + + return _xobj.removeAttr( name ); + } + + void setAttrValue ( QName name, String value ) + { + assert isContainer(); + + _xobj.setAttr( name, value ); + } + + boolean toAttr ( QName name ) + { + assert isNode(); + + Xobj a = _xobj.getAttr( name ); + + if (a == null) + return false; + + moveTo( a ); + + return true; + } + + boolean toFirstAttr ( ) + { + assert isNode(); + + Xobj firstAttr = _xobj.firstAttr(); + + if (firstAttr == null) + return false; + + moveTo( firstAttr ); + + return true; + } + + boolean toLastAttr ( ) + { + assert isNode(); + + if (!toFirstAttr()) + return false; + + while ( toNextAttr() ) + ; + + return true; + } + + boolean toNextAttr ( ) + { + assert isAttr() || isContainer(); + + Xobj nextAttr = _xobj.nextAttr(); + + if (nextAttr == null) + return false; + + moveTo( nextAttr ); + + return true; + } + + boolean toPrevAttr ( ) + { + if (isAttr()) + { + if (_xobj._prevSibling == null) + moveTo( _xobj.ensureParent() ); + else + moveTo( _xobj._prevSibling ); + + return true; + } + + prev(); + + if (!isContainer()) + { + next(); + return false; + } + + return toLastAttr(); + } + + boolean skipWithAttrs ( ) + { + assert isNode(); + + if (skip()) + return true; + + if (_xobj.isRoot()) + return false; + + assert _xobj.isAttr(); + + toParent(); + + next(); + + return true; + } + + boolean skip ( ) + { + assert isNode(); + + if (_xobj.isRoot()) + return false; + + if (_xobj.isAttr()) + { + if (_xobj._nextSibling == null || !_xobj._nextSibling.isAttr()) + return false; + + moveTo( _xobj._nextSibling, 0 ); + } + else + moveTo( getNormal( _xobj, _xobj.posAfter() ), _posTemp ); + + return true; + } + + void toEnd ( ) + { + assert isNode(); + + moveTo( _xobj, END_POS ); + } + + void moveToCharNode ( CharNode node ) + { + assert node.getDom() != null && node.getDom().locale() == _locale; + + moveToDom( node.getDom() ); + + CharNode n; + + _xobj.ensureOccupancy(); + + n = _xobj._charNodesValue = + updateCharNodes( _locale, _xobj, _xobj._charNodesValue, _xobj._cchValue ); + + for ( ; n != null ; n = n._next ) + { + if (node == n) + { + moveTo( getNormal( _xobj, n._off + 1 ), _posTemp ); + return; + } + } + + n = _xobj._charNodesAfter = + updateCharNodes( _locale, _xobj, _xobj._charNodesAfter, _xobj._cchAfter ); + + for ( ; n != null ; n = n._next ) + { + if (node == n) + { + moveTo( getNormal( _xobj, n._off + _xobj._cchValue + 2 ), _posTemp ); + return; + } + } + + assert false; + } + + boolean prevWithAttrs ( ) + { + if (prev()) + return true; + + if (!isAttr()) + return false; + + toParent(); + + return true; + } + + boolean prev ( ) + { + assert isPositioned(); + + if (_xobj.isRoot() && _pos == 0) + return false; + + if (_xobj.isAttr() && _pos == 0 && _xobj._prevSibling == null) + return false; + + Xobj x = getDenormal(); + int p = _posTemp; + + assert p > 0 && p != END_POS; + + int pa = x.posAfter(); + + if (p > pa) + p = pa; + else if (p == pa) + { + // Text after an attr is allowed only on the last attr, + // and that text belongs to the parent container.. + // + // If we're a thte end of the last attr, then we were just + // inside the container, and we need to skip the attrs. + + if (x.isAttr() && + (x._cchAfter > 0 || x._nextSibling == null || !x._nextSibling.isAttr())) + { + x = x.ensureParent(); + p = 0; + } + else + p = END_POS; + } + else if (p == pa - 1) + { + x.ensureOccupancy(); + p = x._cchValue > 0 ? 1 : 0; + } + else if (p > 1) + p = 1; + else + { + assert p == 1; + p = 0; + } + + moveTo( getNormal( x, p ), _posTemp ); + + return true; + } + + boolean next ( boolean withAttrs ) + { + return withAttrs ? nextWithAttrs() : next(); + } + + boolean nextWithAttrs ( ) + { + int k = kind(); + + if (kindIsContainer( k )) + { + if (toFirstAttr()) + return true; + } + else if (k == -ATTR) + { + if (next()) + return true; + + toParent(); + + if (!toParentRaw()) + return false; + } + + return next(); + } + + boolean next ( ) + { + assert isNormal(); + + Xobj x = _xobj; + int p = _pos; + + int pa = x.posAfter(); + + if (p >= pa) + p = _xobj.posMax(); + else if (p == END_POS) + { + if (x.isRoot() || (x.isAttr() && (x._nextSibling == null || !x._nextSibling.isAttr()))) + return false; + + p = pa; + } + else if (p > 0) + { + assert x._firstChild == null || !x._firstChild.isAttr(); + + if (x._firstChild != null) + { + x = x._firstChild; + p = 0; + } + else + p = END_POS; + } + else + { + assert p == 0; + + x.ensureOccupancy(); + + p = 1; + + if (x._cchValue == 0) + { + if (x._firstChild != null) + { + if (x._firstChild.isAttr()) + { + Xobj a = x._firstChild; + + while ( a._nextSibling != null && a._nextSibling.isAttr() ) + a = a._nextSibling; + + if (a._cchAfter > 0) + { + x = a; + p = a.posAfter(); + } + else if (a._nextSibling != null) + { + x = a._nextSibling; + p = 0; + } + } + else + { + x = x._firstChild; + p = 0; + } + } + } + } + + moveTo( getNormal( x, p ), _posTemp ); + + return true; + } + + int prevChars ( int cch ) + { + assert isPositioned(); + + int cchLeft = cchLeft(); + + if (cch < 0 || cch > cchLeft) + cch = cchLeft; + + // Dang, I love this stmt :-) + + if (cch != 0) + moveTo( getNormal( getDenormal(), _posTemp - cch ), _posTemp ); + + return cch; + } + + int nextChars ( int cch ) + { + assert isPositioned(); + + int cchRight = cchRight(); + + if (cchRight == 0) + return 0; + + if (cch < 0 || cch >= cchRight) + { + // Use next to not skip over children + next(); + return cchRight; + } + + moveTo( getNormal( _xobj, _pos + cch ), _posTemp ); + + return cch; + } + + void setCharNodes ( CharNode nodes ) + { + assert nodes == null || _locale == nodes.locale(); + assert isPositioned(); + + Xobj x = getDenormal(); + int p = _posTemp; + + assert !x.isRoot() || (p > 0 && p < x.posAfter()); + + if (p >= x.posAfter()) + x._charNodesAfter = nodes; + else + x._charNodesValue = nodes; + + for ( ; nodes != null ; nodes = nodes._next ) + nodes.setDom( (Dom) x ); + + // No Need to notify text change or alter version, text nodes are + // not part of the infoset + } + + CharNode getCharNodes ( ) + { + assert isPositioned(); + assert !isRoot(); + + Xobj x = getDenormal(); + + CharNode nodes; + + if (_posTemp >= x.posAfter()) + { + nodes = x._charNodesAfter = + updateCharNodes( _locale, x, x._charNodesAfter, x._cchAfter ); + } + else + { + x.ensureOccupancy(); + + nodes = x._charNodesValue = + updateCharNodes( _locale, x, x._charNodesValue, x._cchValue ); + } + + return nodes; + } + + // private + static CharNode updateCharNodes ( Locale l, Xobj x, CharNode nodes, int cch ) + { + assert nodes == null || nodes.locale() == l; + + CharNode node = nodes; + int i = 0; + + while ( node != null && cch > 0 ) + { + assert node.getDom() == x; + + if (node._cch > cch) + node._cch = cch; + + node._off = i; + i += node._cch; + cch -= node._cch; + + node = node._next; + } + + if (cch <= 0) + { + for ( ; node != null ; node = node._next ) + { + assert node.getDom() == x; + + if (node._cch != 0) + node._cch = 0; + + node._off = i; + } + } + else + { + node = l.createTextNode(); + node.setDom( (Dom) x ); + node._cch = cch; + node._off = i; + nodes = CharNode.appendNode( nodes, node ); + } + + return nodes; + } + + final QName getXsiTypeName ( ) + { + assert isNode(); + + return _xobj.getXsiTypeName(); + } + + final void setXsiType ( QName value ) + { + assert isContainer(); + + setAttrValueAsQName( Locale._xsiType, value ); + } + + final QName valueAsQName ( ) + { + throw new RuntimeException( "Not implemented" ); + } + + final String namespaceForPrefix ( String prefix, boolean defaultAlwaysMapped ) + { + return _xobj.namespaceForPrefix( prefix, defaultAlwaysMapped ); + } + + final String prefixForNamespace ( String ns, String suggestion, boolean createIfMissing ) + { + return + (isContainer() ? _xobj : getParent()). + prefixForNamespace( ns, suggestion, createIfMissing ); + } + + // Does the node at this cursor properly contain the position specified by the argument + + boolean contains ( Cur that ) + { + assert isNode(); + assert that != null && that.isPositioned(); + + return _xobj.contains( that ); + } + + void insertString ( String s ) + { + if (s != null) + insertChars( s, 0, s.length() ); + } + + void insertChars ( Object src, int off, int cch ) + { + assert isPositioned() && !isRoot(); + assert CharUtil.isValid( src, off, cch ); + + // Check for nothing to insert + + if (cch <= 0) + return; + + _locale.notifyChange(); + + // The only situation where I need to ensure occupancy is when I'm at the end of a node. + // All other positions will require occupancy. For example, if I'm at the beginning of a + // node, then I will either insert in the after text of the previous sibling, or I will + // insert in the value of the parent. In the latter case, because the parent has a child, + // it cannot be vacant. + + if (_pos == END_POS) + _xobj.ensureOccupancy(); + + // Get the denormailized Xobj and pos. This is the Xobj which will actually receive + // the new chars. Note that a denormalized position can never be <= 0. + + Xobj x = getDenormal(); + int p = _posTemp; + + assert p > 0; + + // This will move "this" cursor to be after the inserted text. No worries, I'll update its + // position after. This insertChars takes care of all the appropriate invalidations + // (passing true as last arg). + + x.insertCharsHelper( p, src, off, cch, true ); + + // Reposition the cursor to be just before the newly inserted text. It's current + // position could have been shifted, or it may have been just before the end tag, or + // normalized on another Xobj. + + moveTo( x, p ); + + _locale._versionAll++; + } + + // Move the chars just after this Cur to the "to" Cur. If no "to" Cur is specified, + // then remove the chars. + + Object moveChars ( Cur to, int cchMove ) + { + assert isPositioned(); + assert cchMove <= 0 || cchMove <= cchRight(); + assert to == null || (to.isPositioned() && !to.isRoot()); + + if (cchMove < 0) + cchMove = cchRight(); + + // If we're instructed to move 0 characters, then return the null triple. + + if (cchMove == 0) + { + _offSrc = 0; + _cchSrc = 0; + + return null; + } + + // Here I record the triple of the chars to move. I will return this. No need to save + // cch 'cause cchMove will be that value. + + Object srcMoved = getChars( cchMove ); + int offMoved = _offSrc; + + // Either I'm moving text from the value or the after text. If after, then the container + // must be occupied. If in the value, because we're just before text, it must be occupied. + + assert isText() && (_pos >= _xobj.posAfter() ? _xobj._parent : _xobj).isOccupied(); + + if (to == null) + { + // In this case, I'm removing chars vs moving them. Normally I would like to blow + // them away entirely, but if there are any references to those chars via a bookmark + // I need to keep them alive. I do this by moving these chars to a new root. Note + // that because Curs will stay behind, I don't have to check for them. + + for ( Bookmark b = _xobj._bookmarks ; b != null ; b = b._next ) + { + if (inChars( b, cchMove, false )) + { + Cur c = _locale.tempCur(); + + c.createRoot(); + c.next(); + + Object chars = moveChars( c, cchMove ); + + c.release(); + + return chars; + } + } + } + else + { + // If the target, "to", is inside or on the edge of the text to be moved, then this + // is a no-op. In this case, I still want to return the text "moved". + // + // Note how I move "to" and this cur around. I move "to" to be at the beginning of the + // chars moved and "this" to be at the end. If the text were really moving to a + // different location, then "to" would be at the beginning of the newly moved chars, + // and "this" would be at the gap left by the newly removed chars. + + if (inChars( to, cchMove, true )) + { + // BUGBUG - may want to consider shuffling the interior cursors to the right just + // like I move "this" to the right... + + to.moveToCur( this ); + nextChars( cchMove ); + + _offSrc = offMoved; + _cchSrc = cchMove; + + return srcMoved; + } + + // Copy the chars here, I'll remove the originals next + + to.insertChars( srcMoved, offMoved, cchMove ); + } + + // Notice that I can delay the general change notification to this point because any + // modifications up to this point are made by calling other high level operations which + // generate this notification themselves. Also, no need to notify of general change in + // the "to" locale because the insertion of chars above handles that. + + _locale.notifyChange(); + + // + //if ( _xobj != null ) + { + if (to == null) + _xobj.removeCharsHelper( _pos, cchMove, null, NO_POS, false, true ); + else + _xobj.removeCharsHelper( _pos, cchMove, to._xobj, to._pos, false, true ); + } + + // Need to update the position of this cursor even though it did not move anywhere. This + // needs to happen because it may not be properly normalized anymore. Note that because + // of the removal of the text, this cur may not be normal any more, thus I call moveTo + // which does not assume this. + + _locale._versionAll++; + + _offSrc = offMoved; + _cchSrc = cchMove; + + return srcMoved; + } + + void moveNode ( Cur to ) + { + assert isNode() && !isRoot(); + assert to == null || to.isPositioned(); + assert to == null || !contains( to ); + assert to == null || !to.isRoot(); + + // TODO - should assert that is an attr is being moved, it is ok there + + + // Record the node to move and skip this cur past it. This moves this cur to be after + // the move to move/remove -- it's final resting place. The only piece of information + // about the source of the move is the node itself. + + Xobj x = _xobj; + + skip(); + + // I call another function here to move the node. I do this because I don't have to + // worry about messing with "this" here given that it not should be treated like any other + // cursor after this point. + + moveNode( x, to ); + } + + // Moves text from one place to another in a low-level way, used as a helper for the higher + // level functions. Takes care of moving bookmarks and cursors. In the high level content + // manipulation functions, cursors do not follow content, but this helper moves them. The + // arguments are denormalized. The Xobj's must be different from eachother but from the same + // locale. The destination must not be not be vacant. + + private static void transferChars ( Xobj xFrom, int pFrom, Xobj xTo, int pTo, int cch ) + { + assert xFrom != xTo; + assert xFrom._locale == xTo._locale; + assert pFrom > 0 && pFrom < xFrom.posMax(); + assert pTo > 0 && pTo <= xTo .posMax(); + assert cch > 0 && cch <= xFrom.cchRight( pFrom ); + assert pTo >= xTo.posAfter() || xTo.isOccupied(); + + // Copy the chars from -> to without performing any invalidations. This will scoot curs + // and marks around appropriately. Note that I get the cars with getCharsHelper which + // does not check for normalization because the state of the tree at this moment may not + // exactly be "correct" here. + + xTo.insertCharsHelper( + pTo, xFrom.getCharsHelper( pFrom, cch ), + xFrom._locale._offSrc, xFrom._locale._cchSrc, false ); + + xFrom.removeCharsHelper( pFrom, cch, xTo, pTo, true, false ); + } + + // Moves the node x to "to", or removes it if to is null. + + static void moveNode ( Xobj x, Cur to ) + { + assert x != null && !x.isRoot(); + assert to == null || to.isPositioned(); + assert to == null || !x.contains( to ); + assert to == null || !to.isRoot(); + + if (to != null) + { + // Before I go much further, I want to make sure that if "to" is in the container of + // a vacant node, I get it occupied. I do not need to worry about the source being + // vacant. + + if (to._pos == END_POS) + to._xobj.ensureOccupancy(); + + // See if the destination is on the edge of the node to be moved (a no-op). It is + // illegal to call this fcn when to is contained within the node to be moved. Note + // that I make sure that to gets oved to the beginning of the node. The position of + // to in all operations should leave to just before the content moved/inserted. + + if ((to._pos == 0 && to._xobj == x) || to.isJustAfterEnd( x )) + { + // TODO - should shuffle contained curs to the right??? + + to.moveTo( x ); + return; + } + } + + // Notify the locale(s) about the change I am about to make. + + x._locale.notifyChange(); + + x._locale._versionAll++; + x._locale._versionSansText++; + + if (to != null && to._locale != x._locale) + { + to._locale.notifyChange(); + + to._locale._versionAll++; + to._locale._versionSansText++; + } + + // Node is going away. Invalidate the parent (the text around the node is merging). + // Also, this node may be an attribute -- invalidate special attrs ... + + if (x.isAttr()) + x.invalidateSpecialAttr( to == null ? null : to.getParentRaw() ); + else + { + if (x._parent != null) + x._parent.invalidateUser(); + + if (to != null && to.hasParent()) + to.getParent().invalidateUser(); + } + + // If there is any text after x, I move it to be before x. This frees me to extract x + // and it's contents with out this text coming along for the ride. Note that if this + // node is the last attr and there is text after it, transferText will move the text + // to a potential previous attr. This is an invalid state for a short period of time. + // I need to move this text away here so that when I walk the tree next, *all* curs + // embedded in this node or deeper will be moved off this node. + + if (x._cchAfter > 0) + transferChars( x, x.posAfter(), x.getDenormal( 0 ), x.posTemp(), x._cchAfter ); + + assert x._cchAfter == 0; + + // Walk the node tree, moving curs out, disconnecting users and relocating to a, possibly, + // new locale. I embed the cursors in this locale before itersting to just cause the + // embed to happen once. + + x._locale.embedCurs(); + + for ( Xobj y = x ; y != null ; y = y.walk( x, true ) ) + { + while ( y._embedded != null ) + y._embedded.moveTo( x.getNormal( x.posAfter() ) ); + + y.disconnectUser(); + + if (to != null) + y._locale = to._locale; + } + + // Now, actually remove the node + + x.removeXobj(); + + // Now, if there is a destination, insert the node there and shuffle the text in the + // vicinity of the destination appropriately. + + if (to != null) + { + // To know where I should insert/append the node to move, I need to see where "to" + // would be if there were no text after it. However, I need to keep "to" where it + // is when I move the text after it later. + + Xobj here = to._xobj; + boolean append = to._pos != 0; + + int cchRight = to.cchRight(); + + if (cchRight > 0) + { + to.push(); + to.next(); + here = to._xobj; + append = to._pos != 0; + to.pop(); + } + + if (append) + here.appendXobj( x ); + else + here.insertXobj( x ); + + // The only text I need to move is that to the right of "to". Even considering all + // the cases where an attribute is involed! + + if (cchRight > 0) + transferChars( to._xobj, to._pos, x, x.posAfter(), cchRight ); + + to.moveTo( x ); + } + } + + void moveNodeContents ( Cur to, boolean moveAttrs ) + { + assert _pos==0; + assert to == null || !to.isRoot(); + + // By calling this helper, I do not have to deal with this Cur any longer. Basically, + // this Cur is out of the picture, it behaves like any other cur at this point. + + moveNodeContents( _xobj, to, moveAttrs ); + } + + static void moveNodeContents ( Xobj x, Cur to, boolean moveAttrs ) + { + // TODO - should assert that is an attr is being moved, it is ok there + + assert to == null || !to.isRoot(); + + // Collect a bit of information about the contents to move first. Note that the collection + // of this info must not cause a vacant value to become occupied. + + boolean hasAttrs = x.hasAttrs(); + boolean noSubNodesToMove = !x.hasChildren() && (!moveAttrs || !hasAttrs); + + // Deal with the cases where only text is involved in the move + + if (noSubNodesToMove) + { + // If we're vacant and there is no place to move a potential value, then I can avoid + // acquiring the text from the TypeStoreUser. Otherwise, there may be text here I + // need to move somewhere else. + + if (x.isVacant() && to == null) + { + x.clearBit( Xobj.VACANT ); + + x.invalidateUser(); + x.invalidateSpecialAttr( null ); + x._locale._versionAll++; + } + else if (x.hasTextEnsureOccupancy()) + { + Cur c = x.tempCur(); + c.next(); + c.moveChars( to, -1 ); + c.release(); + } + + return; + } + + // Here I check to see if "to" is just inside x. In this case this is a no-op. Note that + // the value of x may still be vacant. + + if (to != null) + { + // Quick check of the right edge. If it is there, I need to move "to" to the left edge + // so that it is positioned at the beginning of the "moved" content. + + if (x == to._xobj && to._pos == END_POS) + { + // TODO - shuffle interior curs? + + to.moveTo( x ); + to.next( moveAttrs && hasAttrs ); + + return; + } + + // Here I need to see if to is at the left edge. I push to's current position and + // then navigate it to the left edge then compare it to the pushed position... + // Note: gotta be careful to make sure to and x are not in different locales, curs + // may not go to a different locale. + + boolean isAtLeftEdge = false; + + if (to._locale == x._locale) + { + to.push(); + to.moveTo( x ); + to.next( moveAttrs && hasAttrs ); + isAtLeftEdge = to.isAtLastPush(); + to.pop(); + } + + // TODO - shuffle interior curs? + + if (isAtLeftEdge) + return; + + // Now, after dealing with the edge condition, I can assert that to is not inside x + + assert !x.contains( to ); + + // So, at this point, I've taken case of the no-op cases and the movement of just text. + // Also, to must be occupied because I took care of the text only and nothing to move + // cases. + + assert to.getParent().isOccupied(); + } + + // TODO - did I forget to put a changeNotification here? Look more closely ... + + // Deal with the value text of x which is either on x or the last attribute of x. + // I need to get it out of the way to properly deal with the walk of the contents. + // In order to reposition "to" properly later, I need to record how many chars were moved. + + int valueMovedCch = 0; + + if (x.hasTextNoEnsureOccupancy()) + { + Cur c = x.tempCur(); + c.next(); + c.moveChars( to, -1 ); + c.release(); + + if (to != null) + to.nextChars( valueMovedCch = c._cchSrc ); + } + + // Now, walk all the contents, invalidating special attrs, reportioning cursors, + // disconnecting users and relocating to a potentially different locale. Because I moved + // the value text above, no top level attrs should have any text. + + x._locale.embedCurs(); + + Xobj firstToMove = x.walk( x, true ); + boolean sawBookmark = false; + + for ( Xobj y = firstToMove ; y != null ; y = y.walk( x, true ) ) + { + if (y._parent == x && y.isAttr()) + { + assert y._cchAfter == 0; + + if (!moveAttrs) + { + firstToMove = y._nextSibling; + continue; + } + + y.invalidateSpecialAttr( to == null ? null : to.getParent() ); + } + + for ( Cur c ; (c = y._embedded) != null ; ) + c.moveTo( x, END_POS ); + + y.disconnectUser(); + + if (to != null) + y._locale = to._locale; + + sawBookmark = sawBookmark || y._bookmarks != null; + } + + Xobj lastToMove = x._lastChild; + + // If there were any bookmarks in the tree to remove, to preserve the content that these + // bookmarks reference, move the contents to a new root. Note that I already moved the + // first piece of text above elsewhere. Note: this has the effect of keeping all of the + // contents alive even if there is one bookmark deep into the tree. I should really + // disband all the content, except for the pieces which are bookmarked. + + Cur surragateTo = null; + + if (sawBookmark && to == null) + { + surragateTo = to = x._locale.tempCur(); + to.createRoot(); + to.next(); + } + + // Perform the rest of the invalidations. If only attrs are moving, then no user + // invalidation needed. If I've move text to "to" already, no need to invalidate + // again. + + if (!lastToMove.isAttr()) + x.invalidateUser(); + + x._locale._versionAll++; + x._locale._versionSansText++; + + if (to != null && valueMovedCch == 0) + { + to.getParent().invalidateUser(); + to._locale._versionAll++; + to._locale._versionSansText++; + } + + // Remove the children and, if needed, move them + + x.removeXobjs( firstToMove, lastToMove ); + + if (to != null) + { + // To know where I should insert/append the contents to move, I need to see where "to" + // would be if there were no text after it. + + Xobj here = to._xobj; + boolean append = to._pos != 0; + + int cchRight = to.cchRight(); + + if (cchRight > 0) + { + to.push(); + to.next(); + here = to._xobj; + append = to._pos != 0; + to.pop(); + } + + // Now, I have to shuffle the text around "to" in special ways. A complication is + // the insertion of attributes. First, if I'm inserting attrs here then, logically, + // there can be no text to the left because attrs can only live after another attr + // or just inside a container. So, If attrs are being inserted and there is value + // text on the target container, I will need to move this value text to be after + // the lew last attribute. Note that this value text may already live on a current + // last attr (before the inserting). Also, I need to figure this all out before I + // move the text after "to" because this text may end up being sent to the same place + // as the containers value text when the last new node being inserted is an attr! + // Whew! + + if (firstToMove.isAttr()) + { + Xobj lastNewAttr = firstToMove; + + while ( lastNewAttr._nextSibling != null && lastNewAttr._nextSibling.isAttr() ) + lastNewAttr = lastNewAttr._nextSibling; + + // Get to's parnet now before I potentially move him with the next transfer + + Xobj y = to.getParent(); + + if (cchRight > 0) + transferChars( to._xobj, to._pos, lastNewAttr, lastNewAttr.posMax(), cchRight ); + + if (y.hasTextNoEnsureOccupancy()) + { + int p, cch; + + if (y._cchValue > 0) + { + p = 1; + cch = y._cchValue; + } + else + { + y = y.lastAttr(); + p = y.posAfter(); + cch = y._cchAfter; + } + + transferChars( y, p, lastNewAttr, lastNewAttr.posAfter(), cch ); + } + } + else if (cchRight > 0) + transferChars( to._xobj, to._pos, lastToMove, lastToMove.posMax(), cchRight ); + + // After mucking with the text, splice the new tree in + + if (append) + here.appendXobjs( firstToMove, lastToMove ); + else + here.insertXobjs( firstToMove, lastToMove ); + + // Position "to" to be at the beginning of the newly inserted contents + + to.moveTo( firstToMove ); + to.prevChars( valueMovedCch ); + } + + // If I consed up a to, release it here + + if (surragateTo != null) + surragateTo.release(); + } + + protected final Bookmark setBookmark ( Object key, Object value ) + { + assert isNormal(); + assert key != null; + + return _xobj.setBookmark( _pos, key, value ); + } + + Object getBookmark ( Object key ) + { + assert isNormal(); + assert key != null; + + for ( Bookmark b = _xobj._bookmarks ; b != null ; b = b._next ) + if (b._pos == _pos && b._key == key) + return b._value; + + return null; + } + + int firstBookmarkInChars ( Object key, int cch ) + { + assert isNormal(); + assert key != null; + assert cch > 0; + assert cch <= cchRight(); + + int d = -1; + + if (isText()) + { + for ( Bookmark b = _xobj._bookmarks ; b != null ; b = b._next ) + if (b._key == key && inChars( b, cch, false )) + d = (d == -1 || b._pos - _pos < d) ? b._pos - _pos : d; + } + + return d; + } + + int firstBookmarkInCharsLeft ( Object key, int cch ) + { + assert isNormal(); + assert key != null; + assert cch > 0; + assert cch <= cchLeft(); + + int d = -1; + + if (cchLeft() > 0) + { + Xobj x = getDenormal(); + int p = _posTemp - cch; + + for ( Bookmark b = x._bookmarks ; b != null ; b = b._next ) + if (b._key == key && x.inChars( p, b._xobj, b._pos, cch, false )) + d = (d == -1 || b._pos - p < d) ? b._pos - p : d; + } + + return d; + } + + String getCharsAsString ( int cch ) + { + assert isNormal() && _xobj != null; + + return getCharsAsString( cch, Locale.WS_PRESERVE ); + } + + String getCharsAsString ( int cch, int wsr ) + { + return _xobj.getCharsAsString( _pos, cch, wsr ); + } + + String getValueAsString ( int wsr ) + { + assert isNode(); + + return _xobj.getValueAsString( wsr ); + } + + String getValueAsString ( ) + { + assert isNode(); + assert ! hasChildren(); + + return _xobj.getValueAsString(); + } + + Object getChars ( int cch ) + { + assert isPositioned(); + + return _xobj.getChars( _pos, cch, this ); + } + + Object getFirstChars ( ) + { + assert isNode(); + + Object src = _xobj.getFirstChars(); + + _offSrc = _locale._offSrc; + _cchSrc = _locale._cchSrc; + + return src; + } + + void copyNode ( Cur to ) + { + assert to != null; + assert isNode(); + + Xobj copy = _xobj.copyNode( to._locale ); + + // TODO - in the moveNode case, I would not have to walk the tree for cursors ... optimize + + if (to.isPositioned()) + Cur.moveNode( copy, to ); + else + to.moveTo( copy ); + } + + Cur weakCur ( Object o ) + { + Cur c = _locale.weakCur( o ); + c.moveToCur( this ); + return c; + } + + Cur tempCur ( ) + { + return tempCur( null ); + } + + Cur tempCur ( String id ) + { + Cur c = _locale.tempCur( id ); + c.moveToCur( this ); + return c; + } + + private Cur tempCur ( Xobj x, int p ) + { + assert _locale == x._locale; + assert x != null || p == NO_POS; + + Cur c = _locale.tempCur(); + + if (x != null) + c.moveTo( getNormal( x, p ), _posTemp ); + + return c; + } + + // Is a cursor (c) in the chars defined by cch chars after where this Cur is positioned. + // Is inclusive on the left, and inclusive/exclusive on the right depending on the value + // of includeEnd. + + boolean inChars ( Cur c, int cch, boolean includeEnd ) + { + assert isPositioned() && isText() && cchRight() >= cch; + assert c.isNormal(); + + return _xobj.inChars( _pos, c._xobj, c._pos, cch, includeEnd ); + } + + boolean inChars ( Bookmark b, int cch, boolean includeEnd ) + { + assert isPositioned() && isText() && cchRight() >= cch; + assert b._xobj.isNormal( b._pos ); + + return _xobj.inChars( _pos, b._xobj, b._pos, cch, includeEnd ); + } + + // Can't be static because I need to communicate pos in _posTemp :-( + // I wish I had multiple return vars ... + + private Xobj getNormal ( Xobj x, int p ) + { + Xobj nx = x.getNormal( p ); + _posTemp = x._locale._posTemp; + return nx; + } + + private Xobj getDenormal ( ) + { + assert isPositioned(); + + return getDenormal( _xobj, _pos ); + } + + private Xobj getDenormal ( Xobj x, int p ) + { + Xobj dx = x.getDenormal( p ); + _posTemp = x._locale._posTemp; + return dx; + } + + // May throw IllegalArgumentException if can't change the type + + void setType ( SchemaType type ) + { + setType( type, true ); + } + + void setType ( SchemaType type, boolean complain ) + { + assert type != null; + assert isUserNode(); + + TypeStoreUser user = peekUser(); + + if (user != null && user.get_schema_type() == type) + return; + + if (isRoot()) + { + _xobj.setStableType( type ); + return; + } + + // Gotta get the parent user to make sure this type is ok here + + TypeStoreUser parentUser = _xobj.ensureParent().getUser(); + + // One may only set the type of an attribute to its 'natural' type because + // attributes cannot take advantage of the xsiType attribute. + + if (isAttr()) + { + if (complain && parentUser.get_attribute_type( getName() ) != type) + { + throw + new IllegalArgumentException( + "Can't set type of attribute to " + type.toString() ); + } + + return; + } + + assert isElem(); + + // First check to see if this type can be here sans xsi:type. + // If so, make sure there is no xsi:type + + if (parentUser.get_element_type( getName(), null ) == type) + { + removeAttr( Locale._xsiType ); + return; + } + + // If the desired type has no name, then it cannot be + // referenced via xsi:type + + QName typeName = type.getName(); + + if (typeName == null) + { + if (complain) + throw new IllegalArgumentException( "Can't set type of element, type is un-named" ); + else + return; + } + + // See if setting xsiType would result in the target type + + if (parentUser.get_element_type( getName(), typeName ) != type) + { + if (complain) + throw new IllegalArgumentException( "Can't set type of element, invalid type" ); + else + return; + } + + setAttrValueAsQName( Locale._xsiType, typeName ); + } + + void setSubstitution ( QName name, SchemaType type ) + { + setSubstitution( name, type, true ); + } + + void setSubstitution ( QName name, SchemaType type, boolean complain ) + { + assert name != null; + assert type != null; + assert isUserNode(); + + TypeStoreUser user = peekUser(); + + if (user != null && user.get_schema_type() == type && name.equals(getName())) + return; + + if (isRoot()) + { + // If this is the root node, we can't set its name, so the whole + // operation is aborted + return; + } + + // Gotta get the parent user to make sure this type is ok here + + TypeStoreUser parentUser = _xobj.ensureParent().getUser(); + + // One may only set the type of an attribute to its 'natural' type because + // attributes cannot take advantage of the xsiType attribute. + + if (isAttr()) + { + if (complain) + { + throw + new IllegalArgumentException( + "Can't use substitution with attributes"); + } + + return; + } + + assert isElem(); + + // First check to see if this type can be here sans xsi:type. + // If so, make sure there is no xsi:type + + if (parentUser.get_element_type( name, null ) == type) + { + setName( name ); + removeAttr( Locale._xsiType ); + return; + } + + // If the desired type has no name, then it cannot be + // referenced via xsi:type + + QName typeName = type.getName(); + + if (typeName == null) + { + if (complain) + throw new IllegalArgumentException( "Can't set xsi:type on element, type is un-named" ); + else + return; + } + + // See if setting xsiType would result in the target type + + if (parentUser.get_element_type( name, typeName ) != type) + { + if (complain) + throw new IllegalArgumentException( "Can't set xsi:type on element, invalid type" ); + else + return; + } + + setName( name ); + setAttrValueAsQName( Locale._xsiType, typeName ); + } + + TypeStoreUser peekUser ( ) + { + assert isUserNode(); + + return _xobj._user; + } + + XmlObject getObject ( ) + { + return isUserNode() ? (XmlObject) getUser() : null; + } + + TypeStoreUser getUser ( ) + { + assert isUserNode(); + + return _xobj.getUser(); + } + + Dom getDom ( ) + { + assert isNormal(); + assert isPositioned(); + + if (isText()) + { + int cch = cchLeft(); + + for ( CharNode cn = getCharNodes() ; ; cn = cn._next ) + if ((cch -= cn._cch) < 0) + return cn; + } + + return _xobj.getDom(); + } + + static void release ( Cur c ) + { + if (c != null) + c.release(); + } + + void release ( ) + { + if (_tempFrame >= 0) + { + if (_nextTemp != null) + _nextTemp._prevTemp = _prevTemp; + + if (_prevTemp == null) + _locale._tempFrames[ _tempFrame ] = _nextTemp; + else + _prevTemp._nextTemp = _nextTemp; + + _prevTemp = _nextTemp = null; + _tempFrame = -1; + } + + if (_state != POOLED && _state != DISPOSED) + { + // Clean up any state + + while ( _stackTop != -1 ) + popButStay(); + + clearSelection(); + + _id = null; + + // Unposition + + moveToCur( null ); + + assert isNormal(); + + assert _xobj == null; + assert _pos == NO_POS; + + // Release weak reference and attacked value + + if (_ref != null) + { + _ref.clear(); + _ref._cur = null; + } + + _ref = null; + + // Unregister and either diapose of cursor or add it back to pool + + assert _state == REGISTERED; + _locale._registered = listRemove( _locale._registered ); + + if (_locale._curPoolCount < 16) + { + _locale._curPool = listInsert( _locale._curPool ); + _state = POOLED; + _locale._curPoolCount++; + } + else + { + _locale = null; + _state = DISPOSED; + } + } + } + + boolean isOnList ( Cur head ) + { + for ( ; head != null ; head = head._next ) + if (head == this) + return true; + + return false; + } + + Cur listInsert ( Cur head ) + { + assert _next == null && _prev == null; + + if (head == null) + head = _prev = this; + else + { + _prev = head._prev; + head._prev = head._prev._next = this; + } + + return head; + } + + Cur listRemove ( Cur head ) + { + assert _prev != null && isOnList( head ); + + if (_prev == this) + head = null; + else + { + if (head == this) + head = _next; + else + _prev._next = _next; + + if (_next == null) + head._prev = _prev; + else + { + _next._prev = _prev; + _next = null; + } + } + + _prev = null; + assert _next == null; + + return head; + } + +// boolean isNormal ( Cur that ) +// { +// return isNormal() && (that == null || (_locale == that._locale && that.isNormal())); +// } + + boolean isNormal ( ) + { + if (_state == POOLED || _state == DISPOSED) + return false; + + if (_xobj == null) + return _pos == NO_POS; + + if (!_xobj.isNormal( _pos )) + return false; + + if (_state == EMBEDDED) + return isOnList( _xobj._embedded ); + + assert _state == REGISTERED; + + return isOnList( _locale._registered ); + } + + static final String LOAD_USE_LOCALE_CHAR_UTIL = "LOAD_USE_LOCALE_CHAR_UTIL"; + + static final class CurLoadContext extends LoadContext + { + CurLoadContext ( Locale l, XmlOptions options ) + { + options = XmlOptions.maskNull( options ); + + _locale = l; + + _charUtil = + options.hasOption( LOAD_USE_LOCALE_CHAR_UTIL ) + ? _locale.getCharUtil() + : CharUtil.getThreadLocalCharUtil(); + + _frontier = createDomDocumentRootXobj( _locale ); + _after = false; + + _lastXobj = _frontier; + _lastPos = 0; + + if (options.hasOption( XmlOptions.LOAD_REPLACE_DOCUMENT_ELEMENT )) + { + _replaceDocElem = (QName) options.get( XmlOptions.LOAD_REPLACE_DOCUMENT_ELEMENT ); + _discardDocElem = true; + } + + _stripWhitespace = options.hasOption( XmlOptions.LOAD_STRIP_WHITESPACE ); + _stripComments = options.hasOption( XmlOptions.LOAD_STRIP_COMMENTS ); + _stripProcinsts = options.hasOption( XmlOptions.LOAD_STRIP_PROCINSTS ); + + _substituteNamespaces = (Map) options.get( XmlOptions.LOAD_SUBSTITUTE_NAMESPACES ); + _additionalNamespaces = (Map) options.get( XmlOptions.LOAD_ADDITIONAL_NAMESPACES ); + + _locale._versionAll++; + _locale._versionSansText++; + } + + // + // Really primitive load context operations + // + + private void start ( Xobj xo ) + { + assert _frontier != null; + assert !_after || _frontier._parent != null; + + flushText(); + + if (_after) + { + _frontier = _frontier._parent; + _after = false; + } + + _frontier.appendXobj( xo ); + _frontier = xo; + + _lastXobj = xo; + _lastPos = 0; + } + + private void end ( ) + { + assert _frontier != null; + assert !_after || _frontier._parent != null; + + flushText(); + + if (_after) + _frontier = _frontier._parent; + else + _after = true; + + _lastXobj = _frontier; + _lastPos = END_POS; + } + + private void text ( Object src, int off, int cch ) + { + if (cch <= 0) + return; + + _lastXobj = _frontier; + _lastPos = _frontier._cchValue + 1; + + if (_after) + { + _lastPos += _frontier._cchAfter + 1; + + _frontier._srcAfter = + _charUtil.saveChars( + src, off, cch, + _frontier._srcAfter, _frontier._offAfter, _frontier._cchAfter ); + + _frontier._offAfter = _charUtil._offSrc; + _frontier._cchAfter = _charUtil._cchSrc; + + } + else + { + _frontier._srcValue = + _charUtil.saveChars( + src, off, cch, + _frontier._srcValue, _frontier._offValue, _frontier._cchValue ); + + _frontier._offValue = _charUtil._offSrc; + _frontier._cchValue = _charUtil._cchSrc; + } + } + + private void flushText ( ) + { + if (_stripWhitespace) + { + if (_after) + { + _frontier._srcAfter = + _charUtil.stripRight( + _frontier._srcAfter, _frontier._offAfter, _frontier._cchAfter ); + + _frontier._offAfter = _charUtil._offSrc; + _frontier._cchAfter = _charUtil._cchSrc; + } + else + { + _frontier._srcValue = + _charUtil.stripRight( + _frontier._srcValue, _frontier._offValue, _frontier._cchValue ); + + _frontier._offValue = _charUtil._offSrc; + _frontier._cchValue = _charUtil._cchSrc; + } + } + } + + private Xobj parent ( ) + { + return _after ? _frontier._parent : _frontier; + } + + private QName checkName ( QName name, boolean local ) + { + if (_substituteNamespaces != null && (!local || name.getNamespaceURI().length() > 0)) + { + String substituteUri = (String) _substituteNamespaces.get( name.getNamespaceURI() ); + + if (substituteUri != null) + name = _locale.makeQName( substituteUri, name.getLocalPart(), name.getPrefix()); + } + + return name; + } + + // + // + // + + protected void startDTD (String name, String publicId, String systemId ) + { + _doctypeName = name; + _doctypePublicId = publicId; + _doctypeSystemId = systemId; + } + + protected void endDTD ( ) + { + } + + protected void startElement ( QName name ) + { + start( createElementXobj( _locale, checkName( name, false ), parent()._name ) ); + _stripLeft = true; + } + + protected void endElement ( ) + { + assert parent().isElem(); + + end(); + _stripLeft = true; + } + + protected void xmlns ( String prefix, String uri ) + { + assert parent().isContainer(); + // BUGBUG - should assert there that there is no text before this attr + + // Namespace attrs are different than regular attrs -- I don't change their name, + // I change their value! + + if (_substituteNamespaces != null) + { + String substituteUri = (String) _substituteNamespaces.get( uri ); + + if (substituteUri != null) + uri = substituteUri; + } + + Xobj x = new Xobj.AttrXobj( _locale, _locale.createXmlns( prefix ) ); + + start( x ); + text( uri, 0, uri.length() ); + end(); + + _lastXobj = x; + _lastPos = 0; + } + + protected void attr ( QName name, String value ) + { + assert parent().isContainer(); + // BUGBUG - should assert there that there is no text before this attr + + QName parentName = _after? + _lastXobj._parent.getQName(): _lastXobj.getQName(); + boolean isId = isAttrOfTypeId(name, parentName); + + Xobj x = isId ? + new Xobj.AttrIdXobj(_locale, checkName(name, true)) : + new Xobj.AttrXobj(_locale, checkName(name, true)); + start(x); + text(value, 0, value.length()); + end(); + if (isId) + { + Cur c1 = x.tempCur(); + c1.toRoot(); + Xobj doc = c1._xobj; + c1.release(); + if (doc instanceof Xobj.DocumentXobj) + ((Xobj.DocumentXobj) doc).addIdElement(value, + x._parent.getDom()); + } + _lastXobj = x; + _lastPos = 0; + } + protected void attr ( String local, String uri, String prefix, String value ) + { + attr( _locale.makeQName( uri, local, prefix ), value ); + } + + protected void procInst ( String target, String value ) + { + if (!_stripProcinsts) + { + Xobj x = new Xobj.ProcInstXobj( _locale, target ); + + start( x ); + text( value, 0, value.length() ); + end(); + + _lastXobj = x; + _lastPos = 0; + } + _stripLeft = true; + } + + protected void comment ( String comment ) + { + if (!_stripComments) + comment( comment, 0, comment.length() ); + _stripLeft = true; + } + + protected void comment ( char[] chars, int off, int cch ) + { + if (!_stripComments) + { + comment( + _charUtil.saveChars( chars, off, cch ), + _charUtil._offSrc, _charUtil._cchSrc ); + } + _stripLeft = true; + } + + private void comment ( Object src, int off, int cch ) + { + Xobj x = new Xobj.CommentXobj( _locale ); + + start( x ); + text( src, off, cch ); + end(); + + _lastXobj = x; + _lastPos = 0; + } + + private boolean _stripLeft = true; + + private void stripText ( Object src, int off, int cch ) + { + if (_stripWhitespace) + { + // this is to avoid bug in cases like Procter & Gamble + if (_stripLeft) + { + src = _charUtil.stripLeft( src, off, cch ); + _stripLeft = false; + off = _charUtil._offSrc; + cch = _charUtil._cchSrc; + } + } + + text( src, off, cch ); + } + + protected void text ( String s ) + { + if (s == null) + return; + + stripText( s, 0, s.length() ); + } + + protected void text ( char[] src, int off, int cch ) + { + stripText( src, off, cch ); + } + + protected void bookmark ( XmlBookmark bm ) + { + _lastXobj.setBookmark( _lastPos, bm.getKey(), bm ); + } + + protected void bookmarkLastNonAttr ( XmlBookmark bm ) + { + if (_lastPos > 0 || !_lastXobj.isAttr()) + _lastXobj.setBookmark( _lastPos, bm.getKey(), bm ); + else + { + assert _lastXobj._parent != null; + + _lastXobj._parent.setBookmark( 0, bm.getKey(), bm ); + } + } + + protected void bookmarkLastAttr ( QName attrName, XmlBookmark bm ) + { + if (_lastPos == 0 && _lastXobj.isAttr()) + { + assert _lastXobj._parent != null; + + Xobj a = _lastXobj._parent.getAttr( attrName ); + + if (a != null) + a.setBookmark( 0, bm.getKey(), bm ); + } + } + + protected void lineNumber ( int line, int column, int offset ) + { + _lastXobj.setBookmark( + _lastPos, + XmlLineNumber.class, + new XmlLineNumber( line, column, offset ) ); + } + + protected void abort ( ) + { + _stripLeft = true; + while ( !parent().isRoot() ) + end(); + + finish().release(); + } + + protected Cur finish ( ) + { + flushText(); + + if (_after) + _frontier = _frontier._parent; + + assert _frontier != null && _frontier._parent == null && _frontier.isRoot(); + + Cur c = _frontier.tempCur(); + + if (!Locale.toFirstChildElement( c )) + return c; + + // See if the document element is a fragment + + boolean isFrag = Locale.isFragmentQName( c.getName() ); + + if (_discardDocElem || isFrag) + { + if (_replaceDocElem != null) + c.setName( _replaceDocElem ); + else + { + // Remove the content around the element to remove so that that content + // does not appear to have been the contents of the removed element. + + while ( c.toParent() ) + ; + + c.next(); + + while ( !c.isElem() ) + if (c.isText()) c.moveChars( null, -1 ); else c.moveNode( null ); + + assert c.isElem(); + c.skip(); + + while ( !c.isFinish() ) + if (c.isText()) c.moveChars( null, -1 ); else c.moveNode( null ); + + c.toParent(); + + c.next(); + + assert c.isElem(); + + Cur c2 = c.tempCur(); + + c.moveNodeContents( c, true ); + + c.moveToCur( c2 ); + + c2.release(); + + c.moveNode( null ); + } + + // Remove the fragment namespace decl + + if (isFrag) + { + c.moveTo( _frontier ); + + if (c.toFirstAttr()) + { + for ( ; ; ) + { + if (c.isXmlns() && c.getXmlnsUri().equals( Locale._openFragUri )) + { + c.moveNode( null ); + + if (!c.isAttr()) + break; + } + else if (!c.toNextAttr()) + break; + } + } + + c.moveTo(_frontier); + _frontier = createDomDocumentRootXobj( _locale, true ); + + Cur c2 = _frontier.tempCur(); + c2.next(); + c.moveNodeContents(c2, true); + c.moveTo(_frontier); + c2.release(); + } + } + + + if (_additionalNamespaces != null) + { + c.moveTo( _frontier ); + Locale.toFirstChildElement( c ); + Locale.applyNamespaces( c, _additionalNamespaces ); + } + + if (_doctypeName != null && (_doctypePublicId != null || _doctypeSystemId != null)) + { + XmlDocumentProperties props = Locale.getDocProps(c, true); + props.setDoctypeName(_doctypeName); + if (_doctypePublicId != null) + props.setDoctypePublicId(_doctypePublicId); + if (_doctypeSystemId != null) + props.setDoctypeSystemId(_doctypeSystemId); + } + + c.moveTo( _frontier ); + + assert c.isRoot(); + + return c; + } + + public void dump ( ) + { + _frontier.dump(); + } + + private Locale _locale; + private CharUtil _charUtil; + + private Xobj _frontier; + private boolean _after; + + private Xobj _lastXobj; + private int _lastPos; + + private boolean _discardDocElem; + private QName _replaceDocElem; + private boolean _stripWhitespace; + private boolean _stripComments; + private boolean _stripProcinsts; + private Map _substituteNamespaces; + private Map _additionalNamespaces; + + private String _doctypeName; + private String _doctypePublicId; + private String _doctypeSystemId; + } + + // + // + // + + static String kindName ( int kind ) + { + switch ( kind ) + { + case ROOT : return "ROOT"; + case ELEM : return "ELEM"; + case ATTR : return "ATTR"; + case COMMENT : return "COMMENT"; + case PROCINST : return "PROCINST"; + case TEXT : return "TEXT"; + default : return "<< Unknown Kind (" + kind + ") >>"; + } + } + + static void dump ( PrintStream o, Dom d, Object ref ) + { + } + + static void dump ( PrintStream o, Dom d ) + { + d.dump( o ); + } + + static void dump ( Dom d ) + { + dump( System.out, d ); + } + + static void dump ( Node n ) + { + dump( System.out, n ); + } + + static void dump ( PrintStream o, Node n ) + { + dump( o, (Dom) n ); + } + + void dump ( ) + { + dump( System.out, _xobj, this ); + } + + void dump ( PrintStream o ) + { + if (_xobj == null) + { + o.println( "Unpositioned xptr" ); + return; + } + + dump( o, _xobj, this ); + } + + public static void dump ( PrintStream o, Xobj xo, Object ref ) + { + if (ref == null) + ref = xo; + + while ( xo._parent != null ) + xo = xo._parent; + + dumpXobj( o, xo, 0, ref ); + + o.println(); + } + + private static void dumpCur ( PrintStream o, String prefix, Cur c, Object ref ) + { + o.print( " " ); + + if (ref == c) + o.print( "*:" ); + + o.print( prefix + (c._id == null ? "" : c._id) + "[" + c._pos + "]" ); + } + + private static void dumpCurs ( PrintStream o, Xobj xo, Object ref ) + { + for ( Cur c = xo._embedded ; c != null ; c = c._next ) + dumpCur( o, "E:", c, ref ); + + for ( Cur c = xo._locale._registered ; c != null ; c = c._next ) + { + if (c._xobj == xo) + dumpCur( o, "R:", c, ref ); + } + } + + private static void dumpBookmarks ( PrintStream o, Xobj xo, Object ref ) + { + for ( Bookmark b = xo._bookmarks ; b != null ; b = b._next ) + { + o.print( " " ); + + if (ref == b) + o.print( "*:" ); + + if (b._value instanceof XmlLineNumber) + { + XmlLineNumber l = (XmlLineNumber) b._value; + o.print( "" + "[" + b._pos + "]" ); + } + else + o.print( "" + "[" + b._pos + "]" ); + } + } + + private static void dumpCharNodes ( PrintStream o, CharNode nodes, Object ref ) + { + for ( CharNode n = nodes ; n != null ; n = n._next ) + { + o.print( " " ); + + if (n == ref) + o.print( "*" ); + + o.print( (n instanceof TextNode ? "TEXT" : "CDATA") + "[" + n._cch + "]" ); + } + } + + private static void dumpChars ( PrintStream o, Object src, int off, int cch ) + { +// CharUtil.dumpChars( o, src, off, cch ); + + o.print( "\"" ); + + String s = CharUtil.getString( src, off, cch ); + + for ( int i = 0 ; i < s.length() ; i++ ) + { + if (i== 36) + { + o.print( "..." ); + break; + } + + char ch = s.charAt( i ); + + if (ch >= 32 && ch < 127) + o.print( ch ); + else if (ch == '\n') + o.print( "\\n" ); + else if (ch == '\r') + o.print( "\\r" ); + else if (ch == '\t') + o.print( "\\t" ); + else if (ch == '\"') + o.print( "\\\"" ); + else + o.print( "<#" + ((int) ch) + ">" ); + } + + o.print( "\"" ); + } + + private static void dumpXobj ( PrintStream o, Xobj xo, int level, Object ref ) + { + if (xo == null) + return; + + if (xo == ref) + o.print( "* " ); + else + o.print( " " ); + + for ( int i = 0 ; i < level ; i++ ) + o.print( " " ); + + o.print( kindName( xo.kind() ) ); + + if (xo._name != null) + { + o.print( " " ); + + if (xo._name.getPrefix().length() > 0) + o.print( xo._name.getPrefix() + ":" ); + + o.print( xo._name.getLocalPart() ); + + if (xo._name.getNamespaceURI().length() > 0) + o.print( "@" + xo._name.getNamespaceURI() ); + } + + if (xo._srcValue != null || xo._charNodesValue != null) + { + o.print( " Value( " ); + dumpChars( o, xo._srcValue, xo._offValue, xo._cchValue ); + dumpCharNodes( o, xo._charNodesValue, ref ); + o.print( " )" ); + } + + if (xo._user != null) + o.print( " (USER)" ); + + if (xo.isVacant()) + o.print( " (VACANT)" ); + + if (xo._srcAfter != null || xo._charNodesAfter != null) + { + o.print( " After( " ); + dumpChars( o, xo._srcAfter, xo._offAfter, xo._cchAfter ); + dumpCharNodes( o, xo._charNodesAfter, ref ); + o.print( " )" ); + } + + dumpCurs( o, xo, ref ); + dumpBookmarks( o, xo, ref ); + + String className = xo.getClass().getName(); + + int i = className.lastIndexOf( '.' ); + + if (i > 0) + { + className = className.substring( i + 1 ); + + i = className.lastIndexOf( '$' ); + + if (i > 0) + className = className.substring( i + 1 ); + } + + o.print( " (" ); + o.print( className ); + o.print( ")" ); + + o.println(); + + for ( xo = xo._firstChild ; xo != null ; xo = xo._nextSibling ) + dumpXobj( o, xo, level + 1, ref ); + } + + void setId ( String id ) + { + _id = id; + } + + // + // + // + + Locale _locale; + + Xobj _xobj; + int _pos; + + int _state; + + String _id; + + Cur _nextTemp; + Cur _prevTemp; + int _tempFrame; + + Cur _next; + Cur _prev; + + Locale.Ref _ref; + + int _stackTop; + + int _selectionFirst; + int _selectionN; + int _selectionLoc; + int _selectionCount; + + private int _posTemp; + + int _offSrc; + int _cchSrc; +} \ No newline at end of file diff --git a/xmlbeans/src/store/org/apache/xmlbeans/impl/store/Cursor.java b/xmlbeans/src/store/org/apache/xmlbeans/impl/store/Cursor.java new file mode 100755 index 000000000..fc3708f1a --- /dev/null +++ b/xmlbeans/src/store/org/apache/xmlbeans/impl/store/Cursor.java @@ -0,0 +1,4377 @@ +/* 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.store; + +import java.util.ArrayList; + +import java.io.PrintStream; + +import javax.xml.namespace.QName; + +import javax.xml.stream.XMLStreamReader; + +import org.apache.xmlbeans.xml.stream.XMLInputStream; + +import org.apache.xmlbeans.SchemaTypeLoader; +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.XmlCursor; +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.XmlOptions; +import org.apache.xmlbeans.XmlDocumentProperties; + +import org.apache.xmlbeans.impl.common.XMLChar; +import org.apache.xmlbeans.impl.common.GlobalLock; + +import java.util.Map; +import java.util.Collection; + +import java.io.InputStream; +import java.io.OutputStream; +import java.io.Reader; +import java.io.Writer; +import java.io.File; +import java.io.IOException; +import java.io.FileOutputStream; + +import org.w3c.dom.Node; + +import org.xml.sax.ContentHandler; +import org.xml.sax.ext.LexicalHandler; +import org.xml.sax.SAXException; + +import org.apache.xmlbeans.impl.store.Saver.TextSaver; +import org.apache.xmlbeans.impl.store.Locale.ChangeListener; +import org.apache.xmlbeans.impl.store.Path.PathEngine; + +public final class Cursor implements XmlCursor, ChangeListener { + static final int ROOT = Cur.ROOT; + static final int ELEM = Cur.ELEM; + static final int ATTR = Cur.ATTR; + static final int COMMENT = Cur.COMMENT; + static final int PROCINST = Cur.PROCINST; + static final int TEXT = Cur.TEXT; + + Cursor(Xobj x, int p) { + _cur = x._locale.weakCur(this); + _cur.moveTo(x, p); + _currentSelection = -1; + } + + Cursor(Cur c) { + this(c._xobj, c._pos); + } + + private static boolean isValid(Cur c) { + if (c.kind() <= 0) { + c.push(); + + if (c.toParentRaw()) { + int pk = c.kind(); + + if (pk == COMMENT || pk == PROCINST || pk == ATTR) + return false; + } + + c.pop(); + } + + return true; + } + + private boolean isValid() { + return isValid(_cur); + } + + Locale locale() { + return _cur._locale; + } + + Cur tempCur() { + return _cur.tempCur(); + } + + public void dump(PrintStream o) { + _cur.dump(o); + } + + static void validateLocalName(QName name) { + if (name == null) + throw new IllegalArgumentException("QName is null"); + + validateLocalName(name.getLocalPart()); + } + + static void validateLocalName(String name) { + if (name == null) + throw new IllegalArgumentException("Name is null"); + + if (name.length() == 0) + throw new IllegalArgumentException("Name is empty"); + + if (!XMLChar.isValidNCName(name)) + throw new IllegalArgumentException("Name is not valid"); + } + + static void validatePrefix(String name) { + if (name == null) + throw new IllegalArgumentException("Prefix is null"); + + if (name.length() == 0) + throw new IllegalArgumentException("Prefix is empty"); + + if (Locale.beginsWithXml(name)) + throw new IllegalArgumentException("Prefix begins with 'xml'"); + + if (!XMLChar.isValidNCName(name)) + throw new IllegalArgumentException("Prefix is not valid"); + } + + private static void complain(String msg) { + throw new IllegalArgumentException(msg); + } + + private void checkInsertionValidity(Cur that) { + int thatKind = that.kind(); + + if (thatKind < 0) + complain("Can't move/copy/insert an end token."); + + if (thatKind == ROOT) + complain("Can't move/copy/insert a whole document."); + + int thisKind = _cur.kind(); + + if (thisKind == ROOT) + complain("Can't insert before the start of the document."); + + if (thatKind == ATTR) { + _cur.push(); + _cur.prevWithAttrs(); + int pk = _cur.kind(); + _cur.pop(); + + if (pk != ELEM && pk != ROOT && pk != -ATTR) { + complain("Can only insert attributes before other attributes or after containers."); + } + } + + if (thisKind == ATTR && thatKind != ATTR) + complain("Can only insert attributes before other attributes or after containers."); + } + + private void insertNode(Cur that, String text) { + assert !that.isRoot(); + assert that.isNode(); + assert isValid(that); + assert isValid(); + + if (text != null && text.length() > 0) { + that.next(); + that.insertString(text); + that.toParent(); + } + + checkInsertionValidity(that); + + that.moveNode(_cur); + + _cur.toEnd(); + _cur.nextWithAttrs(); + } + + // + // + // + + // TODO - deal with cursors moving to other documents upon release? + // Can I move the ref from one q to another? If not I will have to + // change from a phantom ref to a soft/weak ref so I can know what + // to do when I dequeue from the old q. + + public void _dispose() { + _cur.release(); + _cur = null; + } + + public XmlCursor _newCursor() { + return new Cursor(_cur); + } + + public QName _getName() { + // TODO - consider taking this out of the gateway + + switch (_cur.kind()) { + case ATTR: + + if (_cur.isXmlns()) { + return + _cur._locale.makeQNameNoCheck(_cur.getXmlnsUri(), _cur.getXmlnsPrefix()); + } + + // Fall thru + + case ELEM: + case PROCINST: + return _cur.getName(); + } + + return null; + } + + public void _setName(QName name) { + if (name == null) + throw new IllegalArgumentException("Name is null"); + + switch (_cur.kind()) { + case ELEM: + case ATTR: + { + validateLocalName(name.getLocalPart()); + break; + } + + case PROCINST: + { + validatePrefix(name.getLocalPart()); + + if (name.getNamespaceURI().length() > 0) + throw new IllegalArgumentException("Procinst name must have no URI"); + + if (name.getPrefix().length() > 0) + throw new IllegalArgumentException("Procinst name must have no prefix"); + + break; + } + + default : + throw + new IllegalStateException("Can set name on element, atrtribute and procinst only"); + } + + _cur.setName(name); + } + + public TokenType _currentTokenType() { + assert isValid(); + + switch (_cur.kind()) { + case ROOT: + return TokenType.STARTDOC; + case -ROOT: + return TokenType.ENDDOC; + case ELEM: + return TokenType.START; + case -ELEM: + return TokenType.END; + case TEXT: + return TokenType.TEXT; + case ATTR: + return _cur.isXmlns() ? TokenType.NAMESPACE : TokenType.ATTR; + case COMMENT: + return TokenType.COMMENT; + case PROCINST: + return TokenType.PROCINST; + + default : + throw new IllegalStateException(); + } + } + + public boolean _isStartdoc() { + //return _currentTokenType().isStartdoc(); + assert isValid(); + return _cur.isRoot(); + } + + public boolean _isEnddoc() { + //return _currentTokenType().isEnddoc(); + assert isValid(); + return _cur.isEndRoot(); + } + + public boolean _isStart() { + //return _currentTokenType().isStart(); + assert isValid(); + return _cur.isElem(); + } + + public boolean _isEnd() { + //return _currentTokenType().isEnd(); + assert isValid(); + return _cur.isEnd(); + } + + public boolean _isText() { + //return _currentTokenType().isText(); + assert isValid(); + return _cur.isText(); + } + + public boolean _isAttr() { + //return _currentTokenType().isAttr(); + assert isValid(); + return _cur.isNormalAttr(); + } + + public boolean _isNamespace() { + //return _currentTokenType().isNamespace(); + assert isValid(); + return _cur.isXmlns(); + } + + public boolean _isComment() { + //return _currentTokenType().isComment(); + assert isValid(); + return _cur.isComment(); + } + + public boolean _isProcinst() { + //return _currentTokenType().isProcinst(); + assert isValid(); + return _cur.isProcinst(); + } + + public boolean _isContainer() { + //return _currentTokenType().isContainer(); + assert isValid(); + return _cur.isContainer(); + } + + public boolean _isFinish() { + //return _currentTokenType().isFinish(); + assert isValid(); + return _cur.isFinish(); + } + + public boolean _isAnyAttr() { + //return _currentTokenType().isAnyAttr(); + assert isValid(); + return _cur.isAttr(); + } + + public TokenType _toNextToken() { + assert isValid(); + + switch (_cur.kind()) { + case ROOT: + case ELEM: + { + if (!_cur.toFirstAttr()) + _cur.next(); + + break; + } + + case ATTR: + { + if (!_cur.toNextSibling()) { + _cur.toParent(); + _cur.next(); + } + + break; + } + + case COMMENT: + case PROCINST: + { + _cur.skip(); + break; + } + + default : + { + if (!_cur.next()) + return TokenType.NONE; + + break; + } + } + + return _currentTokenType(); + } + + public TokenType _toPrevToken() { + assert isValid(); + + // This method is different than the Cur version of prev in a few ways. First, + // Cursor iterates over attrs inline with all the other content. Cur will skip attrs, or + // if the Cur in in attrs, it will not jump out of attrs. Also, if moving backwards and + // text is to the left and right, Cur will move to the beginning of that text, while + // Cursor will move further so that the token type to the right is not text. + + boolean wasText = _cur.isText(); + + if (!_cur.prev()) { + assert _cur.isRoot() || _cur.isAttr(); + + if (_cur.isRoot()) + return TokenType.NONE; + + _cur.toParent(); + } else { + int k = _cur.kind(); + + if (k < 0 && (k == -COMMENT || k == -PROCINST || k == -ATTR)) + _cur.toParent(); + else if (_cur.isContainer()) + _cur.toLastAttr(); + else if (wasText && _cur.isText()) + return _toPrevToken(); + } + + return _currentTokenType(); + } + + public Object _monitor() { + // TODO - some of these methods need not be protected by a + // gatway. This is one of them. Inline this. + + return _cur._locale; + } + + public boolean _toParent() { + Cur c = _cur.tempCur(); + + if (!c.toParent()) + return false; + + _cur.moveToCur(c); + + c.release(); + + return true; + } + + private static final class ChangeStampImpl implements ChangeStamp { + ChangeStampImpl(Locale l) { + _locale = l; + _versionStamp = _locale.version(); + } + + public boolean hasChanged() { + return _versionStamp != _locale.version(); + } + + private final Locale _locale; + private final long _versionStamp; + } + + public ChangeStamp _getDocChangeStamp() { + return new ChangeStampImpl(_cur._locale); + } + + // + // These simply delegate to the version of the method which takes XmlOptions + // + + /** + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public XMLInputStream _newXMLInputStream() { + return _newXMLInputStream(null); + } + + public XMLStreamReader _newXMLStreamReader() { + return _newXMLStreamReader(null); + } + + public Node _newDomNode() { + return _newDomNode(null); + } + + public InputStream _newInputStream() { + return _newInputStream(null); + } + + public String _xmlText() { + return _xmlText(null); + } + + public Reader _newReader() { + return _newReader(null); + } + + public void _save(File file) throws IOException { + _save(file, null); + } + + public void _save(OutputStream os) throws IOException { + _save(os, null); + } + + public void _save(Writer w) throws IOException { + _save(w, null); + } + + public void _save(ContentHandler ch, LexicalHandler lh) throws SAXException { + _save(ch, lh, null); + } + + // + // + // + + public XmlDocumentProperties _documentProperties() { + return Locale.getDocProps(_cur, true); + } + + public XMLStreamReader _newXMLStreamReader(XmlOptions options) { + return Jsr173.newXmlStreamReader(_cur, options); + } + + /** + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public XMLInputStream _newXMLInputStream(XmlOptions options) { + return new Saver.XmlInputStreamImpl(_cur, options); + } + + public String _xmlText(XmlOptions options) { + assert isValid(); + + return new TextSaver(_cur, options, null).saveToString(); + } + + public InputStream _newInputStream(XmlOptions options) { + return new Saver.InputStreamSaver(_cur, options); + } + + public Reader _newReader(XmlOptions options) { + return new Saver.TextReader(_cur, options); + } + + public void _save(ContentHandler ch, LexicalHandler lh, XmlOptions options) + throws SAXException { + new Saver.SaxSaver(_cur, options, ch, lh); + } + + public void _save(File file, XmlOptions options) throws IOException { + if (file == null) + throw new IllegalArgumentException("Null file specified"); + + OutputStream os = new FileOutputStream(file); + + try { + _save(os, options); + } finally { + os.close(); + } + } + + public void _save(OutputStream os, XmlOptions options) throws IOException { + if (os == null) + throw new IllegalArgumentException("Null OutputStream specified"); + + InputStream is = _newInputStream(options); + + try { + byte[] bytes = new byte[8192]; + + for (; ;) { + int n = is.read(bytes); + + if (n < 0) + break; + + os.write(bytes, 0, n); + } + } finally { + is.close(); + } + } + + public void _save(Writer w, XmlOptions options) throws IOException { + if (w == null) + throw new IllegalArgumentException("Null Writer specified"); + + if (options != null && options.hasOption( XmlOptions.SAVE_OPTIMIZE_FOR_SPEED )) + { + Saver.OptimizedForSpeedSaver.save(_cur, w); //ignore all other options + return; + } + + Reader r = _newReader(options); + + try { + char[] chars = new char[8192]; + + for (; ;) { + int n = r.read(chars); + + if (n < 0) + break; + + w.write(chars, 0, n); + } + } finally { + r.close(); + } + } + + public Node _getDomNode() { + return (Node) _cur.getDom(); + } + + private boolean isDomFragment() { + if (!isStartdoc()) + return true; + + boolean seenElement = false; + + XmlCursor c = newCursor(); + int token = c.toNextToken().intValue(); + + try { + LOOP: for (; ;) { + SWITCH: switch (token) { + case TokenType.INT_START: + if (seenElement) + return true; + seenElement = true; + token = c.toEndToken().intValue(); + break SWITCH; + + case TokenType.INT_TEXT: + if (!Locale.isWhiteSpace(c.getChars())) + return true; + token = c.toNextToken().intValue(); + break SWITCH; + + case TokenType.INT_NONE: + case TokenType.INT_ENDDOC: + break LOOP; + + case TokenType.INT_ATTR: + case TokenType.INT_NAMESPACE: + return true; + + case TokenType.INT_END: + case TokenType.INT_COMMENT: + case TokenType.INT_PROCINST: + token = c.toNextToken().intValue(); + break SWITCH; + + case TokenType.INT_STARTDOC: + assert false; + break LOOP; + } + } + } finally { + c.dispose(); + } + + return !seenElement; + } + + private static final class DomSaver extends Saver { + DomSaver(Cur c, boolean isFrag, XmlOptions options) { + super(c, options); + + if (c.isUserNode()) + _type = c.getUser().get_schema_type(); + + _stl = c._locale._schemaTypeLoader; + _options = options; + _isFrag = isFrag; + } + + Node saveDom() { + Locale l = Locale.getLocale(_stl, _options); + + l.enter(); + + try { + _nodeCur = l.getCur(); // Not weak or temp + + // Build the tree + + while (process()) + ; + + // Set the type + + while (!_nodeCur.isRoot()) + _nodeCur.toParent(); + + if (_type != null) + _nodeCur.setType(_type); + + Node node = (Node) _nodeCur.getDom(); + + _nodeCur.release(); + + _nodeCur = null; + + return node; + } finally { + l.exit(); + } + } + + protected boolean emitElement(SaveCur c, ArrayList attrNames, ArrayList attrValues) { + // If there was text or comments before the frag element, I will loose them -- oh well + // Also, I will lose any attributes and namesapces on the fragment -- DOM can + // have attrs in fragments + + if (Locale.isFragmentQName(c.getName())) + _nodeCur.moveTo(null, Cur.NO_POS); + + ensureDoc(); + + _nodeCur.createElement(getQualifiedName(c, c.getName())); + _nodeCur.next(); + + for (iterateMappings(); hasMapping(); nextMapping()) { + _nodeCur.createAttr(_nodeCur._locale.createXmlns(mappingPrefix())); + _nodeCur.next(); + _nodeCur.insertString(mappingUri()); + _nodeCur.toParent(); + _nodeCur.skipWithAttrs(); + } + + for (int i = 0; i < attrNames.size(); i++) { + _nodeCur.createAttr(getQualifiedName(c, (QName) attrNames.get(i))); + _nodeCur.next(); + _nodeCur.insertString((String) attrValues.get(i)); + _nodeCur.toParent(); + _nodeCur.skipWithAttrs(); + } + + return false; + } + + protected void emitFinish(SaveCur c) { + if (!Locale.isFragmentQName(c.getName())) { + assert _nodeCur.isEnd(); + _nodeCur.next(); + } + } + + protected void emitText(SaveCur c) { + ensureDoc(); + + Object src = c.getChars(); + + if (c._cchSrc > 0) { + _nodeCur.insertChars(src, c._offSrc, c._cchSrc); + _nodeCur.next(); + } + } + + protected void emitComment(SaveCur c) { + ensureDoc(); + + _nodeCur.createComment(); + emitTextValue(c); + _nodeCur.skip(); + } + + protected void emitProcinst(SaveCur c) { + ensureDoc(); + + _nodeCur.createProcinst(c.getName().getLocalPart()); + emitTextValue(c); + _nodeCur.skip(); + } + + protected void emitDocType(String docTypeName, String publicId, String systemId) { + ensureDoc(); + + XmlDocumentProperties props = Locale.getDocProps(_nodeCur, true); + props.setDoctypeName(docTypeName); + props.setDoctypePublicId(publicId); + props.setDoctypeSystemId(systemId); + } + + protected void emitStartDoc(SaveCur c) { + ensureDoc(); + } + + protected void emitEndDoc ( SaveCur c ) + { + } + + private QName getQualifiedName(SaveCur c, QName name) { + String uri = name.getNamespaceURI(); + + String prefix = uri.length() > 0 ? getUriMapping(uri) : ""; + + if (prefix.equals(name.getPrefix())) + return name; + + return _nodeCur._locale.makeQName(uri, name.getLocalPart(), prefix); + } + + private void emitTextValue(SaveCur c) { + c.push(); + c.next(); + + if (c.isText()) { + _nodeCur.next(); + _nodeCur.insertChars(c.getChars(), c._offSrc, c._cchSrc); + _nodeCur.toParent(); + } + + c.pop(); + } + + private void ensureDoc() { + if (!_nodeCur.isPositioned()) { + if (_isFrag) + _nodeCur.createDomDocFragRoot(); + else + _nodeCur.createDomDocumentRoot(); + + _nodeCur.next(); + } + } + + private Cur _nodeCur; + private SchemaType _type; + private SchemaTypeLoader _stl; + private XmlOptions _options; + private boolean _isFrag; + } + + public Node _newDomNode(XmlOptions options) { + // Must ignore inner options for compat with v1. + + if (XmlOptions.hasOption(options, XmlOptions.SAVE_INNER)) { + options = new XmlOptions(options); + options.remove(XmlOptions.SAVE_INNER); + } + + return new DomSaver(_cur, isDomFragment(), options).saveDom(); + } + + public boolean _toCursor(Cursor other) { + assert _cur._locale == other._cur._locale; + + _cur.moveToCur(other._cur); + + return true; + } + + public void _push() { + _cur.push(); + } + + public boolean _pop() { + return _cur.pop(); + } + + public void notifyChange() { + // Force any path to get exausted, cursor may be disposed, but still be on the notification + // list. + + if (_cur != null) + _getSelectionCount(); + } + + public void setNextChangeListener(ChangeListener listener) { + _nextChangeListener = listener; + } + + public ChangeListener getNextChangeListener() { + return _nextChangeListener; + } + + public void _selectPath(String path) { + _selectPath(path, null); + } + + public void _selectPath(String pathExpr, XmlOptions options) { + _clearSelections(); + + assert _pathEngine == null; + + _pathEngine = Path.getCompiledPath(pathExpr, options).execute(_cur, options); + + _cur._locale.registerForChange(this); + } + + public boolean _hasNextSelection() { + int curr = _currentSelection; + push(); + + try { + return _toNextSelection(); + } finally { + _currentSelection = curr; + pop(); + } + } + + public boolean _toNextSelection() { + return _toSelection(_currentSelection + 1); + } + + public boolean _toSelection(int i) { + if (i < 0) + return false; + + while (i >= _cur.selectionCount()) { + if (_pathEngine == null) + return false; + + if (!_pathEngine.next(_cur)) { + _pathEngine.release(); + _pathEngine = null; + + return false; + } + } + + _cur.moveToSelection(_currentSelection = i); + + return true; + } + + public int _getSelectionCount() { + // Should never get to MAX_VALUE selection index, so, state should not change + _toSelection(Integer.MAX_VALUE); + + return _cur.selectionCount(); + } + + public void _addToSelection() { + _toSelection(Integer.MAX_VALUE); + + _cur.addToSelection(); + } + + public void _clearSelections() { + if (_pathEngine != null) { + _pathEngine.release(); + _pathEngine = null; + } + + _cur.clearSelection(); + + _currentSelection = -1; + } + + public String _namespaceForPrefix(String prefix) { + if (!_cur.isContainer()) + throw new IllegalStateException("Not on a container"); + + return _cur.namespaceForPrefix(prefix, true); + } + + public String _prefixForNamespace(String ns) { + if (ns == null || ns.length() == 0) + throw new IllegalArgumentException("Must specify a namespace"); + +// Note: I loosen this requirement in v2, can call this from anywhere +// if (!_cur.isContainer()) +// throw new IllegalStateException( "Not on a container" ); + + return _cur.prefixForNamespace(ns, null, true); + } + + public void _getAllNamespaces(Map addToThis) { + if (!_cur.isContainer()) + throw new IllegalStateException("Not on a container"); + + if (addToThis != null) + Locale.getAllNamespaces(_cur, addToThis); + } + + public XmlObject _getObject() { + return _cur.getObject(); + } + + public TokenType _prevTokenType() { + _cur.push(); + + TokenType tt = _toPrevToken(); + + _cur.pop(); + + return tt; + } + + public boolean _hasNextToken() { + //return _cur.kind() != -ROOT; + return _cur._pos!=Cur.END_POS || _cur._xobj.kind()!=ROOT; + } + + public boolean _hasPrevToken() { + return _cur.kind() != ROOT; + } + + public TokenType _toFirstContentToken() { + if (!_cur.isContainer()) + return TokenType.NONE; + + _cur.next(); + + return currentTokenType(); + } + + public TokenType _toEndToken() { + if (!_cur.isContainer()) + return TokenType.NONE; + + _cur.toEnd(); + + return currentTokenType(); + } + + public boolean _toChild(String local) { + return _toChild(null, local); + } + + public boolean _toChild(QName name) { + return _toChild(name, 0); + } + + public boolean _toChild(int index) { + return _toChild(null, index); + } + + public boolean _toChild(String uri, String local) { + validateLocalName(local); + + return _toChild(_cur._locale.makeQName(uri, local), 0); + } + + public boolean _toChild(QName name, int index) { + return Locale.toChild(_cur, name, index); + } + + public int _toNextChar(int maxCharacterCount) { + return _cur.nextChars(maxCharacterCount); + } + + public int _toPrevChar(int maxCharacterCount) { + return _cur.prevChars(maxCharacterCount); + } + + public boolean _toPrevSibling() { + return Locale.toPrevSiblingElement(_cur); + } + + public boolean _toLastChild() { + return Locale.toLastChildElement(_cur); + } + + public boolean _toFirstChild() { + return Locale.toFirstChildElement(_cur); + } + + public boolean _toNextSibling(String name) { + return _toNextSibling(new QName(name)); + } + + public boolean _toNextSibling(String uri, String local) { + validateLocalName(local); + + return _toNextSibling(_cur._locale._qnameFactory.getQName(uri, local)); + } + + public boolean _toNextSibling(QName name) { + _cur.push(); + + while (___toNextSibling()) { + if (_cur.getName().equals(name)) { + _cur.popButStay(); + return true; + } + } + + _cur.pop(); + + return false; + } + + public boolean _toFirstAttribute() { + return _cur.isContainer() && Locale.toFirstNormalAttr(_cur); + } + + public boolean _toLastAttribute() { + if (_cur.isContainer()) { + _cur.push(); + _cur.push(); + + boolean foundAttr = false; + + while (_cur.toNextAttr()) { + if (_cur.isNormalAttr()) { + _cur.popButStay(); + _cur.push(); + foundAttr = true; + } + } + + _cur.pop(); + + if (foundAttr) { + _cur.popButStay(); + return true; + } + + _cur.pop(); + } + + return false; + } + + public boolean _toNextAttribute() { + return _cur.isAttr() && Locale.toNextNormalAttr(_cur); + } + + public boolean _toPrevAttribute() { + return _cur.isAttr() && Locale.toPrevNormalAttr(_cur); + } + + public String _getAttributeText(QName attrName) { + if (attrName == null) + throw new IllegalArgumentException("Attr name is null"); + + if (!_cur.isContainer()) + return null; + + return _cur.getAttrValue(attrName); + } + + public boolean _setAttributeText(QName attrName, String value) { + if (attrName == null) + throw new IllegalArgumentException("Attr name is null"); + + validateLocalName(attrName.getLocalPart()); + + if (!_cur.isContainer()) + return false; + + _cur.setAttrValue(attrName, value); + + return true; + } + + public boolean _removeAttribute(QName attrName) { + if (attrName == null) + throw new IllegalArgumentException("Attr name is null"); + + if (!_cur.isContainer()) + return false; + + return _cur.removeAttr(attrName); + } + + public String _getTextValue() { + if (_cur.isText()) + return _getChars(); + + if (!_cur.isNode()) { + throw new IllegalStateException("Can't get text value, current token can have no text value"); + } + + return _cur.hasChildren() ? Locale.getTextValue(_cur) : _cur.getValueAsString(); + } + + public int _getTextValue(char[] chars, int offset, int max) { + if (_cur.isText()) + return _getChars(chars, offset, max); + + if (chars == null) + throw new IllegalArgumentException("char buffer is null"); + + if (offset < 0) + throw new IllegalArgumentException("offset < 0"); + + if (offset >= chars.length) + throw new IllegalArgumentException("offset off end"); + + if (max < 0) + max = Integer.MAX_VALUE; + + if (offset + max > chars.length) + max = chars.length - offset; + + if (!_cur.isNode()) { + throw new IllegalStateException("Can't get text value, current token can have no text value"); + } + + // If there are no children (hopefully the common case), I can get the text faster. + + if (_cur.hasChildren()) + return Locale.getTextValue(_cur, Locale.WS_PRESERVE, chars, offset, max); + + // Fast way + + Object src = _cur.getFirstChars(); + + if (_cur._cchSrc > max) + _cur._cchSrc = max; + + if (_cur._cchSrc <= 0) + return 0; + + CharUtil.getChars(chars, offset, src, _cur._offSrc, _cur._cchSrc); + + return _cur._cchSrc; + } + + private void setTextValue(Object src, int off, int cch) { + if (!_cur.isNode()) { + throw new IllegalStateException("Can't set text value, current token can have no text value"); + } + + _cur.moveNodeContents(null, false); + _cur.next(); + _cur.insertChars(src, off, cch); + _cur.toParent(); + } + + public void _setTextValue(String text) { + if (text == null) + text = ""; + + setTextValue(text, 0, text.length()); + } + + public void _setTextValue(char[] sourceChars, int offset, int length) { + if (length < 0) + throw new IndexOutOfBoundsException("setTextValue: length < 0"); + + if (sourceChars == null) { + if (length > 0) + throw new IllegalArgumentException("setTextValue: sourceChars == null"); + + setTextValue(null, 0, 0); + + return; + } + + if (offset < 0 || offset >= sourceChars.length) + throw new IndexOutOfBoundsException("setTextValue: offset out of bounds"); + + if (offset + length > sourceChars.length) + length = sourceChars.length - offset; + + CharUtil cu = _cur._locale.getCharUtil(); + + setTextValue(cu.saveChars(sourceChars, offset, length), cu._offSrc, cu._cchSrc); + } + + public String _getChars() { + return _cur.getCharsAsString(-1); + } + + public int _getChars(char[] buf, int off, int cch) { + int cchRight = _cur.cchRight(); + + if (cch < 0 || cch > cchRight) + cch = cchRight; + + if (buf == null || off >= buf.length) + return 0; + + if (buf.length - off < cch) + cch = buf.length - off; + + Object src = _cur.getChars(cch); + + CharUtil.getChars(buf, off, src, _cur._offSrc, _cur._cchSrc); + + return _cur._cchSrc; + } + + public void _toStartDoc() { +// while (_cur.toParent()) +// ; + _cur.toRoot(); + } + + public void _toEndDoc() { + _toStartDoc(); + + _cur.toEnd(); + } + + public int _comparePosition(Cursor other) { + int s = _cur.comparePosition(other._cur); + + if (s == 2) + throw new IllegalArgumentException("Cursors not in same document"); + + assert s >= -1 && s <= 1; + + return s; + } + + public boolean _isLeftOf(Cursor other) { + return _comparePosition(other) < 0; + } + + public boolean _isAtSamePositionAs(Cursor other) { + return _cur.isSamePos(other._cur); + } + + public boolean _isRightOf(Cursor other) { + return _comparePosition(other) > 0; + } + + public XmlCursor _execQuery(String query) { + return _execQuery(query, null); + } + + public XmlCursor _execQuery(String query, XmlOptions options) { + checkThisCursor(); + return Query.cursorExecQuery(_cur,query,options); + + } + + + public boolean _toBookmark(XmlBookmark bookmark) { + if (bookmark == null || !(bookmark._currentMark instanceof Xobj.Bookmark)) + return false; + + Xobj.Bookmark m = (Xobj.Bookmark) bookmark._currentMark; + + if (m._xobj == null || m._xobj._locale != _cur._locale) + return false; + + _cur.moveTo(m._xobj, m._pos); + + return true; + } + + public XmlBookmark _toNextBookmark(Object key) { + if (key == null) + return null; + + int cch; + + _cur.push(); + + for (; ;) { + // Move a minimal amount. If at text, move to a potential bookmark in the text. + + if ((cch = _cur.cchRight()) > 1) { + _cur.nextChars(1); + _cur.nextChars((cch = _cur.firstBookmarkInChars(key, cch - 1)) >= 0 ? cch : -1); + } else if (_toNextToken().isNone()) { + _cur.pop(); + return null; + } + + XmlBookmark bm = getBookmark(key, _cur); + + if (bm != null) { + _cur.popButStay(); + return bm; + } + + if (_cur.kind() == -ROOT) { + _cur.pop(); + return null; + } + } + } + + public XmlBookmark _toPrevBookmark(Object key) { + if (key == null) + return null; + + int cch; + + _cur.push(); + + for (; ;) { + // Move a minimal amount. If at text, move to a potential bookmark in the text. + + if ((cch = _cur.cchLeft()) > 1) { + _cur.prevChars(1); + + _cur.prevChars((cch = _cur.firstBookmarkInCharsLeft(key, cch - 1)) >= 0 ? cch : -1); + } else if (cch == 1) { + // _toPrevToken will not skip to the beginning of the text, it will go further + // so that the token to the right is not text. I need to simply skip to + // the beginning of the text ... + + _cur.prevChars(1); + } else if (_toPrevToken().isNone()) { + _cur.pop(); + return null; + } + + XmlBookmark bm = getBookmark(key, _cur); + + if (bm != null) { + _cur.popButStay(); + return bm; + } + + if (_cur.kind() == ROOT) { + _cur.pop(); + return null; + } + } + } + + public void _setBookmark(XmlBookmark bookmark) { + if (bookmark != null) { + if (bookmark.getKey() == null) + throw new IllegalArgumentException("Annotation key is null"); + + // TODO - I Don't do weak bookmarks yet ... perhaps I'll never do them .... + + bookmark._currentMark = _cur.setBookmark(bookmark.getKey(), bookmark); + } + } + + static XmlBookmark getBookmark(Object key, Cur c) { + // TODO - I Don't do weak bookmarks yet ... + + if (key == null) + return null; + + Object bm = c.getBookmark(key); + + return bm != null && bm instanceof XmlBookmark ? (XmlBookmark) bm : null; + } + + public XmlBookmark _getBookmark(Object key) { + return key == null ? null : getBookmark(key, _cur); + } + + public void _clearBookmark(Object key) { + if (key != null) + _cur.setBookmark(key, null); + } + + public void _getAllBookmarkRefs(Collection listToFill) { + if (listToFill != null) { + for (Xobj.Bookmark b = _cur._xobj._bookmarks; b != null; b = b._next) + if (b._value instanceof XmlBookmark) + listToFill.add(b._value); + } + } + + public boolean _removeXml() { + if (_cur.isRoot()) + throw new IllegalStateException("Can't remove a whole document."); + + if (_cur.isFinish()) + return false; + + assert _cur.isText() || _cur.isNode(); + + if (_cur.isText()) + _cur.moveChars(null, -1); + else + _cur.moveNode(null); + + return true; + } + + public boolean _moveXml(Cursor to) { + to.checkInsertionValidity(_cur); + + // Check for a no-op + + if (_cur.isText()) { + int cchRight = _cur.cchRight(); + + assert cchRight > 0; + + if (_cur.inChars(to._cur, cchRight, true)) + return false; + + _cur.moveChars(to._cur, cchRight); + + to._cur.nextChars(cchRight); + + return true; + } + + if (_cur.contains(to._cur)) + return false; + + // Make a cur which will float to the right of the insertion + + Cur c = to.tempCur(); + + _cur.moveNode(to._cur); + + to._cur.moveToCur(c); + + c.release(); + + return true; + } + + public boolean _copyXml(Cursor to) { + to.checkInsertionValidity(_cur); + + assert _cur.isText() || _cur.isNode(); + + Cur c = to.tempCur(); + + if (_cur.isText()) + to._cur.insertChars(_cur.getChars(-1), _cur._offSrc, _cur._cchSrc); + else + _cur.copyNode(to._cur); + + to._cur.moveToCur(c); + + c.release(); + + return true; + } + + public boolean _removeXmlContents() { + if (!_cur.isContainer()) + return false; + + _cur.moveNodeContents(null, false); + + return true; + } + + private boolean checkContentInsertionValidity(Cursor to) { + _cur.push(); + + _cur.next(); + + if (_cur.isFinish()) { + _cur.pop(); + return false; + } + + try { + to.checkInsertionValidity(_cur); + } catch (IllegalArgumentException e) { + _cur.pop(); + throw e; + } + + _cur.pop(); + + return true; + } + + public boolean _moveXmlContents(Cursor to) { + if (!_cur.isContainer() || _cur.contains(to._cur)) + return false; + + if (!checkContentInsertionValidity(to)) + return false; + + Cur c = to.tempCur(); + + _cur.moveNodeContents(to._cur, false); + + to._cur.moveToCur(c); + + c.release(); + + return true; + } + + public boolean _copyXmlContents(Cursor to) { + if (!_cur.isContainer() || _cur.contains(to._cur)) + return false; + + if (!checkContentInsertionValidity(to)) + return false; + + // I don't have a primitive to copy contents, make a copy of the node and them move the + // contents + + Cur c = _cur._locale.tempCur(); + + _cur.copyNode(c); + + Cur c2 = to._cur.tempCur(); + + c.moveNodeContents(to._cur, false); + + c.release(); + + to._cur.moveToCur(c2); + + c2.release(); + + return true; + } + + public int _removeChars(int cch) { + int cchRight = _cur.cchRight(); + + if (cchRight == 0 || cch == 0) + return 0; + + if (cch < 0 || cch > cchRight) + cch = cchRight; + + _cur.moveChars(null, cch); + + return _cur._cchSrc; + } + + public int _moveChars(int cch, Cursor to) { + int cchRight = _cur.cchRight(); + + if (cchRight <= 0 || cch == 0) + return 0; + + if (cch < 0 || cch > cchRight) + cch = cchRight; + + to.checkInsertionValidity(_cur); + + _cur.moveChars(to._cur, cch); + + to._cur.nextChars(_cur._cchSrc); + + return _cur._cchSrc; + } + + public int _copyChars(int cch, Cursor to) { + int cchRight = _cur.cchRight(); + + if (cchRight <= 0 || cch == 0) + return 0; + + if (cch < 0 || cch > cchRight) + cch = cchRight; + + to.checkInsertionValidity(_cur); + + to._cur.insertChars(_cur.getChars(cch), _cur._offSrc, _cur._cchSrc); + + to._cur.nextChars(_cur._cchSrc); + + return _cur._cchSrc; + } + + public void _insertChars(String text) { + int l = text == null ? 0 : text.length(); + + if (l > 0) { + if (_cur.isRoot() || _cur.isAttr()) { + throw + new IllegalStateException("Can't insert before the document or an attribute."); + } + + _cur.insertChars(text, 0, l); + _cur.nextChars(l); + } + } + + // + // Inserting elements + // + + public void _beginElement(String localName) { + _insertElementWithText(localName, null, null); + _toPrevToken(); + } + + public void _beginElement(String localName, String uri) { + _insertElementWithText(localName, uri, null); + _toPrevToken(); + } + + public void _beginElement(QName name) { + _insertElementWithText(name, null); + _toPrevToken(); + } + + public void _insertElement(String localName) { + _insertElementWithText(localName, null, null); + } + + public void _insertElement(String localName, String uri) { + _insertElementWithText(localName, uri, null); + } + + public void _insertElement(QName name) { + _insertElementWithText(name, null); + } + + public void _insertElementWithText(String localName, String text) { + _insertElementWithText(localName, null, text); + } + + public void _insertElementWithText(String localName, String uri, String text) { + validateLocalName(localName); + + _insertElementWithText(_cur._locale.makeQName(uri, localName), text); + } + + public void _insertElementWithText(QName name, String text) { + validateLocalName(name.getLocalPart()); + + Cur c = _cur._locale.tempCur(); + + c.createElement(name); + + insertNode(c, text); + + c.release(); + } + + // + // + // + + public void _insertAttribute(String localName) { + _insertAttributeWithValue(localName, null); + } + + public void _insertAttribute(String localName, String uri) { + _insertAttributeWithValue(localName, uri, null); + } + + public void _insertAttribute(QName name) { + _insertAttributeWithValue(name, null); + } + + public void _insertAttributeWithValue(String localName, String value) { + _insertAttributeWithValue(localName, null, value); + } + + public void _insertAttributeWithValue(String localName, String uri, String value) { + validateLocalName(localName); + + _insertAttributeWithValue(_cur._locale.makeQName(uri, localName), value); + } + + public void _insertAttributeWithValue(QName name, String text) { + validateLocalName(name.getLocalPart()); + + Cur c = _cur._locale.tempCur(); + + c.createAttr(name); + + insertNode(c, text); + + c.release(); + } + + // + // + // + + public void _insertNamespace(String prefix, String namespace) { + _insertAttributeWithValue(_cur._locale.createXmlns(prefix), namespace); + } + + public void _insertComment(String text) { + Cur c = _cur._locale.tempCur(); + + c.createComment(); + + insertNode(c, text); + + c.release(); + } + + public void _insertProcInst(String target, String text) { + validateLocalName(target); + + if (Locale.beginsWithXml(target) && target.length() == 3) + throw new IllegalArgumentException("Target is 'xml'"); + + Cur c = _cur._locale.tempCur(); + + c.createProcinst(target); + + insertNode(c, text); + + c.release(); + } + + public void _dump() { + _cur.dump(); + } + + // + // + // + // + // + // + // + + private void checkThisCursor() { + if (_cur == null) + throw new IllegalStateException("This cursor has been disposed"); + } + + private Cursor checkCursors(XmlCursor xOther) { + checkThisCursor(); + + if (xOther == null) + throw new IllegalArgumentException("Other cursor is "); + + if (!(xOther instanceof Cursor)) + throw new IllegalArgumentException("Incompatible cursors: " + xOther); + + Cursor other = (Cursor) xOther; + + if (other._cur == null) + throw new IllegalStateException("Other cursor has been disposed"); + + return other; + } + + // + // The following operations have two cursors, and can be in different documents + // + + private static final int MOVE_XML = 0; + private static final int COPY_XML = 1; + private static final int MOVE_XML_CONTENTS = 2; + private static final int COPY_XML_CONTENTS = 3; + private static final int MOVE_CHARS = 4; + private static final int COPY_CHARS = 5; + + private int twoLocaleOp(XmlCursor xOther, int op, int arg) { + Cursor other = checkCursors(xOther); + + Locale locale = _cur._locale; + Locale otherLocale = other._cur._locale; + + if (locale == otherLocale) { + if (locale.noSync()) + return twoLocaleOp(other, op, arg); + else { + synchronized (locale) { + return twoLocaleOp(other, op, arg); + } + } + } + + if (locale.noSync()) { + if (otherLocale.noSync()) + return twoLocaleOp(other, op, arg); + else { + synchronized (otherLocale) { + return twoLocaleOp(other, op, arg); + } + } + } else if (otherLocale.noSync()) { + synchronized (locale) { + return twoLocaleOp(other, op, arg); + } + } + + boolean acquired = false; + + try { + GlobalLock.acquire(); + acquired = true; + + synchronized (locale) { + synchronized (otherLocale) { + GlobalLock.release(); + acquired = false; + + return twoLocaleOp(other, op, arg); + } + } + } catch (InterruptedException e) { + throw new RuntimeException(e.getMessage(), e); + } finally { + if (acquired) + GlobalLock.release(); + } + } + + private int twoLocaleOp(Cursor other, int op, int arg) { + Locale locale = _cur._locale; + Locale otherLocale = other._cur._locale; + + locale.enter(otherLocale); + + try { + switch (op) { + case MOVE_XML: + return _moveXml(other) ? 1 : 0; + case COPY_XML: + return _copyXml(other) ? 1 : 0; + case MOVE_XML_CONTENTS: + return _moveXmlContents(other) ? 1 : 0; + case COPY_XML_CONTENTS: + return _copyXmlContents(other) ? 1 : 0; + case MOVE_CHARS: + return _moveChars(arg, other); + case COPY_CHARS: + return _copyChars(arg, other); + + default : + throw new RuntimeException("Unknown operation: " + op); + } + } finally { + locale.exit(otherLocale); + } + } + + public boolean moveXml(XmlCursor xTo) { + return twoLocaleOp(xTo, MOVE_XML, 0) == 1; + } + + public boolean copyXml(XmlCursor xTo) { + return twoLocaleOp(xTo, COPY_XML, 0) == 1; + } + + public boolean moveXmlContents(XmlCursor xTo) { + return twoLocaleOp(xTo, MOVE_XML_CONTENTS, 0) == 1; + } + + public boolean copyXmlContents(XmlCursor xTo) { + return twoLocaleOp(xTo, COPY_XML_CONTENTS, 0) == 1; + } + + public int moveChars(int cch, XmlCursor xTo) { + return twoLocaleOp(xTo, MOVE_CHARS, cch); + } + + public int copyChars(int cch, XmlCursor xTo) { + return twoLocaleOp(xTo, COPY_CHARS, cch); + } + + // + // Special methods involving multiple cursors which can be in different locales, but do not + // require sync on both locales. + // + + public boolean toCursor(XmlCursor xOther) { + // One may only move cursors within the same locale + + Cursor other = checkCursors(xOther); + + if (_cur._locale != other._cur._locale) + return false; + + if (_cur._locale.noSync()) { + _cur._locale.enter(); + try { + return _toCursor(other); + } finally { + _cur._locale.exit(); + } + } else { + synchronized (_cur._locale) { + _cur._locale.enter(); + try { + return _toCursor(other); + } finally { + _cur._locale.exit(); + } + } + } + } + + public boolean isInSameDocument(XmlCursor xOther) { + return xOther == null ? false : _cur.isInSameTree(checkCursors(xOther)._cur); + } + + // + // The following operations have two cursors, but they must be in the same document + // + + private Cursor preCheck(XmlCursor xOther) { + Cursor other = checkCursors(xOther); + + if (_cur._locale != other._cur._locale) + throw new IllegalArgumentException("Cursors not in same document"); + + return other; + } + + public int comparePosition(XmlCursor xOther) { + Cursor other = preCheck(xOther); + if (_cur._locale.noSync()) { + _cur._locale.enter(); + try { + return _comparePosition(other); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + return _comparePosition(other); + } finally { + _cur._locale.exit(); + } + } + } + + public boolean isLeftOf(XmlCursor xOther) { + Cursor other = preCheck(xOther); + if (_cur._locale.noSync()) { + _cur._locale.enter(); + try { + return _isLeftOf(other); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + return _isLeftOf(other); + } finally { + _cur._locale.exit(); + } + } + } + + public boolean isAtSamePositionAs(XmlCursor xOther) { + Cursor other = preCheck(xOther); + if (_cur._locale.noSync()) { + _cur._locale.enter(); + try { + return _isAtSamePositionAs(other); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + return _isAtSamePositionAs(other); + } finally { + _cur._locale.exit(); + } + } + } + + public boolean isRightOf(XmlCursor xOther) { + Cursor other = preCheck(xOther); + if (_cur._locale.noSync()) { + _cur._locale.enter(); + try { + return _isRightOf(other); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + return _isRightOf(other); + } finally { + _cur._locale.exit(); + } + } + } + + // + // Create a cursor from an Xobj -- used for XmlBookmark.createCursor + // + + public static XmlCursor newCursor(Xobj x, int p) { + Locale l = x._locale; + if (l.noSync()) { + l.enter(); + try { + return new Cursor(x, p); + } finally { + l.exit(); + } + } else synchronized (l) { + l.enter(); + try { + return new Cursor(x, p); + } finally { + l.exit(); + } + } + } + + // + // The following operations involve only one cursor + // + + private boolean preCheck() { + checkThisCursor(); + return _cur._locale.noSync(); + } + + public void dispose() { + if (_cur != null) { + Locale l = _cur._locale; + if (preCheck()) { + l.enter(); + try { + _dispose(); + } finally { + l.exit(); + } + } else synchronized (l) { + l.enter(); + try { + _dispose(); + } finally { + l.exit(); + } + } + } + } + + public Object monitor() { + if (preCheck()) { + _cur._locale.enter(); + try { + return _monitor(); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + return _monitor(); + } finally { + _cur._locale.exit(); + } + } + } + + public XmlDocumentProperties documentProperties() { + if (preCheck()) { + _cur._locale.enter(); + try { + return _documentProperties(); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + return _documentProperties(); + } finally { + _cur._locale.exit(); + } + } + } + + public XmlCursor newCursor() { + if (preCheck()) { + _cur._locale.enter(); + try { + return _newCursor(); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + return _newCursor(); + } finally { + _cur._locale.exit(); + } + } + } + + public XMLStreamReader newXMLStreamReader() { + if (preCheck()) { + _cur._locale.enter(); + try { + return _newXMLStreamReader(); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + return _newXMLStreamReader(); + } finally { + _cur._locale.exit(); + } + } + } + + public XMLStreamReader newXMLStreamReader(XmlOptions options) { + if (preCheck()) { + _cur._locale.enter(); + try { + return _newXMLStreamReader(options); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + return _newXMLStreamReader(options); + } finally { + _cur._locale.exit(); + } + } + } + + /** + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public XMLInputStream newXMLInputStream() { + if (preCheck()) { + _cur._locale.enter(); + try { + return _newXMLInputStream(); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + return _newXMLInputStream(); + } finally { + _cur._locale.exit(); + } + } + } + + public String xmlText() { + if (preCheck()) { + _cur._locale.enter(); + try { + return _xmlText(); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + return _xmlText(); + } finally { + _cur._locale.exit(); + } + } + } + + public InputStream newInputStream() { + if (preCheck()) { + _cur._locale.enter(); + try { + return _newInputStream(); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + return _newInputStream(); + } finally { + _cur._locale.exit(); + } + } + } + + public Reader newReader() { + if (preCheck()) { + _cur._locale.enter(); + try { + return _newReader(); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + return _newReader(); + } finally { + _cur._locale.exit(); + } + } + } + + public Node newDomNode() { + if (preCheck()) { + _cur._locale.enter(); + try { + return _newDomNode(); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + return _newDomNode(); + } finally { + _cur._locale.exit(); + } + } + } + + public Node getDomNode() { + if (preCheck()) { + _cur._locale.enter(); + try { + return _getDomNode(); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + return _getDomNode(); + } finally { + _cur._locale.exit(); + } + } + } + + public void save(ContentHandler ch, LexicalHandler lh) throws SAXException { + if (preCheck()) { + _cur._locale.enter(); + try { + _save(ch, lh); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + _save(ch, lh); + } finally { + _cur._locale.exit(); + } + } + } + + public void save(File file) throws IOException { + if (preCheck()) { + _cur._locale.enter(); + try { + _save(file); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + _save(file); + } finally { + _cur._locale.exit(); + } + } + } + + public void save(OutputStream os) throws IOException { + if (preCheck()) { + _cur._locale.enter(); + try { + _save(os); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + _save(os); + } finally { + _cur._locale.exit(); + } + } + } + + public void save(Writer w) throws IOException { + if (preCheck()) { + _cur._locale.enter(); + try { + _save(w); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + _save(w); + } finally { + _cur._locale.exit(); + } + } + } + + /** + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public XMLInputStream newXMLInputStream(XmlOptions options) { + if (preCheck()) { + _cur._locale.enter(); + try { + return _newXMLInputStream(options); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + return _newXMLInputStream(options); + } finally { + _cur._locale.exit(); + } + } + } + + public String xmlText(XmlOptions options) { + if (preCheck()) { + _cur._locale.enter(); + try { + return _xmlText(options); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + return _xmlText(options); + } finally { + _cur._locale.exit(); + } + } + } + + public InputStream newInputStream(XmlOptions options) { + if (preCheck()) { + _cur._locale.enter(); + try { + return _newInputStream(options); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + return _newInputStream(options); + } finally { + _cur._locale.exit(); + } + } + } + + public Reader newReader(XmlOptions options) { + if (preCheck()) { + _cur._locale.enter(); + try { + return _newReader(options); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + return _newReader(options); + } finally { + _cur._locale.exit(); + } + } + } + + public Node newDomNode(XmlOptions options) { + if (preCheck()) { + _cur._locale.enter(); + try { + return _newDomNode(options); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + return _newDomNode(options); + } finally { + _cur._locale.exit(); + } + } + } + + public void save(ContentHandler ch, LexicalHandler lh, XmlOptions options) throws SAXException { + if (preCheck()) { + _cur._locale.enter(); + try { + _save(ch, lh, options); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + _save(ch, lh, options); + } finally { + _cur._locale.exit(); + } + } + } + + public void save(File file, XmlOptions options) throws IOException { + if (preCheck()) { + _cur._locale.enter(); + try { + _save(file, options); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + _save(file, options); + } finally { + _cur._locale.exit(); + } + } + } + + public void save(OutputStream os, XmlOptions options) throws IOException { + if (preCheck()) { + _cur._locale.enter(); + try { + _save(os, options); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + _save(os, options); + } finally { + _cur._locale.exit(); + } + } + } + + public void save(Writer w, XmlOptions options) throws IOException { + if (preCheck()) { + _cur._locale.enter(); + try { + _save(w, options); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + _save(w, options); + } finally { + _cur._locale.exit(); + } + } + } + + public void push() { + if (preCheck()) { + _cur._locale.enter(); + try { + _push(); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + _push(); + } finally { + _cur._locale.exit(); + } + } + } + + public boolean pop() { + if (preCheck()) { + _cur._locale.enter(); + try { + return _pop(); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + return _pop(); + } finally { + _cur._locale.exit(); + } + } + } + + public void selectPath(String path) { + if (preCheck()) { + _cur._locale.enter(); + try { + _selectPath(path); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + _selectPath(path); + } finally { + _cur._locale.exit(); + } + } + } + + public void selectPath(String path, XmlOptions options) { + if (preCheck()) { + _cur._locale.enter(); + try { + _selectPath(path, options); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + _selectPath(path, options); + } finally { + _cur._locale.exit(); + } + } + } + + public boolean hasNextSelection() { + if (preCheck()) { + _cur._locale.enter(); + try { + return _hasNextSelection(); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + return _hasNextSelection(); + } finally { + _cur._locale.exit(); + } + } + } + + public boolean toNextSelection() { + if (preCheck()) { + _cur._locale.enter(); + try { + return _toNextSelection(); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + return _toNextSelection(); + } finally { + _cur._locale.exit(); + } + } + } + + public boolean toSelection(int i) { + if (preCheck()) { + _cur._locale.enter(); + try { + return _toSelection(i); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + return _toSelection(i); + } finally { + _cur._locale.exit(); + } + } + } + + public int getSelectionCount() { + if (preCheck()) { + _cur._locale.enter(); + try { + return _getSelectionCount(); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + return _getSelectionCount(); + } finally { + _cur._locale.exit(); + } + } + } + + public void addToSelection() { + if (preCheck()) { + _cur._locale.enter(); + try { + _addToSelection(); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + _addToSelection(); + } finally { + _cur._locale.exit(); + } + } + } + + public void clearSelections() { + if (preCheck()) { + _cur._locale.enter(); + try { + _clearSelections(); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + _clearSelections(); + } finally { + _cur._locale.exit(); + } + } + } + + public boolean toBookmark(XmlBookmark bookmark) { + if (preCheck()) { + _cur._locale.enter(); + try { + return _toBookmark(bookmark); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + return _toBookmark(bookmark); + } finally { + _cur._locale.exit(); + } + } + } + + public XmlBookmark toNextBookmark(Object key) { + if (preCheck()) { + _cur._locale.enter(); + try { + return _toNextBookmark(key); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + return _toNextBookmark(key); + } finally { + _cur._locale.exit(); + } + } + } + + public XmlBookmark toPrevBookmark(Object key) { + if (preCheck()) { + _cur._locale.enter(); + try { + return _toPrevBookmark(key); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + return _toPrevBookmark(key); + } finally { + _cur._locale.exit(); + } + } + } + + public QName getName() { + if (preCheck()) { + _cur._locale.enter(); + try { + return _getName(); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + return _getName(); + } finally { + _cur._locale.exit(); + } + } + } + + public void setName(QName name) { + if (preCheck()) { + _cur._locale.enter(); + try { + _setName(name); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + _setName(name); + } finally { + _cur._locale.exit(); + } + } + } + + public String namespaceForPrefix(String prefix) { + if (preCheck()) { + _cur._locale.enter(); + try { + return _namespaceForPrefix(prefix); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + return _namespaceForPrefix(prefix); + } finally { + _cur._locale.exit(); + } + } + } + + public String prefixForNamespace(String namespaceURI) { + if (preCheck()) { + _cur._locale.enter(); + try { + return _prefixForNamespace(namespaceURI); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + return _prefixForNamespace(namespaceURI); + } finally { + _cur._locale.exit(); + } + } + } + + public void getAllNamespaces(Map addToThis) { + if (preCheck()) { + _cur._locale.enter(); + try { + _getAllNamespaces(addToThis); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + _getAllNamespaces(addToThis); + } finally { + _cur._locale.exit(); + } + } + } + + public XmlObject getObject() { + if (preCheck()) { + _cur._locale.enter(); + try { + return _getObject(); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + return _getObject(); + } finally { + _cur._locale.exit(); + } + } + } + + public TokenType currentTokenType() { + if (preCheck()) { +// _cur._locale.enter(); +// try { + return _currentTokenType(); +// } finally { +// _cur._locale.exit(); +// } + } else synchronized (_cur._locale) { +// _cur._locale.enter(); +// try { + return _currentTokenType(); +// } finally { +// _cur._locale.exit(); +// } + } + } + + public boolean isStartdoc() { + if (preCheck()) { +// _cur._locale.enter(); +// try { + return _isStartdoc(); +// } finally { +// _cur._locale.exit(); +// } + } else synchronized (_cur._locale) { +// _cur._locale.enter(); +// try { + return _isStartdoc(); +// } finally { +// _cur._locale.exit(); +// } + } + } + + public boolean isEnddoc() { + if (preCheck()) { +// _cur._locale.enter(); +// try { + return _isEnddoc(); +// } finally { +// _cur._locale.exit(); +// } + } else synchronized (_cur._locale) { +// _cur._locale.enter(); +// try { + return _isEnddoc(); +// } finally { +// _cur._locale.exit(); +// } + } + } + + public boolean isStart() { + if (preCheck()) { +// _cur._locale.enter(); +// try { + return _isStart(); +// } finally { +// _cur._locale.exit(); +// } + } else synchronized (_cur._locale) { +// _cur._locale.enter(); +// try { + return _isStart(); +// } finally { +// _cur._locale.exit(); +// } + } + } + + public boolean isEnd() { + if (preCheck()) { +// _cur._locale.enter(); +// try { + return _isEnd(); +// } finally { +// _cur._locale.exit(); +// } + } else synchronized (_cur._locale) { +// _cur._locale.enter(); +// try { + return _isEnd(); +// } finally { +// _cur._locale.exit(); +// } + } + } + + public boolean isText() { + if (preCheck()) { +// _cur._locale.enter(); +// try { + return _isText(); +// } finally { +// _cur._locale.exit(); +// } + } else synchronized (_cur._locale) { +// _cur._locale.enter(); +// try { + return _isText(); +// } finally { +// _cur._locale.exit(); +// } + } + } + + public boolean isAttr() { + if (preCheck()) { +// _cur._locale.enter(); +// try { + return _isAttr(); +// } finally { +// _cur._locale.exit(); +// } + } else synchronized (_cur._locale) { +// _cur._locale.enter(); +// try { + return _isAttr(); +// } finally { +// _cur._locale.exit(); +// } + } + } + + public boolean isNamespace() { + if (preCheck()) { +// _cur._locale.enter(); +// try { + return _isNamespace(); +// } finally { +// _cur._locale.exit(); +// } + } else synchronized (_cur._locale) { +// _cur._locale.enter(); +// try { + return _isNamespace(); +// } finally { +// _cur._locale.exit(); +// } + } + } + + public boolean isComment() { + if (preCheck()) { +// _cur._locale.enter(); +// try { + return _isComment(); +// } finally { +// _cur._locale.exit(); +// } + } else synchronized (_cur._locale) { +// _cur._locale.enter(); +// try { + return _isComment(); +// } finally { +// _cur._locale.exit(); +// } + } + } + + public boolean isProcinst() { + if (preCheck()) { +// _cur._locale.enter(); +// try { + return _isProcinst(); +// } finally { +// _cur._locale.exit(); +// } + } else synchronized (_cur._locale) { +// _cur._locale.enter(); +// try { + return _isProcinst(); +// } finally { +// _cur._locale.exit(); +// } + } + } + + public boolean isContainer() { + if (preCheck()) { +// _cur._locale.enter(); +// try { + return _isContainer(); +// } finally { +// _cur._locale.exit(); +// } + } else synchronized (_cur._locale) { +// _cur._locale.enter(); +// try { + return _isContainer(); +// } finally { +// _cur._locale.exit(); +// } + } + } + + public boolean isFinish() { + if (preCheck()) { +// _cur._locale.enter(); +// try { + return _isFinish(); +// } finally { +// _cur._locale.exit(); +// } + } else synchronized (_cur._locale) { +// _cur._locale.enter(); +// try { + return _isFinish(); +// } finally { +// _cur._locale.exit(); +// } + } + } + + public boolean isAnyAttr() { + if (preCheck()) { +// _cur._locale.enter(); +// try { + return _isAnyAttr(); +// } finally { +// _cur._locale.exit(); +// } + } else synchronized (_cur._locale) { +// _cur._locale.enter(); +// try { + return _isAnyAttr(); +// } finally { +// _cur._locale.exit(); +// } + } + } + + public TokenType prevTokenType() { + if (preCheck()) { + _cur._locale.enter(); + try { + return _prevTokenType(); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + return _prevTokenType(); + } finally { + _cur._locale.exit(); + } + } + } + + public boolean hasNextToken() { + if (preCheck()) { +// _cur._locale.enter(); +// try { + return _hasNextToken(); +// } finally { +// _cur._locale.exit(); +// } + } else synchronized (_cur._locale) { +// _cur._locale.enter(); +// try { + return _hasNextToken(); +// } finally { +// _cur._locale.exit(); +// } + } + } + + public boolean hasPrevToken() { + if (preCheck()) { + _cur._locale.enter(); + try { + return _hasPrevToken(); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + return _hasPrevToken(); + } finally { + _cur._locale.exit(); + } + } + } + + public TokenType toNextToken() { + if (preCheck()) { + _cur._locale.enter(); + try { + return _toNextToken(); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + return _toNextToken(); + } finally { + _cur._locale.exit(); + } + } + } + + public TokenType toPrevToken() { + if (preCheck()) { + _cur._locale.enter(); + try { + return _toPrevToken(); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + return _toPrevToken(); + } finally { + _cur._locale.exit(); + } + } + } + + public TokenType toFirstContentToken() { + if (preCheck()) { + _cur._locale.enter(); + try { + return _toFirstContentToken(); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + return _toFirstContentToken(); + } finally { + _cur._locale.exit(); + } + } + } + + public TokenType toEndToken() { + if (preCheck()) { + _cur._locale.enter(); + try { + return _toEndToken(); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + return _toEndToken(); + } finally { + _cur._locale.exit(); + } + } + } + + public int toNextChar(int cch) { + if (preCheck()) { + _cur._locale.enter(); + try { + return _toNextChar(cch); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + return _toNextChar(cch); + } finally { + _cur._locale.exit(); + } + } + } + + public int toPrevChar(int cch) { + if (preCheck()) { + _cur._locale.enter(); + try { + return _toPrevChar(cch); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + return _toPrevChar(cch); + } finally { + _cur._locale.exit(); + } + } + } + +// public boolean _toNextSibling() +// { +// return Locale.toNextSiblingElement(_cur); +// } + + public boolean ___toNextSibling() + { + if (!_cur.hasParent()) + return false; + + Xobj parent = _cur.getParentNoRoot(); + + if (parent==null) + { + _cur._locale.enter(); + try + { + parent = _cur.getParent(); + } finally { + _cur._locale.exit(); + } + } + + return Locale.toNextSiblingElement(_cur, parent); + } + + public boolean toNextSibling() + { + if (preCheck()) { + return ___toNextSibling(); + } else synchronized (_cur._locale) { + return ___toNextSibling(); + } + } + + public boolean toPrevSibling() { + if (preCheck()) { + _cur._locale.enter(); + try { + return _toPrevSibling(); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + return _toPrevSibling(); + } finally { + _cur._locale.exit(); + } + } + } + + public boolean toParent() { + if (preCheck()) { + _cur._locale.enter(); + try { + return _toParent(); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + return _toParent(); + } finally { + _cur._locale.exit(); + } + } + } + + public boolean toFirstChild() { + if (preCheck()) { +// _cur._locale.enter(); +// try { + return _toFirstChild(); +// } finally { +// _cur._locale.exit(); +// } + } else synchronized (_cur._locale) { +// _cur._locale.enter(); +// try { + return _toFirstChild(); +// } finally { +// _cur._locale.exit(); +// } + } + } + + public boolean toLastChild() { + if (preCheck()) { + _cur._locale.enter(); + try { + return _toLastChild(); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + return _toLastChild(); + } finally { + _cur._locale.exit(); + } + } + } + + public boolean toChild(String name) { + if (preCheck()) { + _cur._locale.enter(); + try { + return _toChild(name); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + return _toChild(name); + } finally { + _cur._locale.exit(); + } + } + } + + public boolean toChild(String namespace, String name) { + if (preCheck()) { + _cur._locale.enter(); + try { + return _toChild(namespace, name); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + return _toChild(namespace, name); + } finally { + _cur._locale.exit(); + } + } + } + + public boolean toChild(QName name) { + if (preCheck()) { + _cur._locale.enter(); + try { + return _toChild(name); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + return _toChild(name); + } finally { + _cur._locale.exit(); + } + } + } + + public boolean toChild(int index) { + if (preCheck()) { + _cur._locale.enter(); + try { + return _toChild(index); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + return _toChild(index); + } finally { + _cur._locale.exit(); + } + } + } + + public boolean toChild(QName name, int index) { + if (preCheck()) { + _cur._locale.enter(); + try { + return _toChild(name, index); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + return _toChild(name, index); + } finally { + _cur._locale.exit(); + } + } + } + + public boolean toNextSibling(String name) { + if (preCheck()) { + _cur._locale.enter(); + try { + return _toNextSibling(name); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + return _toNextSibling(name); + } finally { + _cur._locale.exit(); + } + } + } + + public boolean toNextSibling(String namespace, String name) { + if (preCheck()) { + _cur._locale.enter(); + try { + return _toNextSibling(namespace, name); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + return _toNextSibling(namespace, name); + } finally { + _cur._locale.exit(); + } + } + } + + public boolean toNextSibling(QName name) { + if (preCheck()) { + _cur._locale.enter(); + try { + return _toNextSibling(name); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + return _toNextSibling(name); + } finally { + _cur._locale.exit(); + } + } + } + + public boolean toFirstAttribute() { + if (preCheck()) { +// _cur._locale.enter(); +// try { + return _toFirstAttribute(); +// } finally { +// _cur._locale.exit(); +// } + } else synchronized (_cur._locale) { +// _cur._locale.enter(); +// try { + return _toFirstAttribute(); +// } finally { +// _cur._locale.exit(); +// } + } + } + + public boolean toLastAttribute() { + if (preCheck()) { + _cur._locale.enter(); + try { + return _toLastAttribute(); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + return _toLastAttribute(); + } finally { + _cur._locale.exit(); + } + } + } + + public boolean toNextAttribute() { + if (preCheck()) { + _cur._locale.enter(); + try { + return _toNextAttribute(); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + return _toNextAttribute(); + } finally { + _cur._locale.exit(); + } + } + } + + public boolean toPrevAttribute() { + if (preCheck()) { + _cur._locale.enter(); + try { + return _toPrevAttribute(); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + return _toPrevAttribute(); + } finally { + _cur._locale.exit(); + } + } + } + + public String getAttributeText(QName attrName) { + if (preCheck()) { + _cur._locale.enter(); + try { + return _getAttributeText(attrName); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + return _getAttributeText(attrName); + } finally { + _cur._locale.exit(); + } + } + } + + public boolean setAttributeText(QName attrName, String value) { + if (preCheck()) { + _cur._locale.enter(); + try { + return _setAttributeText(attrName, value); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + return _setAttributeText(attrName, value); + } finally { + _cur._locale.exit(); + } + } + } + + public boolean removeAttribute(QName attrName) { + if (preCheck()) { + _cur._locale.enter(); + try { + return _removeAttribute(attrName); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + return _removeAttribute(attrName); + } finally { + _cur._locale.exit(); + } + } + } + + public String getTextValue() { + if (preCheck()) { + _cur._locale.enter(); + try { + return _getTextValue(); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + return _getTextValue(); + } finally { + _cur._locale.exit(); + } + } + } + + public int getTextValue(char[] chars, int offset, int cch) { + if (preCheck()) { + _cur._locale.enter(); + try { + return _getTextValue(chars, offset, cch); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + return _getTextValue(chars, offset, cch); + } finally { + _cur._locale.exit(); + } + } + } + + public void setTextValue(String text) { + if (preCheck()) { + _cur._locale.enter(); + try { + _setTextValue(text); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + _setTextValue(text); + } finally { + _cur._locale.exit(); + } + } + } + + public void setTextValue(char[] sourceChars, int offset, int length) { + if (preCheck()) { + _cur._locale.enter(); + try { + _setTextValue(sourceChars, offset, length); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + _setTextValue(sourceChars, offset, length); + } finally { + _cur._locale.exit(); + } + } + } + + public String getChars() { + if (preCheck()) { + _cur._locale.enter(); + try { + return _getChars(); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + return _getChars(); + } finally { + _cur._locale.exit(); + } + } + } + + public int getChars(char[] chars, int offset, int cch) { + if (preCheck()) { + _cur._locale.enter(); + try { + return _getChars(chars, offset, cch); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + return _getChars(chars, offset, cch); + } finally { + _cur._locale.exit(); + } + } + } + + public void toStartDoc() { + if (preCheck()) { +// _cur._locale.enter(); +// try { + _toStartDoc(); +// } finally { +// _cur._locale.exit(); +// } + } else synchronized (_cur._locale) { +// _cur._locale.enter(); +// try { + _toStartDoc(); +// } finally { +// _cur._locale.exit(); +// } + } + } + + public void toEndDoc() { + if (preCheck()) { +// _cur._locale.enter(); +// try { + _toEndDoc(); +// } finally { +// _cur._locale.exit(); +// } + } else synchronized (_cur._locale) { +// _cur._locale.enter(); +// try { + _toEndDoc(); +// } finally { +// _cur._locale.exit(); +// } + } + } + + public XmlCursor execQuery(String query) { + if (preCheck()) { + _cur._locale.enter(); + try { + return _execQuery(query); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + return _execQuery(query); + } finally { + _cur._locale.exit(); + } + } + } + + public XmlCursor execQuery(String query, XmlOptions options) { + if (preCheck()) { + _cur._locale.enter(); + try { + return _execQuery(query, options); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + return _execQuery(query, options); + } finally { + _cur._locale.exit(); + } + } + } + + public ChangeStamp getDocChangeStamp() { + if (preCheck()) { + _cur._locale.enter(); + try { + return _getDocChangeStamp(); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + return _getDocChangeStamp(); + } finally { + _cur._locale.exit(); + } + } + } + + public void setBookmark(XmlBookmark bookmark) { + if (preCheck()) { + _cur._locale.enter(); + try { + _setBookmark(bookmark); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + _setBookmark(bookmark); + } finally { + _cur._locale.exit(); + } + } + } + + public XmlBookmark getBookmark(Object key) { + if (preCheck()) { + _cur._locale.enter(); + try { + return _getBookmark(key); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + return _getBookmark(key); + } finally { + _cur._locale.exit(); + } + } + } + + public void clearBookmark(Object key) { + if (preCheck()) { + _cur._locale.enter(); + try { + _clearBookmark(key); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + _clearBookmark(key); + } finally { + _cur._locale.exit(); + } + } + } + + public void getAllBookmarkRefs(Collection listToFill) { + if (preCheck()) { + _cur._locale.enter(); + try { + _getAllBookmarkRefs(listToFill); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + _getAllBookmarkRefs(listToFill); + } finally { + _cur._locale.exit(); + } + } + } + + public boolean removeXml() { + if (preCheck()) { + _cur._locale.enter(); + try { + return _removeXml(); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + return _removeXml(); + } finally { + _cur._locale.exit(); + } + } + } + + public boolean removeXmlContents() { + if (preCheck()) { + _cur._locale.enter(); + try { + return _removeXmlContents(); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + return _removeXmlContents(); + } finally { + _cur._locale.exit(); + } + } + } + + public int removeChars(int cch) { + if (preCheck()) { + _cur._locale.enter(); + try { + return _removeChars(cch); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + return _removeChars(cch); + } finally { + _cur._locale.exit(); + } + } + } + + public void insertChars(String text) { + if (preCheck()) { + _cur._locale.enter(); + try { + _insertChars(text); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + _insertChars(text); + } finally { + _cur._locale.exit(); + } + } + } + + public void insertElement(QName name) { + if (preCheck()) { + _cur._locale.enter(); + try { + _insertElement(name); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + _insertElement(name); + } finally { + _cur._locale.exit(); + } + } + } + + public void insertElement(String localName) { + if (preCheck()) { + _cur._locale.enter(); + try { + _insertElement(localName); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + _insertElement(localName); + } finally { + _cur._locale.exit(); + } + } + } + + public void insertElement(String localName, String uri) { + if (preCheck()) { + _cur._locale.enter(); + try { + _insertElement(localName, uri); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + _insertElement(localName, uri); + } finally { + _cur._locale.exit(); + } + } + } + + public void beginElement(QName name) { + if (preCheck()) { + _cur._locale.enter(); + try { + _beginElement(name); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + _beginElement(name); + } finally { + _cur._locale.exit(); + } + } + } + + public void beginElement(String localName) { + if (preCheck()) { + _cur._locale.enter(); + try { + _beginElement(localName); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + _beginElement(localName); + } finally { + _cur._locale.exit(); + } + } + } + + public void beginElement(String localName, String uri) { + if (preCheck()) { + _cur._locale.enter(); + try { + _beginElement(localName, uri); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + _beginElement(localName, uri); + } finally { + _cur._locale.exit(); + } + } + } + + public void insertElementWithText(QName name, String text) { + if (preCheck()) { + _cur._locale.enter(); + try { + _insertElementWithText(name, text); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + _insertElementWithText(name, text); + } finally { + _cur._locale.exit(); + } + } + } + + public void insertElementWithText(String localName, String text) { + if (preCheck()) { + _cur._locale.enter(); + try { + _insertElementWithText(localName, text); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + _insertElementWithText(localName, text); + } finally { + _cur._locale.exit(); + } + } + } + + public void insertElementWithText(String localName, String uri, String text) { + if (preCheck()) { + _cur._locale.enter(); + try { + _insertElementWithText(localName, uri, text); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + _insertElementWithText(localName, uri, text); + } finally { + _cur._locale.exit(); + } + } + } + + public void insertAttribute(String localName) { + if (preCheck()) { + _cur._locale.enter(); + try { + _insertAttribute(localName); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + _insertAttribute(localName); + } finally { + _cur._locale.exit(); + } + } + } + + public void insertAttribute(String localName, String uri) { + if (preCheck()) { + _cur._locale.enter(); + try { + _insertAttribute(localName, uri); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + _insertAttribute(localName, uri); + } finally { + _cur._locale.exit(); + } + } + } + + public void insertAttribute(QName name) { + if (preCheck()) { + _cur._locale.enter(); + try { + _insertAttribute(name); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + _insertAttribute(name); + } finally { + _cur._locale.exit(); + } + } + } + + public void insertAttributeWithValue(String Name, String value) { + if (preCheck()) { + _cur._locale.enter(); + try { + _insertAttributeWithValue(Name, value); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + _insertAttributeWithValue(Name, value); + } finally { + _cur._locale.exit(); + } + } + } + + public void insertAttributeWithValue(String name, String uri, String value) { + if (preCheck()) { + _cur._locale.enter(); + try { + _insertAttributeWithValue(name, uri, value); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + _insertAttributeWithValue(name, uri, value); + } finally { + _cur._locale.exit(); + } + } + } + + public void insertAttributeWithValue(QName name, String value) { + if (preCheck()) { + _cur._locale.enter(); + try { + _insertAttributeWithValue(name, value); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + _insertAttributeWithValue(name, value); + } finally { + _cur._locale.exit(); + } + } + } + + public void insertNamespace(String prefix, String namespace) { + if (preCheck()) { + _cur._locale.enter(); + try { + _insertNamespace(prefix, namespace); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + _insertNamespace(prefix, namespace); + } finally { + _cur._locale.exit(); + } + } + } + + public void insertComment(String text) { + if (preCheck()) { + _cur._locale.enter(); + try { + _insertComment(text); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + _insertComment(text); + } finally { + _cur._locale.exit(); + } + } + } + + public void insertProcInst(String target, String text) { + if (preCheck()) { + _cur._locale.enter(); + try { + _insertProcInst(target, text); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + _insertProcInst(target, text); + } finally { + _cur._locale.exit(); + } + } + } + + public void dump() { + if (preCheck()) { + _cur._locale.enter(); + try { + _dump(); + } finally { + _cur._locale.exit(); + } + } else synchronized (_cur._locale) { + _cur._locale.enter(); + try { + _dump(); + } finally { + _cur._locale.exit(); + } + } + } + + // + // + // + + private Cur _cur; + private PathEngine _pathEngine; + private int _currentSelection; + + private ChangeListener _nextChangeListener; +} diff --git a/xmlbeans/src/store/org/apache/xmlbeans/impl/store/DomImpl.java b/xmlbeans/src/store/org/apache/xmlbeans/impl/store/DomImpl.java new file mode 100755 index 000000000..a15b72ca9 --- /dev/null +++ b/xmlbeans/src/store/org/apache/xmlbeans/impl/store/DomImpl.java @@ -0,0 +1,4907 @@ +/* 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.store; + +import org.w3c.dom.Attr; +import org.w3c.dom.CDATASection; +import org.w3c.dom.CharacterData; +import org.w3c.dom.Comment; +import org.w3c.dom.Document; +import org.w3c.dom.DocumentFragment; +import org.w3c.dom.DocumentType; +import org.w3c.dom.DOMException; +import org.w3c.dom.DOMImplementation; +import org.w3c.dom.Element; +import org.w3c.dom.EntityReference; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.w3c.dom.ProcessingInstruction; +import org.w3c.dom.Text; +import org.w3c.dom.DOMImplementation; + +// DOM Level 3 +import org.w3c.dom.UserDataHandler; + + +import org.apache.xmlbeans.impl.common.XMLChar; +import org.apache.xmlbeans.impl.soap.Detail; +import org.apache.xmlbeans.impl.soap.DetailEntry; +import org.apache.xmlbeans.impl.soap.MimeHeaders; +import org.apache.xmlbeans.impl.soap.Name; +import org.apache.xmlbeans.impl.soap.SOAPBody; +import org.apache.xmlbeans.impl.soap.SOAPBodyElement; +import org.apache.xmlbeans.impl.soap.SOAPElement; +import org.apache.xmlbeans.impl.soap.SOAPEnvelope; +import org.apache.xmlbeans.impl.soap.SOAPException; +import org.apache.xmlbeans.impl.soap.SOAPFactory; +import org.apache.xmlbeans.impl.soap.SOAPFault; +import org.apache.xmlbeans.impl.soap.SOAPHeader; +import org.apache.xmlbeans.impl.soap.SOAPHeaderElement; +import org.apache.xmlbeans.impl.soap.SOAPPart; + +import javax.xml.stream.XMLStreamReader; + +import java.io.PrintStream; + +import java.util.ArrayList; +import java.util.Iterator; + +import javax.xml.transform.Source; +import javax.xml.namespace.QName; + +import org.apache.xmlbeans.XmlException; +import org.apache.xmlbeans.XmlRuntimeException; +import org.apache.xmlbeans.XmlCursor; +import org.apache.xmlbeans.XmlObject; + +final class DomImpl +{ + static final int ELEMENT = Node.ELEMENT_NODE; + static final int ATTR = Node.ATTRIBUTE_NODE; + static final int TEXT = Node.TEXT_NODE; + static final int CDATA = Node.CDATA_SECTION_NODE; + static final int ENTITYREF = Node.ENTITY_REFERENCE_NODE; + static final int ENTITY = Node.ENTITY_NODE; + static final int PROCINST = Node.PROCESSING_INSTRUCTION_NODE; + static final int COMMENT = Node.COMMENT_NODE; + static final int DOCUMENT = Node.DOCUMENT_NODE; + static final int DOCTYPE = Node.DOCUMENT_TYPE_NODE; + static final int DOCFRAG = Node.DOCUMENT_FRAGMENT_NODE; + static final int NOTATION = Node.NOTATION_NODE; + + interface Dom + { + Locale locale ( ); + int nodeType ( ); + Cur tempCur ( ); + QName getQName ( ); + boolean nodeCanHavePrefixUri( ); + + void dump ( ); + void dump ( PrintStream o ); + void dump ( PrintStream o, Object ref ); + }; + + static Dom parent ( Dom d ) { return node_getParentNode ( d ); } + static Dom firstChild ( Dom d ) { return node_getFirstChild ( d ); } + static Dom nextSibling ( Dom d ) { return node_getNextSibling( d ); } + static Dom prevSibling ( Dom d ) { return node_getPreviousSibling( d ); } + + public static Dom append ( Dom n, Dom p ) + { + return node_insertBefore( p, n, null ); + } + + public static Dom insert ( Dom n, Dom b ) + { + assert b != null; + return node_insertBefore( parent( b ), n, b ); + } + + public static Dom remove ( Dom n ) + { + Dom p = parent( n ); + + if (p != null) + node_removeChild( p, n ); + + return n; + } + + // + // Handy dandy Dom exceptions + // + + static class HierarchyRequestErr extends DOMException + { + HierarchyRequestErr ( ) { this( "This node isn't allowed there" ); } + HierarchyRequestErr ( String message ) { super( HIERARCHY_REQUEST_ERR, message ); } + } + + static class WrongDocumentErr extends DOMException + { + WrongDocumentErr ( ) { this( "Nodes do not belong to the same document" ); } + WrongDocumentErr ( String message ) { super( WRONG_DOCUMENT_ERR, message ); } + } + + static class NotFoundErr extends DOMException + { + NotFoundErr ( ) { this( "Node not found" ); } + NotFoundErr ( String message ) { super( NOT_FOUND_ERR, message ); } + } + + static class NamespaceErr extends DOMException + { + NamespaceErr ( ) { this( "Namespace error" ); } + NamespaceErr ( String message ) { super( NAMESPACE_ERR, message ); } + } + + static class NoModificationAllowedErr extends DOMException + { + NoModificationAllowedErr ( ) { this( "No modification allowed error" ); } + NoModificationAllowedErr ( String message ) { super( NO_MODIFICATION_ALLOWED_ERR, message ); } + } + + static class InuseAttributeError extends DOMException + { + InuseAttributeError ( ) { this( "Attribute currently in use error" ); } + InuseAttributeError ( String message ) { super( INUSE_ATTRIBUTE_ERR, message ); } + } + + static class IndexSizeError extends DOMException + { + IndexSizeError ( ) { this( "Index Size Error" ); } + IndexSizeError ( String message ) { super( INDEX_SIZE_ERR, message ); } + } + + static class NotSupportedError extends DOMException + { + NotSupportedError ( ) { this( "This operation is not supported" ); } + NotSupportedError ( String message ) { super( NOT_SUPPORTED_ERR, message ); } + } + + static class InvalidCharacterError extends DOMException + { + InvalidCharacterError ( ) { this( "The name contains an invalid character" ); } + InvalidCharacterError ( String message ) { super( INVALID_CHARACTER_ERR, message ); } + } + + // + // Helper fcns + // + + private static final class EmptyNodeList implements NodeList + { + public int getLength ( ) { return 0; } + public Node item ( int i ) { return null; } + } + + public static NodeList _emptyNodeList = new EmptyNodeList(); + + static String nodeKindName ( int t ) + { + switch ( t ) + { + case ATTR : return "attribute"; + case CDATA : return "cdata section"; + case COMMENT : return "comment"; + case DOCFRAG : return "document fragment"; + case DOCUMENT : return "document"; + case DOCTYPE : return "document type"; + case ELEMENT : return "element"; + case ENTITY : return "entity"; + case ENTITYREF : return "entity reference"; + case NOTATION : return "notation"; + case PROCINST : return "processing instruction"; + case TEXT : return "text"; + + default : throw new RuntimeException( "Unknown node type" ); + } + } + + private static String isValidChild ( Dom parent, Dom child ) + { + int pk = parent.nodeType(); + int ck = child.nodeType(); + + switch ( pk ) + { + case DOCUMENT : + { + switch ( ck ) + { + case ELEMENT : + { + if (document_getDocumentElement( parent ) != null) + return "Documents may only have a maximum of one document element"; + + return null; + } + case DOCTYPE : + { + if (document_getDoctype( parent ) != null) + return "Documents may only have a maximum of one document type node"; + + return null; + } + case PROCINST : + case COMMENT : + return null; + } + + break; + } + + case ATTR : + { + if (ck == TEXT || ck == ENTITYREF) + return null; + + // TODO -- traverse the entity tree, making sure that there are + // only entity refs and text nodes in it. + + break; + } + + case DOCFRAG : + case ELEMENT : + case ENTITY : + case ENTITYREF : + { + switch ( ck ) + { + case ELEMENT : + case ENTITYREF: + case CDATA : + case TEXT : + case COMMENT : + case PROCINST : + return null; + } + + break; + } + + case CDATA : + case TEXT : + case COMMENT : + case PROCINST : + case DOCTYPE : + case NOTATION : + return nodeKindName( pk ) + " nodes may not have any children"; + } + + return + nodeKindName( pk ) + " nodes may not have " + + nodeKindName( ck ) + " nodes as children"; + } + + private static void validateNewChild ( Dom parent, Dom child ) + { + String msg = isValidChild( parent, child ); + + if (msg != null) + throw new HierarchyRequestErr( msg ); + + if (parent == child) + throw new HierarchyRequestErr( "New child and parent are the same node" ); + + while ( (parent = parent( parent )) != null ) + { + // TODO - use read only state on a node to know if it is under an + // entity ref + + if (child.nodeType() == ENTITYREF) + throw new NoModificationAllowedErr( "Entity reference trees may not be modified" ); + + if (child == parent) + throw new HierarchyRequestErr( "New child is an ancestor node of the parent node" ); + } + } + + private static String validatePrefix ( + String prefix, String uri, String local, boolean isAttr ) + { + validateNcName( prefix ); + + if (prefix == null) + prefix = ""; + + if (uri == null) + uri = ""; + + if (prefix.length() > 0 && uri.length() == 0) + throw new NamespaceErr( "Attempt to give a prefix for no namespace" ); + + if (prefix.equals( "xml" ) && !uri.equals( Locale._xml1998Uri )) + throw new NamespaceErr( "Invalid prefix - begins with 'xml'" ); + + if (isAttr) + { + if (prefix.length() > 0) + { + if (local.equals( "xmlns" )) + throw new NamespaceErr( "Invalid namespace - attr is default namespace already" ); + + if (Locale.beginsWithXml( local )) + throw new NamespaceErr( "Invalid namespace - attr prefix begins with 'xml'" ); + + if (prefix.equals( "xmlns" ) && !uri.equals( Locale._xmlnsUri )) + throw new NamespaceErr( "Invalid namespace - uri is not '" + Locale._xmlnsUri+";" ); + } + else + { + if (local.equals( "xmlns" ) && !uri.equals( Locale._xmlnsUri )) + throw new NamespaceErr( "Invalid namespace - uri is not '" + Locale._xmlnsUri+";" ); + } + } + else if (Locale.beginsWithXml( prefix )) + throw new NamespaceErr( "Invalid prefix - begins with 'xml'" ); + + return prefix; + } + + private static void validateName ( String name ) + { + if (name == null) + throw new IllegalArgumentException( "Name is null" ); + + if (name.length() == 0) + throw new IllegalArgumentException( "Name is empty" ); + + if (!XMLChar.isValidName( name )) + throw new InvalidCharacterError( "Name has an invalid character" ); + } + + private static void validateNcName ( String name ) + { + if (name != null && name.length() > 0 && !XMLChar.isValidNCName( name )) + throw new InvalidCharacterError(); + } + + private static void validateQualifiedName ( String name, String uri, boolean isAttr ) + { + assert name != null; + + if (uri == null) + uri = ""; + + int i = name.indexOf( ':' ); + + String local; + + if (i < 0) + { + validateNcName( local = name ); + + if (isAttr && local.equals( "xmlns" ) && !uri.equals( Locale._xmlnsUri )) + { + throw + new NamespaceErr( + "Default xmlns attribute does not have namespace: " + Locale._xmlnsUri ); + } + } + else + { + if (i == 0) + throw new NamespaceErr( "Invalid qualified name, no prefix specified" ); + + String prefix = name.substring( 0, i ); + + validateNcName( prefix ); + + if (uri.length() == 0) + throw new NamespaceErr( "Attempt to give a prefix for no namespace" ); + + local = name.substring( i + 1 ); + + if (local.indexOf( ':' ) >= 0) + throw new NamespaceErr( "Invalid qualified name, more than one colon" ); + + validateNcName( local ); + + if (prefix.equals( "xml" ) && !uri.equals( Locale._xml1998Uri )) + throw new NamespaceErr( "Invalid prefix - begins with 'xml'" ); + } + + if (local.length() == 0) + throw new NamespaceErr( "Invalid qualified name, no local part specified" ); + } + + private static void removeNode ( Dom n ) + { + assert n.nodeType() != TEXT && n.nodeType() != CDATA; + + Cur cFrom = n.tempCur(); + + cFrom.toEnd(); + + // Move any char nodes which ater after the node to remove to be before it. The call to + // Next here does two things, it tells me if I can get after the move to remove (all nodes + // but the root) and it positions me at the place where there are char nodes after. + + if (cFrom.next()) + { + CharNode fromNodes = cFrom.getCharNodes(); + + if (fromNodes != null) + { + cFrom.setCharNodes( null ); + Cur cTo = n.tempCur(); + cTo.setCharNodes( CharNode.appendNodes( cTo.getCharNodes(), fromNodes ) ); + cTo.release(); + } + } + + cFrom.release(); + + Cur.moveNode( (Xobj) n, null ); + } + + private abstract static class ElementsNodeList implements NodeList + { + ElementsNodeList ( Dom root ) + { + assert root.nodeType() == DOCUMENT || root.nodeType() == ELEMENT; + + _root = root; + _locale = _root.locale(); + _version = 0; + } + + public int getLength ( ) + { + ensureElements(); + + return _elements.size(); + } + + public Node item ( int i ) + { + ensureElements(); + + return i < 0 || i >= _elements.size() ? (Node) null : (Node) _elements.get( i ); + } + + private void ensureElements ( ) + { + if (_version == _locale.version()) + return; + + _version = _locale.version(); + + _elements = new ArrayList(); + + Locale l = _locale; + + if (l.noSync()) { l.enter(); try { addElements( _root ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { addElements( _root ); } finally { l.exit(); } } + } + + private void addElements ( Dom node ) + { + for ( Dom c = firstChild( node ) ; c != null ; c = nextSibling( c ) ) + { + if (c.nodeType() == ELEMENT) + { + if (match( c )) + _elements.add( c ); + + addElements( c ); + } + } + } + + protected abstract boolean match ( Dom element ); + + private Dom _root; + private Locale _locale; + private long _version; + private ArrayList _elements; + } + + private static class ElementsByTagNameNodeList extends ElementsNodeList + { + ElementsByTagNameNodeList ( Dom root, String name ) + { + super( root ); + + _name = name; + } + + protected boolean match ( Dom element ) + { + return _name.equals( "*" ) ? true : _node_getNodeName( element ).equals( _name ); + } + + private String _name; + } + + private static class ElementsByTagNameNSNodeList extends ElementsNodeList + { + ElementsByTagNameNSNodeList ( Dom root, String uri, String local ) + { + super( root ); + + _uri = uri == null ? "" : uri; + _local = local; + } + + protected boolean match ( Dom element ) + { + if (!(_uri.equals( "*" ) ? true : _node_getNamespaceURI( element ).equals( _uri ))) + return false; + + return _local.equals( "*" ) ? true : _node_getLocalName( element ).equals( _local ); + } + + private String _uri; + private String _local; + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static Document _domImplementation_createDocument ( + Locale l, String u, String n, DocumentType t ) + { + Document d; + + if (l.noSync()) { l.enter(); try { return domImplementation_createDocument( l, u, n, t ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return domImplementation_createDocument( l, u, n, t ); } finally { l.exit(); } } + } + + public static Document domImplementation_createDocument ( + Locale l, String namespaceURI, String qualifiedName, DocumentType doctype ) + { + validateQualifiedName( qualifiedName, namespaceURI, false ); + + Cur c = l.tempCur(); + + c.createDomDocumentRoot(); + + Document doc = (Document) c.getDom(); + + c.next(); + + c.createElement( l.makeQualifiedQName( namespaceURI, qualifiedName ) ); + + if (doctype != null) + throw new RuntimeException( "Not impl" ); + + c.toParent(); + + try + { + Locale.autoTypeDocument( c, null, null ); + } + catch (XmlException e ) + { + throw new XmlRuntimeException( e ); + } + + c.release(); + + return doc; + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static boolean _domImplementation_hasFeature ( Locale l, String feature, String version ) + { + if (feature == null) + return false; + + if (version != null && version.length() > 0 && + !version.equals( "1.0" ) && !version.equals( "2.0" )) + { + return false; + } + + if (feature.equalsIgnoreCase( "core" )) + return true; + + if (feature.equalsIgnoreCase( "xml" )) + return true; + + return false; + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static Element _document_getDocumentElement ( Dom d ) + { + Locale l = d.locale(); + + Dom e; + + if (l.noSync()) { l.enter(); try { e = document_getDocumentElement( d ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { e = document_getDocumentElement( d ); } finally { l.exit(); } } + + return (Element) e; + } + + public static Dom document_getDocumentElement ( Dom d ) + { + for ( d = firstChild( d ) ; d != null ; d = nextSibling( d ) ) + { + if (d.nodeType() == ELEMENT) + return d; + } + + return null; + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static DocumentFragment _document_createDocumentFragment ( Dom d ) + { + Locale l = d.locale(); + + Dom f; + + if (l.noSync()) { l.enter(); try { f = document_createDocumentFragment( d ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { f = document_createDocumentFragment( d ); } finally { l.exit(); } } + + return (DocumentFragment) f; + } + + public static Dom document_createDocumentFragment ( Dom d ) + { + Cur c = d.locale().tempCur(); + + c.createDomDocFragRoot(); + + Dom f = c.getDom(); + + c.release(); + + return f; + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static Element _document_createElement ( Dom d, String name ) + { + Locale l = d.locale(); + + Dom e; + + if (l.noSync()) { l.enter(); try { e = document_createElement( d, name ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { e = document_createElement( d, name ); } finally { l.exit(); } } + + return (Element) e; + } + + public static Dom document_createElement ( Dom d, String name ) + { + validateName( name ); + + Locale l = d.locale(); + + Cur c = l.tempCur(); + + c.createElement( l.makeQualifiedQName( "", name ) ); + + Dom e = c.getDom(); + + c.release(); + ((Xobj.ElementXobj)e)._canHavePrefixUri = false; + return e; + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static Element _document_createElementNS ( Dom d, String uri, String qname ) + { + Locale l = d.locale(); + + Dom e; + + if (l.noSync()) { l.enter(); try { e = document_createElementNS( d, uri, qname ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { e = document_createElementNS( d, uri, qname ); } finally { l.exit(); } } + + return (Element) e; + } + + public static Dom document_createElementNS ( Dom d, String uri, String qname ) + { + validateQualifiedName( qname, uri, false ); + + Locale l = d.locale(); + + Cur c = l.tempCur(); + + c.createElement( l.makeQualifiedQName( uri, qname ) ); + + Dom e = c.getDom(); + + c.release(); + + return e; + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static Attr _document_createAttribute ( Dom d, String name ) + { + Locale l = d.locale(); + + Dom a; + + if (l.noSync()) { l.enter(); try { a = document_createAttribute( d, name ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { a = document_createAttribute( d, name ); } finally { l.exit(); } } + + return (Attr) a; + } + + public static Dom document_createAttribute ( Dom d, String name ) + { + validateName( name ); + + Locale l = d.locale(); + + Cur c = l.tempCur(); + + c.createAttr( l.makeQualifiedQName( "", name ) ); + + Dom e = c.getDom(); + + c.release(); + ((Xobj.AttrXobj)e)._canHavePrefixUri = false; + return e; + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static Attr _document_createAttributeNS ( Dom d, String uri, String qname ) + { + Locale l = d.locale(); + + Dom a; + + if (l.noSync()) { l.enter(); try { a = document_createAttributeNS( d, uri, qname ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { a = document_createAttributeNS( d, uri, qname ); } finally { l.exit(); } } + + return (Attr) a; + } + + public static Dom document_createAttributeNS ( Dom d, String uri, String qname ) + { + validateQualifiedName( qname, uri, true ); + + Locale l = d.locale(); + + Cur c = l.tempCur(); + + c.createAttr( l.makeQualifiedQName( uri, qname ) ); + + Dom e = c.getDom(); + + c.release(); + + return e; + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static Comment _document_createComment ( Dom d, String data ) + { + Locale l = d.locale(); + + Dom c; + + if (l.noSync()) { l.enter(); try { c = document_createComment( d, data ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { c = document_createComment( d, data ); } finally { l.exit(); } } + + return (Comment) c; + } + + public static Dom document_createComment ( Dom d, String data ) + { + Locale l = d.locale(); + + Cur c = l.tempCur(); + + c.createComment(); + + Dom comment = c.getDom(); + + if (data != null) + { + c.next(); + c.insertString( data ); + } + + c.release(); + + return comment; + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static ProcessingInstruction _document_createProcessingInstruction ( Dom d, String target, String data ) + { + Locale l = d.locale(); + + Dom pi; + + if (l.noSync()) { l.enter(); try { pi = document_createProcessingInstruction( d, target, data ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { pi = document_createProcessingInstruction( d, target, data ); } finally { l.exit(); } } + + return (ProcessingInstruction) pi; + } + + public static Dom document_createProcessingInstruction ( Dom d, String target, String data ) + { + if (target == null) + throw new IllegalArgumentException( "Target is null" ); + + if (target.length() == 0) + throw new IllegalArgumentException( "Target is empty" ); + + if (!XMLChar.isValidName( target )) + throw new InvalidCharacterError( "Target has an invalid character" ); + + if (Locale.beginsWithXml( target ) && target.length() == 3) + throw new InvalidCharacterError( "Invalid target - is 'xml'" ); + + Locale l = d.locale(); + + Cur c = l.tempCur(); + + c.createProcinst( target ); + + Dom pi = c.getDom(); + + if (data != null) + { + c.next(); + c.insertString( data ); + } + + c.release(); + + return pi; + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static CDATASection _document_createCDATASection ( Dom d, String data ) + { + return (CDATASection) document_createCDATASection( d, data ); + } + + public static Dom document_createCDATASection ( Dom d, String data ) + { + TextNode t = d.locale().createCdataNode(); + + if (data == null) + data = ""; + + t.setChars( data, 0, data.length() ); + + return t; + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static Text _document_createTextNode ( Dom d, String data ) + { + return (Text) document_createTextNode( d, data ); + } + + public static CharNode document_createTextNode ( Dom d, String data ) + { + TextNode t = d.locale().createTextNode(); + + if (data == null) + data = ""; + + t.setChars( data, 0, data.length() ); + + return t; + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static EntityReference _document_createEntityReference ( Dom d, String name ) + { + throw new RuntimeException( "Not implemented" ); + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static Element _document_getElementById ( Dom d, String elementId ) + { + throw new RuntimeException( "Not implemented" ); + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static NodeList _document_getElementsByTagName ( Dom d, String name ) + { + Locale l = d.locale(); + + if (l.noSync()) { l.enter(); try { return document_getElementsByTagName( d, name ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return document_getElementsByTagName( d, name ); } finally { l.exit(); } } + } + + public static NodeList document_getElementsByTagName ( Dom d, String name ) + { + return new ElementsByTagNameNodeList( d, name ); + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static NodeList _document_getElementsByTagNameNS ( Dom d, String uri, String local ) + { + Locale l = d.locale(); + + if (l.noSync()) { l.enter(); try { return document_getElementsByTagNameNS( d, uri, local ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return document_getElementsByTagNameNS( d, uri, local ); } finally { l.exit(); } } + } + + public static NodeList document_getElementsByTagNameNS ( Dom d, String uri, String local ) + { + return new ElementsByTagNameNSNodeList( d, uri, local ); + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static DOMImplementation _document_getImplementation ( Dom d ) + { + return (DOMImplementation) d.locale(); + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static Node _document_importNode ( Dom d, Node n, boolean deep ) + { + Locale l = d.locale(); + Dom i; + +// // TODO - need to wrap this in sync .. +// if (n instanceof Dom) +// i = node_cloneNode( (Dom) n, deep, m ); +// else +// TODO -- I'm importing my own nodes through DOM methods! -- make this faster + { + if (l.noSync()) { l.enter(); try { i = document_importNode( d, n, deep ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { i = document_importNode( d, n, deep ); } finally { l.exit(); } } + } + + return (Node) i; + } + + public static Dom document_importNode ( Dom d, Node n, boolean deep ) + { + if (n == null) + return null; + + Dom i; + + boolean copyChildren = false; + + switch ( n.getNodeType() ) + { + case DOCUMENT : + throw new NotSupportedError( "Document nodes may not be imported" ); + + case DOCTYPE : + throw new NotSupportedError( "Document type nodes may not be imported" ); + + case ELEMENT : + { + String local = n.getLocalName(); + + if (local == null || local.length() == 0) + i = document_createElement( d, n.getNodeName() ); + else + { + String prefix = n.getPrefix(); + String name = prefix == null || prefix.length() == 0 ? local : prefix + ":" + local; + String uri = n.getNamespaceURI(); + + if (uri == null || uri.length() == 0) + i = document_createElement( d, name ); + else + i = document_createElementNS( d, uri, name ); + } + + NamedNodeMap attrs = n.getAttributes(); + + for ( int a = 0 ; a < attrs.getLength() ; a++ ) + attributes_setNamedItem( i, document_importNode( d, attrs.item( a ), true ) ); + + copyChildren = deep; + + break; + } + + case ATTR : + { + String local = n.getLocalName(); + + if (local == null || local.length() == 0) + i = document_createAttribute( d, n.getNodeName() ); + else + { + String prefix = n.getPrefix(); + String name = prefix == null || prefix.length() == 0 ? local : prefix + ":" + local; + String uri = n.getNamespaceURI(); + + if (uri == null || uri.length() == 0) + i = document_createAttribute( d, name ); + else + i = document_createAttributeNS( d, uri, name ); + } + + copyChildren = true; + + break; + } + + case DOCFRAG : + { + i = document_createDocumentFragment( d ); + + copyChildren = deep; + + break; + } + + case PROCINST : + { + i = document_createProcessingInstruction( d, n.getNodeName(), n.getNodeValue() ); + break; + } + + case COMMENT : + { + i = document_createComment( d, n.getNodeValue() ); + break; + } + + case TEXT : + { + i = document_createTextNode( d, n.getNodeValue() ); + break; + } + + case CDATA : + { + i = document_createCDATASection( d, n.getNodeValue() ); + break; + } + + case ENTITYREF : + case ENTITY : + case NOTATION : + throw new RuntimeException( "Not impl" ); + + default : throw new RuntimeException( "Unknown kind" ); + } + + if (copyChildren) + { + NodeList children = n.getChildNodes(); + + for ( int c = 0 ; c < children.getLength() ; c++ ) + node_insertBefore( i, document_importNode( d, children.item( c ), true ), null); + } + + return i; + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static DocumentType _document_getDoctype ( Dom d ) + { + Locale l = d.locale(); + + Dom dt; + + if (l.noSync()) { l.enter(); try { dt = document_getDoctype( d ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { dt = document_getDoctype( d ); } finally { l.exit(); } } + + return (DocumentType) dt; + } + + public static Dom document_getDoctype ( Dom d ) + { + return null; + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static Document _node_getOwnerDocument ( Dom n ) + { + Locale l = n.locale(); + + Dom d; + + if (l.noSync()) { l.enter(); try { d = node_getOwnerDocument( n ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { d = node_getOwnerDocument( n ); } finally { l.exit(); } } + + return (Document) d; + } + + public static Dom node_getOwnerDocument ( Dom n ) + { + if (n.nodeType() == DOCUMENT) + return null; + + Locale l = n.locale(); + + if (l._ownerDoc == null) + { + Cur c = l.tempCur(); + c.createDomDocumentRoot(); + l._ownerDoc = c.getDom(); + c.release(); + } + + return l._ownerDoc; + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static Node _node_getParentNode ( Dom n ) + { + Locale l = n.locale(); + + Dom p; + + if (l.noSync()) { l.enter(); try { p = node_getParentNode( n ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { p = node_getParentNode( n ); } finally { l.exit(); } } + + return (Node) p; + } + + public static Dom node_getParentNode ( Dom n ) + { + Cur c = null; + + switch ( n.nodeType() ) + { + case DOCUMENT : + case DOCFRAG : + case ATTR : + break; + + case PROCINST : + case COMMENT : + case ELEMENT : + { + if (!(c = n.tempCur()).toParentRaw()) + { + c.release(); + c = null; + } + + break; + } + + case TEXT : + case CDATA : + { + if ((c = n.tempCur()) != null) + c.toParent(); + + break; + } + + case ENTITYREF : + throw new RuntimeException( "Not impl" ); + + case ENTITY : + case DOCTYPE : + case NOTATION : + throw new RuntimeException( "Not impl" ); + + default : throw new RuntimeException( "Unknown kind" ); + } + + if (c == null) + return null; + + Dom d = c.getDom(); + + c.release(); + + return d; + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static Node _node_getFirstChild ( Dom n ) + { + Locale l = n.locale(); + + Dom fc; + assert n instanceof Xobj; + Xobj node = (Xobj)n; + if (!node.isVacant()) + { + if (node.isFirstChildPtrDomUsable()) + return (Node) node._firstChild; + Xobj lastAttr = node.lastAttr(); + if (lastAttr != null && + lastAttr.isNextSiblingPtrDomUsable()) + return (Xobj.NodeXobj) lastAttr._nextSibling; + if (node.isExistingCharNodesValueUsable()) + return node._charNodesValue; + } + if (l.noSync()) { fc = node_getFirstChild( n ); } + else synchronized ( l ) { fc = node_getFirstChild( n ); } + + return (Node) fc; + } + + public static Dom node_getFirstChild ( Dom n ) + { + Dom fc = null; + + switch ( n.nodeType() ) + { + case TEXT : + case CDATA : + case PROCINST : + case COMMENT : + break; + + case ENTITYREF : + throw new RuntimeException( "Not impl" ); + + case ENTITY : + case DOCTYPE : + case NOTATION : + throw new RuntimeException( "Not impl" ); + + case ELEMENT : + case DOCUMENT : + case DOCFRAG : + case ATTR : + { + + Xobj node = (Xobj) n; + node.ensureOccupancy(); + if (node.isFirstChildPtrDomUsable()) + return (Xobj.NodeXobj) node._firstChild; + Xobj lastAttr = node.lastAttr(); + if (lastAttr != null) + { + if (lastAttr.isNextSiblingPtrDomUsable()) + return (Xobj.NodeXobj) lastAttr._nextSibling; + else if (lastAttr.isCharNodesAfterUsable()) + return (CharNode) lastAttr._charNodesAfter; + } + if (node.isCharNodesValueUsable()) + return node._charNodesValue; + + + break; + } + } + + // TODO - handle entity refs here ... + + return fc; + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static Node _node_getLastChild ( Dom n ) + { + Locale l = n.locale(); + + Dom lc; + + if (l.noSync()) { l.enter(); try { lc = node_getLastChild( n ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { lc = node_getLastChild( n ); } finally { l.exit(); } } + + return (Node) lc; + } + + public static Dom node_getLastChild ( Dom n ) + { + switch ( n.nodeType() ) + { + case TEXT : + case CDATA : + case PROCINST : + case COMMENT : + return null; + + case ENTITYREF : + throw new RuntimeException( "Not impl" ); + + case ENTITY : + case DOCTYPE : + case NOTATION : + throw new RuntimeException( "Not impl" ); + + case ELEMENT : + case DOCUMENT : + case DOCFRAG : + case ATTR : + break; + } + + Dom lc = null; + CharNode nodes; + + Cur c = n.tempCur(); + + if (c.toLastChild()) + { + lc = c.getDom(); + + c.skip(); + + if ((nodes = c.getCharNodes()) != null) + lc = null; + } + else + { + c.next(); + nodes = c.getCharNodes(); + } + + if (lc == null && nodes != null) + { + while ( nodes._next != null ) + nodes = nodes._next; + + lc = nodes; + } + + c.release(); + + // TODO - handle entity refs here ... + + return lc; + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static Node _node_getNextSibling ( Dom n ) + { + Locale l = n.locale(); + + Dom ns; + + if (l.noSync()) { ns = node_getNextSibling( n ); } + else synchronized ( l ) { ns = node_getNextSibling( n ); } + + return (Node) ns; + } + + public static Dom node_getNextSibling ( Dom n ) + { + Dom ns = null; + + switch ( n.nodeType() ) + { + case DOCUMENT : + case DOCFRAG : + case ATTR : + break; + + case TEXT : + case CDATA : + { + CharNode cn = (CharNode) n; + //if src is attr & next is null , ret null; + //if src is container and + // a) this node is aftertext && src._nextSib = null; ret null + // b) this node is value && src._fc = null; ret null + + + if (! (cn._src instanceof Xobj) ) + return null; + Xobj src = (Xobj) cn._src; + //if src is attr this node is always value and + // next is always the next ptr of the attr + src._charNodesAfter = + Cur.updateCharNodes( src._locale, src, src._charNodesAfter, src._cchAfter ); + + src._charNodesValue = + Cur.updateCharNodes( src._locale, src, src._charNodesValue, src._cchValue ); + + if (cn._next != null) + { + ns = cn._next; + break; + } + boolean isThisNodeAfterText = cn.isNodeAftertext(); + + if (isThisNodeAfterText) + ns = (Xobj.NodeXobj) src._nextSibling; + else //srcValue or attribute source + ns = (Xobj.NodeXobj) src._firstChild; + break; + + } + + case PROCINST : + case COMMENT : + case ELEMENT : + { + assert n instanceof Xobj: "PI, Comments and Elements always backed up by Xobj"; + Xobj node = (Xobj) n; + node.ensureOccupancy(); + if (node.isNextSiblingPtrDomUsable()) + return + (Xobj.NodeXobj) node._nextSibling; + if (node.isCharNodesAfterUsable()) + return node._charNodesAfter; + break; + } + + case ENTITY : + case NOTATION : + case ENTITYREF : + case DOCTYPE : + throw new RuntimeException( "Not implemented" ); + } + + // TODO - handle entity refs here ... + + return ns; + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static Node _node_getPreviousSibling ( Dom n ) + { + Locale l = n.locale(); + + Dom ps; + + if (l.noSync()) { ps = node_getPreviousSibling( n ); } + else synchronized ( l ) { ps = node_getPreviousSibling( n ); } + + return (Node) ps; + } + + public static Dom node_getPreviousSibling ( Dom n ) + { + Dom prev = null; + Dom temp; + switch (n.nodeType()) + { + case TEXT: + case CDATA: + { + assert n instanceof CharNode: "Text/CData should be a CharNode"; + CharNode node = (CharNode) n; + if (!(node._src instanceof Xobj)) + return null; + Xobj src = (Xobj) node._src; + src.ensureOccupancy(); + boolean isThisNodeAfterText = node.isNodeAftertext(); + prev = node._prev; + if (prev == null) + prev = isThisNodeAfterText ? (Dom) src : + src._charNodesValue; + break; + } + default: + { + assert n instanceof Xobj; + Xobj node = (Xobj) n; + prev = (Dom) node._prevSibling; + if (prev == null && node._parent != null) + prev = (Dom) node_getFirstChild((Dom) node._parent); + } + } + temp = (Dom) prev; + while (temp != null && + (temp = node_getNextSibling(temp)) != n) + prev = temp; + return prev; + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static boolean _node_hasAttributes ( Dom n ) + { + Locale l = n.locale(); + + if (l.noSync()) { l.enter(); try { return node_hasAttributes( n ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return node_hasAttributes( n ); } finally { l.exit(); } } + } + + public static boolean node_hasAttributes ( Dom n ) + { + boolean hasAttrs = false; + + if (n.nodeType() == ELEMENT) + { + Cur c = n.tempCur(); + + hasAttrs = c.hasAttrs(); + + c.release(); + } + + return hasAttrs; + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static boolean _node_isSupported ( Dom n, String feature, String version ) + { + return _domImplementation_hasFeature( n.locale(), feature, version ); + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static void _node_normalize ( Dom n ) + { + Locale l = n.locale(); + + if (l.noSync()) { l.enter(); try { node_normalize( n ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { node_normalize( n ); } finally { l.exit(); } } + } + + public static void node_normalize ( Dom n ) + { + switch ( n.nodeType() ) + { + case TEXT : + case CDATA : + case PROCINST : + case COMMENT : + return; + + case ENTITYREF : + throw new RuntimeException( "Not impl" ); + + case ENTITY : + case DOCTYPE : + case NOTATION : + throw new RuntimeException( "Not impl" ); + + case ELEMENT : + case DOCUMENT : + case DOCFRAG : + case ATTR : + break; + } + + Cur c = n.tempCur(); + + c.push(); + + do + { + c.nextWithAttrs(); + + CharNode cn = c.getCharNodes(); + + if (cn != null) + { + if (!c.isText()) + { + while ( cn != null ) + { + cn.setChars( null, 0, 0 ); + cn = CharNode.remove( cn, cn ); + } + } + else if (cn._next != null) + { + while ( cn._next != null ) + { + cn.setChars( null, 0, 0 ); + cn = CharNode.remove( cn, cn._next ); + } + + cn._cch = Integer.MAX_VALUE; + } + + c.setCharNodes( cn ); + } + } + while ( ! c.isAtEndOfLastPush() ); + + c.release(); + + n.locale().invalidateDomCaches(n); + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static boolean _node_hasChildNodes ( Dom n ) + { + // TODO - make this faster + return _node_getFirstChild( n ) != null; + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static Node _node_appendChild ( Dom p, Node newChild ) + { + return _node_insertBefore( p, newChild, null ); + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static Node _node_replaceChild ( Dom p, Node newChild, Node oldChild ) + { + Locale l = p.locale(); + + if (newChild == null) + throw new IllegalArgumentException( "Child to add is null" ); + + if (oldChild == null) + throw new NotFoundErr( "Child to replace is null" ); + + Dom nc; + + if (!(newChild instanceof Dom) || (nc = (Dom) newChild).locale() != l) + throw new WrongDocumentErr( "Child to add is from another document" ); + + Dom oc = null; + + if (!(oldChild instanceof Dom) || (oc = (Dom) oldChild).locale() != l) + throw new WrongDocumentErr( "Child to replace is from another document" ); + + Dom d; + + if (l.noSync()) { l.enter(); try { d = node_replaceChild( p, nc, oc ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { d = node_replaceChild( p, nc, oc ); } finally { l.exit(); } } + + return (Node) d; + } + + public static Dom node_replaceChild ( Dom p, Dom newChild, Dom oldChild ) + { + // Remove the old child firest to avoid a dom exception raised + // when inserting two document elements + + Dom nextNode = node_getNextSibling( oldChild ); + + node_removeChild( p, oldChild ); + + try + { + node_insertBefore( p, newChild, nextNode ); + } + catch ( DOMException e ) + { + node_insertBefore( p, oldChild, nextNode ); + + throw e; + } + + return oldChild; + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static Node _node_insertBefore ( Dom p, Node newChild, Node refChild ) + { + Locale l = p.locale(); + + if (newChild == null) + throw new IllegalArgumentException( "Child to add is null" ); + + Dom nc; + + if (!(newChild instanceof Dom) || (nc = (Dom) newChild).locale() != l) + throw new WrongDocumentErr( "Child to add is from another document" ); + + Dom rc = null; + + if (refChild != null) + { + if (!(refChild instanceof Dom) || (rc = (Dom) refChild).locale() != l) + throw new WrongDocumentErr( "Reference child is from another document" ); + } + + Dom d; + + if (l.noSync()) { l.enter(); try { d = node_insertBefore( p, nc, rc ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { d = node_insertBefore( p, nc, rc ); } finally { l.exit(); } } + + return (Node) d; + } + + public static Dom node_insertBefore ( Dom p, Dom nc, Dom rc ) + { + assert nc != null; + + // Inserting self before self is a no-op + + if (nc == rc) + return nc; + + if (rc != null && parent( rc ) != p) + throw new NotFoundErr( "RefChild is not a child of this node" ); + + // TODO - obey readonly status of a substree + + int nck = nc.nodeType(); + + if (nck == DOCFRAG) + { + for ( Dom c = firstChild( nc ) ; c != null ; c = nextSibling( c ) ) + validateNewChild( p, c ); + + for ( Dom c = firstChild( nc ) ; c != null ; ) + { + Dom n = nextSibling( c ); + + if (rc == null) + append( c, p ); + else + insert( c, rc ); + + c = n; + } + + return nc; + } + + // + // Make sure the new child is allowed here + // + + validateNewChild( p, nc ); + + // + // Orphan the child before establishing a new parent + // + + remove( nc ); + + int pk = p.nodeType(); + + // Only these nodes can be modifiable parents + assert pk == ATTR || pk == DOCFRAG || pk == DOCUMENT || pk == ELEMENT; + + switch ( nck ) + { + case ELEMENT : + case COMMENT : + case PROCINST : + { + if (rc == null) + { + Cur cTo = p.tempCur(); + cTo.toEnd(); + Cur.moveNode( (Xobj) nc, cTo ); + cTo.release(); + } + else + { + int rck = rc.nodeType(); + + if (rck == TEXT || rck == CDATA) + { + // Quick and dirty impl.... + + ArrayList charNodes = new ArrayList(); + + while ( rc != null && (rc.nodeType() == TEXT || rc.nodeType() == CDATA ) ) + { + Dom next = nextSibling( rc ); + charNodes.add( remove( rc ) ); + rc = next; + } + + if (rc == null) + append( nc, p ); + else + insert( nc, rc ); + + rc = nextSibling( nc ); + + for ( int i = 0 ; i < charNodes.size() ; i++ ) + { + Dom n = (Dom) charNodes.get( i ); + + if (rc == null) + append( n, p ); + else + insert( n, rc ); + } + } + else if (rck == ENTITYREF) + { + throw new RuntimeException( "Not implemented" ); + } + else + { + assert rck == ELEMENT || rck == PROCINST || rck == COMMENT; + Cur cTo = rc.tempCur(); + Cur.moveNode( (Xobj) nc, cTo ); + cTo.release(); + } + } + + break; + } + + case TEXT : + case CDATA : + { + CharNode n = (CharNode) nc; + + assert n._prev == null && n._next == null; + + CharNode refCharNode = null; + Cur c = p.tempCur(); + + if (rc == null) + c.toEnd(); + else + { + int rck = rc.nodeType(); + + if (rck == TEXT || rck == CDATA) + c.moveToCharNode( refCharNode = (CharNode) rc ); + else if (rck == ENTITYREF) + throw new RuntimeException( "Not implemented" ); + else + c.moveToDom( rc ); + } + + CharNode nodes = c.getCharNodes(); + + nodes = CharNode.insertNode( nodes, n, refCharNode ); + + c.insertChars( n._src, n._off, n._cch ); + + c.setCharNodes( nodes ); + + c.release(); + + break; + } + + case ENTITYREF : + { + throw new RuntimeException( "Not implemented" ); + } + + case DOCTYPE : + { + // TODO - don't actually insert this here, associate it with the + // doc?? Hmm .. Perhaps I should disallow insertion into the tree + // at all. + + throw new RuntimeException( "Not implemented" ); + } + + default : throw new RuntimeException( "Unexpected child node type" ); + } + + return nc; + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static Node _node_removeChild ( Dom p, Node child ) + { + Locale l = p.locale(); + + if (child == null) + throw new NotFoundErr( "Child to remove is null" ); + + Dom c; + + if (!(child instanceof Dom) || (c = (Dom) child).locale() != l) + throw new WrongDocumentErr( "Child to remove is from another document" ); + + Dom d; + + if (l.noSync()) { l.enter(); try { d = node_removeChild( p, c ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { d = node_removeChild( p, c ); } finally { l.exit(); } } + + return (Node) d; + } + + public static Dom node_removeChild ( Dom parent, Dom child ) + { + if (parent( child ) != parent) + throw new NotFoundErr( "Child to remove is not a child of given parent" ); + + switch ( child.nodeType() ) + { + case DOCUMENT : + case DOCFRAG : + case ATTR : + throw new IllegalStateException(); + + case ELEMENT : + case PROCINST : + case COMMENT : + removeNode( child ); + break; + + case TEXT : + case CDATA : + { + Cur c = child.tempCur(); + + CharNode nodes = c.getCharNodes(); + + CharNode cn = (CharNode) child; + + assert cn._src instanceof Dom; + + cn.setChars( c.moveChars( null, cn._cch ), c._offSrc, c._cchSrc ); + + c.setCharNodes( CharNode.remove( nodes, cn ) ); + + c.release(); + + break; + } + + case ENTITYREF : + throw new RuntimeException( "Not impl" ); + + case ENTITY : + case DOCTYPE : + case NOTATION : + throw new RuntimeException( "Not impl" ); + + default : throw new RuntimeException( "Unknown kind" ); + } + + return child; + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static Node _node_cloneNode ( Dom n, boolean deep ) + { + Locale l = n.locale(); + + Dom c; + + if (l.noSync()) { l.enter(); try { c = node_cloneNode( n, deep ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { c = node_cloneNode( n, deep ); } finally { l.exit(); } } + + return (Node) c; + } + + public static Dom node_cloneNode ( Dom n, boolean deep ) + { + Locale l = n.locale(); + + Dom clone = null; + + if (!deep) + { + Cur shallow = null; + + switch ( n.nodeType() ) + { + case DOCUMENT : + shallow = l.tempCur(); + shallow.createDomDocumentRoot(); + break; + + case DOCFRAG : + shallow = l.tempCur(); + shallow.createDomDocFragRoot(); + break; + + case ELEMENT : + { + shallow = l.tempCur(); + shallow.createElement( n.getQName() ); + + Element elem = (Element) shallow.getDom(); + NamedNodeMap attrs = ((Element) n).getAttributes(); + + for ( int i = 0 ; i < attrs.getLength() ; i++ ) + elem.setAttributeNodeNS( (Attr) attrs.item( i ).cloneNode( true ) ); + + break; + } + + case ATTR : + shallow = l.tempCur(); + shallow.createAttr( n.getQName() ); + break; + + case PROCINST : + case COMMENT : + case TEXT : + case CDATA : + case ENTITYREF : + case ENTITY : + case DOCTYPE : + case NOTATION : + break; + } + + if (shallow != null) + { + clone = shallow.getDom(); + shallow.release(); + } + } + + if (clone == null) + { + switch ( n.nodeType() ) + { + case DOCUMENT : + case DOCFRAG : + case ATTR : + case ELEMENT : + case PROCINST : + case COMMENT : + { + Cur cClone = l.tempCur(); + Cur cSrc = n.tempCur(); + cSrc.copyNode( cClone ); + clone = cClone.getDom(); + cClone.release(); + cSrc.release(); + + break; + } + + case TEXT : + case CDATA : + { + Cur c = n.tempCur(); + + CharNode cn = n.nodeType() == TEXT ? l.createTextNode() : l.createCdataNode(); + + cn.setChars( c.getChars( ((CharNode) n)._cch ), c._offSrc, c._cchSrc ); + + clone = cn; + + c.release(); + + break; + } + + case ENTITYREF : + case ENTITY : + case DOCTYPE : + case NOTATION : + throw new RuntimeException( "Not impl" ); + + default : throw new RuntimeException( "Unknown kind" ); + } + } + + return clone; + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static String _node_getLocalName ( Dom n ) + { + if (! n.nodeCanHavePrefixUri() ) return null; + QName name = n.getQName(); + return name == null ? "" : name.getLocalPart(); + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static String _node_getNamespaceURI ( Dom n ) + { + if (! n.nodeCanHavePrefixUri() ) return null; + QName name = n.getQName(); + // TODO - should return the correct namespace for xmlns ... + return name == null ? "": + //name.getNamespaceURI().equals("")? null: + name.getNamespaceURI(); + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static void _node_setPrefix ( Dom n, String prefix ) + { + Locale l = n.locale(); + + if (l.noSync()) { l.enter(); try { node_setPrefix( n, prefix ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { node_setPrefix( n, prefix ); } finally { l.exit(); } } + } + + public static void node_setPrefix ( Dom n, String prefix ) + { + // TODO - make it possible to set the prefix of an xmlns + // TODO - test to make use prefix: xml maps to the predefined namespace + // if set???? hmmm ... perhaps I should not allow the setting of any + // prefixes which start with xml unless the namespace is the predefined + // one and the prefix is 'xml' all other prefixes which start with + // 'xml' should fail. + + if (n.nodeType() == ELEMENT || n.nodeType() == ATTR) + { + Cur c = n.tempCur(); + QName name = c.getName(); + String uri = name.getNamespaceURI(); + String local = name.getLocalPart(); + + prefix = validatePrefix( prefix, uri, local, n.nodeType() == ATTR ); + + c.setName( n.locale().makeQName( uri, local, prefix ) ); + + c.release(); + } + else + validatePrefix( prefix, "", "", false ); + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static String _node_getPrefix ( Dom n ) + { + if (! n.nodeCanHavePrefixUri() ) return null; + QName name = n.getQName(); + return name == null ? "" : + name.getPrefix(); + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static String _node_getNodeName ( Dom n ) + { + switch ( n.nodeType() ) + { + case CDATA : return "#cdata-section"; + case COMMENT : return "#comment"; + case DOCFRAG : return "#document-fragment"; + case DOCUMENT : return "#document"; + case PROCINST : return n.getQName().getLocalPart(); + case TEXT : return "#text"; + + case ATTR : + case ELEMENT : + { + QName name = n.getQName(); + String prefix = name.getPrefix(); + return prefix.length() == 0 ? name.getLocalPart() : prefix + ":" + name.getLocalPart(); + } + + case DOCTYPE : + case ENTITY : + case ENTITYREF : + case NOTATION : + throw new RuntimeException( "Not impl" ); + + default : throw new RuntimeException( "Unknown node type" ); + } + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static short _node_getNodeType ( Dom n ) + { + return (short) n.nodeType(); + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static void _node_setNodeValue ( Dom n, String nodeValue ) + { + Locale l = n.locale(); + + if (l.noSync()) { l.enter(); try { node_setNodeValue( n, nodeValue ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { node_setNodeValue( n, nodeValue ); } finally { l.exit(); } } + } + + public static void node_setNodeValue ( Dom n, String nodeValue ) + { + if (nodeValue == null) + nodeValue = ""; + + switch ( n.nodeType() ) + { + case TEXT : + case CDATA : + { + CharNode cn = (CharNode) n; + + Cur c; + + if ((c = cn.tempCur()) != null) + { + c.moveChars( null, cn._cch ); + cn._cch = nodeValue.length(); + c.insertString( nodeValue ); + c.release(); + } + else + cn.setChars( nodeValue, 0, nodeValue.length() ); + + break; + } + + case ATTR : + { + // Try to set an exisiting text node to contain the new value + + NodeList children = ((Node) n).getChildNodes(); + + while ( children.getLength() > 1 ) + node_removeChild( n, (Dom) children.item( 1 ) ); + + if (children.getLength() == 0) + { + TextNode tn = n.locale().createTextNode(); + tn.setChars( nodeValue, 0, nodeValue.length() ); + node_insertBefore( n, tn, null ); + } + else + { + assert children.getLength() == 1; + children.item( 0 ).setNodeValue( nodeValue ); + } + if (((Xobj.AttrXobj) n).isId()) + { + Dom d = DomImpl.node_getOwnerDocument(n); + String val = node_getNodeValue(n); + if (d instanceof Xobj.DocumentXobj) + { + ((Xobj.DocumentXobj) d).removeIdElement(val); + ((Xobj.DocumentXobj) d).addIdElement(nodeValue, + attr_getOwnerElement(n)); + } + } + + break; + } + + case PROCINST : + case COMMENT : + { + Cur c = n.tempCur(); + c.next(); + + c.getChars( -1 ); + c.moveChars( null, c._cchSrc ); + c.insertString( nodeValue ); + + c.release(); + + break; + } + } + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static String _node_getNodeValue ( Dom n ) + { + Locale l = n.locale(); + + if (l.noSync()) { return node_getNodeValue( n ); } + else synchronized ( l ) { return node_getNodeValue( n ); } + } + + public static String node_getNodeValue ( Dom n ) + { + String s = null; + + switch ( n.nodeType() ) + { + case ATTR : + case PROCINST : + case COMMENT : + { + s = ((Xobj)n).getValueAsString(); + break; + } + + case TEXT : + case CDATA : + { + assert n instanceof CharNode: "Text/CData should be a CharNode"; + CharNode node = (CharNode) n; + if (! (node._src instanceof Xobj) ) + s = CharUtil.getString( node._src, node._off, node._cch ); + else{ + Xobj src = (Xobj) node._src; + src.ensureOccupancy(); + boolean isThisNodeAfterText = node.isNodeAftertext(); + if( isThisNodeAfterText ){ + src._charNodesAfter = + Cur.updateCharNodes( src._locale, src, src._charNodesAfter, src._cchAfter ); + s = src.getCharsAfterAsString(node._off, node._cch); + } + else{ + src._charNodesValue = + Cur.updateCharNodes( src._locale, src, src._charNodesValue, src._cchValue ); + s = src.getCharsValueAsString(node._off, node._cch); + } + + } + break; + } + } + + return s; + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static Object _node_getUserData ( Dom n, String key ) + { + throw new RuntimeException( "DOM Level 3 Not implemented" ); + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static Object _node_setUserData ( Dom n, String key, Object data, UserDataHandler handler ) + { + throw new RuntimeException( "DOM Level 3 Not implemented" ); + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static Object _node_getFeature ( Dom n, String feature, String version ) + { + throw new RuntimeException( "DOM Level 3 Not implemented" ); + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static boolean _node_isEqualNode ( Dom n, Node arg ) + { + throw new RuntimeException( "DOM Level 3 Not implemented" ); + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static boolean _node_isSameNode ( Dom n, Node arg ) + { + throw new RuntimeException( "DOM Level 3 Not implemented" ); + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static String _node_lookupNamespaceURI ( Dom n, String prefix ) + { + throw new RuntimeException( "DOM Level 3 Not implemented" ); + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static boolean _node_isDefaultNamespace ( Dom n, String namespaceURI ) + { + throw new RuntimeException( "DOM Level 3 Not implemented" ); + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static String _node_lookupPrefix ( Dom n, String namespaceURI ) + { + throw new RuntimeException( "DOM Level 3 Not implemented" ); + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static void _node_setTextContent ( Dom n, String textContent ) + { + throw new RuntimeException( "DOM Level 3 Not implemented" ); + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static String _node_getTextContent ( Dom n ) + { + throw new RuntimeException( "DOM Level 3 Not implemented" ); + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static short _node_compareDocumentPosition ( Dom n, Node other ) + { + throw new RuntimeException( "DOM Level 3 Not implemented" ); + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static String _node_getBaseURI ( Dom n ) + { + throw new RuntimeException( "DOM Level 3 Not implemented" ); + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static Node _childNodes_item ( Dom n, int i ) + { + Locale l = n.locale(); + + Dom d; + if (i == 0) return _node_getFirstChild(n); + if (l.noSync()) { d = childNodes_item( n, i ); } + else synchronized ( l ) { d = childNodes_item( n, i ); } + + return (Node) d; + } + + public static Dom childNodes_item ( Dom n, int i ) + { + if (i < 0) + return null; + + switch ( n.nodeType() ) + { + case TEXT : + case CDATA : + case PROCINST : + case COMMENT : + return null; + + case ENTITYREF : + throw new RuntimeException( "Not impl" ); + + case ENTITY : + case DOCTYPE : + case NOTATION : + throw new RuntimeException( "Not impl" ); + + case ELEMENT : + case DOCUMENT : + case DOCFRAG : + case ATTR : + break; + } + if ( i == 0 ) + return node_getFirstChild ( n ); + return n.locale().findDomNthChild(n, i); + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static int _childNodes_getLength ( Dom n ) + { + Locale l = n.locale(); + assert n instanceof Xobj; + int count; + Xobj node = (Xobj) n; + if (!node.isVacant() && + (count = node.getDomZeroOneChildren()) < 2) + return count; + if (l.noSync()) { return childNodes_getLength( n ); } + else synchronized ( l ) { return childNodes_getLength( n ); } + } + + public static int childNodes_getLength ( Dom n ) + { + switch ( n.nodeType() ) + { + case TEXT : + case CDATA : + case PROCINST : + case COMMENT : + return 0; + + case ENTITYREF : + throw new RuntimeException( "Not impl" ); + + case ENTITY : + case DOCTYPE : + case NOTATION : + throw new RuntimeException( "Not impl" ); + + case ELEMENT : + case DOCUMENT : + case DOCFRAG : + case ATTR : + break; + } + + int count; + assert n instanceof Xobj; + Xobj node = (Xobj) n; + node.ensureOccupancy(); + if ((count = node.getDomZeroOneChildren()) < 2) + return count; + return n.locale().domLength(n); + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static String _element_getTagName ( Dom e ) + { + return _node_getNodeName( e ); + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static Attr _element_getAttributeNode ( Dom e, String name ) + { + return (Attr) _attributes_getNamedItem( e, name ); + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static Attr _element_getAttributeNodeNS ( Dom e, String uri, String local ) + { + return (Attr) _attributes_getNamedItemNS( e, uri, local ); + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static Attr _element_setAttributeNode ( Dom e, Attr newAttr ) + { + return (Attr) _attributes_setNamedItem( e, newAttr ); + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static Attr _element_setAttributeNodeNS ( Dom e, Attr newAttr ) + { + return (Attr) _attributes_setNamedItemNS( e, newAttr ); + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static String _element_getAttribute ( Dom e, String name ) + { + Node a = _attributes_getNamedItem( e, name ); + return a == null ? "" : a.getNodeValue(); + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static String _element_getAttributeNS ( Dom e, String uri, String local ) + { + Node a = _attributes_getNamedItemNS( e, uri, local ); + return a == null ? "" : a.getNodeValue(); + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static boolean _element_hasAttribute ( Dom e, String name ) + { + return _attributes_getNamedItem( e, name ) != null; + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static boolean _element_hasAttributeNS ( Dom e, String uri, String local ) + { + return _attributes_getNamedItemNS( e, uri, local ) != null; + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static void _element_removeAttribute ( Dom e, String name ) + { + try + { + _attributes_removeNamedItem( e, name ); + } + catch ( NotFoundErr ex ) + { + } + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static void _element_removeAttributeNS ( Dom e, String uri, String local ) + { + try + { + _attributes_removeNamedItemNS( e, uri, local ); + } + catch ( NotFoundErr ex ) + { + } + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static Attr _element_removeAttributeNode ( Dom e, Attr oldAttr ) + { + if (oldAttr == null) + throw new NotFoundErr( "Attribute to remove is null" ); + + if (oldAttr.getOwnerElement() != e) + throw new NotFoundErr( "Attribute to remove does not belong to this element" ); + + return (Attr) _attributes_removeNamedItem( e, oldAttr.getNodeName() ); + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static void _element_setAttribute ( Dom e, String name, String value ) + { + // TODO - validate all attr/element names in all apprpraite + // methdos + + Locale l = e.locale(); + + if (l.noSync()) { l.enter(); try { element_setAttribute( e, name, value ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { element_setAttribute( e, name, value ); } finally { l.exit(); } } + } + + public static void element_setAttribute ( Dom e, String name, String value ) + { + Dom a = attributes_getNamedItem( e, name ); + + if (a == null) + { + a = document_createAttribute( node_getOwnerDocument( e ), name ); + attributes_setNamedItem( e, a ); + } + + node_setNodeValue( a, value ); + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static void _element_setAttributeNS ( Dom e, String uri, String qname, String value ) + { + Locale l = e.locale(); + + if (l.noSync()) { l.enter(); try { element_setAttributeNS( e, uri, qname, value ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { element_setAttributeNS( e, uri, qname, value ); } finally { l.exit(); } } + } + + public static void element_setAttributeNS ( Dom e, String uri, String qname, String value ) + { + validateQualifiedName( qname, uri, true ); + + QName name = e.locale().makeQualifiedQName( uri, qname ); + String local = name.getLocalPart(); + String prefix = validatePrefix( name.getPrefix(), uri, local, true ); + + Dom a = attributes_getNamedItemNS( e, uri, local ); + + if (a == null) + { + a = document_createAttributeNS( node_getOwnerDocument( e ), uri, local ); + attributes_setNamedItemNS( e, a ); + } + + node_setPrefix( a, prefix ); + node_setNodeValue( a, value ); + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static NodeList _element_getElementsByTagName ( Dom e, String name ) + { + Locale l = e.locale(); + + if (l.noSync()) { l.enter(); try { return element_getElementsByTagName( e, name ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return element_getElementsByTagName( e, name ); } finally { l.exit(); } } + + } + public static NodeList element_getElementsByTagName ( Dom e, String name ) + { + return new ElementsByTagNameNodeList( e, name ); + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static NodeList _element_getElementsByTagNameNS ( Dom e, String uri, String local ) + { + Locale l = e.locale(); + + if (l.noSync()) { l.enter(); try { return element_getElementsByTagNameNS( e, uri, local ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return element_getElementsByTagNameNS( e, uri, local ); } finally { l.exit(); } } + } + + public static NodeList element_getElementsByTagNameNS ( Dom e, String uri, String local ) + { + return new ElementsByTagNameNSNodeList( e, uri, local ); + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static int _attributes_getLength ( Dom e ) + { + Locale l = e.locale(); + + if (l.noSync()) { l.enter(); try { return attributes_getLength( e ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return attributes_getLength( e ); } finally { l.exit(); } } + } + + public static int attributes_getLength ( Dom e ) + { + int n = 0; + + Cur c = e.tempCur(); + + while ( c.toNextAttr() ) + n++; + + c.release(); + + return n; + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static Node _attributes_setNamedItem ( Dom e, Node attr ) + { + Locale l = e.locale(); + + if (attr == null) + throw new IllegalArgumentException( "Attr to set is null" ); + + Dom a; + + if (!(attr instanceof Dom) || (a = (Dom) attr).locale() != l) + throw new WrongDocumentErr( "Attr to set is from another document" ); + + Dom oldA; + + if (l.noSync()) { l.enter(); try { oldA = attributes_setNamedItem( e, a ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { oldA = attributes_setNamedItem( e, a ); } finally { l.exit(); } } + + return (Node) oldA; + } + + public static Dom attributes_setNamedItem ( Dom e, Dom a ) + { + if (attr_getOwnerElement( a ) != null) + throw new InuseAttributeError(); + + if (a.nodeType() != ATTR) + throw new HierarchyRequestErr( "Node is not an attribute" ); + + String name = _node_getNodeName( a ); + Dom oldAttr = null; + + Cur c = e.tempCur(); + + while ( c.toNextAttr() ) + { + Dom aa = c.getDom(); + + if (_node_getNodeName( aa ).equals( name )) + { + if (oldAttr == null) + oldAttr = aa; + else + { + removeNode( aa ); + c.toPrevAttr(); + } + } + } + + if (oldAttr == null) + { + c.moveToDom( e ); + c.next(); + Cur.moveNode( (Xobj) a, c ); + } + else + { + c.moveToDom( oldAttr ); + Cur.moveNode( (Xobj) a, c ); + removeNode( oldAttr ); + } + + c.release(); + + return oldAttr; + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static Node _attributes_getNamedItem ( Dom e, String name ) + { + Locale l = e.locale(); + + Dom n; + + if (l.noSync()) { l.enter(); try { n = attributes_getNamedItem( e, name ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { n = attributes_getNamedItem( e, name ); } finally { l.exit(); } } + + return (Node) n; + } + + public static Dom attributes_getNamedItem ( Dom e, String name ) + { + Dom a = null; + + Cur c = e.tempCur(); + + while ( c.toNextAttr() ) + { + Dom d = c.getDom(); + + if (_node_getNodeName( d ).equals( name )) + { + a = d; + break; + } + } + + c.release(); + + return a; + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static Node _attributes_getNamedItemNS ( Dom e, String uri, String local ) + { + Locale l = e.locale(); + + Dom n; + + if (l.noSync()) { l.enter(); try { n = attributes_getNamedItemNS( e, uri, local ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { n = attributes_getNamedItemNS( e, uri, local ); } finally { l.exit(); } } + + return (Node) n; + } + + public static Dom attributes_getNamedItemNS ( Dom e, String uri, String local ) + { + if (uri == null) + uri = ""; + + Dom a = null; + + Cur c = e.tempCur(); + + while ( c.toNextAttr() ) + { + Dom d = c.getDom(); + + QName n = d.getQName(); + + if (n.getNamespaceURI().equals( uri ) && n.getLocalPart().equals( local )) + { + a = d; + break; + } + } + + c.release(); + + return a; + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static Node _attributes_removeNamedItem ( Dom e, String name ) + { + Locale l = e.locale(); + + Dom n; + + if (l.noSync()) { l.enter(); try { n = attributes_removeNamedItem( e, name ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { n = attributes_removeNamedItem( e, name ); } finally { l.exit(); } } + + return (Node) n; + } + + public static Dom attributes_removeNamedItem ( Dom e, String name ) + { + Dom oldAttr = null; + + Cur c = e.tempCur(); + + while ( c.toNextAttr() ) + { + Dom aa = c.getDom(); + + if (_node_getNodeName(aa).equals(name)) + { + if (oldAttr == null) + oldAttr = aa; + + if (((Xobj.AttrXobj) aa).isId()) + { + Dom d = DomImpl.node_getOwnerDocument(aa); + String val = node_getNodeValue( aa ); + if (d instanceof Xobj.DocumentXobj) + ((Xobj.DocumentXobj) d).removeIdElement(val); + } + removeNode(aa); + c.toPrevAttr(); + } + } + + c.release(); + + if (oldAttr == null) + throw new NotFoundErr( "Named item not found: " + name ); + + return oldAttr; + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static Node _attributes_removeNamedItemNS ( Dom e, String uri, String local ) + { + Locale l = e.locale(); + + Dom n; + + if (l.noSync()) { l.enter(); try { n = attributes_removeNamedItemNS( e, uri, local ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { n = attributes_removeNamedItemNS( e, uri, local ); } finally { l.exit(); } } + + return (Node) n; + } + + public static Dom attributes_removeNamedItemNS ( Dom e, String uri, String local ) + { + if (uri == null) + uri = ""; + + Dom oldAttr = null; + + Cur c = e.tempCur(); + + while ( c.toNextAttr() ) + { + Dom aa = c.getDom(); + + QName qn = aa.getQName(); + + if (qn.getNamespaceURI().equals( uri ) && qn.getLocalPart().equals( local )) + { + if (oldAttr == null) + oldAttr = aa; + if (((Xobj.AttrXobj) aa).isId()) + { + Dom d = DomImpl.node_getOwnerDocument(aa); + String val = node_getNodeValue( aa ); + if (d instanceof Xobj.DocumentXobj) + ((Xobj.DocumentXobj) d).removeIdElement(val); + } + removeNode( aa ); + + c.toPrevAttr(); + } + } + + c.release(); + + if (oldAttr == null) + throw new NotFoundErr( "Named item not found: uri=" + uri + ", local=" + local ); + + return oldAttr; + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static Node _attributes_setNamedItemNS ( Dom e, Node attr ) + { + Locale l = e.locale(); + + if (attr == null) + throw new IllegalArgumentException( "Attr to set is null" ); + + Dom a; + + if (!(attr instanceof Dom) || (a = (Dom) attr).locale() != l) + throw new WrongDocumentErr( "Attr to set is from another document" ); + + Dom oldA; + + if (l.noSync()) { l.enter(); try { oldA = attributes_setNamedItemNS( e, a ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { oldA = attributes_setNamedItemNS( e, a ); } finally { l.exit(); } } + + return (Node) oldA; + } + + public static Dom attributes_setNamedItemNS ( Dom e, Dom a ) + { + Dom owner = attr_getOwnerElement( a ); + + if (owner == e) + return a; + + if (owner != null) + throw new InuseAttributeError(); + + if (a.nodeType() != ATTR) + throw new HierarchyRequestErr( "Node is not an attribute" ); + + QName name = a.getQName(); + Dom oldAttr = null; + + Cur c = e.tempCur(); + + while ( c.toNextAttr() ) + { + Dom aa = c.getDom(); + + if (aa.getQName().equals( name )) + { + if (oldAttr == null) + oldAttr = aa; + else + { + removeNode( aa ); + c.toPrevAttr(); + } + } + } + + if (oldAttr == null) + { + c.moveToDom( e ); + c.next(); + Cur.moveNode( (Xobj) a, c ); + } + else + { + c.moveToDom( oldAttr ); + Cur.moveNode( (Xobj) a, c ); + removeNode( oldAttr ); + } + + c.release(); + + return oldAttr; + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static Node _attributes_item ( Dom e, int index ) + { + Locale l = e.locale(); + + Dom a; + + if (l.noSync()) { l.enter(); try { a = attributes_item( e, index ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { a = attributes_item( e, index ); } finally { l.exit(); } } + + return (Node) a; + } + + public static Dom attributes_item ( Dom e, int index ) + { + if (index < 0) + return null; + + Cur c = e.tempCur(); + + Dom a = null; + + while ( c.toNextAttr() ) + { + if (index-- == 0) + { + a = c.getDom(); + break; + } + } + + c.release(); + + return a; + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static String _processingInstruction_getData ( Dom p ) + { + return _node_getNodeValue( p ); + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static String _processingInstruction_getTarget ( Dom p ) + { + return _node_getNodeName( p ); + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static void _processingInstruction_setData ( Dom p, String data ) + { + _node_setNodeValue( p, data ); + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static boolean _attr_getSpecified ( Dom a ) + { + // Can't tell the difference + return true; + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static Element _attr_getOwnerElement ( Dom a ) + { + Locale l = a.locale(); + + Dom e; + + if (l.noSync()) { l.enter(); try { e = attr_getOwnerElement( a ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { e = attr_getOwnerElement( a ); } finally { l.exit(); } } + + return (Element) e; + } + + public static Dom attr_getOwnerElement ( Dom n ) + { + Cur c = n.tempCur(); + + if (!c.toParentRaw()) + { + c.release(); + return null; + } + + Dom p = c.getDom(); + + c.release(); + + return p; + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static void _characterData_appendData ( Dom cd, String arg ) + { + // TODO - fix this *really* cheesy/bad/lousy perf impl + // also fix all the funcitons which follow + + if (arg != null && arg.length() != 0) + _node_setNodeValue( cd, _node_getNodeValue( cd ) + arg ); + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static void _characterData_deleteData ( Dom c, int offset, int count ) + { + String s = _characterData_getData( c ); + + if (offset < 0 || offset > s.length() || count < 0) + throw new IndexSizeError(); + + if (offset + count > s.length()) + count = s.length() - offset; + + if (count > 0) + _characterData_setData( c, s.substring( 0, offset ) + s.substring( offset + count ) ); + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static String _characterData_getData ( Dom c ) + { + return _node_getNodeValue( c ); + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static int _characterData_getLength ( Dom c ) + { + return _characterData_getData( c ).length(); + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static void _characterData_insertData ( Dom c, int offset, String arg ) + { + String s = _characterData_getData( c ); + + if (offset < 0 || offset > s.length()) + throw new IndexSizeError(); + + if (arg != null && arg.length() > 0) + _characterData_setData( c, s.substring( 0, offset ) + arg + s.substring( offset ) ); + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static void _characterData_replaceData ( Dom c, int offset, int count, String arg ) + { + String s = _characterData_getData( c ); + + if (offset < 0 || offset > s.length() || count < 0) + throw new IndexSizeError(); + + if (offset + count > s.length()) + count = s.length() - offset; + + if (count > 0) + { + _characterData_setData( + c, s.substring( 0, offset ) + (arg == null ? "" : arg) + + s.substring( offset + count ) ); + } + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static void _characterData_setData ( Dom c, String data ) + { + _node_setNodeValue( c, data ); + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static String _characterData_substringData ( Dom c, int offset, int count ) + { + String s = _characterData_getData( c ); + + if (offset < 0 || offset > s.length() || count < 0) + throw new IndexSizeError(); + + if (offset + count > s.length()) + count = s.length() - offset; + + return s.substring( offset, offset + count ); + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static Text _text_splitText ( Dom t, int offset ) + { + assert t.nodeType() == TEXT; + + String s = _characterData_getData( t ); + + if (offset < 0 || offset > s.length()) + throw new IndexSizeError(); + + _characterData_deleteData( t, offset, s.length() - offset ); + + // Don't need to pass a doc here, any node will do.. + + Dom t2 = (Dom) _document_createTextNode( t, s.substring( offset ) ); + + Dom p = (Dom) _node_getParentNode( t ); + + if (p != null) + { + _node_insertBefore( p, (Text) t2, _node_getNextSibling( t ) ); + t.locale().invalidateDomCaches(p); + } + + return (Text) t2; + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static String _text_getWholeText ( Dom t ) + { + throw new RuntimeException( "DOM Level 3 Not implemented" ); + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static boolean _text_isElementContentWhitespace ( Dom t ) + { + throw new RuntimeException( "DOM Level 3 Not implemented" ); + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static Text _text_replaceWholeText ( Dom t, String content ) + { + throw new RuntimeException( "DOM Level 3 Not implemented" ); + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static XMLStreamReader _getXmlStreamReader ( Dom n ) + { + Locale l = n.locale(); + + if (l.noSync()) { l.enter(); try { return getXmlStreamReader( n ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return getXmlStreamReader( n ); } finally { l.exit(); } } + } + + public static XMLStreamReader getXmlStreamReader ( Dom n ) + { + XMLStreamReader xs; + + switch ( n.nodeType() ) + { + case DOCUMENT : + case DOCFRAG : + case ATTR : + case ELEMENT : + case PROCINST : + case COMMENT : + { + Cur c = n.tempCur(); + xs = Jsr173.newXmlStreamReader( c, null ); + c.release(); + break; + } + + case TEXT : + case CDATA : + { + CharNode cn = (CharNode) n; + + Cur c; + + if ((c = cn.tempCur()) == null) + { + c = n.locale().tempCur(); + + xs = Jsr173.newXmlStreamReader( c, cn._src, cn._off, cn._cch ); + } + else + { + xs = + Jsr173.newXmlStreamReader( + c , c.getChars( cn._cch ), c._offSrc, c._cchSrc ); + + } + + c.release(); + + break; + } + + case ENTITYREF : + case ENTITY : + case DOCTYPE : + case NOTATION : + throw new RuntimeException( "Not impl" ); + + default : throw new RuntimeException( "Unknown kind" ); + } + + return xs; + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static XmlCursor _getXmlCursor ( Dom n ) + { + Locale l = n.locale(); + + if (l.noSync()) { l.enter(); try { return getXmlCursor( n ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return getXmlCursor( n ); } finally { l.exit(); } } + } + + public static XmlCursor getXmlCursor ( Dom n ) + { + Cur c = n.tempCur(); + + Cursor xc = new Cursor( c ); + + c.release(); + + return xc; + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public static XmlObject _getXmlObject ( Dom n ) + { + Locale l = n.locale(); + + if (l.noSync()) { l.enter(); try { return getXmlObject( n ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return getXmlObject( n ); } finally { l.exit(); } } + } + + public static XmlObject getXmlObject ( Dom n ) + { + Cur c = n.tempCur(); + + XmlObject x = c.getObject(); + + c.release(); + + return x; + } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + static abstract class CharNode implements Dom, Node, CharacterData + { + public CharNode ( Locale l ) + { + assert l != null; + + _locale = l; + } + + public QName getQName ( ) + { + return null; + } + + public Locale locale ( ) + { + assert isValid(); + + return _locale == null ? ((Dom) _src).locale() : _locale; + } + + public void setChars ( Object src, int off, int cch ) + { + assert CharUtil.isValid( src, off, cch ); + assert _locale != null || _src instanceof Dom; + + if (_locale == null) + _locale = ((Dom) _src).locale(); + + _src = src; + _off = off; + _cch = cch; + } + + public Dom getDom ( ) + { + assert isValid(); + + if (_src instanceof Dom) + return (Dom) _src; + + return null; + } + + public void setDom ( Dom d ) + { + assert d != null; + + _src = d; + _locale = null; + } + + public Cur tempCur ( ) + { + assert isValid(); + + if (!(_src instanceof Dom)) + return null; + + Cur c = locale().tempCur(); + c.moveToCharNode( this ); + + return c; + } + + private boolean isValid ( ) + { + if (_src instanceof Dom) + return _locale == null; + + if (_locale == null) + return false; + + return true; + } + + public static boolean isOnList ( CharNode nodes, CharNode node ) + { + assert node != null; + + for ( CharNode cn = nodes ; cn != null ; cn = cn._next ) + if (cn == node) + return true; + + return false; + } + + public static CharNode remove ( CharNode nodes, CharNode node ) + { + assert isOnList( nodes, node ); + + if (nodes == node) + nodes = node._next; + else + node._prev._next = node._next; + + if (node._next != null) + node._next._prev = node._prev; + + node._prev = node._next = null; + + return nodes; + } + + public static CharNode insertNode ( CharNode nodes, CharNode newNode, CharNode before ) + { + assert !isOnList( nodes, newNode ); + assert before == null || isOnList( nodes, before ); + assert newNode != null; + assert newNode._prev == null && newNode._next == null; + + if (nodes == null) + { + assert before == null; + nodes = newNode; + } + else if (nodes == before) + { + nodes._prev = newNode; + newNode._next = nodes; + nodes = newNode; + } + else + { + CharNode n = nodes; + + while ( n._next != before ) + n = n._next; + + if ((newNode._next = n._next) != null) + n._next._prev = newNode; + + newNode._prev = n; + n._next = newNode; + } + + return nodes; + } + + public static CharNode appendNode ( CharNode nodes, CharNode newNode ) + { + return insertNode( nodes, newNode, null ); + } + + public static CharNode appendNodes ( CharNode nodes, CharNode newNodes ) + { + assert newNodes != null; + assert newNodes._prev == null; + + if (nodes == null) + return newNodes; + + CharNode n = nodes; + + while ( n._next != null ) + n = n._next; + + n._next = newNodes; + newNodes._prev = n; + + return nodes; + } + + public static CharNode copyNodes ( CharNode nodes, Object newSrc ) + { + CharNode newNodes = null; + + for ( CharNode n = null ; nodes != null ; nodes = nodes._next ) + { + CharNode newNode; + + if (nodes instanceof TextNode) + newNode = nodes.locale().createTextNode(); + else + newNode = nodes.locale().createCdataNode(); + + // How to deal with entity refs?? + + newNode.setChars( newSrc, nodes._off, nodes._cch ); + + if (newNodes == null) + newNodes = newNode; + + if (n != null) + { + n._next = newNode; + newNode._prev = n; + } + + n = newNode; + } + + return newNodes; + } + + public boolean nodeCanHavePrefixUri() + { + return false; + } + + public boolean isNodeAftertext() + { + assert _src instanceof Xobj : + "this method is to only be used for nodes backed up by Xobjs"; + Xobj src =(Xobj) _src; + return src._charNodesValue == null ? true : + src._charNodesAfter == null ? false : + CharNode.isOnList(src._charNodesAfter, this); + } + public void dump ( PrintStream o, Object ref ) + { + if (_src instanceof Dom) + ((Dom) _src).dump( o, ref ); + else + o.println( "Lonely CharNode: \"" + CharUtil.getString( _src, _off, _cch ) + "\"" ); + } + + public void dump ( PrintStream o ) + { + dump( o, (Object) this ); + } + + public void dump ( ) + { + dump( System.out ); + } + + public Node appendChild ( Node newChild ) { return DomImpl._node_appendChild( this, newChild ); } + public Node cloneNode ( boolean deep ) { return DomImpl._node_cloneNode( this, deep ); } + public NamedNodeMap getAttributes ( ) { return null; } + public NodeList getChildNodes ( ) { return DomImpl._emptyNodeList; } + public Node getParentNode ( ) { return DomImpl._node_getParentNode( this ); } + public Node removeChild ( Node oldChild ) { return DomImpl._node_removeChild( this, oldChild ); } + public Node getFirstChild ( ) { return null; } + public Node getLastChild ( ) { return null; } + public String getLocalName ( ) { return DomImpl._node_getLocalName( this ); } + public String getNamespaceURI ( ) { return DomImpl._node_getNamespaceURI( this ); } + public Node getNextSibling ( ) { return DomImpl._node_getNextSibling( this ); } + public String getNodeName ( ) { return DomImpl._node_getNodeName( this ); } + public short getNodeType ( ) { return DomImpl._node_getNodeType( this ); } + public String getNodeValue ( ) { return DomImpl._node_getNodeValue( this ); } + public Document getOwnerDocument ( ) { return DomImpl._node_getOwnerDocument( this ); } + public String getPrefix ( ) { return DomImpl._node_getPrefix( this ); } + public Node getPreviousSibling ( ) { return DomImpl._node_getPreviousSibling( this ); } + public boolean hasAttributes ( ) { return false; } + public boolean hasChildNodes ( ) { return false; } + public Node insertBefore ( Node newChild, Node refChild ) { return DomImpl._node_insertBefore( this, newChild, refChild ); } + public boolean isSupported ( String feature, String version ) { return DomImpl._node_isSupported( this, feature, version ); } + public void normalize ( ) { DomImpl._node_normalize( this ); } + public Node replaceChild ( Node newChild, Node oldChild ) { return DomImpl._node_replaceChild( this, newChild, oldChild ); } + public void setNodeValue ( String nodeValue ) { DomImpl._node_setNodeValue( this, nodeValue ); } + public void setPrefix ( String prefix ) { DomImpl._node_setPrefix( this, prefix ); } + + // DOM Level 3 + public Object getUserData ( String key ) { return DomImpl._node_getUserData( this, key ); } + public Object setUserData ( String key, Object data, UserDataHandler handler ) { return DomImpl._node_setUserData( this, key, data, handler ); } + public Object getFeature ( String feature, String version ) { return DomImpl._node_getFeature( this, feature, version ); } + public boolean isEqualNode ( Node arg ) { return DomImpl._node_isEqualNode( this, arg ); } + public boolean isSameNode ( Node arg ) { return DomImpl._node_isSameNode( this, arg ); } + public String lookupNamespaceURI ( String prefix ) { return DomImpl._node_lookupNamespaceURI( this, prefix ); } + public String lookupPrefix ( String namespaceURI ) { return DomImpl._node_lookupPrefix( this, namespaceURI ); } + public boolean isDefaultNamespace ( String namespaceURI ) { return DomImpl._node_isDefaultNamespace( this, namespaceURI ); } + public void setTextContent ( String textContent ) { DomImpl._node_setTextContent( this, textContent ); } + public String getTextContent ( ) { return DomImpl._node_getTextContent( this ); } + public short compareDocumentPosition ( Node other ) { return DomImpl._node_compareDocumentPosition( this, other ); } + public String getBaseURI ( ) { return DomImpl._node_getBaseURI( this ); } + + public void appendData ( String arg ) { DomImpl._characterData_appendData( this, arg ); } + public void deleteData ( int offset, int count ) { DomImpl._characterData_deleteData( this, offset, count ); } + public String getData ( ) { return DomImpl._characterData_getData( this ); } + public int getLength ( ) { return DomImpl._characterData_getLength( this ); } + public void insertData ( int offset, String arg ) { DomImpl._characterData_insertData( this, offset, arg ); } + public void replaceData ( int offset, int count, String arg ) { DomImpl._characterData_replaceData( this, offset, count, arg ); } + public void setData ( String data ) { DomImpl._characterData_setData( this, data ); } + public String substringData ( int offset, int count ) { return DomImpl._characterData_substringData( this, offset, count ); } + + private Locale _locale; + + CharNode _next; + CharNode _prev; + + private Object _src; + + int _off; + int _cch; + } + + static class TextNode extends CharNode implements Text + { + TextNode ( Locale l ) + { + super( l ); + } + + public int nodeType ( ) { return DomImpl.TEXT; } + + public String name ( ) { return "#text"; } + + public Text splitText ( int offset ) { return DomImpl._text_splitText ( this, offset ); } + public String getWholeText ( ) { return DomImpl._text_getWholeText( this ); } + public boolean isElementContentWhitespace ( ) { return DomImpl._text_isElementContentWhitespace( this ); } + public Text replaceWholeText ( String content ) { return DomImpl._text_replaceWholeText( this, content ); } + } + + static class CdataNode extends TextNode implements CDATASection + { + CdataNode ( Locale l ) + { + super( l ); + } + + public int nodeType ( ) { return DomImpl.CDATA; } + + public String name ( ) { return "#cdata-section"; } + } + + static class SaajTextNode extends TextNode implements org.apache.xmlbeans.impl.soap.Text + { + SaajTextNode ( Locale l ) + { + super( l ); + } + + public boolean isComment ( ) { return DomImpl._soapText_isComment( this ); } + + public void detachNode ( ) { DomImpl._soapNode_detachNode( this ); } + public void recycleNode ( ) { DomImpl._soapNode_recycleNode( this ); } + public String getValue ( ) { return DomImpl._soapNode_getValue( this ); } + public void setValue ( String value ) { DomImpl._soapNode_setValue( this, value ); } + public SOAPElement getParentElement ( ) { return DomImpl._soapNode_getParentElement( this ); } + public void setParentElement ( SOAPElement p ) { DomImpl._soapNode_setParentElement( this, p ); } + } + + static class SaajCdataNode extends CdataNode implements org.apache.xmlbeans.impl.soap.Text + { + public SaajCdataNode ( Locale l ) + { + super( l ); + } + + public boolean isComment ( ) { return DomImpl._soapText_isComment( this ); } + + public void detachNode ( ) { DomImpl._soapNode_detachNode( this ); } + public void recycleNode ( ) { DomImpl._soapNode_recycleNode( this ); } + public String getValue ( ) { return DomImpl._soapNode_getValue( this ); } + public void setValue ( String value ) { DomImpl._soapNode_setValue( this, value ); } + public SOAPElement getParentElement ( ) { return DomImpl._soapNode_getParentElement( this ); } + public void setParentElement ( SOAPElement p ) { DomImpl._soapNode_setParentElement( this, p ); } + } + + // + // Soap Text Node + // + + public static boolean _soapText_isComment ( Dom n ) + { + Locale l = n.locale(); + + org.apache.xmlbeans.impl.soap.Text text = (org.apache.xmlbeans.impl.soap.Text) n; + + if (l.noSync()) { l.enter(); try { return l._saaj.soapText_isComment( text ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return l._saaj.soapText_isComment( text ); } finally { l.exit(); } } + } + + // + // Soap Node + // + + public static void _soapNode_detachNode ( Dom n ) + { + Locale l = n.locale(); + + org.apache.xmlbeans.impl.soap.Node node = (org.apache.xmlbeans.impl.soap.Node) n; + + if (l.noSync()) { l.enter(); try { l._saaj.soapNode_detachNode( node ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { l._saaj.soapNode_detachNode( node ); } finally { l.exit(); } } + } + + public static void _soapNode_recycleNode ( Dom n ) + { + Locale l = n.locale(); + + org.apache.xmlbeans.impl.soap.Node node = (org.apache.xmlbeans.impl.soap.Node) n; + + if (l.noSync()) { l.enter(); try { l._saaj.soapNode_recycleNode( node ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { l._saaj.soapNode_recycleNode( node ); } finally { l.exit(); } } + } + + public static String _soapNode_getValue ( Dom n ) + { + Locale l = n.locale(); + + org.apache.xmlbeans.impl.soap.Node node = (org.apache.xmlbeans.impl.soap.Node) n; + + if (l.noSync()) { l.enter(); try { return l._saaj.soapNode_getValue( node ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return l._saaj.soapNode_getValue( node ); } finally { l.exit(); } } + } + + public static void _soapNode_setValue ( Dom n, String value ) + { + Locale l = n.locale(); + + org.apache.xmlbeans.impl.soap.Node node = (org.apache.xmlbeans.impl.soap.Node) n; + + if (l.noSync()) { l.enter(); try { l._saaj.soapNode_setValue( node, value ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { l._saaj.soapNode_setValue( node, value ); } finally { l.exit(); } } + } + + public static SOAPElement _soapNode_getParentElement ( Dom n ) + { + Locale l = n.locale(); + + org.apache.xmlbeans.impl.soap.Node node = (org.apache.xmlbeans.impl.soap.Node) n; + + if (l.noSync()) { l.enter(); try { return l._saaj.soapNode_getParentElement( node ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return l._saaj.soapNode_getParentElement( node ); } finally { l.exit(); } } + } + + public static void _soapNode_setParentElement ( Dom n, SOAPElement p ) + { + Locale l = n.locale(); + + org.apache.xmlbeans.impl.soap.Node node = (org.apache.xmlbeans.impl.soap.Node) n; + + if (l.noSync()) { l.enter(); try { l._saaj.soapNode_setParentElement( node, p ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { l._saaj.soapNode_setParentElement( node, p ); } finally { l.exit(); } } + } + + // + // Soap Element + // + + public static void _soapElement_removeContents ( Dom d ) + { + Locale l = d.locale(); + + SOAPElement se = (SOAPElement) d; + + if (l.noSync()) { l.enter(); try { l._saaj.soapElement_removeContents( se ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { l._saaj.soapElement_removeContents( se ); } finally { l.exit(); } } + } + + public static String _soapElement_getEncodingStyle ( Dom d ) + { + Locale l = d.locale(); + + SOAPElement se = (SOAPElement) d; + + if (l.noSync()) { l.enter(); try { return l._saaj.soapElement_getEncodingStyle( se ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return l._saaj.soapElement_getEncodingStyle( se ); } finally { l.exit(); } } + } + + public static void _soapElement_setEncodingStyle ( Dom d, String encodingStyle ) + { + Locale l = d.locale(); + + SOAPElement se = (SOAPElement) d; + + if (l.noSync()) { l.enter(); try { l._saaj.soapElement_setEncodingStyle( se, encodingStyle ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { l._saaj.soapElement_setEncodingStyle( se, encodingStyle ); } finally { l.exit(); } } + } + + public static boolean _soapElement_removeNamespaceDeclaration ( Dom d, String prefix ) + { + Locale l = d.locale(); + + SOAPElement se = (SOAPElement) d; + + if (l.noSync()) { l.enter(); try { return l._saaj.soapElement_removeNamespaceDeclaration( se, prefix ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return l._saaj.soapElement_removeNamespaceDeclaration( se, prefix ); } finally { l.exit(); } } + } + + public static Iterator _soapElement_getAllAttributes ( Dom d ) + { + Locale l = d.locale(); + + SOAPElement se = (SOAPElement) d; + + if (l.noSync()) { l.enter(); try { return l._saaj.soapElement_getAllAttributes( se ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return l._saaj.soapElement_getAllAttributes( se ); } finally { l.exit(); } } + } + + public static Iterator _soapElement_getChildElements ( Dom d ) + { + Locale l = d.locale(); + + SOAPElement se = (SOAPElement) d; + + if (l.noSync()) { l.enter(); try { return l._saaj.soapElement_getChildElements( se ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return l._saaj.soapElement_getChildElements( se ); } finally { l.exit(); } } + } + + public static Iterator _soapElement_getNamespacePrefixes ( Dom d ) + { + Locale l = d.locale(); + + SOAPElement se = (SOAPElement) d; + + if (l.noSync()) { l.enter(); try { return l._saaj.soapElement_getNamespacePrefixes( se ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return l._saaj.soapElement_getNamespacePrefixes( se ); } finally { l.exit(); } } + } + + public static SOAPElement _soapElement_addAttribute ( Dom d, Name name, String value ) throws SOAPException + { + Locale l = d.locale(); + + SOAPElement se = (SOAPElement) d; + + if (l.noSync()) { l.enter(); try { return l._saaj.soapElement_addAttribute( se, name, value ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return l._saaj.soapElement_addAttribute( se, name, value ); } finally { l.exit(); } } + } + + public static SOAPElement _soapElement_addChildElement ( Dom d, SOAPElement oldChild ) throws SOAPException + { + Locale l = d.locale(); + + SOAPElement se = (SOAPElement) d; + + if (l.noSync()) { l.enter(); try { return l._saaj.soapElement_addChildElement( se, oldChild ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return l._saaj.soapElement_addChildElement( se, oldChild ); } finally { l.exit(); } } + } + + public static SOAPElement _soapElement_addChildElement ( Dom d, Name name ) throws SOAPException + { + Locale l = d.locale(); + + SOAPElement se = (SOAPElement) d; + + if (l.noSync()) { l.enter(); try { return l._saaj.soapElement_addChildElement( se, name ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return l._saaj.soapElement_addChildElement( se, name ); } finally { l.exit(); } } + } + + public static SOAPElement _soapElement_addChildElement ( Dom d, String localName ) throws SOAPException + { + Locale l = d.locale(); + + SOAPElement se = (SOAPElement) d; + + if (l.noSync()) { l.enter(); try { return l._saaj.soapElement_addChildElement( se, localName ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return l._saaj.soapElement_addChildElement( se, localName ); } finally { l.exit(); } } + } + + public static SOAPElement _soapElement_addChildElement ( Dom d, String localName, String prefix ) throws SOAPException + { + Locale l = d.locale(); + + SOAPElement se = (SOAPElement) d; + + if (l.noSync()) { l.enter(); try { return l._saaj.soapElement_addChildElement( se, localName, prefix ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return l._saaj.soapElement_addChildElement( se, localName, prefix ); } finally { l.exit(); } } + } + + public static SOAPElement _soapElement_addChildElement ( Dom d, String localName, String prefix, String uri ) throws SOAPException + { + Locale l = d.locale(); + + SOAPElement se = (SOAPElement) d; + + if (l.noSync()) { l.enter(); try { return l._saaj.soapElement_addChildElement( se, localName, prefix, uri ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return l._saaj.soapElement_addChildElement( se, localName, prefix, uri ); } finally { l.exit(); } } + } + + public static SOAPElement _soapElement_addNamespaceDeclaration ( Dom d, String prefix, String uri ) + { + Locale l = d.locale(); + + SOAPElement se = (SOAPElement) d; + + if (l.noSync()) { l.enter(); try { return l._saaj.soapElement_addNamespaceDeclaration( se, prefix, uri ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return l._saaj.soapElement_addNamespaceDeclaration( se, prefix, uri ); } finally { l.exit(); } } + } + + public static SOAPElement _soapElement_addTextNode ( Dom d, String data ) + { + Locale l = d.locale(); + + SOAPElement se = (SOAPElement) d; + + if (l.noSync()) { l.enter(); try { return l._saaj.soapElement_addTextNode( se, data ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return l._saaj.soapElement_addTextNode( se, data ); } finally { l.exit(); } } + } + + public static String _soapElement_getAttributeValue ( Dom d, Name name ) + { + Locale l = d.locale(); + + SOAPElement se = (SOAPElement) d; + + if (l.noSync()) { l.enter(); try { return l._saaj.soapElement_getAttributeValue( se, name ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return l._saaj.soapElement_getAttributeValue( se, name ); } finally { l.exit(); } } + } + + public static Iterator _soapElement_getChildElements ( Dom d, Name name ) + { + Locale l = d.locale(); + + SOAPElement se = (SOAPElement) d; + + if (l.noSync()) { l.enter(); try { return l._saaj.soapElement_getChildElements( se, name ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return l._saaj.soapElement_getChildElements( se, name ); } finally { l.exit(); } } + } + + public static Name _soapElement_getElementName ( Dom d ) + { + Locale l = d.locale(); + + SOAPElement se = (SOAPElement) d; + + if (l.noSync()) { l.enter(); try { return l._saaj.soapElement_getElementName( se ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return l._saaj.soapElement_getElementName( se ); } finally { l.exit(); } } + } + + public static String _soapElement_getNamespaceURI ( Dom d, String prefix ) + { + Locale l = d.locale(); + + SOAPElement se = (SOAPElement) d; + + if (l.noSync()) { l.enter(); try { return l._saaj.soapElement_getNamespaceURI( se, prefix ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return l._saaj.soapElement_getNamespaceURI( se, prefix ); } finally { l.exit(); } } + } + + public static Iterator _soapElement_getVisibleNamespacePrefixes ( Dom d ) + { + Locale l = d.locale(); + + SOAPElement se = (SOAPElement) d; + + if (l.noSync()) { l.enter(); try { return l._saaj.soapElement_getVisibleNamespacePrefixes( se ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return l._saaj.soapElement_getVisibleNamespacePrefixes( se ); } finally { l.exit(); } } + } + + public static boolean _soapElement_removeAttribute ( Dom d, Name name ) + { + Locale l = d.locale(); + + SOAPElement se = (SOAPElement) d; + + if (l.noSync()) { l.enter(); try { return l._saaj.soapElement_removeAttribute( se, name ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return l._saaj.soapElement_removeAttribute( se, name ); } finally { l.exit(); } } + } + + // + // Soap Envelope + // + + public static SOAPBody _soapEnvelope_addBody ( Dom d ) throws SOAPException + { + Locale l = d.locale(); + + SOAPEnvelope se = (SOAPEnvelope) d; + + if (l.noSync()) { l.enter(); try { return l._saaj.soapEnvelope_addBody( se ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return l._saaj.soapEnvelope_addBody( se ); } finally { l.exit(); } } + } + + public static SOAPBody _soapEnvelope_getBody ( Dom d ) throws SOAPException + { + Locale l = d.locale(); + + SOAPEnvelope se = (SOAPEnvelope) d; + + if (l.noSync()) { l.enter(); try { return l._saaj.soapEnvelope_getBody( se ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return l._saaj.soapEnvelope_getBody( se ); } finally { l.exit(); } } + } + + public static SOAPHeader _soapEnvelope_getHeader ( Dom d ) throws SOAPException + { + Locale l = d.locale(); + + SOAPEnvelope se = (SOAPEnvelope) d; + + if (l.noSync()) { l.enter(); try { return l._saaj.soapEnvelope_getHeader( se ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return l._saaj.soapEnvelope_getHeader( se ); } finally { l.exit(); } } + } + + public static SOAPHeader _soapEnvelope_addHeader ( Dom d ) throws SOAPException + { + Locale l = d.locale(); + + SOAPEnvelope se = (SOAPEnvelope) d; + + if (l.noSync()) { l.enter(); try { return l._saaj.soapEnvelope_addHeader( se ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return l._saaj.soapEnvelope_addHeader( se ); } finally { l.exit(); } } + } + + public static Name _soapEnvelope_createName ( Dom d, String localName ) + { + Locale l = d.locale(); + + SOAPEnvelope se = (SOAPEnvelope) d; + + if (l.noSync()) { l.enter(); try { return l._saaj.soapEnvelope_createName( se, localName ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return l._saaj.soapEnvelope_createName( se, localName ); } finally { l.exit(); } } + } + + public static Name _soapEnvelope_createName ( Dom d, String localName, String prefix, String namespaceURI ) + { + Locale l = d.locale(); + + SOAPEnvelope se = (SOAPEnvelope) d; + + if (l.noSync()) { l.enter(); try { return l._saaj.soapEnvelope_createName( se, localName, prefix, namespaceURI ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return l._saaj.soapEnvelope_createName( se, localName, prefix, namespaceURI ); } finally { l.exit(); } } + } + + // + // Soap Header + // + + public static Iterator soapHeader_examineAllHeaderElements ( Dom d ) + { + Locale l = d.locale(); + + SOAPHeader sh = (SOAPHeader) d; + + if (l.noSync()) { l.enter(); try { return l._saaj.soapHeader_examineAllHeaderElements( sh ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return l._saaj.soapHeader_examineAllHeaderElements( sh ); } finally { l.exit(); } } + } + + public static Iterator soapHeader_extractAllHeaderElements ( Dom d ) + { + Locale l = d.locale(); + + SOAPHeader sh = (SOAPHeader) d; + + if (l.noSync()) { l.enter(); try { return l._saaj.soapHeader_extractAllHeaderElements( sh ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return l._saaj.soapHeader_extractAllHeaderElements( sh ); } finally { l.exit(); } } + } + + public static Iterator soapHeader_examineHeaderElements ( Dom d, String actor ) + { + Locale l = d.locale(); + + SOAPHeader sh = (SOAPHeader) d; + + if (l.noSync()) { l.enter(); try { return l._saaj.soapHeader_examineHeaderElements( sh, actor ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return l._saaj.soapHeader_examineHeaderElements( sh, actor ); } finally { l.exit(); } } + } + + public static Iterator soapHeader_examineMustUnderstandHeaderElements ( Dom d, String mustUnderstandString ) + { + Locale l = d.locale(); + + SOAPHeader sh = (SOAPHeader) d; + + if (l.noSync()) { l.enter(); try { return l._saaj.soapHeader_examineMustUnderstandHeaderElements( sh, mustUnderstandString ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return l._saaj.soapHeader_examineMustUnderstandHeaderElements( sh, mustUnderstandString ); } finally { l.exit(); } } + } + + public static Iterator soapHeader_extractHeaderElements ( Dom d, String actor ) + { + Locale l = d.locale(); + + SOAPHeader sh = (SOAPHeader) d; + + if (l.noSync()) { l.enter(); try { return l._saaj.soapHeader_extractHeaderElements( sh, actor ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return l._saaj.soapHeader_extractHeaderElements( sh, actor ); } finally { l.exit(); } } + } + + public static SOAPHeaderElement soapHeader_addHeaderElement ( Dom d, Name name ) + { + Locale l = d.locale(); + + SOAPHeader sh = (SOAPHeader) d; + + if (l.noSync()) { l.enter(); try { return l._saaj.soapHeader_addHeaderElement( sh, name ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return l._saaj.soapHeader_addHeaderElement( sh, name ); } finally { l.exit(); } } + } + + // + // Soap Body + // + + public static boolean soapBody_hasFault ( Dom d ) + { + Locale l = d.locale(); + + SOAPBody sb = (SOAPBody) d; + + if (l.noSync()) { l.enter(); try { return l._saaj.soapBody_hasFault( sb ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return l._saaj.soapBody_hasFault( sb ); } finally { l.exit(); } } + } + + public static SOAPFault soapBody_addFault ( Dom d ) throws SOAPException + { + Locale l = d.locale(); + + SOAPBody sb = (SOAPBody) d; + + if (l.noSync()) { l.enter(); try { return l._saaj.soapBody_addFault( sb ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return l._saaj.soapBody_addFault( sb ); } finally { l.exit(); } } + } + + public static SOAPFault soapBody_getFault ( Dom d ) + { + Locale l = d.locale(); + + SOAPBody sb = (SOAPBody) d; + + if (l.noSync()) { l.enter(); try { return l._saaj.soapBody_getFault( sb ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return l._saaj.soapBody_getFault( sb ); } finally { l.exit(); } } + } + + public static SOAPBodyElement soapBody_addBodyElement ( Dom d, Name name ) + { + Locale l = d.locale(); + + SOAPBody sb = (SOAPBody) d; + + if (l.noSync()) { l.enter(); try { return l._saaj.soapBody_addBodyElement( sb, name ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return l._saaj.soapBody_addBodyElement( sb, name ); } finally { l.exit(); } } + } + + public static SOAPBodyElement soapBody_addDocument ( Dom d, Document document ) + { + Locale l = d.locale(); + + SOAPBody sb = (SOAPBody) d; + + if (l.noSync()) { l.enter(); try { return l._saaj.soapBody_addDocument( sb, document ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return l._saaj.soapBody_addDocument( sb, document ); } finally { l.exit(); } } + } + + public static SOAPFault soapBody_addFault ( Dom d, Name name, String s ) throws SOAPException + { + Locale l = d.locale(); + + SOAPBody sb = (SOAPBody) d; + + if (l.noSync()) { l.enter(); try { return l._saaj.soapBody_addFault( sb, name, s ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return l._saaj.soapBody_addFault( sb, name, s ); } finally { l.exit(); } } + } + + public static SOAPFault soapBody_addFault ( Dom d, Name faultCode, String faultString, java.util.Locale locale ) throws SOAPException + { + Locale l = d.locale(); + + SOAPBody sb = (SOAPBody) d; + + if (l.noSync()) { l.enter(); try { return l._saaj.soapBody_addFault( sb, faultCode, faultString, locale ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return l._saaj.soapBody_addFault( sb, faultCode, faultString, locale ); } finally { l.exit(); } } + } + + // + // Soap Fault + // + + public static void soapFault_setFaultString ( Dom d, String faultString ) + { + Locale l = d.locale(); + + SOAPFault sf = (SOAPFault) d; + + if (l.noSync()) { l.enter(); try { l._saaj.soapFault_setFaultString( sf, faultString ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { l._saaj.soapFault_setFaultString( sf, faultString ); } finally { l.exit(); } } + } + + public static void soapFault_setFaultString ( Dom d, String faultString, java.util.Locale locale ) + { + Locale l = d.locale(); + + SOAPFault sf = (SOAPFault) d; + + if (l.noSync()) { l.enter(); try { l._saaj.soapFault_setFaultString( sf, faultString, locale ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { l._saaj.soapFault_setFaultString( sf, faultString, locale ); } finally { l.exit(); } } + } + + public static void soapFault_setFaultCode ( Dom d, Name faultCodeName ) throws SOAPException + { + Locale l = d.locale(); + + SOAPFault sf = (SOAPFault) d; + + if (l.noSync()) { l.enter(); try { l._saaj.soapFault_setFaultCode( sf, faultCodeName ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { l._saaj.soapFault_setFaultCode( sf, faultCodeName ); } finally { l.exit(); } } + } + + public static void soapFault_setFaultActor ( Dom d, String faultActorString ) + { + Locale l = d.locale(); + + SOAPFault sf = (SOAPFault) d; + + if (l.noSync()) { l.enter(); try { l._saaj.soapFault_setFaultActor( sf, faultActorString ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { l._saaj.soapFault_setFaultActor( sf, faultActorString ); } finally { l.exit(); } } + } + + public static String soapFault_getFaultActor ( Dom d ) + { + Locale l = d.locale(); + + SOAPFault sf = (SOAPFault) d; + + if (l.noSync()) { l.enter(); try { return l._saaj.soapFault_getFaultActor( sf ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return l._saaj.soapFault_getFaultActor( sf ); } finally { l.exit(); } } + } + + public static String soapFault_getFaultCode ( Dom d ) + { + Locale l = d.locale(); + + SOAPFault sf = (SOAPFault) d; + + if (l.noSync()) { l.enter(); try { return l._saaj.soapFault_getFaultCode( sf ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return l._saaj.soapFault_getFaultCode( sf ); } finally { l.exit(); } } + } + + public static void soapFault_setFaultCode ( Dom d, String faultCode ) throws SOAPException + { + Locale l = d.locale(); + + SOAPFault sf = (SOAPFault) d; + + if (l.noSync()) { l.enter(); try { l._saaj.soapFault_setFaultCode( sf, faultCode ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { l._saaj.soapFault_setFaultCode( sf, faultCode ); } finally { l.exit(); } } + } + + public static java.util.Locale soapFault_getFaultStringLocale ( Dom d ) + { + Locale l = d.locale(); + + SOAPFault sf = (SOAPFault) d; + + if (l.noSync()) { l.enter(); try { return l._saaj.soapFault_getFaultStringLocale( sf ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return l._saaj.soapFault_getFaultStringLocale( sf ); } finally { l.exit(); } } + } + + public static Name soapFault_getFaultCodeAsName ( Dom d ) + { + Locale l = d.locale(); + + SOAPFault sf = (SOAPFault) d; + + if (l.noSync()) { l.enter(); try { return l._saaj.soapFault_getFaultCodeAsName( sf ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return l._saaj.soapFault_getFaultCodeAsName( sf ); } finally { l.exit(); } } + } + + public static String soapFault_getFaultString ( Dom d ) + { + Locale l = d.locale(); + + SOAPFault sf = (SOAPFault) d; + + if (l.noSync()) { l.enter(); try { return l._saaj.soapFault_getFaultString( sf ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return l._saaj.soapFault_getFaultString( sf ); } finally { l.exit(); } } + } + + public static Detail soapFault_addDetail ( Dom d ) throws SOAPException + { + Locale l = d.locale(); + + SOAPFault sf = (SOAPFault) d; + + if (l.noSync()) { l.enter(); try { return l._saaj.soapFault_addDetail( sf ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return l._saaj.soapFault_addDetail( sf ); } finally { l.exit(); } } + } + + public static Detail soapFault_getDetail ( Dom d ) + { + Locale l = d.locale(); + + SOAPFault sf = (SOAPFault) d; + + if (l.noSync()) { l.enter(); try { return l._saaj.soapFault_getDetail( sf ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return l._saaj.soapFault_getDetail( sf ); } finally { l.exit(); } } + } + + // + // Soap Header Element + // + + public static void soapHeaderElement_setMustUnderstand ( Dom d, boolean mustUnderstand ) + { + Locale l = d.locale(); + + SOAPHeaderElement she = (SOAPHeaderElement) d; + + if (l.noSync()) { l.enter(); try { l._saaj.soapHeaderElement_setMustUnderstand( she, mustUnderstand ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { l._saaj.soapHeaderElement_setMustUnderstand( she, mustUnderstand ); } finally { l.exit(); } } + } + + public static boolean soapHeaderElement_getMustUnderstand ( Dom d ) + { + Locale l = d.locale(); + + SOAPHeaderElement she = (SOAPHeaderElement) d; + + if (l.noSync()) { l.enter(); try { return l._saaj.soapHeaderElement_getMustUnderstand( she ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return l._saaj.soapHeaderElement_getMustUnderstand( she ); } finally { l.exit(); } } + } + + public static void soapHeaderElement_setActor ( Dom d, String actor ) + { + Locale l = d.locale(); + + SOAPHeaderElement she = (SOAPHeaderElement) d; + + if (l.noSync()) { l.enter(); try { l._saaj.soapHeaderElement_setActor( she, actor ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { l._saaj.soapHeaderElement_setActor( she, actor ); } finally { l.exit(); } } + } + + public static String soapHeaderElement_getActor ( Dom d ) + { + Locale l = d.locale(); + + SOAPHeaderElement she = (SOAPHeaderElement) d; + + if (l.noSync()) { l.enter(); try { return l._saaj.soapHeaderElement_getActor( she ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return l._saaj.soapHeaderElement_getActor( she ); } finally { l.exit(); } } + } + + // + // Soap Header Element + // + + public static DetailEntry detail_addDetailEntry ( Dom d, Name name ) + { + Locale l = d.locale(); + + Detail detail = (Detail) d; + + if (l.noSync()) { l.enter(); try { return l._saaj.detail_addDetailEntry( detail, name ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return l._saaj.detail_addDetailEntry( detail, name ); } finally { l.exit(); } } + } + + public static Iterator detail_getDetailEntries ( Dom d ) + { + Locale l = d.locale(); + + Detail detail = (Detail) d; + + if (l.noSync()) { l.enter(); try { return l._saaj.detail_getDetailEntries( detail ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return l._saaj.detail_getDetailEntries( detail ); } finally { l.exit(); } } + } + + // + // Soap Header Element + // + + public static void _soapPart_removeAllMimeHeaders ( Dom d ) + { + Locale l = d.locale(); + + SOAPPart sp = (SOAPPart) d; + + if (l.noSync()) { l.enter(); try { l._saaj.soapPart_removeAllMimeHeaders( sp ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { l._saaj.soapPart_removeAllMimeHeaders( sp ); } finally { l.exit(); } } + } + + public static void _soapPart_removeMimeHeader ( Dom d, String name ) + { + Locale l = d.locale(); + + SOAPPart sp = (SOAPPart) d; + + if (l.noSync()) { l.enter(); try { l._saaj.soapPart_removeMimeHeader( sp, name ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { l._saaj.soapPart_removeMimeHeader( sp, name ); } finally { l.exit(); } } + } + + public static Iterator _soapPart_getAllMimeHeaders ( Dom d ) + { + Locale l = d.locale(); + + SOAPPart sp = (SOAPPart) d; + + if (l.noSync()) { l.enter(); try { return l._saaj.soapPart_getAllMimeHeaders( sp ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return l._saaj.soapPart_getAllMimeHeaders( sp ); } finally { l.exit(); } } + } + + public static SOAPEnvelope _soapPart_getEnvelope ( Dom d ) + { + Locale l = d.locale(); + + SOAPPart sp = (SOAPPart) d; + + if (l.noSync()) { l.enter(); try { return l._saaj.soapPart_getEnvelope( sp ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return l._saaj.soapPart_getEnvelope( sp ); } finally { l.exit(); } } + } + + public static Source _soapPart_getContent ( Dom d ) + { + Locale l = d.locale(); + + SOAPPart sp = (SOAPPart) d; + + if (l.noSync()) { l.enter(); try { return l._saaj.soapPart_getContent( sp ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return l._saaj.soapPart_getContent( sp ); } finally { l.exit(); } } + } + + public static void _soapPart_setContent ( Dom d, Source source ) + { + Locale l = d.locale(); + + SOAPPart sp = (SOAPPart) d; + + if (l.noSync()) { l.enter(); try { l._saaj.soapPart_setContent( sp, source ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { l._saaj.soapPart_setContent( sp, source ); } finally { l.exit(); } } + } + + public static String[] _soapPart_getMimeHeader ( Dom d, String name ) + { + Locale l = d.locale(); + + SOAPPart sp = (SOAPPart) d; + + if (l.noSync()) { l.enter(); try { return l._saaj.soapPart_getMimeHeader( sp, name ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return l._saaj.soapPart_getMimeHeader( sp, name ); } finally { l.exit(); } } + } + + public static void _soapPart_addMimeHeader ( Dom d, String name, String value ) + { + Locale l = d.locale(); + + SOAPPart sp = (SOAPPart) d; + + if (l.noSync()) { l.enter(); try { l._saaj.soapPart_addMimeHeader( sp, name, value ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { l._saaj.soapPart_addMimeHeader( sp, name, value ); } finally { l.exit(); } } + } + + public static void _soapPart_setMimeHeader ( Dom d, String name, String value ) + { + Locale l = d.locale(); + + SOAPPart sp = (SOAPPart) d; + + if (l.noSync()) { l.enter(); try { l._saaj.soapPart_setMimeHeader( sp, name, value ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { l._saaj.soapPart_setMimeHeader( sp, name, value ); } finally { l.exit(); } } + } + + public static Iterator _soapPart_getMatchingMimeHeaders ( Dom d, String[] names ) + { + Locale l = d.locale(); + + SOAPPart sp = (SOAPPart) d; + + if (l.noSync()) { l.enter(); try { return l._saaj.soapPart_getMatchingMimeHeaders( sp, names ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return l._saaj.soapPart_getMatchingMimeHeaders( sp, names ); } finally { l.exit(); } } + } + + public static Iterator _soapPart_getNonMatchingMimeHeaders ( Dom d, String[] names ) + { + Locale l = d.locale(); + + SOAPPart sp = (SOAPPart) d; + + if (l.noSync()) { l.enter(); try { return l._saaj.soapPart_getNonMatchingMimeHeaders( sp, names ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return l._saaj.soapPart_getNonMatchingMimeHeaders( sp, names ); } finally { l.exit(); } } + } + + // + // Saaj callback + // + + private static class SaajData + { + Object _obj; + } + + public static void saajCallback_setSaajData ( Dom d, Object o ) + { + Locale l = d.locale(); + + if (l.noSync()) { l.enter(); try { impl_saajCallback_setSaajData( d, o ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { impl_saajCallback_setSaajData( d, o ); } finally { l.exit(); } } + } + + public static void impl_saajCallback_setSaajData ( Dom d, Object o ) + { + Locale l = d.locale(); + + Cur c = l.tempCur(); + + c.moveToDom( d ); + + SaajData sd = null; + + if (o != null) + { + sd = (SaajData) c.getBookmark( SaajData.class ); + + if (sd == null) + sd = new SaajData(); + + sd._obj = o; + } + + c.setBookmark( SaajData.class, sd ); + + c.release(); + } + + public static Object saajCallback_getSaajData ( Dom d ) + { + Locale l = d.locale(); + + if (l.noSync()) { l.enter(); try { return impl_saajCallback_getSaajData( d ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return impl_saajCallback_getSaajData( d ); } finally { l.exit(); } } + } + + public static Object impl_saajCallback_getSaajData ( Dom d ) + { + Locale l = d.locale(); + + Cur c = l.tempCur(); + + c.moveToDom( d ); + + SaajData sd = (SaajData) c.getBookmark( SaajData.class ); + + Object o = sd == null ? null : sd._obj; + + c.release(); + + return o; + } + + public static Element saajCallback_createSoapElement ( Dom d, QName name, QName parentName ) + { + Locale l = d.locale(); + + Dom e; + + if (l.noSync()) { l.enter(); try { e = impl_saajCallback_createSoapElement( d, name, parentName ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { e = impl_saajCallback_createSoapElement( d, name, parentName ); } finally { l.exit(); } } + + return (Element) e; + } + + public static Dom impl_saajCallback_createSoapElement ( Dom d, QName name, QName parentName ) + { + Cur c = d.locale().tempCur(); + + c.createElement( name, parentName ); + + Dom e = c.getDom(); + + c.release(); + + return e; + } + + public static Element saajCallback_importSoapElement ( + Dom d, Element elem, boolean deep, QName parentName ) + { + Locale l = d.locale(); + + Dom e; + + if (l.noSync()) { l.enter(); try { e = impl_saajCallback_importSoapElement( d, elem, deep, parentName ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { e = impl_saajCallback_importSoapElement( d, elem, deep, parentName ); } finally { l.exit(); } } + + return (Element) e; + } + + public static Dom impl_saajCallback_importSoapElement ( + Dom d, Element elem, boolean deep, QName parentName ) + { + // TODO -- need to rewrite DomImpl.document_importNode to use an Xcur + // to create the new tree. Then, I can pass the parentName to the new + // fcn and use it to create the correct root parent + + throw new RuntimeException( "Not impl" ); + } + + + public static Text saajCallback_ensureSoapTextNode ( Dom d ) + { + Locale l = d.locale(); + + if (l.noSync()) { l.enter(); try { return impl_saajCallback_ensureSoapTextNode( d ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return impl_saajCallback_ensureSoapTextNode( d ); } finally { l.exit(); } } + } + + public static Text impl_saajCallback_ensureSoapTextNode ( Dom d ) + { +// if (!(d instanceof Text)) +// { +// Xcur x = d.tempCur(); +// +// x.moveTo +// +// x.release(); +// } +// +// return (Text) d; + + return null; + } + +} + diff --git a/xmlbeans/src/store/org/apache/xmlbeans/impl/store/Jsr173.java b/xmlbeans/src/store/org/apache/xmlbeans/impl/store/Jsr173.java new file mode 100755 index 000000000..7bff79dd1 --- /dev/null +++ b/xmlbeans/src/store/org/apache/xmlbeans/impl/store/Jsr173.java @@ -0,0 +1,1252 @@ +/* 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.store; + +import java.io.Reader; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.ConcurrentModificationException; + +import javax.xml.namespace.NamespaceContext; +import javax.xml.namespace.QName; + +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.Location; + +import org.apache.xmlbeans.XmlOptions; +import org.apache.xmlbeans.XmlLineNumber; +import org.apache.xmlbeans.XmlDocumentProperties; + +import org.w3c.dom.Node; + +public class Jsr173 +{ + public static Node nodeFromStream ( XMLStreamReader xs ) + { + if (!(xs instanceof Jsr173GateWay)) + return null; + + Jsr173GateWay gw = (Jsr173GateWay) xs; + + Locale l = gw._l; + + if (l.noSync()) { l.enter(); try { return nodeFromStreamImpl( gw ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return nodeFromStreamImpl( gw ); } finally { l.exit(); } } + + } + + public static Node nodeFromStreamImpl ( Jsr173GateWay gw ) + { + Cur c = gw._xs.getStreamCur(); + + return c.isNode() ? (Node) c.getDom() : (Node) null; + } + + public static XMLStreamReader newXmlStreamReader ( Cur c, Object src, int off, int cch ) + { + XMLStreamReaderBase xs = new XMLStreamReaderForString( c, src, off, cch ); + + if (c._locale.noSync()) + return new UnsyncedJsr173( c._locale, xs ); + else + return new SyncedJsr173( c._locale, xs ); + } + + public static XMLStreamReader newXmlStreamReader ( Cur c, XmlOptions options ) + { + options = XmlOptions.maskNull( options ); + + boolean inner = + options.hasOption( XmlOptions.SAVE_INNER ) && + !options.hasOption( XmlOptions.SAVE_OUTER ); + + XMLStreamReaderBase xs; + + int k = c.kind(); + + if (k == Cur.TEXT || k < 0) + { + xs = new XMLStreamReaderForString( c, c.getChars( -1 ), c._offSrc, c._cchSrc ); + } + else if (inner) + { + if (!c.hasAttrs() && !c.hasChildren()) + xs = new XMLStreamReaderForString( c, c.getFirstChars(), c._offSrc, c._cchSrc ); + else + { + assert c.isContainer(); + xs = new XMLStreamReaderForNode( c, true ); + } + } + else + xs = new XMLStreamReaderForNode( c, false ); + + if (c._locale.noSync()) + return new UnsyncedJsr173( c._locale, xs ); + else + return new SyncedJsr173( c._locale, xs ); + } + + // + // + // + + private static final class XMLStreamReaderForNode extends XMLStreamReaderBase + { + public XMLStreamReaderForNode ( Cur c, boolean inner ) + { + super( c ); + + assert c.isContainer() || c.isComment() || c.isProcinst() || c.isAttr(); + + // Iterate over everything *between* _cur and _end. Do + // not iterate the thing to the right of _end + + if (inner) + { + assert c.isContainer(); + + _cur = c.weakCur( this ); + + if (!_cur.toFirstAttr()) + _cur.next(); + + _end = c.weakCur( this ); + _end.toEnd(); + } + else + { + _cur = c.weakCur( this ); + + if (c.isRoot()) + _wholeDoc = true; + else + { + _end = c.weakCur( this ); + + if (c.isAttr()) + { + if (!_end.toNextAttr()) + { + _end.toParent(); + _end.next(); + } + } + else + _end.skip(); + } + } + + if (!_wholeDoc) + { + // Set the _done bit properly + + _cur.push(); + + try + { + next(); + } + catch ( XMLStreamException e ) + { + throw new RuntimeException( e.getMessage(), e ); + } + + _cur.pop(); + } + + assert _wholeDoc || !_cur.isSamePos( _end ); + } + + protected Cur getStreamCur ( ) + { + return _cur; + } + + // + // + // + + public boolean hasNext ( ) throws XMLStreamException + { + checkChanged(); + + return !_done; + } + + public int getEventType ( ) + { + switch ( _cur.kind() ) + { + case Cur.ROOT : return START_DOCUMENT; + case -Cur.ROOT : return END_DOCUMENT; + case Cur.ELEM : return START_ELEMENT; + case -Cur.ELEM : return END_ELEMENT; + case Cur.ATTR : return _cur.isXmlns() ? NAMESPACE : ATTRIBUTE; + case Cur.TEXT : return CHARACTERS; + case Cur.COMMENT : return COMMENT; + case Cur.PROCINST : return PROCESSING_INSTRUCTION; + default : throw new IllegalStateException(); + } + } + + public int next ( ) throws XMLStreamException + { + checkChanged(); + + if (!hasNext()) + throw new IllegalStateException( "No next event in stream" ); + + int kind = _cur.kind(); + + if (kind == -Cur.ROOT) + { + assert _wholeDoc; + _done = true; + } + else + { + if (kind == Cur.ATTR) + { + if (!_cur.toNextAttr()) + { + _cur.toParent(); + _cur.next(); + } + } + else if (kind == Cur.COMMENT || kind == Cur.PROCINST) + _cur.skip(); + else if (kind == Cur.ROOT) + { + if (!_cur.toFirstAttr()) + _cur.next(); + } + else + _cur.next(); + + assert _wholeDoc || _end != null; + + _done = _wholeDoc ? _cur.kind() == -Cur.ROOT : _cur.isSamePos( _end ); + } + + _textFetched = false; + _srcFetched = false; + + return getEventType(); + } + + public String getText ( ) + { + checkChanged(); + + int k = _cur.kind(); + + if (k == Cur.COMMENT) + return _cur.getValueAsString(); + + if (k == Cur.TEXT) + return _cur.getCharsAsString( -1 ); + + throw new IllegalStateException(); + } + + public boolean isStartElement ( ) + { + return getEventType() == START_ELEMENT; + } + + public boolean isEndElement ( ) + { + return getEventType() == END_ELEMENT; + } + + public boolean isCharacters ( ) + { + return getEventType() == CHARACTERS; + } + + public String getElementText ( ) throws XMLStreamException + { + checkChanged(); + + if (!isStartElement()) + throw new IllegalStateException(); + + StringBuffer sb = new StringBuffer(); + + for ( ; ; ) + { + if (!hasNext()) + throw new XMLStreamException(); + + int e = next(); + + if (e == END_ELEMENT) + break; + else if (e == START_ELEMENT) + throw new XMLStreamException(); + else if (e != COMMENT && e != PROCESSING_INSTRUCTION) + sb.append( getText() ); + } + + return sb.toString(); + } + + public int nextTag ( ) throws XMLStreamException + { + checkChanged(); + + for ( ; ; ) + { + if (isStartElement() || isEndElement()) + return getEventType(); + + if (!isWhiteSpace()) + throw new XMLStreamException(); + + if (!hasNext()) + throw new XMLStreamException(); + + next(); + } + } + + private static boolean matchAttr ( Cur c, String uri, String local ) + { + assert c.isNormalAttr(); + + QName name = c.getName(); + + return + name.getLocalPart().equals( local ) && + (uri == null || name.getNamespaceURI().equals( uri )); + } + + private static Cur toAttr ( Cur c, String uri, String local ) + { + if (uri == null || local == null || local.length() == 0) + throw new IllegalArgumentException(); + + Cur ca = c.tempCur(); + boolean match = false; + + if (c.isElem()) + { + if (ca.toFirstAttr()) + { + do + { + if (ca.isNormalAttr() && matchAttr( ca, uri, local )) + { + match = true; + break; + } + } + while ( ca.toNextSibling() ); + } + } + else if (c.isNormalAttr()) + match = matchAttr( c, uri, local ); + else + throw new IllegalStateException(); + + if (!match) + { + ca.release(); + ca = null; + } + + return ca; + } + + public String getAttributeValue ( String uri, String local ) + { + Cur ca = toAttr( _cur, uri, local ); + + String value = null; + + if (ca != null) + { + value = ca.getValueAsString(); + ca.release(); + } + + return value; + } + + private static Cur toAttr ( Cur c, int i ) + { + if (i < 0) + throw new IndexOutOfBoundsException( "Attribute index is negative" ); + + Cur ca = c.tempCur(); + boolean match = false; + + if (c.isElem()) + { + if (ca.toFirstAttr()) + { + do + { + if (ca.isNormalAttr() && i-- == 0) + { + match = true; + break; + } + } + while ( ca.toNextSibling() ); + } + } + else if (c.isNormalAttr()) + match = i == 0; + else + throw new IllegalStateException(); + + if (!match) + { + ca.release(); + throw new IndexOutOfBoundsException( "Attribute index is too large" ); + } + + return ca; + } + + public int getAttributeCount ( ) + { + int n = 0; + + if (_cur.isElem()) + { + Cur ca = _cur.tempCur(); + + if (ca.toFirstAttr()) + { + do + { + if (ca.isNormalAttr()) + n++; + } + while ( ca.toNextSibling() ); + } + + ca.release(); + } + else if (_cur.isNormalAttr()) + n++; + else + throw new IllegalStateException(); + + return n; + } + + public QName getAttributeName ( int index ) + { + Cur ca = toAttr( _cur, index ); + QName name = ca.getName(); + ca.release(); + return name; + } + + public String getAttributeNamespace ( int index ) + { + return getAttributeName( index ).getNamespaceURI(); + } + + public String getAttributeLocalName ( int index ) + { + return getAttributeName( index ).getLocalPart(); + } + + public String getAttributePrefix ( int index ) + { + return getAttributeName( index ).getPrefix(); + } + + public String getAttributeType ( int index ) + { + toAttr( _cur, index ).release(); + return "CDATA"; + } + + public String getAttributeValue ( int index ) + { + Cur ca = toAttr( _cur, index ); + + String value = null; + + if (ca != null) + { + value = ca.getValueAsString(); + ca.release(); + } + + return value; + } + + public boolean isAttributeSpecified ( int index ) + { + // Go to attr to force index check + Cur ca = toAttr( _cur, index ); + ca.release(); + + return false; + } + + public int getNamespaceCount ( ) + { + int n = 0; + + if (_cur.isElem() || _cur.kind() == -Cur.ELEM) + { + Cur ca = _cur.tempCur(); + + if (_cur.kind() == -Cur.ELEM) + ca.toParent(); + + if (ca.toFirstAttr()) + { + do + { + if (ca.isXmlns()) + n++; + } + while ( ca.toNextSibling() ); + } + + ca.release(); + } + else if (_cur.isXmlns()) + n++; + else + throw new IllegalStateException(); + + return n; + } + + private static Cur toXmlns ( Cur c, int i ) + { + if (i < 0) + throw new IndexOutOfBoundsException( "Namespace index is negative" ); + + Cur ca = c.tempCur(); + boolean match = false; + + if (c.isElem() || c.kind() == -Cur.ELEM) + { + if (c.kind() == -Cur.ELEM) + ca.toParent(); + + if (ca.toFirstAttr()) + { + do + { + if (ca.isXmlns() && i-- == 0) + { + match = true; + break; + } + } + while ( ca.toNextSibling() ); + } + } + else if (c.isXmlns()) + match = i == 0; + else + throw new IllegalStateException(); + + if (!match) + { + ca.release(); + throw new IndexOutOfBoundsException( "Namespace index is too large" ); + } + + return ca; + } + + public String getNamespacePrefix ( int index ) + { + Cur ca = toXmlns( _cur, index ); + String prefix = ca.getXmlnsPrefix(); + ca.release(); + return prefix; + } + + public String getNamespaceURI ( int index ) + { + Cur ca = toXmlns( _cur, index ); + String uri = ca.getXmlnsUri(); + ca.release(); + return uri; + } + + private void fetchChars ( ) + { + if (!_textFetched) + { + int k = _cur.kind(); + + Cur cText = null; + + if (k == Cur.COMMENT) + { + cText = _cur.tempCur(); + cText.next(); + } + else if (k == Cur.TEXT) + cText = _cur; + else + throw new IllegalStateException(); + + Object src = cText.getChars( -1 ); + + ensureCharBufLen( cText._cchSrc ); + + CharUtil.getChars( + _chars, _offChars = 0, src, cText._offSrc, _cchChars = cText._cchSrc ); + + if (cText != _cur) + cText.release(); + + _textFetched = true; + } + } + + private void ensureCharBufLen ( int cch ) + { + if (_chars == null || _chars.length < cch) + { + int l = 256; + + while ( l < cch ) + l *= 2; + + _chars = new char [ l ]; + } + } + + public char[] getTextCharacters ( ) + { + checkChanged(); + + fetchChars(); + + return _chars; + } + + public int getTextStart ( ) + { + checkChanged(); + + fetchChars(); + + return _offChars; + } + + public int getTextLength ( ) + { + checkChanged(); + + fetchChars(); + + return _cchChars; + } + + public int getTextCharacters ( + int sourceStart, char[] target, int targetStart, int length ) + throws XMLStreamException + { + if (length < 0) + throw new IndexOutOfBoundsException(); + + if (targetStart < 0 || targetStart >= target.length) + throw new IndexOutOfBoundsException(); + + if (targetStart + length > target.length) + throw new IndexOutOfBoundsException(); + + if (!_srcFetched) + { + int k = _cur.kind(); + + Cur cText = null; + + if (k == Cur.COMMENT) + { + cText = _cur.tempCur(); + cText.next(); + } + else if (k == Cur.TEXT) + cText = _cur; + else + throw new IllegalStateException(); + + _src = cText.getChars( -1 ); + _offSrc = cText._offSrc; + _cchSrc = cText._cchSrc; + + if (cText != _cur) + cText.release(); + + _srcFetched = true; + } + + if (sourceStart > _cchSrc) + throw new IndexOutOfBoundsException(); + + if (sourceStart + length > _cchSrc) + length = _cchSrc - sourceStart; + + CharUtil.getChars( target, targetStart, _src, _offSrc, length ); + + return length; + } + + public boolean hasText ( ) + { + int k = _cur.kind(); + + return k == Cur.COMMENT || k == Cur.TEXT; + } + + public boolean hasName ( ) + { + int k = _cur.kind(); + return k == Cur.ELEM || k == -Cur.ELEM; + } + + public QName getName ( ) + { + if (!hasName()) + throw new IllegalStateException(); + + return _cur.getName(); + } + + public String getNamespaceURI ( ) + { + return getName().getNamespaceURI(); + } + + public String getLocalName ( ) + { + return getName().getLocalPart(); + } + + public String getPrefix ( ) + { + return getName().getPrefix(); + } + + public String getPITarget ( ) + { + return _cur.kind() == Cur.PROCINST ? _cur.getName().getLocalPart() : null; + } + + public String getPIData ( ) + { + return _cur.kind() == Cur.PROCINST ? _cur.getValueAsString() : null; + } + + // + // + // + + private boolean _wholeDoc; + private boolean _done; + + private Cur _cur; + private Cur _end; + + private boolean _srcFetched; + private Object _src; + private int _offSrc; + private int _cchSrc; + + private boolean _textFetched; + private char[] _chars; + private int _offChars; + private int _cchChars; + } + + // + // + // + + private static abstract class XMLStreamReaderBase + implements XMLStreamReader, NamespaceContext, Location + { + XMLStreamReaderBase ( Cur c ) + { + _locale = c._locale; + _version = _locale.version(); + } + + protected final void checkChanged ( ) + { + if (_version != _locale.version()) + throw new ConcurrentModificationException( "Document changed while streaming" ); + } + + // + // XMLStreamReader methods + // + + public void close ( ) throws XMLStreamException + { + checkChanged(); + } + + public boolean isWhiteSpace ( ) + { + checkChanged(); + + // TODO - avoid creating a string here + String s = getText(); + + return _locale.getCharUtil().isWhiteSpace( s, 0, s.length() ); + } + + public Location getLocation ( ) + { + checkChanged(); + + Cur c = getStreamCur(); + + XmlLineNumber ln = (XmlLineNumber) c.getBookmark( XmlLineNumber.class ); + + // BUGBUG - put source name here + _uri = null; + + if (ln != null) + { + _line = ln.getLine(); + _column = ln.getColumn(); + _offset = ln.getOffset(); + } + else + { + _line = -1; + _column = -1; + _offset = -1; + } + + return this; + } + + + public Object getProperty ( String name ) + { + checkChanged(); + + if (name == null) + throw new IllegalArgumentException( "Property name is null" ); + + // BUGBUG - I should implement some perperties here + + return null; + } + + public String getCharacterEncodingScheme ( ) + { + checkChanged(); + + XmlDocumentProperties props = _locale.getDocProps( getStreamCur(), false ); + + return props == null ? null : props.getEncoding(); + } + + public String getEncoding ( ) + { + // BUGBUG - this should probably return the actual decoding used on the document + return null; + } + + public String getVersion ( ) + { + checkChanged(); + + XmlDocumentProperties props = _locale.getDocProps( getStreamCur(), false ); + + return props == null ? null : props.getVersion(); + } + + public boolean isStandalone ( ) + { + checkChanged(); + + XmlDocumentProperties props = _locale.getDocProps( getStreamCur(), false ); + + return props == null ? false : props.getStandalone(); + } + + public boolean standaloneSet ( ) + { + checkChanged(); + + return false; + } + + public void require ( int type, String namespaceURI, String localName ) + throws XMLStreamException + { + checkChanged(); + + if (type != getEventType()) + throw new XMLStreamException(); + + if (namespaceURI != null && !getNamespaceURI().equals( namespaceURI )) + throw new XMLStreamException(); + + if (localName != null && !getLocalName().equals( localName )) + throw new XMLStreamException(); + } + + // + // Location methods do not need a gatway + // + + public int getCharacterOffset ( ) { return _offset; } + public int getColumnNumber ( ) { return _column; } + public int getLineNumber ( ) { return _line; } + public String getLocationURI ( ) { return _uri; } + + public String getPublicId ( ) { return null; } + public String getSystemId ( ) { return null; } + + public NamespaceContext getNamespaceContext ( ) + { + throw new RuntimeException( "This version of getNamespaceContext should not be called"); + } + + public String getNamespaceURI ( String prefix ) + { + checkChanged(); + + Cur c = getStreamCur(); + + c.push(); + + if (!c.isContainer()) + c.toParent(); + + String ns = c.namespaceForPrefix( prefix, true ); + + c.pop(); + + return ns; + } + + public String getPrefix ( String namespaceURI ) + { + checkChanged(); + + Cur c = getStreamCur(); + + c.push(); + + if (!c.isContainer()) + c.toParent(); + + String prefix = c.prefixForNamespace( namespaceURI, null, false ); + + c.pop(); + + return prefix; + } + + public Iterator getPrefixes ( String namespaceURI ) + { + checkChanged(); + + // BUGBUG - get only one for now ... + + HashMap map = new HashMap(); + + map.put( namespaceURI, getPrefix( namespaceURI ) ); + + return map.values().iterator(); + } + + // + // + // + + protected abstract Cur getStreamCur ( ); + + // + // + // + + private Locale _locale; + private long _version; + + String _uri; + + int _line = -1; + int _column = -1; + int _offset = -1; + } + + // + // + // + + private static final class XMLStreamReaderForString extends XMLStreamReaderBase + { + XMLStreamReaderForString ( Cur c, Object src, int off, int cch ) + { + super( c ); + + _src = src; + _off = off; + _cch = cch; + + _cur = c; + } + + protected Cur getStreamCur ( ) + { + return _cur; + } + + // + // Legal stream methods + // + + public String getText ( ) + { + checkChanged(); + + return CharUtil.getString( _src, _off, _cch ); + } + + public char[] getTextCharacters ( ) + { + checkChanged(); + + char[] chars = new char [ _cch ]; + + CharUtil.getChars( chars, 0, _src, _off, _cch ); + + return chars; + } + public int getTextStart ( ) + { + checkChanged(); + + return _off; + } + public int getTextLength ( ) + { + checkChanged(); + + return _cch; + } + + public int getTextCharacters ( int sourceStart, char[] target, int targetStart, int length ) + { + checkChanged(); + + if (length < 0) + throw new IndexOutOfBoundsException(); + + if (sourceStart > _cch) + throw new IndexOutOfBoundsException(); + + if (sourceStart + length > _cch) + length = _cch - sourceStart; + + CharUtil.getChars( target, targetStart, _src, _off + sourceStart, length ); + + return length; + } + + public int getEventType ( ) { checkChanged(); return CHARACTERS; } + public boolean hasName ( ) { checkChanged(); return false; } + public boolean hasNext ( ) { checkChanged(); return false; } + public boolean hasText ( ) { checkChanged(); return true; } + public boolean isCharacters ( ) { checkChanged(); return true; } + public boolean isEndElement ( ) { checkChanged(); return false; } + public boolean isStartElement ( ) { checkChanged(); return false; } + + // + // Illegal stream methods + // + + public int getAttributeCount ( ) { throw new IllegalStateException(); } + public String getAttributeLocalName ( int index ) { throw new IllegalStateException(); } + public QName getAttributeName ( int index ) { throw new IllegalStateException(); } + public String getAttributeNamespace ( int index ) { throw new IllegalStateException(); } + public String getAttributePrefix ( int index ) { throw new IllegalStateException(); } + public String getAttributeType ( int index ) { throw new IllegalStateException(); } + public String getAttributeValue ( int index ) { throw new IllegalStateException(); } + public String getAttributeValue ( String namespaceURI, String localName ) { throw new IllegalStateException(); } + public String getElementText ( ) { throw new IllegalStateException(); } + public String getLocalName ( ) { throw new IllegalStateException(); } + public QName getName ( ) { throw new IllegalStateException(); } + public int getNamespaceCount ( ) { throw new IllegalStateException(); } + public String getNamespacePrefix ( int index ) { throw new IllegalStateException(); } + public String getNamespaceURI ( int index ) { throw new IllegalStateException(); } + public String getNamespaceURI ( ) { throw new IllegalStateException(); } + public String getPIData ( ) { throw new IllegalStateException(); } + public String getPITarget ( ) { throw new IllegalStateException(); } + public String getPrefix ( ) { throw new IllegalStateException(); } + public boolean isAttributeSpecified ( int index ) { throw new IllegalStateException(); } + public int next ( ) { throw new IllegalStateException(); } + public int nextTag ( ) { throw new IllegalStateException(); } + public String getPublicId() { throw new IllegalStateException(); } + public String getSystemId() { throw new IllegalStateException(); } + + private Cur _cur; + private Object _src; + private int _off; + private int _cch; + } + + // + // + // + + private static abstract class Jsr173GateWay + { + public Jsr173GateWay ( Locale l, XMLStreamReaderBase xs ) { _l = l; _xs = xs; } + + Locale _l; + XMLStreamReaderBase _xs; + } + + private static final class SyncedJsr173 extends Jsr173GateWay implements XMLStreamReader, Location, NamespaceContext + { + public SyncedJsr173 ( Locale l, XMLStreamReaderBase xs ) { super( l, xs ); } + + public Object getProperty ( java.lang.String name ) { synchronized ( _l ) { _l.enter(); try { return _xs.getProperty( name ); } finally { _l.exit(); } } } + public int next ( ) throws XMLStreamException { synchronized ( _l ) { _l.enter(); try { return _xs.next(); } finally { _l.exit(); } } } + public void require ( int type, String namespaceURI, String localName ) throws XMLStreamException { synchronized ( _l ) { _l.enter(); try { _xs.require( type, namespaceURI, localName ); } finally { _l.exit(); } } } + public String getElementText ( ) throws XMLStreamException { synchronized ( _l ) { _l.enter(); try { return _xs.getElementText(); } finally { _l.exit(); } } } + public int nextTag ( ) throws XMLStreamException { synchronized ( _l ) { _l.enter(); try { return _xs.nextTag(); } finally { _l.exit(); } } } + public boolean hasNext ( ) throws XMLStreamException { synchronized ( _l ) { _l.enter(); try { return _xs.hasNext(); } finally { _l.exit(); } } } + public void close ( ) throws XMLStreamException { synchronized ( _l ) { _l.enter(); try { _xs.close(); } finally { _l.exit(); } } } + public String getNamespaceURI ( String prefix ) { synchronized ( _l ) { _l.enter(); try { return _xs.getNamespaceURI ( prefix ); } finally { _l.exit(); } } } + public boolean isStartElement ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.isStartElement(); } finally { _l.exit(); } } } + public boolean isEndElement ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.isEndElement(); } finally { _l.exit(); } } } + public boolean isCharacters ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.isCharacters(); } finally { _l.exit(); } } } + public boolean isWhiteSpace ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.isWhiteSpace(); } finally { _l.exit(); } } } + public String getAttributeValue ( String namespaceURI, String localName ) { synchronized ( _l ) { _l.enter(); try { return _xs.getAttributeValue ( namespaceURI, localName ); } finally { _l.exit(); } } } + public int getAttributeCount ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.getAttributeCount(); } finally { _l.exit(); } } } + public QName getAttributeName ( int index ) { synchronized ( _l ) { _l.enter(); try { return _xs.getAttributeName ( index ); } finally { _l.exit(); } } } + public String getAttributeNamespace ( int index ) { synchronized ( _l ) { _l.enter(); try { return _xs.getAttributeNamespace ( index ); } finally { _l.exit(); } } } + public String getAttributeLocalName ( int index ) { synchronized ( _l ) { _l.enter(); try { return _xs.getAttributeLocalName ( index ); } finally { _l.exit(); } } } + public String getAttributePrefix ( int index ) { synchronized ( _l ) { _l.enter(); try { return _xs.getAttributePrefix ( index ); } finally { _l.exit(); } } } + public String getAttributeType ( int index ) { synchronized ( _l ) { _l.enter(); try { return _xs.getAttributeType ( index ); } finally { _l.exit(); } } } + public String getAttributeValue ( int index ) { synchronized ( _l ) { _l.enter(); try { return _xs.getAttributeValue ( index ); } finally { _l.exit(); } } } + public boolean isAttributeSpecified ( int index ) { synchronized ( _l ) { _l.enter(); try { return _xs.isAttributeSpecified ( index ); } finally { _l.exit(); } } } + public int getNamespaceCount ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.getNamespaceCount(); } finally { _l.exit(); } } } + public String getNamespacePrefix ( int index ) { synchronized ( _l ) { _l.enter(); try { return _xs.getNamespacePrefix ( index ); } finally { _l.exit(); } } } + public String getNamespaceURI ( int index ) { synchronized ( _l ) { _l.enter(); try { return _xs.getNamespaceURI ( index ); } finally { _l.exit(); } } } + public NamespaceContext getNamespaceContext ( ) { return this; } + public int getEventType ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.getEventType(); } finally { _l.exit(); } } } + public String getText ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.getText(); } finally { _l.exit(); } } } + public char[] getTextCharacters ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.getTextCharacters(); } finally { _l.exit(); } } } + public int getTextCharacters ( int sourceStart, char[] target, int targetStart, int length ) throws XMLStreamException { synchronized ( _l ) { _l.enter(); try { return _xs.getTextCharacters ( sourceStart, target, targetStart, length ); } finally { _l.exit(); } } } + public int getTextStart ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.getTextStart(); } finally { _l.exit(); } } } + public int getTextLength ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.getTextLength(); } finally { _l.exit(); } } } + public String getEncoding ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.getEncoding(); } finally { _l.exit(); } } } + public boolean hasText ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.hasText(); } finally { _l.exit(); } } } + public Location getLocation ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.getLocation(); } finally { _l.exit(); } } } + public QName getName ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.getName(); } finally { _l.exit(); } } } + public String getLocalName ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.getLocalName(); } finally { _l.exit(); } } } + public boolean hasName ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.hasName(); } finally { _l.exit(); } } } + public String getNamespaceURI ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.getNamespaceURI(); } finally { _l.exit(); } } } + public String getPrefix ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.getPrefix(); } finally { _l.exit(); } } } + public String getVersion ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.getVersion(); } finally { _l.exit(); } } } + public boolean isStandalone ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.isStandalone(); } finally { _l.exit(); } } } + public boolean standaloneSet ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.standaloneSet(); } finally { _l.exit(); } } } + public String getCharacterEncodingScheme ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.getCharacterEncodingScheme(); } finally { _l.exit(); } } } + public String getPITarget ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.getPITarget(); } finally { _l.exit(); } } } + public String getPIData ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.getPIData(); } finally { _l.exit(); } } } + public String getPrefix ( String namespaceURI ) { synchronized ( _l ) { _l.enter(); try { return _xs.getPrefix( namespaceURI ); } finally { _l.exit(); } } } + public Iterator getPrefixes ( String namespaceURI ) { synchronized ( _l ) { _l.enter(); try { return _xs.getPrefixes( namespaceURI ); } finally { _l.exit(); } } } + public int getCharacterOffset ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.getCharacterOffset(); } finally { _l.exit(); } } } + public int getColumnNumber ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.getColumnNumber(); } finally { _l.exit(); } } } + public int getLineNumber ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.getLineNumber(); } finally { _l.exit(); } } } + public String getLocationURI ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.getLocationURI(); } finally { _l.exit(); } } } + public String getPublicId() { synchronized ( _l ) { _l.enter(); try { return _xs.getPublicId(); } finally { _l.exit(); } } } + public String getSystemId() { synchronized ( _l ) { _l.enter(); try { return _xs.getSystemId(); } finally { _l.exit(); } } } + } + + private static final class UnsyncedJsr173 extends Jsr173GateWay implements XMLStreamReader, Location, NamespaceContext + { + public UnsyncedJsr173 ( Locale l, XMLStreamReaderBase xs ) { super( l, xs ); } + + public Object getProperty ( java.lang.String name ) { try { _l.enter(); return _xs.getProperty( name ); } finally { _l.exit(); } } + public int next ( ) throws XMLStreamException { try { _l.enter(); return _xs.next(); } finally { _l.exit(); } } + public void require ( int type, String namespaceURI, String localName ) throws XMLStreamException { try { _l.enter(); _xs.require( type, namespaceURI, localName ); } finally { _l.exit(); } } + public String getElementText ( ) throws XMLStreamException { try { _l.enter(); return _xs.getElementText(); } finally { _l.exit(); } } + public int nextTag ( ) throws XMLStreamException { try { _l.enter(); return _xs.nextTag(); } finally { _l.exit(); } } + public boolean hasNext ( ) throws XMLStreamException { try { _l.enter(); return _xs.hasNext(); } finally { _l.exit(); } } + public void close ( ) throws XMLStreamException { try { _l.enter(); _xs.close(); } finally { _l.exit(); } } + public String getNamespaceURI ( String prefix ) { try { _l.enter(); return _xs.getNamespaceURI ( prefix ); } finally { _l.exit(); } } + public boolean isStartElement ( ) { try { _l.enter(); return _xs.isStartElement(); } finally { _l.exit(); } } + public boolean isEndElement ( ) { try { _l.enter(); return _xs.isEndElement(); } finally { _l.exit(); } } + public boolean isCharacters ( ) { try { _l.enter(); return _xs.isCharacters(); } finally { _l.exit(); } } + public boolean isWhiteSpace ( ) { try { _l.enter(); return _xs.isWhiteSpace(); } finally { _l.exit(); } } + public String getAttributeValue ( String namespaceURI, String localName ) { try { _l.enter(); return _xs.getAttributeValue ( namespaceURI, localName ); } finally { _l.exit(); } } + public int getAttributeCount ( ) { try { _l.enter(); return _xs.getAttributeCount(); } finally { _l.exit(); } } + public QName getAttributeName ( int index ) { try { _l.enter(); return _xs.getAttributeName ( index ); } finally { _l.exit(); } } + public String getAttributeNamespace ( int index ) { try { _l.enter(); return _xs.getAttributeNamespace ( index ); } finally { _l.exit(); } } + public String getAttributeLocalName ( int index ) { try { _l.enter(); return _xs.getAttributeLocalName ( index ); } finally { _l.exit(); } } + public String getAttributePrefix ( int index ) { try { _l.enter(); return _xs.getAttributePrefix ( index ); } finally { _l.exit(); } } + public String getAttributeType ( int index ) { try { _l.enter(); return _xs.getAttributeType ( index ); } finally { _l.exit(); } } + public String getAttributeValue ( int index ) { try { _l.enter(); return _xs.getAttributeValue ( index ); } finally { _l.exit(); } } + public boolean isAttributeSpecified ( int index ) { try { _l.enter(); return _xs.isAttributeSpecified ( index ); } finally { _l.exit(); } } + public int getNamespaceCount ( ) { try { _l.enter(); return _xs.getNamespaceCount(); } finally { _l.exit(); } } + public String getNamespacePrefix ( int index ) { try { _l.enter(); return _xs.getNamespacePrefix ( index ); } finally { _l.exit(); } } + public String getNamespaceURI ( int index ) { try { _l.enter(); return _xs.getNamespaceURI ( index ); } finally { _l.exit(); } } + public NamespaceContext getNamespaceContext ( ) { return this; } + public int getEventType ( ) { try { _l.enter(); return _xs.getEventType(); } finally { _l.exit(); } } + public String getText ( ) { try { _l.enter(); return _xs.getText(); } finally { _l.exit(); } } + public char[] getTextCharacters ( ) { try { _l.enter(); return _xs.getTextCharacters(); } finally { _l.exit(); } } + public int getTextCharacters ( int sourceStart, char[] target, int targetStart, int length ) throws XMLStreamException { try { _l.enter(); return _xs.getTextCharacters ( sourceStart, target, targetStart, length ); } finally { _l.exit(); } } + public int getTextStart ( ) { try { _l.enter(); return _xs.getTextStart(); } finally { _l.exit(); } } + public int getTextLength ( ) { try { _l.enter(); return _xs.getTextLength(); } finally { _l.exit(); } } + public String getEncoding ( ) { try { _l.enter(); return _xs.getEncoding(); } finally { _l.exit(); } } + public boolean hasText ( ) { try { _l.enter(); return _xs.hasText(); } finally { _l.exit(); } } + public Location getLocation ( ) { try { _l.enter(); return _xs.getLocation(); } finally { _l.exit(); } } + public QName getName ( ) { try { _l.enter(); return _xs.getName(); } finally { _l.exit(); } } + public String getLocalName ( ) { try { _l.enter(); return _xs.getLocalName(); } finally { _l.exit(); } } + public boolean hasName ( ) { try { _l.enter(); return _xs.hasName(); } finally { _l.exit(); } } + public String getNamespaceURI ( ) { try { _l.enter(); return _xs.getNamespaceURI(); } finally { _l.exit(); } } + public String getPrefix ( ) { try { _l.enter(); return _xs.getPrefix(); } finally { _l.exit(); } } + public String getVersion ( ) { try { _l.enter(); return _xs.getVersion(); } finally { _l.exit(); } } + public boolean isStandalone ( ) { try { _l.enter(); return _xs.isStandalone(); } finally { _l.exit(); } } + public boolean standaloneSet ( ) { try { _l.enter(); return _xs.standaloneSet(); } finally { _l.exit(); } } + public String getCharacterEncodingScheme ( ) { try { _l.enter(); return _xs.getCharacterEncodingScheme(); } finally { _l.exit(); } } + public String getPITarget ( ) { try { _l.enter(); return _xs.getPITarget(); } finally { _l.exit(); } } + public String getPIData ( ) { try { _l.enter(); return _xs.getPIData(); } finally { _l.exit(); } } + public String getPrefix ( String namespaceURI ) { try { _l.enter(); return _xs.getPrefix( namespaceURI ); } finally { _l.exit(); } } + public Iterator getPrefixes ( String namespaceURI ) { try { _l.enter(); return _xs.getPrefixes( namespaceURI ); } finally { _l.exit(); } } + public int getCharacterOffset ( ) { try { _l.enter(); return _xs.getCharacterOffset(); } finally { _l.exit(); } } + public int getColumnNumber ( ) { try { _l.enter(); return _xs.getColumnNumber(); } finally { _l.exit(); } } + public int getLineNumber ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.getLineNumber(); } finally { _l.exit(); } } } + public String getLocationURI ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.getLocationURI(); } finally { _l.exit(); } } } + public String getPublicId() { synchronized ( _l ) { _l.enter(); try { return _xs.getPublicId(); } finally { _l.exit(); } } } + public String getSystemId() { synchronized ( _l ) { _l.enter(); try { return _xs.getSystemId(); } finally { _l.exit(); } } } + } +} + + \ No newline at end of file diff --git a/xmlbeans/src/store/org/apache/xmlbeans/impl/store/Locale.java b/xmlbeans/src/store/org/apache/xmlbeans/impl/store/Locale.java new file mode 100755 index 000000000..531f8763e --- /dev/null +++ b/xmlbeans/src/store/org/apache/xmlbeans/impl/store/Locale.java @@ -0,0 +1,3816 @@ +/* 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.store; + +import org.apache.xmlbeans.XmlErrorCodes; +import org.xml.sax.Locator; +import org.xml.sax.Attributes; +import org.xml.sax.ContentHandler; +import org.xml.sax.EntityResolver; +import org.xml.sax.ErrorHandler; +import org.xml.sax.InputSource; +import org.xml.sax.ext.LexicalHandler; +import org.xml.sax.ext.DeclHandler; +import org.xml.sax.SAXParseException; +import org.xml.sax.InputSource; +import org.xml.sax.XMLReader; +import org.xml.sax.SAXException; +import org.xml.sax.DTDHandler; + +import java.util.HashMap; +import java.util.Map; + +import java.lang.ref.ReferenceQueue; +import java.lang.ref.Reference; +import java.lang.ref.PhantomReference; +import java.lang.ref.SoftReference; + +import java.lang.reflect.Method; + +import java.io.InputStream; +import java.io.Reader; +import java.io.StringReader; +import java.io.IOException; + +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamException; + +import org.apache.xmlbeans.xml.stream.Attribute; +import org.apache.xmlbeans.xml.stream.AttributeIterator; +import org.apache.xmlbeans.xml.stream.CharacterData; +import org.apache.xmlbeans.xml.stream.ProcessingInstruction; +import org.apache.xmlbeans.xml.stream.Space; +import org.apache.xmlbeans.xml.stream.StartDocument; +import org.apache.xmlbeans.xml.stream.StartElement; +import org.apache.xmlbeans.xml.stream.XMLEvent; +import org.apache.xmlbeans.xml.stream.XMLInputStream; +import org.apache.xmlbeans.xml.stream.XMLName; + +import org.w3c.dom.DOMImplementation; +import org.w3c.dom.Document; +import org.w3c.dom.DocumentType; +import org.w3c.dom.Node; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Element; + +import javax.xml.namespace.QName; + +import org.apache.xmlbeans.impl.common.XMLNameHelper; +import org.apache.xmlbeans.impl.common.QNameHelper; +import org.apache.xmlbeans.impl.common.XmlLocale; +import org.apache.xmlbeans.impl.common.ResolverUtil; +import org.apache.xmlbeans.impl.common.SystemCache; + +import org.apache.xmlbeans.impl.store.Saaj.SaajCallback; + +import org.apache.xmlbeans.impl.store.DomImpl.Dom; +import org.apache.xmlbeans.impl.store.DomImpl.TextNode; +import org.apache.xmlbeans.impl.store.DomImpl.CdataNode; +import org.apache.xmlbeans.impl.store.DomImpl.SaajTextNode; +import org.apache.xmlbeans.impl.store.DomImpl.SaajCdataNode; + +import org.apache.xmlbeans.impl.store.Cur.Locations; + +import org.apache.xmlbeans.CDataBookmark; +import org.apache.xmlbeans.XmlBeans; +import org.apache.xmlbeans.XmlLineNumber; +import org.apache.xmlbeans.XmlCursor; +import org.apache.xmlbeans.XmlCursor.XmlBookmark; +import org.apache.xmlbeans.XmlSaxHandler; +import org.apache.xmlbeans.XmlException; +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.XmlOptions; +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.SchemaTypeLoader; +import org.apache.xmlbeans.XmlTokenSource; +import org.apache.xmlbeans.QNameSet; +import org.apache.xmlbeans.QNameCache; +import org.apache.xmlbeans.XmlError; +import org.apache.xmlbeans.XmlRuntimeException; +import org.apache.xmlbeans.XmlDocumentProperties; + +import org.apache.xmlbeans.impl.values.TypeStore; +import org.apache.xmlbeans.impl.values.TypeStoreUser; +import org.apache.xmlbeans.impl.values.TypeStoreUserFactory; + +import org.apache.xmlbeans.impl.piccolo.xml.Piccolo; +import org.apache.xmlbeans.impl.piccolo.io.FileFormatException; + +public final class Locale + implements DOMImplementation, SaajCallback, XmlLocale +{ + static final int ROOT = Cur.ROOT; + static final int ELEM = Cur.ELEM; + static final int ATTR = Cur.ATTR; + static final int COMMENT = Cur.COMMENT; + static final int PROCINST = Cur.PROCINST; + static final int TEXT = Cur.TEXT; + + static final int WS_UNSPECIFIED = TypeStore.WS_UNSPECIFIED; + static final int WS_PRESERVE = TypeStore.WS_PRESERVE; + static final int WS_REPLACE = TypeStore.WS_REPLACE; + static final int WS_COLLAPSE = TypeStore.WS_COLLAPSE; + + static final String _xsi = "http://www.w3.org/2001/XMLSchema-instance"; + static final String _schema = "http://www.w3.org/2001/XMLSchema"; + static final String _openFragUri = "http://www.openuri.org/fragment"; + static final String _xml1998Uri = "http://www.w3.org/XML/1998/namespace"; + static final String _xmlnsUri = "http://www.w3.org/2000/xmlns/"; + + static final QName _xsiNil = new QName(_xsi, "nil", "xsi"); + static final QName _xsiType = new QName(_xsi, "type", "xsi"); + static final QName _xsiLoc = new QName(_xsi, "schemaLocation", "xsi"); + static final QName _xsiNoLoc = new QName(_xsi, "noNamespaceSchemaLocation", + "xsi"); + static final QName _openuriFragment = new QName(_openFragUri, "fragment", + "frag"); + static final QName _xmlFragment = new QName("xml-fragment"); + + private Locale(SchemaTypeLoader stl, XmlOptions options) + { + options = XmlOptions.maskNull(options); + + // + // + // + + // TODO - add option for no=sync, or make it all thread safe + // + // Also - have a thread local setting for thread safety? .. Perhaps something + // in the type loader which defines whether ot not sync is on???? + + _noSync = options.hasOption(XmlOptions.UNSYNCHRONIZED); + + _tempFrames = new Cur[_numTempFramesLeft = 8]; + + // BUGBUG - this cannot be thread local .... + // BUGBUG - this cannot be thread local .... + // BUGBUG - this cannot be thread local .... uhh what, again? + // + // Lazy create this (loading up a locale should use the thread locale one) + // same goes for the qname factory .. use thread local for hte most part when loading + + _qnameFactory = new DefaultQNameFactory(); //new LocalDocumentQNameFactory(); + + _locations = new Locations(this); + + _schemaTypeLoader = stl; + + _validateOnSet = options.hasOption(XmlOptions.VALIDATE_ON_SET); + + // + // Check for Saaj implementation request + // + + Object saajObj = options.get(Saaj.SAAJ_IMPL); + + if (saajObj != null) + { + if (!(saajObj instanceof Saaj)) + throw new IllegalStateException( + "Saaj impl not correct type: " + saajObj); + + _saaj = (Saaj) saajObj; + + _saaj.setCallback(this); + } + } + + // + // + // + + public static final String USE_SAME_LOCALE = "USE_SAME_LOCALE"; + /** + * This option is checked in XmlObjectBase._copy(XmlOptions), the locale is used as the synchronization domain. + * useNewLocale = true: copy will use a new locale, false: copy will use the same locale as the source + * @deprecated Replace usages with CopyUseNewSynchronizationDomain option + * @see org.apache.xmlbeans.XmlOptions#setCopyUseNewSynchronizationDomain(boolean) + */ + public static final String COPY_USE_NEW_LOCALE = "COPY_USE_NEW_LOCALE"; + + static Locale getLocale(SchemaTypeLoader stl, XmlOptions options) + { + if (stl == null) + stl = XmlBeans.getContextTypeLoader(); + + options = XmlOptions.maskNull(options); + + Locale l = null; + + if (options.hasOption(USE_SAME_LOCALE)) + { + Object source = options.get(USE_SAME_LOCALE); + + if (source instanceof Locale) + l = (Locale) source; + else if (source instanceof XmlTokenSource) + l = (Locale) ((XmlTokenSource) source).monitor(); + else + throw new IllegalArgumentException( + "Source locale not understood: " + source); + + if (l._schemaTypeLoader != stl) + throw new IllegalArgumentException( + "Source locale does not support same schema type loader"); + + if (l._saaj != null && l._saaj != options.get(Saaj.SAAJ_IMPL)) + throw new IllegalArgumentException( + "Source locale does not support same saaj"); + + if (l._validateOnSet && + !options.hasOption(XmlOptions.VALIDATE_ON_SET)) + throw new IllegalArgumentException( + "Source locale does not support same validate on set"); + + // TODO - other things to check? + } + else + l = new Locale(stl, options); + + return l; + } + + // + // + // + + static void associateSourceName(Cur c, XmlOptions options) + { + String sourceName = (String) XmlOptions.safeGet(options, + XmlOptions.DOCUMENT_SOURCE_NAME); + + if (sourceName != null) + getDocProps(c, true).setSourceName(sourceName); + } + + // + // + // + + static void autoTypeDocument(Cur c, SchemaType requestedType, + XmlOptions options) + throws XmlException + { + assert c.isRoot(); + + // The type in the options overrides all sniffing + + options = XmlOptions.maskNull(options); + + SchemaType optionType = (SchemaType) options.get( + XmlOptions.DOCUMENT_TYPE); + + if (optionType != null) + { + c.setType(optionType); + return; + } + + SchemaType type = null; + + // An xsi:type can be used to pick a type out of the loader, or used to refine + // a type with a name. + + if (requestedType == null || requestedType.getName() != null) + { + QName xsiTypeName = c.getXsiTypeName(); + + SchemaType xsiSchemaType = + xsiTypeName == null ? + null : c._locale._schemaTypeLoader.findType(xsiTypeName); + + if (requestedType == null || + requestedType.isAssignableFrom(xsiSchemaType)) + type = xsiSchemaType; + } + + // Look for a document element to establish type + + if (type == null && + (requestedType == null || requestedType.isDocumentType())) + { + assert c.isRoot(); + + c.push(); + + QName docElemName = + !c.hasAttrs() && Locale.toFirstChildElement(c) && + !Locale.toNextSiblingElement(c) + ? c.getName() : null; + + c.pop(); + + if (docElemName != null) + { + type = + c._locale._schemaTypeLoader.findDocumentType(docElemName); + + if (type != null && requestedType != null) + { + QName requesteddocElemNameName = requestedType.getDocumentElementName(); + + if (!requesteddocElemNameName.equals(docElemName) && + !requestedType.isValidSubstitution(docElemName)) + { + throw + new XmlException("Element " + + QNameHelper.pretty(docElemName) + + " is not a valid " + + QNameHelper.pretty(requesteddocElemNameName) + + " document or a valid substitution."); + } + } + } + } + + if (type == null && requestedType == null) + { + c.push(); + + type = + Locale.toFirstNormalAttr(c) && !Locale.toNextNormalAttr(c) + ? + c._locale._schemaTypeLoader.findAttributeType(c.getName()) : + null; + + c.pop(); + } + + if (type == null) + type = requestedType; + + if (type == null) + type = XmlBeans.NO_TYPE; + + c.setType(type); + + if (requestedType != null) + { + if (type.isDocumentType()) + verifyDocumentType(c, type.getDocumentElementName()); + else if (type.isAttributeType()) + verifyAttributeType(c, type.getAttributeTypeAttributeName()); + } + } + + private static boolean namespacesSame(QName n1, QName n2) + { + if (n1 == n2) + return true; + + if (n1 == null || n2 == null) + return false; + + if (n1.getNamespaceURI() == n2.getNamespaceURI()) + return true; + + if (n1.getNamespaceURI() == null || n2.getNamespaceURI() == null) + return false; + + return n1.getNamespaceURI().equals(n2.getNamespaceURI()); + } + + private static void addNamespace(StringBuffer sb, QName name) + { + if (name.getNamespaceURI() == null) + sb.append(""); + else + { + sb.append("\""); + sb.append(name.getNamespaceURI()); + sb.append("\""); + } + } + + private static void verifyDocumentType(Cur c, QName docElemName) + throws XmlException + { + assert c.isRoot(); + + c.push(); + + try + { + StringBuffer sb = null; + + if (!Locale.toFirstChildElement(c) || + Locale.toNextSiblingElement(c)) + { + sb = new StringBuffer(); + + sb.append("The document is not a "); + sb.append(QNameHelper.pretty(docElemName)); + sb.append( + c.isRoot() ? + ": no document element" : ": multiple document elements"); + } + else + { + QName name = c.getName(); + + if (!name.equals(docElemName)) + { + sb = new StringBuffer(); + + sb.append("The document is not a "); + sb.append(QNameHelper.pretty(docElemName)); + + if (docElemName.getLocalPart().equals(name.getLocalPart())) + { + sb.append(": document element namespace mismatch "); + sb.append("expected "); + addNamespace(sb, docElemName); + sb.append(" got "); + addNamespace(sb, name); + } + else if (namespacesSame(docElemName, name)) + { + sb.append(": document element local name mismatch "); + sb.append("expected " + docElemName.getLocalPart()); + sb.append(" got " + name.getLocalPart()); + } + else + { + sb.append(": document element mismatch "); + sb.append("got "); + sb.append(QNameHelper.pretty(name)); + } + } + } + + if (sb != null) + { + XmlError err = XmlError.forCursor(sb.toString(), + new Cursor(c)); + throw new XmlException(err.toString(), null, err); + } + } + finally + { + c.pop(); + } + } + + private static void verifyAttributeType(Cur c, QName attrName) + throws XmlException + { + assert c.isRoot(); + + c.push(); + + try + { + StringBuffer sb = null; + + if (!Locale.toFirstNormalAttr(c) || Locale.toNextNormalAttr(c)) + { + sb = new StringBuffer(); + + sb.append("The document is not a "); + sb.append(QNameHelper.pretty(attrName)); + sb.append( + c.isRoot() ? ": no attributes" : ": multiple attributes"); + } + else + { + QName name = c.getName(); + + if (!name.equals(attrName)) + { + sb = new StringBuffer(); + + sb.append("The document is not a "); + sb.append(QNameHelper.pretty(attrName)); + + if (attrName.getLocalPart().equals(name.getLocalPart())) + { + sb.append(": attribute namespace mismatch "); + sb.append("expected "); + addNamespace(sb, attrName); + sb.append(" got "); + addNamespace(sb, name); + } + else if (namespacesSame(attrName, name)) + { + sb.append(": attribute local name mismatch "); + sb.append("expected " + attrName.getLocalPart()); + sb.append(" got " + name.getLocalPart()); + } + else + { + sb.append(": attribute element mismatch "); + sb.append("got "); + sb.append(QNameHelper.pretty(name)); + } + } + } + + if (sb != null) + { + XmlError err = XmlError.forCursor(sb.toString(), + new Cursor(c)); + throw new XmlException(err.toString(), null, err); + } + } + finally + { + c.pop(); + } + } + + static boolean isFragmentQName(QName name) + { + return name.equals(Locale._openuriFragment) || + name.equals(Locale._xmlFragment); + } + + static boolean isFragment(Cur start, Cur end) + { + assert !end.isAttr(); + + start.push(); + end.push(); + + int numDocElems = 0; + boolean isFrag = false; + + while (!start.isSamePos(end)) + { + int k = start.kind(); + + if (k == ATTR) + break; + + if (k == TEXT && !isWhiteSpace(start.getCharsAsString(-1))) + { + isFrag = true; + break; + } + + if (k == ELEM && ++numDocElems > 1) + { + isFrag = true; + break; + } + + // Move to next token + + assert k != ATTR; + + if (k != TEXT) + start.toEnd(); + + start.next(); + } + + start.pop(); + end.pop(); + + return isFrag || numDocElems != 1; + } + + // + // + // + + public static XmlObject newInstance(SchemaTypeLoader stl, SchemaType type, + XmlOptions options) + { + Locale l = getLocale(stl, options); + + if (l.noSync()) + { + l.enter(); + try + { + return l.newInstance(type, options); + } + finally + { + l.exit(); + } + } + else + synchronized (l) + { + l.enter(); + try + { + return l.newInstance(type, options); + } + finally + { + l.exit(); + } + } + } + + private XmlObject newInstance(SchemaType type, XmlOptions options) + { + options = XmlOptions.maskNull(options); + + Cur c = tempCur(); + + + SchemaType sType = (SchemaType) options.get(XmlOptions.DOCUMENT_TYPE); + + if (sType == null) + sType = type == null ? XmlObject.type : type; + if (sType.isDocumentType()) + c.createDomDocumentRoot(); + else + c.createRoot(); + c.setType(sType); + + XmlObject x = (XmlObject) c.getUser(); + + c.release(); + + return x; + } + + // + // + // + + public static DOMImplementation newDomImplementation(SchemaTypeLoader stl, + XmlOptions options) + { + return (DOMImplementation) getLocale(stl, options); + } + + // + // + // + + public static XmlObject parseToXmlObject(SchemaTypeLoader stl, + String xmlText, SchemaType type, XmlOptions options) + throws XmlException + { + Locale l = getLocale(stl, options); + + if (l.noSync()) + { + l.enter(); + try + { + return l.parseToXmlObject(xmlText, type, options); + } + finally + { + l.exit(); + } + } + else + synchronized (l) + { + l.enter(); + try + { + return l.parseToXmlObject(xmlText, type, options); + } + finally + { + l.exit(); + } + } + } + + private XmlObject parseToXmlObject(String xmlText, SchemaType type, + XmlOptions options) + throws XmlException + { + Cur c = parse(xmlText, type, options); + + XmlObject x = (XmlObject) c.getUser(); + + c.release(); + + return x; + } + + Cur parse(String s, SchemaType type, XmlOptions options) + throws XmlException + { + Reader r = new StringReader(s); + + try + { + Cur c = getSaxLoader(options).load(this, new InputSource(r), + options); + + autoTypeDocument(c, type, options); + + return c; + } + catch (IOException e) + { + assert false: "StringReader should not throw IOException"; + + throw new XmlException(e.getMessage(), e); + } + finally + { + try + { + r.close(); + } + catch (IOException e) + { + } + } + } + + // + // + // + + /** + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XmlObject parseToXmlObject(SchemaTypeLoader stl, + XMLInputStream xis, SchemaType type, XmlOptions options) + throws XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException + { + Locale l = getLocale(stl, options); + + if (l.noSync()) + { + l.enter(); + try + { + return l.parseToXmlObject(xis, type, options); + } + finally + { + l.exit(); + } + } + else + synchronized (l) + { + l.enter(); + try + { + return l.parseToXmlObject(xis, type, options); + } + finally + { + l.exit(); + } + } + } + + /** + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public XmlObject parseToXmlObject(XMLInputStream xis, SchemaType type, + XmlOptions options) + throws XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException + { + Cur c; + + try + { + c = loadXMLInputStream(xis, options); + } + catch (org.apache.xmlbeans.xml.stream.XMLStreamException e) + { + throw new XmlException(e.getMessage(), e); + } + + autoTypeDocument(c, type, options); + + XmlObject x = (XmlObject) c.getUser(); + + c.release(); + + return x; + } + + // + // + // + + public static XmlObject parseToXmlObject(SchemaTypeLoader stl, + XMLStreamReader xsr, SchemaType type, XmlOptions options) + throws XmlException + { + Locale l = getLocale(stl, options); + + if (l.noSync()) + { + l.enter(); + try + { + return l.parseToXmlObject(xsr, type, options); + } + finally + { + l.exit(); + } + } + else + synchronized (l) + { + l.enter(); + try + { + return l.parseToXmlObject(xsr, type, options); + } + finally + { + l.exit(); + } + } + } + + public XmlObject parseToXmlObject(XMLStreamReader xsr, SchemaType type, + XmlOptions options) + throws XmlException + { + Cur c; + + try + { + c = loadXMLStreamReader(xsr, options); + } + catch (XMLStreamException e) + { + throw new XmlException(e.getMessage(), e); + } + + autoTypeDocument(c, type, options); + + XmlObject x = (XmlObject) c.getUser(); + + c.release(); + + return x; + } + + private static void lineNumber(XMLEvent xe, LoadContext context) + { + org.apache.xmlbeans.xml.stream.Location loc = xe.getLocation(); + + if (loc != null) + context.lineNumber(loc.getLineNumber(), loc.getColumnNumber(), -1); + } + + private static void lineNumber(XMLStreamReader xsr, LoadContext context) + { + javax.xml.stream.Location loc = xsr.getLocation(); + + if (loc != null) + { + context.lineNumber(loc.getLineNumber(), loc.getColumnNumber(), + loc.getCharacterOffset()); + } + } + + private void doAttributes(XMLStreamReader xsr, LoadContext context) + { + int n = xsr.getAttributeCount(); + + for (int a = 0; a < n; a++) + { + context.attr(xsr.getAttributeLocalName(a), + xsr.getAttributeNamespace(a), + xsr.getAttributePrefix(a), + xsr.getAttributeValue(a)); + } + } + + private void doNamespaces(XMLStreamReader xsr, LoadContext context) + { + int n = xsr.getNamespaceCount(); + + for (int a = 0; a < n; a++) + { + String prefix = xsr.getNamespacePrefix(a); + + if (prefix == null || prefix.length() == 0) + context.attr("xmlns", _xmlnsUri, null, + xsr.getNamespaceURI(a)); + else + context.attr(prefix, _xmlnsUri, "xmlns", + xsr.getNamespaceURI(a)); + } + + } + + /** + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + private Cur loadXMLInputStream(XMLInputStream xis, XmlOptions options) + throws org.apache.xmlbeans.xml.stream.XMLStreamException + { + options = XmlOptions.maskNull(options); + + boolean lineNums = options.hasOption(XmlOptions.LOAD_LINE_NUMBERS); + + XMLEvent x = xis.peek(); + + if (x != null && x.getType() == XMLEvent.START_ELEMENT) + { + Map nsMap = ((StartElement) x).getNamespaceMap(); + + if (nsMap != null && nsMap.size() > 0) + { + Map namespaces = new HashMap(); + + namespaces.putAll(nsMap); + + options = new XmlOptions(options); + + options.put(XmlOptions.LOAD_ADDITIONAL_NAMESPACES, namespaces); + } + } + + String systemId = null; + String encoding = null; + String version = null; + boolean standAlone = true; + + LoadContext context = new Cur.CurLoadContext(this, options); + + events: + for (XMLEvent xe = xis.next(); xe != null; xe = xis.next()) + { + switch (xe.getType()) + { + case XMLEvent.START_DOCUMENT: + StartDocument doc = (StartDocument) xe; + + systemId = doc.getSystemId(); + encoding = doc.getCharacterEncodingScheme(); + version = doc.getVersion(); + standAlone = doc.isStandalone(); + standAlone = doc.isStandalone(); + + if (lineNums) + lineNumber(xe, context); + + break; + + case XMLEvent.END_DOCUMENT: + if (lineNums) + lineNumber(xe, context); + + break events; + + case XMLEvent.NULL_ELEMENT: + if (!xis.hasNext()) + break events; + break; + + case XMLEvent.START_ELEMENT: + context.startElement(XMLNameHelper.getQName(xe.getName())); + + if (lineNums) + lineNumber(xe, context); + + for (AttributeIterator ai = ((StartElement) xe).getAttributes(); + ai.hasNext();) + { + Attribute attr = ai.next(); + + context.attr(XMLNameHelper.getQName(attr.getName()), + attr.getValue()); + } + + for (AttributeIterator ai = ((StartElement) xe).getNamespaces() + ; ai.hasNext();) + { + Attribute attr = ai.next(); + + XMLName name = attr.getName(); + String local = name.getLocalName(); + + if (name.getPrefix() == null && local.equals("xmlns")) + local = ""; + + context.xmlns(local, attr.getValue()); + } + + break; + + case XMLEvent.END_ELEMENT: + context.endElement(); + + if (lineNums) + lineNumber(xe, context); + + break; + + case XMLEvent.SPACE: + if (((Space) xe).ignorable()) + break; + + // Fall through + + case XMLEvent.CHARACTER_DATA: + CharacterData cd = (CharacterData) xe; + + if (cd.hasContent()) + { + context.text(cd.getContent()); + + if (lineNums) + lineNumber(xe, context); + } + + break; + + case XMLEvent.COMMENT: + org.apache.xmlbeans.xml.stream.Comment comment = + (org.apache.xmlbeans.xml.stream.Comment) xe; + + if (comment.hasContent()) + { + context.comment(comment.getContent()); + + if (lineNums) + lineNumber(xe, context); + } + + break; + + case XMLEvent.PROCESSING_INSTRUCTION: + ProcessingInstruction procInstr = (ProcessingInstruction) xe; + + context.procInst(procInstr.getTarget(), procInstr.getData()); + + if (lineNums) + lineNumber(xe, context); + + break; + + // These are ignored + case XMLEvent.ENTITY_REFERENCE: + case XMLEvent.START_PREFIX_MAPPING: + case XMLEvent.END_PREFIX_MAPPING: + case XMLEvent.CHANGE_PREFIX_MAPPING: + case XMLEvent.XML_EVENT: + break; + + default : + throw new RuntimeException( + "Unhandled xml event type: " + xe.getTypeAsString()); + } + } + + Cur c = context.finish(); + + associateSourceName(c, options); + + XmlDocumentProperties props = getDocProps(c, true); + + props.setDoctypeSystemId(systemId); + props.setEncoding(encoding); + props.setVersion(version); + props.setStandalone(standAlone); + + return c; + } + + private Cur loadXMLStreamReader(XMLStreamReader xsr, XmlOptions options) + throws XMLStreamException + { + options = XmlOptions.maskNull(options); + + boolean lineNums = options.hasOption(XmlOptions.LOAD_LINE_NUMBERS); + + String encoding = null, version = null; + boolean standAlone = false; + + LoadContext context = new Cur.CurLoadContext(this, options); + int depth = 0; + + events: + for (int eventType = xsr.getEventType(); ; eventType = xsr.next()) + { + switch (eventType) + { + case XMLStreamReader.START_DOCUMENT: + { + depth++; + + encoding = xsr.getCharacterEncodingScheme(); + version = xsr.getVersion(); + standAlone = xsr.isStandalone(); + + if (lineNums) + lineNumber(xsr, context); + + break; + } + + case XMLStreamReader.END_DOCUMENT: + { + depth--; + + if (lineNums) + lineNumber(xsr, context); + + break events; + } + + case XMLStreamReader.START_ELEMENT: + { + depth++; + context.startElement(xsr.getName()); + + if (lineNums) + lineNumber(xsr, context); + + doAttributes(xsr, context); + doNamespaces(xsr, context); + + break; + } + + case XMLStreamReader.END_ELEMENT: + { + depth--; + context.endElement(); + + if (lineNums) + lineNumber(xsr, context); + + break; + } + + case XMLStreamReader.CHARACTERS: + case XMLStreamReader.CDATA: + { + context.text(xsr.getTextCharacters(), xsr.getTextStart(), + xsr.getTextLength()); + + if (lineNums) + lineNumber(xsr, context); + + break; + } + + case XMLStreamReader.COMMENT: + { + String comment = xsr.getText(); + + context.comment(comment); + + if (lineNums) + lineNumber(xsr, context); + + break; + } + + case XMLStreamReader.PROCESSING_INSTRUCTION: + { + context.procInst(xsr.getPITarget(), xsr.getPIData()); + + if (lineNums) + lineNumber(xsr, context); + + break; + } + + case XMLStreamReader.ATTRIBUTE: + { + doAttributes(xsr, context); + break; + } + + case XMLStreamReader.NAMESPACE: + { + doNamespaces(xsr, context); + break; + } + + case XMLStreamReader.ENTITY_REFERENCE: + { + context.text(xsr.getText()); + break; + } + + case XMLStreamReader.SPACE: + case XMLStreamReader.DTD: + break; + + default : + throw new RuntimeException( + "Unhandled xml event type: " + eventType); + } + + if (!xsr.hasNext() || depth <= 0) + break; + } + + Cur c = context.finish(); + + associateSourceName(c, options); + + XmlDocumentProperties props = getDocProps(c, true); + + props.setEncoding(encoding); + props.setVersion(version); + props.setStandalone(standAlone); + + return c; + } + + // + // + // + + public static XmlObject parseToXmlObject(SchemaTypeLoader stl, + InputStream is, SchemaType type, XmlOptions options) + throws XmlException, IOException + { + Locale l = getLocale(stl, options); + + if (l.noSync()) + { + l.enter(); + try + { + return l.parseToXmlObject(is, type, options); + } + finally + { + l.exit(); + } + } + else + synchronized (l) + { + l.enter(); + try + { + return l.parseToXmlObject(is, type, options); + } + finally + { + l.exit(); + } + } + } + + private XmlObject parseToXmlObject(InputStream is, SchemaType type, + XmlOptions options) + throws XmlException, IOException + { + Cur c = getSaxLoader(options).load(this, new InputSource(is), + options); + + autoTypeDocument(c, type, options); + + XmlObject x = (XmlObject) c.getUser(); + + c.release(); + + return x; + } + + // + // + // + + public static XmlObject parseToXmlObject(SchemaTypeLoader stl, + Reader reader, SchemaType type, XmlOptions options) + throws XmlException, IOException + { + Locale l = getLocale(stl, options); + + if (l.noSync()) + { + l.enter(); + try + { + return l.parseToXmlObject(reader, type, options); + } + finally + { + l.exit(); + } + } + else + synchronized (l) + { + l.enter(); + try + { + return l.parseToXmlObject(reader, type, options); + } + finally + { + l.exit(); + } + } + } + + private XmlObject parseToXmlObject(Reader reader, SchemaType type, + XmlOptions options) + throws XmlException, IOException + { + Cur c = getSaxLoader(options).load(this, new InputSource(reader), + options); + + autoTypeDocument(c, type, options); + + XmlObject x = (XmlObject) c.getUser(); + + c.release(); + + return x; + } + + // + // + // + + public static XmlObject parseToXmlObject(SchemaTypeLoader stl, Node node, + SchemaType type, XmlOptions options) + throws XmlException + { + Locale l = getLocale(stl, options); + + if (l.noSync()) + { + l.enter(); + try + { + return l.parseToXmlObject(node, type, options); + } + finally + { + l.exit(); + } + } + else + synchronized (l) + { + l.enter(); + try + { + return l.parseToXmlObject(node, type, options); + } + finally + { + l.exit(); + } + } + } + + public XmlObject parseToXmlObject(Node node, SchemaType type, + XmlOptions options) + throws XmlException + { + LoadContext context = new Cur.CurLoadContext(this, options); + + loadNode(node, context); + + Cur c = context.finish(); + + associateSourceName(c, options); + + autoTypeDocument(c, type, options); + + XmlObject x = (XmlObject) c.getUser(); + + c.release(); + + return x; + } + + private void loadNodeChildren(Node n, LoadContext context) + { + for (Node c = n.getFirstChild(); c != null; c = c.getNextSibling()) + loadNode(c, context); + } + + void loadNode(Node n, LoadContext context) + { + switch (n.getNodeType()) + { + case Node.DOCUMENT_NODE: + case Node.DOCUMENT_FRAGMENT_NODE: + case Node.ENTITY_REFERENCE_NODE: + { + loadNodeChildren(n, context); + + break; + } + case Node.ELEMENT_NODE: + { + context.startElement( + makeQualifiedQName(n.getNamespaceURI(), n.getNodeName())); + + NamedNodeMap attrs = n.getAttributes(); + + for (int i = 0; i < attrs.getLength(); i++) + { + Node a = attrs.item(i); + + String attrName = a.getNodeName(); + String attrValue = a.getNodeValue(); + + if (attrName.toLowerCase().startsWith("xmlns")) + { + if (attrName.length() == 5) + context.xmlns(null, attrValue); + else + context.xmlns(attrName.substring(6), attrValue); + } + else + context.attr( + makeQualifiedQName(a.getNamespaceURI(), attrName), + attrValue); + } + + loadNodeChildren(n, context); + + context.endElement(); + + break; + } + case Node.TEXT_NODE: + case Node.CDATA_SECTION_NODE: + { + context.text(n.getNodeValue()); + break; + } + case Node.COMMENT_NODE: + { + context.comment(n.getNodeValue()); + break; + } + case Node.PROCESSING_INSTRUCTION_NODE: + { + context.procInst(n.getNodeName(), n.getNodeValue()); + break; + } + case Node.DOCUMENT_TYPE_NODE: + case Node.ENTITY_NODE: + case Node.NOTATION_NODE: + case Node.ATTRIBUTE_NODE: + { + throw new RuntimeException("Unexpected node"); + } + } + } + + // + // + // + + private class XmlSaxHandlerImpl + extends SaxHandler + implements XmlSaxHandler + { + XmlSaxHandlerImpl(Locale l, SchemaType type, XmlOptions options) + { + super(null); + + _options = options; + _type = type; + + // Because SAX loading is not atomic with respect to XmlBeans, I can't use the default + // thread local CharUtil. Instruct the SaxHandler (and the LoadContext, eventually) + // to use the Locale specific CharUtil. + + XmlOptions saxHandlerOptions = new XmlOptions(options); + saxHandlerOptions.put(Cur.LOAD_USE_LOCALE_CHAR_UTIL); + + initSaxHandler(l, saxHandlerOptions); + } + + public ContentHandler getContentHandler() + { + return _context == null ? null : this; + } + + public LexicalHandler getLexicalHandler() + { + return _context == null ? null : this; + } + + public void bookmarkLastEvent(XmlBookmark mark) + { + _context.bookmarkLastNonAttr(mark); + } + + public void bookmarkLastAttr(QName attrName, XmlBookmark mark) + { + _context.bookmarkLastAttr(attrName, mark); + } + + public XmlObject getObject() + throws XmlException + { + if (_context == null) + return null; + + _locale.enter(); + + try + { + Cur c = _context.finish(); + + autoTypeDocument(c, _type, _options); + + XmlObject x = (XmlObject) c.getUser(); + + c.release(); + + _context = null; + + return x; + } + finally + { + _locale.exit(); + } + } + + private SchemaType _type; + private XmlOptions _options; + } + + public static XmlSaxHandler newSaxHandler(SchemaTypeLoader stl, + SchemaType type, XmlOptions options) + { + Locale l = getLocale(stl, options); + + if (l.noSync()) + { + l.enter(); + try + { + return l.newSaxHandler(type, options); + } + finally + { + l.exit(); + } + } + else + synchronized (l) + { + l.enter(); + try + { + return l.newSaxHandler(type, options); + } + finally + { + l.exit(); + } + } + } + + public XmlSaxHandler newSaxHandler(SchemaType type, XmlOptions options) + { + return new XmlSaxHandlerImpl(this, type, options); + } + + // TODO (ericvas ) - have a qname factory here so that the same factory may be + // used by the parser. This factory would probably come from my + // high speed parser. Otherwise, use a thread local on + + QName makeQName(String uri, String localPart) + { + assert localPart != null && localPart.length() > 0; + // TODO - make sure name is a well formed name? + + return _qnameFactory.getQName(uri, localPart); + } + + QName makeQNameNoCheck(String uri, String localPart) + { + return _qnameFactory.getQName(uri, localPart); + } + + QName makeQName(String uri, String local, String prefix) + { + return _qnameFactory.getQName(uri, local, prefix == null ? "" : prefix); + } + + QName makeQualifiedQName(String uri, String qname) + { + if (qname == null) + qname = ""; + + int i = qname.indexOf(':'); + + return i < 0 + ? + _qnameFactory.getQName(uri, qname) + : + _qnameFactory.getQName(uri, qname.substring(i + 1), + qname.substring(0, i)); + } + + static private class DocProps + extends XmlDocumentProperties + { + private HashMap _map = new HashMap(); + + public Object put(Object key, Object value) + { + return _map.put(key, value); + } + + public Object get(Object key) + { + return _map.get(key); + } + + public Object remove(Object key) + { + return _map.remove(key); + } + } + + static XmlDocumentProperties getDocProps(Cur c, boolean ensure) + { + c.push(); + + while (c.toParent()) + ; + + DocProps props = (DocProps) c.getBookmark(DocProps.class); + + if (props == null && ensure) + c.setBookmark(DocProps.class, props = new DocProps()); + + c.pop(); + + return props; + } + + interface ChangeListener + { + void notifyChange(); + + void setNextChangeListener(ChangeListener listener); + + ChangeListener getNextChangeListener(); + } + + void registerForChange(ChangeListener listener) + { + if (listener.getNextChangeListener() == null) + { + if (_changeListeners == null) + listener.setNextChangeListener(listener); + else + listener.setNextChangeListener(_changeListeners); + + _changeListeners = listener; + } + } + + void notifyChange() + { + // First, notify the registered listeners ... + + while (_changeListeners != null) + { + _changeListeners.notifyChange(); + + if (_changeListeners.getNextChangeListener() == _changeListeners) + _changeListeners.setNextChangeListener(null); + + ChangeListener next = _changeListeners.getNextChangeListener(); + + _changeListeners.setNextChangeListener(null); + + _changeListeners = next; + } + + // Then, prepare for the change in a locale specific way. Need to create real Curs for + // 'virtual' Curs in Locations + + _locations.notifyChange(); + } + + // + // Cursor helpers + // + + static String getTextValue(Cur c) + { + assert c.isNode(); + + if (!c.hasChildren()) + return c.getValueAsString(); + + StringBuffer sb = new StringBuffer(); + + c.push(); + + for (c.next(); !c.isAtEndOfLastPush(); c.next()) + if (c.isText()) + { + if ( (c._xobj.isComment() || c._xobj.isProcinst() ) && c._pos maxCch) + n = maxCch; + + if (n <= 0) + return 0; + + s.getChars(0, n, chars, off); + + return n; + } + + static String applyWhiteSpaceRule(String s, int wsr) + { + int l = s == null ? 0 : s.length(); + + if (l == 0 || wsr == WS_PRESERVE) + return s; + + char ch; + + if (wsr == WS_REPLACE) + { + for (int i = 0; i < l; i++) + if ((ch = s.charAt(i)) == '\n' || ch == '\r' || ch == '\t') + return processWhiteSpaceRule(s, wsr); + } + else if (wsr == Locale.WS_COLLAPSE) + { + if (CharUtil.isWhiteSpace(s.charAt(0)) || + CharUtil.isWhiteSpace(s.charAt(l - 1))) + return processWhiteSpaceRule(s, wsr); + + boolean lastWasWhite = false; + + for (int i = 1; i < l; i++) + { + boolean isWhite = CharUtil.isWhiteSpace(s.charAt(i)); + + if (isWhite && lastWasWhite) + return processWhiteSpaceRule(s, wsr); + + lastWasWhite = isWhite; + } + } + + return s; + } + + static String processWhiteSpaceRule(String s, int wsr) + { + ScrubBuffer sb = getScrubBuffer(wsr); + + sb.scrub(s, 0, s.length()); + + return sb.getResultAsString(); + } + + static final class ScrubBuffer + { + ScrubBuffer() + { + _sb = new StringBuffer(); + } + + void init(int wsr) + { + _sb.delete(0, _sb.length()); + + _wsr = wsr; + _state = START_STATE; + } + + void scrub(Object src, int off, int cch) + { + if (cch == 0) + return; + + if (_wsr == Locale.WS_PRESERVE) + { + CharUtil.getString(_sb, src, off, cch); + return; + } + + char[] chars; + + if (src instanceof char[]) + chars = (char[]) src; + else + { + if (cch <= _srcBuf.length) + chars = _srcBuf; + else if (cch <= 16384) + chars = _srcBuf = new char[16384]; + else + chars = new char[cch]; + + CharUtil.getChars(chars, 0, src, off, cch); + off = 0; + } + + int start = 0; + + for (int i = 0; i < cch; i++) + { + char ch = chars[off + i]; + + if (ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t') + { + _sb.append(chars, off + start, i - start); + + start = i + 1; + + if (_wsr == Locale.WS_REPLACE) + _sb.append(' '); + else if (_state == NOSPACE_STATE) + _state = SPACE_SEEN_STATE; + } + else + { + if (_state == SPACE_SEEN_STATE) + _sb.append(' '); + + _state = NOSPACE_STATE; + } + } + + _sb.append(chars, off + start, cch - start); + } + + String getResultAsString() + { + return _sb.toString(); + } + + private static final int START_STATE = 0; + private static final int SPACE_SEEN_STATE = 1; + private static final int NOSPACE_STATE = 2; + + private int _state; + + private int _wsr; + + private char[] _srcBuf = new char[1024]; + private StringBuffer _sb; + } + + private static ThreadLocal tl_scrubBuffer = + new ThreadLocal() + { + protected Object initialValue() + { + return new SoftReference(new ScrubBuffer()); + } + }; + + static ScrubBuffer getScrubBuffer(int wsr) + { + SoftReference softRef = (SoftReference) tl_scrubBuffer.get(); + ScrubBuffer scrubBuffer = (ScrubBuffer) (softRef).get(); + if (scrubBuffer == null) + { + scrubBuffer = new ScrubBuffer(); + tl_scrubBuffer.set(new SoftReference(scrubBuffer)); + } + + scrubBuffer.init(wsr); + return scrubBuffer; + } + + static boolean pushToContainer(Cur c) + { + c.push(); + + for (; ;) + { + switch (c.kind()) + { + case ROOT: + case ELEM: + return true; + case -ROOT: + case -ELEM: + c.pop(); + return false; + case COMMENT: + case PROCINST: + c.skip(); + break; + default : + c.nextWithAttrs(); + break; + } + } + } + + static boolean toFirstNormalAttr(Cur c) + { + c.push(); + + if (c.toFirstAttr()) + { + do + { + if (!c.isXmlns()) + { + c.popButStay(); + return true; + } + } + while (c.toNextAttr()); + } + + c.pop(); + + return false; + } + + static boolean toPrevNormalAttr(Cur c) + { + if (c.isAttr()) + { + c.push(); + + for (; ;) + { + assert c.isAttr(); + + // See if I can move backward. If I'm at the first attr, prev must return + // false and not move. + + if (!c.prev()) + break; + + // Skip past the text value or attr begin + + c.prev(); + + // I might have skipped over text above + + if (!c.isAttr()) + c.prev(); + + if (c.isNormalAttr()) + { + c.popButStay(); + return true; + } + } + + c.pop(); + } + + return false; + } + + static boolean toNextNormalAttr(Cur c) + { + c.push(); + + while (c.toNextAttr()) + { + if (!c.isXmlns()) + { + c.popButStay(); + return true; + } + } + + c.pop(); + + return false; + } + + Xobj findNthChildElem(Xobj parent, QName name, QNameSet set, int n) + { + // only one of (set or name) is not null + // or both are null for a wildcard + assert (name == null || set == null); + assert n >= 0; + + if (parent == null) + return null; + + int da = _nthCache_A.distance(parent, name, set, n); + int db = _nthCache_B.distance(parent, name, set, n); + + Xobj x = + da <= db + ? _nthCache_A.fetch(parent, name, set, n) + : _nthCache_B.fetch(parent, name, set, n); + + if (da == db) + { + nthCache temp = _nthCache_A; + _nthCache_A = _nthCache_B; + _nthCache_B = temp; + } + + return x; + } + + int count(Xobj parent, QName name, QNameSet set) + { + int n = 0; + + for (Xobj x = findNthChildElem(parent, name, set, 0); + x != null; x = x._nextSibling) + { + if (x.isElem()) + { + if (set == null) + { + if (x._name.equals(name)) + n++; + } + else if (set.contains(x._name)) + n++; + } + } + + return n; + } + + static boolean toChild(Cur c, QName name, int n) + { + if (n >= 0 && pushToContainer(c)) + { + Xobj x = c._locale.findNthChildElem(c._xobj, name, null, n); + + c.pop(); + + if (x != null) + { + c.moveTo(x); + return true; + } + } + + return false; + } + + static boolean toFirstChildElement(Cur c) + { +// if (!pushToContainer(c)) +// return false; +// +// if (!c.toFirstChild() || (!c.isElem() && !toNextSiblingElement(c))) +// { +// c.pop(); +// return false; +// } +// +// c.popButStay(); +// +// return true; + + Xobj originalXobj = c._xobj; + int originalPos = c._pos; + + loop: + for (; ;) + { + switch (c.kind()) + { + case ROOT: + case ELEM: + break loop; + case -ROOT: + case -ELEM: + c.moveTo(originalXobj, originalPos); + return false; + case COMMENT: + case PROCINST: + c.skip(); + break; + default: + c.nextWithAttrs(); + break; + } + } + + if (!c.toFirstChild() || (!c.isElem() && !toNextSiblingElement(c))) + { + c.moveTo(originalXobj, originalPos); + return false; + } + + return true; + } + + static boolean toLastChildElement(Cur c) + { + if (!pushToContainer(c)) + return false; + + if (!c.toLastChild() || (!c.isElem() && !toPrevSiblingElement(c))) + { + c.pop(); + return false; + } + + c.popButStay(); + + return true; + } + + static boolean toPrevSiblingElement(Cur cur) + { + if (!cur.hasParent()) + return false; + + Cur c = cur.tempCur(); + + boolean moved = false; + + int k = c.kind(); + + if (k != ATTR) + { + for (; ;) + { + if (!c.prev()) + break; + + k = c.kind(); + + if (k == ROOT || k == ELEM) + break; + + if (c.kind() == -ELEM) + { + c.toParent(); + + cur.moveToCur(c); + moved = true; + + break; + } + } + } + + c.release(); + + return moved; + } + + static boolean toNextSiblingElement(Cur c) + { + if (!c.hasParent()) + return false; + + c.push(); + + int k = c.kind(); + + if (k == ATTR) + { + c.toParent(); + c.next(); + } + else if (k == ELEM) + c.skip(); + + while ((k = c.kind()) >= 0) + { + if (k == ELEM) + { + c.popButStay(); + return true; + } + + if (k > 0) + c.toEnd(); + + c.next(); + } + + c.pop(); + + return false; + } + + static boolean toNextSiblingElement(Cur c, Xobj parent) + { + Xobj originalXobj = c._xobj; + int originalPos = c._pos; + + int k = c.kind(); + + if (k == ATTR) + { + c.moveTo(parent); + c.next(); + } + else if (k == ELEM) + c.skip(); + + while ((k = c.kind()) >= 0) + { + if (k == ELEM) + { + return true; + } + + if (k > 0) + c.toEnd(); + + c.next(); + } + + c.moveTo(originalXobj, originalPos); + + return false; + } + + static void applyNamespaces(Cur c, Map namespaces) + { + assert c.isContainer(); + + java.util.Iterator i = namespaces.keySet().iterator(); + + while (i.hasNext()) + { + String prefix = (String) i.next(); + + // Usually, this is the predefined xml namespace + if (!prefix.toLowerCase().startsWith("xml")) + { + if (c.namespaceForPrefix(prefix, false) == null) + { + c.push(); + + c.next(); + c.createAttr(c._locale.createXmlns(prefix)); + c.next(); + + c.insertString((String) namespaces.get(prefix)); + + c.pop(); + } + } + } + } + + static Map getAllNamespaces(Cur c, Map filleMe) + { + assert c.isNode(); + + c.push(); + + if (!c.isContainer()) + c.toParent(); + + assert c.isContainer(); + + do + { + QName cName = c.getName(); + + while (c.toNextAttr()) + { + if (c.isXmlns()) + { + String prefix = c.getXmlnsPrefix(); + String uri = c.getXmlnsUri(); + + if (filleMe == null) + filleMe = new HashMap(); + + if (!filleMe.containsKey(prefix)) + filleMe.put(prefix, uri); + } + } + + if (!c.isContainer()) + c.toParentRaw(); + } + while (c.toParentRaw()); + + c.pop(); + + return filleMe; + } + + class nthCache + { + private boolean namesSame(QName pattern, QName name) + { + return pattern == null || pattern.equals(name); + } + + private boolean setsSame(QNameSet patternSet, QNameSet set) + { + // value equality is probably too expensive. Since the use case + // involves QNameSets that are generated by the compiler, we + // can use identity comparison. + + return patternSet != null && patternSet == set; + } + + private boolean nameHit(QName namePattern, QNameSet setPattern, + QName name) + { + return + setPattern == null + ? namesSame(namePattern, name) + : setPattern.contains(name); + } + + private boolean cacheSame(QName namePattern, QNameSet setPattern) + { + return + setPattern == null + ? namesSame(namePattern, _name) + : setsSame(setPattern, _set); + } + + int distance(Xobj parent, QName name, QNameSet set, int n) + { + assert n >= 0; + + if (_version != Locale.this.version()) + return Integer.MAX_VALUE - 1; + + if (parent != _parent || !cacheSame(name, set)) + return Integer.MAX_VALUE; + + return n > _n ? n - _n : _n - n; + } + + Xobj fetch(Xobj parent, QName name, QNameSet set, int n) + { + assert n >= 0; + + if (_version != Locale.this.version() || _parent != parent || + !cacheSame(name, set) || n == 0) + { + _version = Locale.this.version(); + _parent = parent; + _name = name; + _child = null; + _n = -1; + + loop: + for (Xobj x = parent._firstChild; + x != null; x = x._nextSibling) + { + if (x.isElem() && nameHit(name, set, x._name)) + { + _child = x; + _n = 0; + + break loop; + } + } + } + + if (_n < 0) + return null; + + if (n > _n) + { + while (n > _n) + { + for (Xobj x = _child._nextSibling; ; x = x._nextSibling) + { + if (x == null) + return null; + + if (x.isElem() && nameHit(name, set, x._name)) + { + _child = x; + _n++; + + break; + } + } + } + } + else if (n < _n) + { + while (n < _n) + { + for (Xobj x = _child._prevSibling; ; x = x._prevSibling) + { + if (x == null) + return null; + + if (x.isElem() && nameHit(name, set, x._name)) + { + _child = x; + _n--; + + break; + } + } + } + } + + return _child; + } + + private long _version; + private Xobj _parent; + private QName _name; + private QNameSet _set; + private Xobj _child; + private int _n; + } + + // + // + // + + Dom findDomNthChild ( Dom parent, int n ) + { + assert n >= 0; + + if (parent == null) + return null; + + int da = _domNthCache_A.distance(parent, n); + int db = _domNthCache_B.distance(parent, n); + + + // the "better" cache should never walk more than 1/2 len + Dom x = null; + boolean bInvalidate = (db - _domNthCache_B._len / 2 > 0) && + (db - _domNthCache_B._len / 2 - domNthCache.BLITZ_BOUNDARY > 0); + boolean aInvalidate = (da - _domNthCache_A._len / 2 > 0) && + (da - _domNthCache_A._len / 2 - domNthCache.BLITZ_BOUNDARY > 0); + if (da <= db) + if (!aInvalidate) + x = _domNthCache_A.fetch(parent, n); + else + { + _domNthCache_B._version = -1;//blitz the cache + x = _domNthCache_B.fetch(parent, n); + } + else if (!bInvalidate) + x = _domNthCache_B.fetch(parent, n); + else + { + _domNthCache_A._version = -1;//blitz the cache + x = _domNthCache_A.fetch(parent, n); + } + + if (da == db) + { + domNthCache temp = _domNthCache_A; + _domNthCache_A = _domNthCache_B; + _domNthCache_B = temp; + } + + return x; + } + + int domLength ( Dom parent ) + { + if (parent == null) + return 0; + + int da = _domNthCache_A.distance( parent, 0 ); + int db = _domNthCache_B.distance( parent, 0 ); + + int len = + da <= db + ? _domNthCache_A.length( parent ) + : _domNthCache_B.length( parent ); + + if (da == db) + { + domNthCache temp = _domNthCache_A; + _domNthCache_A = _domNthCache_B; + _domNthCache_B = temp; + } + + return len; + } + + void invalidateDomCaches ( Dom d ) + { + if (_domNthCache_A._parent == d) + _domNthCache_A._version = -1; + if (_domNthCache_B._parent == d) + _domNthCache_B._version = -1; + } + + boolean isDomCached ( Dom d ) + { + return _domNthCache_A._parent == d || _domNthCache_B._parent == d; + } + + class domNthCache + { + + int distance ( Dom parent, int n ) + { + assert n >= 0; + + if (_version != Locale.this.version()) + return Integer.MAX_VALUE - 1; + + if (parent != _parent) + return Integer.MAX_VALUE; + + return n > _n ? n - _n : _n - n; + } + + int length ( Dom parent ) + { + if (_version != Locale.this.version() || _parent != parent) + { + _parent = parent; + _version = Locale.this.version(); + _child = null; + _n = -1; + _len = -1; + } + + if (_len == -1) + { + Dom x = null; + + if (_child != null && _n != -1) + { + x = _child; + _len = _n; + } + else + { + x = DomImpl.firstChild(_parent); + _len = 0; + + // cache the 0th child + _child = x; + _n = 0; + } + + for (; x != null; x = DomImpl.nextSibling(x) ) + { + _len++; + } + } + + + return _len; + } + + Dom fetch ( Dom parent, int n ) + { + assert n >= 0; + + if (_version != Locale.this.version() || _parent != parent) + { + _parent = parent; + _version = Locale.this.version(); + _child = null; + _n = -1; + _len = -1; + + for (Dom x = DomImpl.firstChild(_parent); x != null; x = DomImpl.nextSibling(x) ) + { + _n++; + if (_child == null && n == _n ) + { + _child = x; + break; + } + } + + return _child; + } + + if (_n < 0) + return null; + + if (n > _n) + { + while ( n > _n ) + { + for (Dom x = DomImpl.nextSibling(_child); ; x = DomImpl.nextSibling(x) ) + { + if (x == null) + return null; + + _child = x; + _n++; + + break; + } + } + } + else if (n < _n) + { + while ( n < _n ) + { + for (Dom x = DomImpl.prevSibling(_child); ; x = DomImpl.prevSibling(x) ) + { + if (x == null) + return null; + + _child = x; + _n--; + + break; + } + } + } + + return _child; + } + + public static final int BLITZ_BOUNDARY = 40; //walk small lists + private long _version; + private Dom _parent; + private Dom _child; + private int _n; + private int _len; + } + + // + // + // + + CharUtil getCharUtil() + { + if (_charUtil == null) + _charUtil = new CharUtil(1024); + + return _charUtil; + } + + long version() + { + return _versionAll; + } + + Cur weakCur(Object o) + { + assert o != null && !(o instanceof Ref); + + Cur c = getCur(); + + assert c._tempFrame == -1; + assert c._ref == null; + + c._ref = new Ref(c, o); + + return c; + } + + final ReferenceQueue refQueue() + { + if (_refQueue == null) + _refQueue = new ReferenceQueue(); + + return _refQueue; + } + + final static class Ref + extends PhantomReference + { + Ref(Cur c, Object obj) + { + super(obj, c._locale.refQueue()); + + _cur = c; + } + + Cur _cur; + } + + Cur tempCur() + { + return tempCur(null); + } + + Cur tempCur(String id) + { + Cur c = getCur(); + + assert c._tempFrame == -1; + + assert _numTempFramesLeft < _tempFrames.length : "Temp frame not pushed"; + + int frame = _tempFrames.length - _numTempFramesLeft - 1; + + assert frame >= 0 && frame < _tempFrames.length; + + Cur next = _tempFrames[frame]; + + c._nextTemp = next; + assert c._prevTemp == null; + + if (next != null) + { + assert next._prevTemp == null; + next._prevTemp = c; + } + + _tempFrames[frame] = c; + c._tempFrame = frame; + + c._id = id; + + return c; + } + + Cur getCur() + { + assert _curPool == null || _curPoolCount > 0; + + Cur c; + + if (_curPool == null) + c = new Cur(this); + else + { + _curPool = _curPool.listRemove(c = _curPool); + _curPoolCount--; + } + + assert c._state == Cur.POOLED; + assert c._prev == null && c._next == null; + assert c._xobj == null && c._pos == Cur.NO_POS; + assert c._ref == null; + + _registered = c.listInsert(_registered); + c._state = Cur.REGISTERED; + + return c; + } + + void embedCurs() + { + for (Cur c; (c = _registered) != null;) + { + assert c._xobj != null; + + _registered = c.listRemove(_registered); + c._xobj._embedded = c.listInsert(c._xobj._embedded); + c._state = Cur.EMBEDDED; + } + } + + TextNode createTextNode() + { + return _saaj == null ? new TextNode(this) : new SaajTextNode(this); + } + + CdataNode createCdataNode() + { + return _saaj == null ? + new CdataNode(this) : new SaajCdataNode(this); + } + + boolean entered() + { + return _tempFrames.length - _numTempFramesLeft > 0; + } + + public void enter(Locale otherLocale) + { + enter(); + + if (otherLocale != this) + otherLocale.enter(); + } + + public void enter() + { + assert _numTempFramesLeft >= 0; + + if (--_numTempFramesLeft <= 0) + { + Cur[] newTempFrames = new Cur[_tempFrames.length * 2]; + //move this assignment down so if array allocation fails, error is not masked + _numTempFramesLeft = _tempFrames.length; + System.arraycopy(_tempFrames, 0, newTempFrames, 0, + _tempFrames.length); + _tempFrames = newTempFrames; + } + + if (++_entryCount > 1000) + { + pollQueue(); + _entryCount = 0; + } + } + + private void pollQueue() + { + if (_refQueue != null) + { + for (; ;) + { + Ref ref = (Ref) _refQueue.poll(); + + if (ref == null) + break; + + if (ref._cur != null) + ref._cur.release(); + } + } + } + + public void exit(Locale otherLocale) + { + exit(); + + if (otherLocale != this) + otherLocale.exit(); + } + + public void exit() + { + // assert _numTempFramesLeft >= 0; + //asserts computed frame fits between 0 and _tempFrames.length + assert _numTempFramesLeft >= 0 && + (_numTempFramesLeft <= _tempFrames.length - 1): + " Temp frames mismanaged. Impossible stack frame. Unsynchronized: " + + noSync(); + + int frame = _tempFrames.length - ++_numTempFramesLeft; + + while (_tempFrames[frame] != null) + _tempFrames[frame].release(); + } + + // + // + // + + public boolean noSync() + { + return _noSync; + } + + public boolean sync() + { + return !_noSync; + } + + static final boolean isWhiteSpace(String s) + { + int l = s.length(); + + while (l-- > 0) + if (!CharUtil.isWhiteSpace(s.charAt(l))) + return false; + + return true; + } + + static final boolean isWhiteSpace(StringBuffer sb) + { + int l = sb.length(); + + while (l-- > 0) + if (!CharUtil.isWhiteSpace(sb.charAt(l))) + return false; + + return true; + } + + static boolean beginsWithXml(String name) + { + if (name.length() < 3) + return false; + + char ch; + + if (((ch = name.charAt(0)) == 'x' || ch == 'X') && + ((ch = name.charAt(1)) == 'm' || ch == 'M') && + ((ch = name.charAt(2)) == 'l' || ch == 'L')) + { + return true; + } + + return false; + } + + static boolean isXmlns(QName name) + { + String prefix = name.getPrefix(); + + if (prefix.equals("xmlns")) + return true; + + return prefix.length() == 0 && name.getLocalPart().equals("xmlns"); + } + + QName createXmlns(String prefix) + { + if (prefix == null) + prefix = ""; + + return + prefix.length() == 0 + ? makeQName(_xmlnsUri, "xmlns", "") + : makeQName(_xmlnsUri, prefix, "xmlns"); + } + + static String xmlnsPrefix(QName name) + { + return name.getPrefix().equals("xmlns") ? name.getLocalPart() : ""; + } + + // + // Loading/parsing + // + + static abstract class LoadContext + { + protected abstract void startDTD(String name, String publicId, + String systemId); + + protected abstract void endDTD(); + + protected abstract void startElement(QName name); + + protected abstract void endElement(); + + protected abstract void attr(QName name, String value); + + protected abstract void attr(String local, String uri, String prefix, + String value); + + protected abstract void xmlns(String prefix, String uri); + + protected abstract void comment(char[] buff, int off, int cch); + + protected abstract void comment(String comment); + + protected abstract void procInst(String target, String value); + + protected abstract void text(char[] buff, int off, int cch); + + protected abstract void text(String s); + + protected abstract Cur finish(); + + protected abstract void abort(); + + protected abstract void bookmark(XmlBookmark bm); + + protected abstract void bookmarkLastNonAttr(XmlBookmark bm); + + protected abstract void bookmarkLastAttr(QName attrName, + XmlBookmark bm); + + protected abstract void lineNumber(int line, int column, int offset); + + protected void addIdAttr(String eName, String aName){ + if ( _idAttrs == null ) + _idAttrs = new java.util.Hashtable(); + _idAttrs.put(aName,eName); + } + + protected boolean isAttrOfTypeId(QName aqn, QName eqn){ + if (_idAttrs == null) + return false; + String pre = aqn.getPrefix(); + String lName = aqn.getLocalPart(); + String urnName = "".equals(pre)?lName:pre + ":" + lName; + String eName = (String) _idAttrs.get(urnName); + if (eName == null ) return false; + //get the name of the parent elt + pre = eqn.getPrefix(); + lName = eqn.getLocalPart(); + lName = eqn.getLocalPart(); + urnName = "".equals(pre)?lName:pre + ":" + lName; + return eName.equals(urnName); + } + private java.util.Hashtable _idAttrs; + } + + private static class DefaultEntityResolver + implements EntityResolver + { + public InputSource resolveEntity(String publicId, String systemId) + { + return new InputSource(new StringReader("")); + } + } + + private static SaxLoader getPiccoloSaxLoader() + { + SaxLoader piccoloLoader = (SaxLoader) SystemCache.get().getSaxLoader(); + if (piccoloLoader == null) + { + piccoloLoader = PiccoloSaxLoader.newInstance(); + SystemCache.get().setSaxLoader(piccoloLoader); + } + return piccoloLoader; + } + + private static SaxLoader getSaxLoader(XmlOptions options) + { + options = XmlOptions.maskNull(options); + + EntityResolver er = null; + + if (!options.hasOption(XmlOptions.LOAD_USE_DEFAULT_RESOLVER)) + { + er = (EntityResolver) options.get(XmlOptions.ENTITY_RESOLVER); + + if (er == null) + er = ResolverUtil.getGlobalEntityResolver(); + + if (er == null) + er = new DefaultEntityResolver(); + } + + SaxLoader sl; + + if (options.hasOption(XmlOptions.LOAD_USE_XMLREADER)) + { + XMLReader xr = (XMLReader) options.get( + XmlOptions.LOAD_USE_XMLREADER); + + if (xr == null) + throw new IllegalArgumentException("XMLReader is null"); + + sl = new XmlReaderSaxLoader(xr); + + // I've noticed that most XMLReaders don't like a null EntityResolver... + + if (er != null) + xr.setEntityResolver(er); + } + else + { + sl = getPiccoloSaxLoader(); + + // Piccolo doesnot mind a null entity resolver ... + + sl.setEntityResolver(er); + } + + return sl; + } + + private static class XmlReaderSaxLoader + extends SaxLoader + { + XmlReaderSaxLoader(XMLReader xr) + { + super(xr, null); + } + } + + private static class PiccoloSaxLoader + extends SaxLoader + { + private PiccoloSaxLoader(Piccolo p) + { + super(p, p.getStartLocator()); + + _piccolo = p; + } + + static PiccoloSaxLoader newInstance() + { + return new PiccoloSaxLoader(new Piccolo()); + } + + void postLoad(Cur c) + { + XmlDocumentProperties props = getDocProps(c, true); + + props.setEncoding(_piccolo.getEncoding()); + props.setVersion(_piccolo.getVersion()); + + super.postLoad(c); + } + + private Piccolo _piccolo; + } + + private static abstract class SaxHandler + implements ContentHandler, LexicalHandler , DeclHandler, DTDHandler + { + SaxHandler(Locator startLocator) + { + _startLocator = startLocator; + } + + SaxHandler() + { + this(null); + } + + void initSaxHandler(Locale l, XmlOptions options) + { + _locale = l; + + options = XmlOptions.maskNull(options); + + _context = new Cur.CurLoadContext(_locale, options); + + _wantLineNumbers = + _startLocator != null && + options.hasOption(XmlOptions.LOAD_LINE_NUMBERS); + _wantLineNumbersAtEndElt = + _startLocator != null && + options.hasOption(XmlOptions.LOAD_LINE_NUMBERS_END_ELEMENT); + _wantCdataBookmarks = + _startLocator != null && + options.hasOption(XmlOptions.LOAD_SAVE_CDATA_BOOKMARKS); + + if (options.hasOption(XmlOptions.LOAD_ENTITY_BYTES_LIMIT)) + _entityBytesLimit = ((Integer)(options.get(XmlOptions.LOAD_ENTITY_BYTES_LIMIT))).intValue(); + } + + public void startDocument() + throws SAXException + { + // Do nothing ... start of document is implicit + } + + public void endDocument() + throws SAXException + { + // Do nothing ... end of document is implicit + } + + public void startElement(String uri, String local, String qName, + Attributes atts) + throws SAXException + { + if (local.length() == 0) + local = qName; + + // Out current parser (Piccolo) does not error when a + // namespace is used and not defined. Check for these here + + if (qName.indexOf(':') >= 0 && uri.length() == 0) + { + XmlError err = + XmlError.forMessage("Use of undefined namespace prefix: " + + qName.substring(0, qName.indexOf(':'))); + + throw new XmlRuntimeException(err.toString(), null, err); + } + + _context.startElement(_locale.makeQualifiedQName(uri, qName)); + + if (_wantLineNumbers) + { + _context.bookmark( + new XmlLineNumber(_startLocator.getLineNumber(), + _startLocator.getColumnNumber() - 1, -1)); + } + + for (int i = 0, len = atts.getLength(); i < len; i++) + { + String aqn = atts.getQName(i); + + if (aqn.equals("xmlns")) + { + _context.xmlns("", atts.getValue(i)); + } + else if (aqn.startsWith("xmlns:")) + { + String prefix = aqn.substring(6); + + if (prefix.length() == 0) + { + XmlError err = + XmlError.forMessage("Prefix not specified", + XmlError.SEVERITY_ERROR); + + throw new XmlRuntimeException(err.toString(), null, + err); + } + + String attrUri = atts.getValue(i); + + if (attrUri.length() == 0) + { + XmlError err = + XmlError.forMessage( + "Prefix can't be mapped to no namespace: " + + prefix, + XmlError.SEVERITY_ERROR); + + throw new XmlRuntimeException(err.toString(), null, + err); + } + + _context.xmlns(prefix, attrUri); + } + else + { + int colon = aqn.indexOf(':'); + + if (colon < 0) + _context.attr(aqn, atts.getURI(i), null, + atts.getValue(i)); + else + { + _context.attr(aqn.substring(colon + 1), atts.getURI(i), aqn.substring( + 0, colon), + atts.getValue(i)); + } + } + } + } + + public void endElement(String namespaceURI, String localName, + String qName) + throws SAXException + { + _context.endElement(); + if (_wantLineNumbersAtEndElt) + { + _context.bookmark( + new XmlLineNumber(_startLocator.getLineNumber(), + _startLocator.getColumnNumber() - 1, -1)); + } + } + + public void characters(char ch[], int start, int length) + throws SAXException + { + _context.text(ch, start, length); + + if (_wantCdataBookmarks && _insideCDATA) + _context.bookmarkLastNonAttr(CDataBookmark.CDATA_BOOKMARK); + + if (_insideEntity!=0) + { + if ((_entityBytes += length) > _entityBytesLimit) + { + XmlError err = XmlError.forMessage(XmlErrorCodes.EXCEPTION_EXCEEDED_ENTITY_BYTES, + new Integer[]{ new Integer(_entityBytesLimit) }); + + throw new SAXException(err.getMessage()); + } + } + } + + public void ignorableWhitespace(char ch[], int start, int length) + throws SAXException + { + } + + public void comment(char ch[], int start, int length) + throws SAXException + { + _context.comment(ch, start, length); + } + + public void processingInstruction(String target, String data) + throws SAXException + { + _context.procInst(target, data); + } + + public void startDTD(String name, String publicId, String systemId) + throws SAXException + { + _context.startDTD(name, publicId, systemId); + } + + public void endDTD() + throws SAXException + { + _context.endDTD(); + } + + public void startPrefixMapping(String prefix, String uri) + throws SAXException + { + if (beginsWithXml(prefix) && + !("xml".equals(prefix) && _xml1998Uri.equals(uri))) + { + XmlError err = + XmlError.forMessage( + "Prefix can't begin with XML: " + prefix, + XmlError.SEVERITY_ERROR); + + throw new XmlRuntimeException(err.toString(), null, err); + } + } + + public void endPrefixMapping(String prefix) + throws SAXException + { + } + + public void skippedEntity(String name) + throws SAXException + { +// throw new RuntimeException( "Not impl: skippedEntity" ); + } + + public void startCDATA() + throws SAXException + { + _insideCDATA = true; + } + + public void endCDATA() + throws SAXException + { + _insideCDATA = false; + } + + public void startEntity(String name) + throws SAXException + { + _insideEntity++; + } + + public void endEntity(String name) + throws SAXException + { + _insideEntity--; + assert _insideEntity>=0; + + if (_insideEntity==0) + { + _entityBytes=0; + } + } + + public void setDocumentLocator(Locator locator) + { + // TODO - for non-Piccolo use cases, use a locator to get line numbers + } + //DeclHandler + public void attributeDecl(String eName, String aName, String type, String valueDefault, String value){ + if (type.equals("ID")){ + _context.addIdAttr(eName,aName); + } + } + public void elementDecl(String name, String model){ + } + public void externalEntityDecl(String name, String publicId, String systemId){ + } + public void internalEntityDecl(String name, String value){ + } + + //DTDHandler + public void notationDecl(String name, String publicId, String systemId){ + } + public void unparsedEntityDecl(String name, String publicId, String systemId, String notationName){ + } + protected Locale _locale; + + protected LoadContext _context; + + private boolean _wantLineNumbers; + private boolean _wantLineNumbersAtEndElt; + private boolean _wantCdataBookmarks; + private Locator _startLocator; + private boolean _insideCDATA = false; + private int _entityBytesLimit = 10240; + private int _entityBytes = 0; + private int _insideEntity = 0; + } + + private static abstract class SaxLoader + extends SaxHandler + implements ErrorHandler + { + SaxLoader(XMLReader xr, Locator startLocator) + { + super(startLocator); + + _xr = xr; + + try + { + _xr.setFeature( + "http://xml.org/sax/features/namespace-prefixes", true); + _xr.setFeature("http://xml.org/sax/features/namespaces", true); + _xr.setFeature("http://xml.org/sax/features/validation", false); + _xr.setProperty( + "http://xml.org/sax/properties/lexical-handler", this); + _xr.setContentHandler(this); + _xr.setProperty("http://xml.org/sax/properties/declaration-handler", this); + _xr.setDTDHandler(this); + _xr.setErrorHandler(this); + } + catch (Throwable e) + { + throw new RuntimeException(e.getMessage(), e); + } + } + + void setEntityResolver(EntityResolver er) + { + _xr.setEntityResolver(er); + } + + void postLoad(Cur c) + { + // fix garbage collection of Locale -> Xobj -> STL + _locale = null; + _context = null; + } + + public Cur load(Locale l, InputSource is, XmlOptions options) + throws XmlException, IOException + { + is.setSystemId("file://"); + + initSaxHandler(l, options); + + try + { + _xr.parse(is); + + Cur c = _context.finish(); + + associateSourceName(c, options); + + postLoad(c); + + return c; + } + catch (FileFormatException e) + { + _context.abort(); + + throw new XmlException(e.getMessage(), e); + } + catch (XmlRuntimeException e) + { + _context.abort(); + + throw new XmlException(e); + } + catch (SAXParseException e) + { + _context.abort(); + + XmlError err = + XmlError.forLocation(e.getMessage(), + (String) XmlOptions.safeGet(options, + XmlOptions.DOCUMENT_SOURCE_NAME), + e.getLineNumber(), e.getColumnNumber(), -1); + + throw new XmlException(err.toString(), e, err); + } + catch (SAXException e) + { + _context.abort(); + + XmlError err = XmlError.forMessage(e.getMessage()); + + throw new XmlException(err.toString(), e, err); + } + catch (RuntimeException e) + { + _context.abort(); + + throw e; + } + } + + public void fatalError(SAXParseException e) + throws SAXException + { + throw e; + } + + public void error(SAXParseException e) + throws SAXException + { + throw e; + } + + public void warning(SAXParseException e) + throws SAXException + { + throw e; + } + + private XMLReader _xr; + } + + private Dom load(InputSource is, XmlOptions options) + throws XmlException, IOException + { + return getSaxLoader(options).load(this, is, options).getDom(); + } + + public Dom load(Reader r) + throws XmlException, IOException + { + return load(r, null); + } + + public Dom load(Reader r, XmlOptions options) + throws XmlException, IOException + { + return load(new InputSource(r), options); + } + + public Dom load(InputStream in) + throws XmlException, IOException + { + return load(in, null); + } + + public Dom load(InputStream in, XmlOptions options) + throws XmlException, IOException + { + return load(new InputSource(in), options); + } + + public Dom load(String s) + throws XmlException + { + return load(s, null); + } + + public Dom load(String s, XmlOptions options) + throws XmlException + { + Reader r = new StringReader(s); + + try + { + return load(r, options); + } + catch (IOException e) + { + assert false: "StringReader should not throw IOException"; + + throw new XmlException(e.getMessage(), e); + } + finally + { + try + { + r.close(); + } + catch (IOException e) + { + } + } + } + + // + // DOMImplementation methods + // + + public Document createDocument(String uri, String qname, + DocumentType doctype) + { + return DomImpl._domImplementation_createDocument(this, uri, qname, + doctype); + } + + public DocumentType createDocumentType(String qname, String publicId, + String systemId) + { + throw new RuntimeException("Not implemented"); +// return DomImpl._domImplementation_createDocumentType( this, qname, publicId, systemId ); + } + + public boolean hasFeature(String feature, String version) + { + return DomImpl._domImplementation_hasFeature(this, feature, version); + } + + public Object getFeature(String feature, String version) + { + throw new RuntimeException("DOM Level 3 Not implemented"); + } + + // + // Dom methods + // + + private static Dom checkNode(Node n) + { + if (n == null) + throw new IllegalArgumentException("Node is null"); + + if (!(n instanceof Dom)) + throw new IllegalArgumentException("Node is not an XmlBeans node"); + + return (Dom) n; + } + + public static XmlCursor nodeToCursor(Node n) + { + return DomImpl._getXmlCursor(checkNode(n)); + } + + public static XmlObject nodeToXmlObject(Node n) + { + return DomImpl._getXmlObject(checkNode(n)); + } + + public static XMLStreamReader nodeToXmlStream(Node n) + { + return DomImpl._getXmlStreamReader(checkNode(n)); + } + + public static Node streamToNode(XMLStreamReader xs) + { + return Jsr173.nodeFromStream(xs); + } + + // + // SaajCallback methods + // + + public void setSaajData(Node n, Object o) + { + assert n instanceof Dom; + + DomImpl.saajCallback_setSaajData((Dom) n, o); + } + + public Object getSaajData(Node n) + { + assert n instanceof Dom; + + return DomImpl.saajCallback_getSaajData((Dom) n); + } + + public Element createSoapElement(QName name, QName parentName) + { + assert _ownerDoc != null; + + return DomImpl.saajCallback_createSoapElement(_ownerDoc, name, + parentName); + } + + public Element importSoapElement(Document doc, Element elem, boolean deep, + QName parentName) + { + assert doc instanceof Dom; + + return DomImpl.saajCallback_importSoapElement((Dom) doc, elem, deep, + parentName); + } + + + private static final class DefaultQNameFactory + implements QNameFactory + { + private QNameCache _cache = XmlBeans.getQNameCache(); + + public QName getQName(String uri, String local) + { + return _cache.getName(uri, local, ""); + } + + public QName getQName(String uri, String local, String prefix) + { + return _cache.getName(uri, local, prefix); + } + + public QName getQName(char[] uriSrc, int uriPos, int uriCch, + char[] localSrc, int localPos, int localCch) + { + return + _cache.getName(new String(uriSrc, uriPos, uriCch), + new String(localSrc, localPos, localCch), + ""); + } + + public QName getQName(char[] uriSrc, int uriPos, int uriCch, + char[] localSrc, int localPos, int localCch, + char[] prefixSrc, int prefixPos, int prefixCch) + { + return + _cache.getName(new String(uriSrc, uriPos, uriCch), + new String(localSrc, localPos, localCch), + new String(prefixSrc, prefixPos, prefixCch)); + } + } + + + private static final class LocalDocumentQNameFactory + implements QNameFactory + { + private QNameCache _cache = new QNameCache( 32 ); + + public QName getQName(String uri, String local) + { + return _cache.getName(uri, local, ""); + } + + public QName getQName(String uri, String local, String prefix) + { + return _cache.getName(uri, local, prefix); + } + + public QName getQName(char[] uriSrc, int uriPos, int uriCch, + char[] localSrc, int localPos, int localCch) + { + return + _cache.getName(new String(uriSrc, uriPos, uriCch), + new String(localSrc, localPos, localCch), + ""); + } + + public QName getQName(char[] uriSrc, int uriPos, int uriCch, + char[] localSrc, int localPos, int localCch, + char[] prefixSrc, int prefixPos, int prefixCch) + { + return + _cache.getName(new String(uriSrc, uriPos, uriCch), + new String(localSrc, localPos, localCch), + new String(prefixSrc, prefixPos, prefixCch)); + } + } + + // + // + // + + boolean _noSync; + + SchemaTypeLoader _schemaTypeLoader; + + private ReferenceQueue _refQueue; + private int _entryCount; + + int _numTempFramesLeft; + Cur[] _tempFrames; + + Cur _curPool; + int _curPoolCount; + + Cur _registered; + + ChangeListener _changeListeners; + + long _versionAll; + long _versionSansText; + + Locations _locations; + + private CharUtil _charUtil; + + int _offSrc; + int _cchSrc; + + Saaj _saaj; + + Dom _ownerDoc; + + QNameFactory _qnameFactory; + + boolean _validateOnSet; + + int _posTemp; + + nthCache _nthCache_A = new nthCache(); + nthCache _nthCache_B = new nthCache(); + + domNthCache _domNthCache_A = new domNthCache(); + domNthCache _domNthCache_B = new domNthCache(); +} diff --git a/xmlbeans/src/store/org/apache/xmlbeans/impl/store/Path.java b/xmlbeans/src/store/org/apache/xmlbeans/impl/store/Path.java new file mode 100755 index 000000000..7d50fac5a --- /dev/null +++ b/xmlbeans/src/store/org/apache/xmlbeans/impl/store/Path.java @@ -0,0 +1,715 @@ +/* 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.store; + +import java.io.*; +import java.util.*; + +import java.lang.reflect.Method; +import java.lang.reflect.InvocationTargetException; +import java.lang.ref.WeakReference; +import java.math.BigDecimal; +import java.util.concurrent.locks.ReentrantReadWriteLock; + +import org.apache.xmlbeans.impl.common.XPath; +import org.apache.xmlbeans.impl.common.XPath.XPathCompileException; +import org.apache.xmlbeans.impl.common.XPath.ExecutionContext; + +import org.apache.xmlbeans.*; +import org.w3c.dom.Node; + + +// TODO - This class handled query *and* path ... rename it? + +public abstract class Path +{ + public static final String PATH_DELEGATE_INTERFACE = "PATH_DELEGATE_INTERFACE"; + public static String _useDelegateForXpath = "use delegate for xpath"; + public static String _useXdkForXpath = "use xdk for xpath"; + public static String _useXqrlForXpath = "use xqrl for xpath"; + public static String _useXbeanForXpath = "use xbean for xpath"; + public static String _forceXqrl2002ForXpathXQuery = "use xqrl-2002 for xpath"; + + private static final int USE_XBEAN = 0x01; + private static final int USE_XQRL = 0x02; + private static final int USE_DELEGATE = 0x04; + private static final int USE_XQRL2002 = 0x08; + private static final int USE_XDK = 0x10; + + private static Map _xbeanPathCache = new WeakHashMap(); + private static Map _xdkPathCache = new WeakHashMap(); + private static Map _xqrlPathCache = new WeakHashMap(); + private static Map _xqrl2002PathCache = new WeakHashMap(); + + private static Method _xdkCompilePath; + private static Method _xqrlCompilePath; + private static Method _xqrl2002CompilePath; + + private static boolean _xdkAvailable = true; + private static boolean _xqrlAvailable = true; + private static boolean _xqrl2002Available = true; + + private static String _delIntfName; + private static final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); + + static + { + ClassLoader cl = Path.class.getClassLoader(); + String id = "META-INF/services/org.apache.xmlbeans.impl.store.PathDelegate.SelectPathInterface"; + InputStream in = cl.getResourceAsStream(id); + try + { + BufferedReader br = new BufferedReader(new InputStreamReader(in)); + _delIntfName = br.readLine().trim(); + br.close(); + } + catch (Exception e) + { + _delIntfName = null; + } + } + + protected final String _pathKey; + + Path(String key) + { + _pathKey = key; + } + + + interface PathEngine + { + void release(); + + boolean next(Cur c); + } + + abstract PathEngine execute(Cur c, XmlOptions options); + + // + // + // + + static String getCurrentNodeVar(XmlOptions options) + { + String currentNodeVar = "this"; + + options = XmlOptions.maskNull(options); + + if (options.hasOption(XmlOptions.XQUERY_CURRENT_NODE_VAR)) { + currentNodeVar = (String) options.get(XmlOptions.XQUERY_CURRENT_NODE_VAR); + + if (currentNodeVar.startsWith("$")) { + throw new IllegalArgumentException("Omit the '$' prefix for the current node variable"); + } + } + + return currentNodeVar; + } + + public static Path getCompiledPath(String pathExpr, XmlOptions options) + { + options = XmlOptions.maskNull(options); + + int force = + options.hasOption(_useDelegateForXpath) ? USE_DELEGATE + : options.hasOption(_useXqrlForXpath) ? USE_XQRL + : options.hasOption(_useXdkForXpath) ? USE_XDK + : options.hasOption(_useXbeanForXpath) ? USE_XBEAN + : options.hasOption(_forceXqrl2002ForXpathXQuery) ? USE_XQRL2002 + : USE_XBEAN|USE_XQRL|USE_XDK|USE_DELEGATE; //set all bits except XQRL2002 + String delIntfName = + options.hasOption(PATH_DELEGATE_INTERFACE) ? + (String)options.get(PATH_DELEGATE_INTERFACE) : _delIntfName; + + return getCompiledPath(pathExpr, force, getCurrentNodeVar(options), delIntfName); + } + + static Path getCompiledPath(String pathExpr, int force, + String currentVar, String delIntfName) + { + Path path = null; + WeakReference pathWeakRef = null; + Map namespaces = (force & USE_DELEGATE) != 0 ? new HashMap() : null; + lock.readLock().lock(); + try { + if ((force & USE_XBEAN) != 0) + pathWeakRef = (WeakReference)_xbeanPathCache.get(pathExpr); + if (pathWeakRef == null && (force & USE_XQRL) != 0) + pathWeakRef = (WeakReference)_xqrlPathCache.get(pathExpr); + if (pathWeakRef == null && (force & USE_XDK) != 0) + pathWeakRef = (WeakReference)_xdkPathCache.get(pathExpr); + if (pathWeakRef == null && (force & USE_XQRL2002) != 0) + pathWeakRef = (WeakReference)_xqrl2002PathCache.get(pathExpr); + + if (pathWeakRef!=null) + path = (Path)pathWeakRef.get(); + if (path != null) + return path; + } finally { + lock.readLock().unlock(); + } + lock.writeLock().lock(); + try { + if ((force & USE_XBEAN) != 0) { + pathWeakRef = (WeakReference)_xbeanPathCache.get(pathExpr); + if (pathWeakRef != null) + path = (Path)pathWeakRef.get(); + if (path==null) + path = getCompiledPathXbean(pathExpr, currentVar, namespaces); + } + if (path == null && (force & USE_XQRL) != 0) { + pathWeakRef = (WeakReference)_xqrlPathCache.get(pathExpr); + if (pathWeakRef != null) + path = (Path)pathWeakRef.get(); + if (path==null) + path = getCompiledPathXqrl(pathExpr, currentVar); + } + if (path == null && (force & USE_XDK) != 0) { + pathWeakRef = (WeakReference)_xdkPathCache.get(pathExpr); + if (pathWeakRef != null) + path = (Path)pathWeakRef.get(); + if (path==null) + path = getCompiledPathXdk(pathExpr, currentVar); + } + if (path == null && (force & USE_DELEGATE) != 0) { + path = getCompiledPathDelegate(pathExpr, currentVar, namespaces, delIntfName); + } + if (path == null && (force & USE_XQRL2002) != 0) { + pathWeakRef = (WeakReference)_xqrl2002PathCache.get(pathExpr); + if (pathWeakRef != null) + path = (Path)pathWeakRef.get(); + if (path==null) + path = getCompiledPathXqrl2002(pathExpr, currentVar); + } + if (path == null) + { + StringBuffer errMessage = new StringBuffer(); + if ((force & USE_XBEAN) != 0) + errMessage.append(" Trying XBeans path engine..."); + if ((force & USE_XQRL) != 0) + errMessage.append(" Trying XQRL..."); + if ((force & USE_XDK) != 0) + errMessage.append(" Trying XDK..."); + if ((force & USE_DELEGATE) != 0) + errMessage.append(" Trying delegated path engine..."); + if ((force & USE_XQRL2002) != 0) + errMessage.append(" Trying XQRL2002..."); + + throw new RuntimeException(errMessage.toString() + " FAILED on " + pathExpr); + } + } finally { + lock.writeLock().unlock(); + } + return path; + } + + static private Path getCompiledPathXdk(String pathExpr, String currentVar) + { + Path path = createXdkCompiledPath(pathExpr, currentVar); + if (path != null) + _xdkPathCache.put(path._pathKey, new WeakReference(path)); + + return path; + } + + static private Path getCompiledPathXqrl(String pathExpr, String currentVar) + { + Path path = createXqrlCompiledPath(pathExpr, currentVar); + if (path != null) + _xqrlPathCache.put(path._pathKey, new WeakReference(path)); + + return path; + } + + static private Path getCompiledPathXqrl2002(String pathExpr, String currentVar) + { + Path path = createXqrl2002CompiledPath(pathExpr, currentVar); + if (path != null) + _xqrl2002PathCache.put(path._pathKey, new WeakReference(path)); + + return path; + } + + static private Path getCompiledPathXbean(String pathExpr, + String currentVar, Map namespaces) + { + Path path = XbeanPath.create(pathExpr, currentVar, namespaces); + if (path != null) + _xbeanPathCache.put(path._pathKey, new WeakReference(path)); + + return path; + } + + static private Path getCompiledPathDelegate(String pathExpr, String currentVar, Map namespaces, String delIntfName) + { + Path path = null; + if ( namespaces == null ) + namespaces = new HashMap(); + + try + { + XPath.compileXPath(pathExpr, currentVar, namespaces); + } + catch (XPath.XPathCompileException e) + { + //do nothing, this function is only called to populate the namespaces map + } + + int offset = + namespaces.get(XPath._NS_BOUNDARY) == null ? + 0 : + ((Integer) namespaces.get(XPath._NS_BOUNDARY)).intValue(); + namespaces.remove(XPath._NS_BOUNDARY); + path = DelegatePathImpl.create(delIntfName, + pathExpr.substring(offset), + currentVar, + namespaces); + + return path; + } + + + public static String compilePath(String pathExpr, XmlOptions options) + { + return getCompiledPath(pathExpr, options)._pathKey; + } + + // + // Xbean store specific implementation of compiled path + // + + private static final class XbeanPath extends Path + { + static Path create(String pathExpr, String currentVar, Map namespaces) + { + try + { + return new XbeanPath(pathExpr, currentVar, + XPath.compileXPath(pathExpr, currentVar, namespaces)); + } + catch (XPathCompileException e) { + return null; + } + } + + private XbeanPath(String pathExpr, String currentVar, XPath xpath) + { + super(pathExpr); + + _currentVar = currentVar; + _compiledPath = xpath; + } + + PathEngine execute(Cur c, XmlOptions options) + { + options = XmlOptions.maskNull(options); + String delIntfName = + options.hasOption(PATH_DELEGATE_INTERFACE) ? + (String)options.get(PATH_DELEGATE_INTERFACE) : _delIntfName; + + // The builtin XPath engine works only on containers. Delegate to + // xqrl otherwise. Also, if the path had a //. at the end, the + // simple xpath engine can't do the generate case, it only handles + // attrs and elements. + + if (!c.isContainer() || _compiledPath.sawDeepDot()) + { + int force = USE_DELEGATE | USE_XQRL | USE_XDK; + return getCompiledPath(_pathKey, force, _currentVar, delIntfName).execute(c, options); + } + return new XbeanPathEngine(_compiledPath, c); + } + + private final String _currentVar; + private final XPath _compiledPath; + public Map namespaces; + } + + private static Path createXdkCompiledPath(String pathExpr, String currentVar) + { + if (!_xdkAvailable) + return null; + + if (_xdkCompilePath == null) + { + try + { + Class xdkImpl = Class.forName("org.apache.xmlbeans.impl.store.OXQXBXqrlImpl"); + + _xdkCompilePath = + xdkImpl.getDeclaredMethod("compilePath", + new Class[]{String.class, String.class, Boolean.class}); + } + catch (ClassNotFoundException e) + { + _xdkAvailable = false; + return null; + } + catch (Exception e) + { + _xdkAvailable = false; + throw new RuntimeException(e.getMessage(), e); + } + } + + Object[] args = new Object[]{pathExpr, currentVar, new Boolean(true)}; + + try { + return (Path) _xdkCompilePath.invoke(null, args); + } + catch (InvocationTargetException e) { + Throwable t = e.getCause(); + throw new RuntimeException(t.getMessage(), t); + } + catch (IllegalAccessException e) { + throw new RuntimeException(e.getMessage(), e); + } + } + + private static Path createXqrlCompiledPath(String pathExpr, String currentVar) + { + if (!_xqrlAvailable) + return null; + + if (_xqrlCompilePath == null) + { + try + { + Class xqrlImpl = Class.forName("org.apache.xmlbeans.impl.store.XqrlImpl"); + + _xqrlCompilePath = + xqrlImpl.getDeclaredMethod("compilePath", + new Class[]{String.class, String.class, Boolean.class}); + } + catch (ClassNotFoundException e) + { + _xqrlAvailable = false; + return null; + } + catch (Exception e) + { + _xqrlAvailable = false; + throw new RuntimeException(e.getMessage(), e); + } + } + + Object[] args = new Object[]{pathExpr, currentVar, new Boolean(true)}; + + try { + return (Path) _xqrlCompilePath.invoke(null, args); + } + catch (InvocationTargetException e) { + Throwable t = e.getCause(); + throw new RuntimeException(t.getMessage(), t); + } + catch (IllegalAccessException e) { + throw new RuntimeException(e.getMessage(), e); + } + } + + private static Path createXqrl2002CompiledPath(String pathExpr, String currentVar) + { + if (!_xqrl2002Available) + return null; + + if (_xqrl2002CompilePath == null) + { + try + { + Class xqrlImpl = Class.forName("org.apache.xmlbeans.impl.store.Xqrl2002Impl"); + + _xqrl2002CompilePath = + xqrlImpl.getDeclaredMethod("compilePath", + new Class[]{String.class, String.class, Boolean.class}); + } + catch (ClassNotFoundException e) + { + _xqrl2002Available = false; + return null; + } + catch (Exception e) + { + _xqrl2002Available = false; + throw new RuntimeException(e.getMessage(), e); + } + } + + Object[] args = new Object[]{pathExpr, currentVar, new Boolean(true)}; + + try + { + return (Path) _xqrl2002CompilePath.invoke(null, args); + } + catch (InvocationTargetException e) + { + Throwable t = e.getCause(); + throw new RuntimeException(t.getMessage(), t); + } + catch (IllegalAccessException e) + { + throw new RuntimeException(e.getMessage(), e); + } + } + + private static final class XbeanPathEngine + extends ExecutionContext + implements PathEngine + { + XbeanPathEngine(XPath xpath, Cur c) + { + assert c.isContainer(); + + _version = c._locale.version(); + _cur = c.weakCur(this); + + _cur.push(); + + init(xpath); + + int ret = start(); + + if ((ret & HIT) != 0) + c.addToSelection(); + + doAttrs(ret, c); + + if ((ret & DESCEND) == 0 || !Locale.toFirstChildElement(_cur)) + release(); + } + + private void advance(Cur c) + { + assert _cur != null; + + if (_cur.isFinish()) + { + if (_cur.isAtEndOfLastPush()) + release(); + else { + end(); + _cur.next(); + } + } + else if (_cur.isElem()) + { + int ret = element(_cur.getName()); + + if ((ret & HIT) != 0) + c.addToSelection(_cur); + + doAttrs(ret, c); + + if ((ret & DESCEND) == 0 || !Locale.toFirstChildElement(_cur)) + { + end(); + _cur.skip(); + } + } + else + { + do + { + _cur.next(); + } + while(!_cur.isContainerOrFinish()); + } + } + + private void doAttrs(int ret, Cur c) + { + assert _cur.isContainer(); + + if ((ret & ATTRS) != 0) { + if (_cur.toFirstAttr()) { + do { + if (attr(_cur.getName())) + c.addToSelection(_cur); + } + while (_cur.toNextAttr()); + + _cur.toParent(); + } + } + } + + public boolean next(Cur c) + { + if (_cur != null && _version != _cur._locale.version()) + throw new ConcurrentModificationException("Document changed during select"); + + int startCount = c.selectionCount(); + + while (_cur != null) { + advance(c); + + if (startCount != c.selectionCount()) + return true; + } + + return false; + } + + public void release() + { + if (_cur != null) { + _cur.release(); + _cur = null; + } + } + + private final long _version; + private Cur _cur; + } + + private static final class DelegatePathImpl + extends Path + { + private PathDelegate.SelectPathInterface _xpathImpl; + + static Path create(String implClassName, String pathExpr, String currentNodeVar, Map namespaceMap) + { + assert !currentNodeVar.startsWith("$"); // cezar review with ericvas + + PathDelegate.SelectPathInterface impl = + PathDelegate.createInstance(implClassName, pathExpr, currentNodeVar, namespaceMap); + if (impl == null) + return null; + + return new DelegatePathImpl(impl, pathExpr); + } + + + private DelegatePathImpl(PathDelegate.SelectPathInterface xpathImpl, + String pathExpr) + { + super(pathExpr); + _xpathImpl = xpathImpl; + } + + protected PathEngine execute(Cur c, XmlOptions options) + { + return new DelegatePathEngine(_xpathImpl, c); + } + + private static class DelegatePathEngine + extends XPath.ExecutionContext + implements PathEngine + { + + DelegatePathEngine(PathDelegate.SelectPathInterface xpathImpl, + Cur c) + { + _engine = xpathImpl; + _version = c._locale.version(); + _cur = c.weakCur(this); + } + + public boolean next(Cur c) + { + if (!_firstCall) + return false; + + _firstCall = false; + + if (_cur != null && _version != _cur._locale.version()) + throw new ConcurrentModificationException("Document changed during select"); + + List resultsList; + Object context_node; + + context_node = _cur.getDom(); + resultsList = _engine.selectPath(context_node); + + int i; + for (i = 0; i < resultsList.size(); i++) { + //simple type function results + Object node = resultsList.get(i); + Cur pos = null; + if (!(node instanceof Node)) { + String value; + + value = resultsList.get(i).toString(); + + //we cannot leave the cursor's locale, as + //everything is done in the selections of this cursor + + Locale l = c._locale; + try { + pos = l.load("").tempCur(); + pos.setValue(value); + SchemaType type = getType(node); + Locale.autoTypeDocument(pos, type, null); + //move the cur to the actual text + pos.next(); + } + catch (Exception e) { + throw new RuntimeException(e); + } + } + else { + assert (node instanceof DomImpl.Dom): + "New object created in XPATH!"; + pos = ((DomImpl.Dom) node).tempCur(); + + } + c.addToSelection(pos); + pos.release(); + } + release(); + _engine = null; + return true; + } + + private SchemaType getType(Object node) + { + SchemaType type; + if (node instanceof Integer) + type = XmlInteger.type; + else if (node instanceof Double) + type = XmlDouble.type; + else if (node instanceof Long) + type = XmlLong.type; + else if (node instanceof Float) + type = XmlFloat.type; + else if (node instanceof BigDecimal) + type = XmlDecimal.type; + else if (node instanceof Boolean) + type = XmlBoolean.type; + else if (node instanceof String) + type = XmlString.type; + else if (node instanceof Date) + type = XmlDate.type; + else + type = XmlAnySimpleType.type; + return type; + } + + public void release() + { + if (_cur != null) { + _cur.release(); + _cur = null; + } + } + + private Cur _cur; + private PathDelegate.SelectPathInterface _engine; + private boolean _firstCall = true; + private long _version; + } + } +} diff --git a/xmlbeans/src/store/org/apache/xmlbeans/impl/store/PathDelegate.java b/xmlbeans/src/store/org/apache/xmlbeans/impl/store/PathDelegate.java new file mode 100644 index 000000000..8dfd59abf --- /dev/null +++ b/xmlbeans/src/store/org/apache/xmlbeans/impl/store/PathDelegate.java @@ -0,0 +1,94 @@ +/* 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.store; + +import java.util.List; +import java.util.Map; +import java.util.HashMap; +import java.lang.reflect.Constructor; + +import org.apache.xmlbeans.impl.common.XPath; + +public final class PathDelegate +{ + private static HashMap _constructors = new HashMap(); + + private PathDelegate() + {} + + private static synchronized void init(String implClassName) + { + // default to Saxon + if (implClassName == null) + implClassName = "org.apache.xmlbeans.impl.xpath.saxon.XBeansXPath"; + Class selectPathInterfaceImpl = null; + boolean engineAvailable = true; + try + { + selectPathInterfaceImpl = Class.forName(implClassName); + } + catch (ClassNotFoundException e) + { + engineAvailable = false; + } + catch (NoClassDefFoundError e) + { + engineAvailable = false; + } + + if (engineAvailable) + { + try + { + Constructor constructor = selectPathInterfaceImpl.getConstructor( + new Class[] {String.class, String.class, Map.class, String.class}); + _constructors.put(implClassName, constructor); + } + catch (Exception e) + { + throw new RuntimeException(e); + } + } + } + + public static synchronized SelectPathInterface createInstance(String implClassName, + String xpath, String contextVar, Map namespaceMap) + { + if (_constructors.get(implClassName) == null) + init(implClassName); + + if (_constructors.get(implClassName) == null) + return null; + + Constructor constructor = (Constructor)_constructors.get(implClassName); + try + { + Object defaultNS = namespaceMap.get(XPath._DEFAULT_ELT_NS); + if (defaultNS != null) + namespaceMap.remove(XPath._DEFAULT_ELT_NS); + return (SelectPathInterface)constructor.newInstance( + new Object[] {xpath, contextVar, namespaceMap, (String)defaultNS}); + } + catch (Exception e) + { + throw new RuntimeException(e); + } + } + + public static interface SelectPathInterface + { + public List selectPath(Object node); + } +} diff --git a/xmlbeans/src/store/org/apache/xmlbeans/impl/store/Public2.java b/xmlbeans/src/store/org/apache/xmlbeans/impl/store/Public2.java new file mode 100755 index 000000000..93f20ae2f --- /dev/null +++ b/xmlbeans/src/store/org/apache/xmlbeans/impl/store/Public2.java @@ -0,0 +1,380 @@ +/* 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.store; + +import javax.xml.stream.XMLStreamReader; + +import java.io.InputStream; +import java.io.OutputStream; +import java.io.IOException; + +import org.w3c.dom.DOMImplementation; +import org.w3c.dom.Node; +import org.w3c.dom.Document; + +import org.apache.xmlbeans.XmlBeans; +import org.apache.xmlbeans.XmlCursor; +import org.apache.xmlbeans.XmlOptions; +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.XmlException; + +import java.io.PrintStream; + +import org.apache.xmlbeans.impl.store.DomImpl.Dom; + +import org.apache.xmlbeans.impl.store.Saver.TextSaver; + +import org.apache.xmlbeans.impl.values.TypeStore; +import org.apache.xmlbeans.impl.values.TypeStoreUser; +import org.apache.xmlbeans.impl.values.TypeStoreVisitor; +import org.apache.xmlbeans.impl.values.TypeStoreUserFactory; + +import org.apache.xmlbeans.SchemaType; + +import org.apache.xmlbeans.impl.values.NamespaceManager; + +import javax.xml.namespace.QName; + +import org.apache.xmlbeans.SchemaField; + +import org.apache.xmlbeans.QNameSet; + +public final class Public2 +{ + private static Locale newLocale ( Saaj saaj ) + { + XmlOptions options = null; + + if (saaj != null) + { + options = new XmlOptions(); + options.put( org.apache.xmlbeans.impl.store.Saaj.SAAJ_IMPL, saaj ); + } + + return Locale.getLocale( null, options ); + } + + private static Locale newLocale ( ) + { + return Locale.getLocale( null, null ); + } + + public static void setSync ( Document doc, boolean sync ) + { + assert doc instanceof Dom; + + Locale l = ((Dom) doc).locale(); + + l._noSync = ! sync; + } + + public static String compilePath ( String path, XmlOptions options ) + { + return Path.compilePath( path, options ); + } + + public static DOMImplementation getDomImplementation ( ) + { + return newLocale( ); + } + + public static DOMImplementation getDomImplementation ( Saaj saaj ) + { + return newLocale( saaj ); + } + + public static Document parse ( String s ) + throws XmlException + { + Locale l = newLocale(); + + Dom d; + + if (l.noSync()) { l.enter(); try { d = l.load( s ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { d = l.load( s ); } finally { l.exit(); } } + + return (Document) d; + } + + public static Document parse ( String s, XmlOptions options ) + throws XmlException + { + Locale l = newLocale(); + + Dom d; + + if (l.noSync()) { l.enter(); try { d = l.load( s, options ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { d = l.load( s, options ); } finally { l.exit(); } } + + return (Document) d; + } + + public static Document parse ( String s, Saaj saaj ) + throws XmlException + { + Locale l = newLocale( saaj ); + + Dom d; + + if (l.noSync()) { l.enter(); try { d = l.load( s ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { d = l.load( s ); } finally { l.exit(); } } + + return (Document) d; + } + + public static Document parse ( InputStream is, XmlOptions options ) + throws XmlException, IOException + { + Locale l = newLocale(); + + Dom d; + + if (l.noSync()) { l.enter(); try { d = l.load( is, options ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { d = l.load( is, options ); } finally { l.exit(); } } + + return (Document) d; + } + + public static Document parse ( InputStream is, Saaj saaj ) + throws XmlException, IOException + { + Locale l = newLocale( saaj ); + + Dom d; + + if (l.noSync()) { l.enter(); try { d = l.load( is ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { d = l.load( is ); } finally { l.exit(); } } + + return (Document) d; + } + + public static Node getNode ( XMLStreamReader s ) + { + return Jsr173.nodeFromStream( s ); + } + + public static XMLStreamReader getStream ( Node n ) + { + assert n instanceof Dom; + + Dom d = (Dom) n; + + Locale l = d.locale(); + + if (l.noSync()) { l.enter(); try { return DomImpl.getXmlStreamReader( d ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return DomImpl.getXmlStreamReader( d ); } finally { l.exit(); } } + } + + public static String save ( Node n ) + { + return save( n, null ); + } + + public static void save ( Node n, OutputStream os, XmlOptions options ) throws IOException + { + XmlCursor c = getCursor( n ); + + c.save( os, options ); + + c.dispose(); + } + + public static String save ( Node n, XmlOptions options ) + { + assert n instanceof Dom; + + Dom d = (Dom) n; + + Locale l = d.locale(); + + if (l.noSync()) { l.enter(); try { return saveImpl( d, options ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return saveImpl( d, options ); } finally { l.exit(); } } + } + + private static String saveImpl ( Dom d, XmlOptions options ) + { + Cur c = d.tempCur(); + + String s = new TextSaver( c, options, null ).saveToString(); + + c.release(); + + return s; + } + + public static String save ( XmlCursor c ) + { + return save( c, null ); + } + + public static String save ( XmlCursor xc, XmlOptions options ) + { + Cursor cursor = (Cursor) xc; + + Locale l = cursor.locale(); + + if (l.noSync()) { l.enter(); try { return saveImpl( cursor, options ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return saveImpl( cursor, options ); } finally { l.exit(); } } + } + + private static String saveImpl ( Cursor cursor, XmlOptions options ) + { + Cur c = cursor.tempCur(); + + String s = new TextSaver( c, options, null ).saveToString(); + + c.release(); + + return s; + } + + public static XmlCursor newStore ( ) + { + return newStore( null ); + } + + public static XmlCursor newStore ( Saaj saaj ) + { + Locale l = newLocale( saaj ); + + if (l.noSync()) { l.enter(); try { return _newStore( l ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return _newStore( l ); } finally { l.exit(); } } + } + + public static XmlCursor _newStore ( Locale l ) + { + Cur c = l.tempCur(); + + c.createRoot(); + + Cursor cursor = new Cursor( c ); + + c.release(); + + return cursor; + } + + public static XmlCursor getCursor ( Node n ) + { + assert n instanceof Dom; + + Dom d = (Dom) n; + + Locale l = d.locale(); + + if (l.noSync()) { l.enter(); try { return DomImpl.getXmlCursor( d ); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return DomImpl.getXmlCursor( d ); } finally { l.exit(); } } + } + + public static void dump ( PrintStream o, Dom d ) + { + d.dump( o ); + } + + public static void dump ( PrintStream o, Node n ) + { + dump( o, (Dom) n ); + } + + public static void dump ( PrintStream o, XmlCursor c ) + { + ((Cursor) c).dump( o ); + } + + public static void dump ( PrintStream o, XmlObject x ) + { + XmlCursor xc = x.newCursor(); + Node n = xc.getDomNode(); + Dom d = (Dom) n; + xc.dispose(); + + dump( o, d ); + } + + public static void dump ( Dom d ) { dump( System.out, d ); } + public static void dump ( Node n ) { dump( System.out, n ); } + public static void dump ( XmlCursor c ) { dump( System.out, c ); } + public static void dump ( XmlObject x ) { dump( System.out, x ); } + + private static class TestTypeStoreUser implements TypeStoreUser + { + TestTypeStoreUser ( String value ) { _value = value; } + public void attach_store(TypeStore store) { } + public SchemaType get_schema_type() { throw new RuntimeException( "Not impl" ); } + public TypeStore get_store() { throw new RuntimeException( "Not impl" ); } + public void invalidate_value() { } + public boolean uses_invalidate_value() { throw new RuntimeException( "Not impl" ); } + public String build_text(NamespaceManager nsm) { return _value; } + public boolean build_nil() { throw new RuntimeException( "Not impl" ); } + public void invalidate_nilvalue() { throw new RuntimeException( "Not impl" ); } + public void invalidate_element_order() { throw new RuntimeException( "Not impl" ); } + public void validate_now() { throw new RuntimeException( "Not impl" ); } + public void disconnect_store() { throw new RuntimeException( "Not impl" ); } + public TypeStoreUser create_element_user(QName eltName, QName xsiType) { return new TestTypeStoreUser( "ELEM" ); } + public TypeStoreUser create_attribute_user(QName attrName) { throw new RuntimeException( "Not impl" ); } + public String get_default_element_text(QName eltName) { throw new RuntimeException( "Not impl" ); } + public String get_default_attribute_text(QName attrName) { throw new RuntimeException( "Not impl" ); } + public SchemaType get_element_type(QName eltName, QName xsiType) { throw new RuntimeException( "Not impl" ); } + public SchemaType get_attribute_type(QName attrName) { throw new RuntimeException( "Not impl" ); } + public int get_elementflags(QName eltName) { throw new RuntimeException( "Not impl" ); } + public int get_attributeflags(QName attrName) { throw new RuntimeException( "Not impl" ); } + public SchemaField get_attribute_field(QName attrName) { throw new RuntimeException( "Not impl" ); } + public boolean is_child_element_order_sensitive() { throw new RuntimeException( "Not impl" ); } + public QNameSet get_element_ending_delimiters(QName eltname) { throw new RuntimeException( "Not impl" ); } + public TypeStoreVisitor new_visitor() { throw new RuntimeException( "Not impl" ); } + + private String _value; + } + + public static void test ( ) throws Exception + { + Xobj x = (Xobj) Public2.parse( "XY" ); + + Locale l = x._locale; + + l.enter(); + + try + { + Cur c = x.tempCur(); + + c.next(); + + Cur c2 = c.tempCur(); + c2.next(); + + Cur c3 = c2.tempCur(); + c3.nextChars( 1 ); + + Cur c4 = c3.tempCur(); + c4.nextChars( 1 ); + + c.dump(); + + c.moveNodeContents( c, true ); + + c.dump(); + } + catch ( Throwable e ) + { + e.printStackTrace(); + } + finally + { + l.exit(); + } + } +} diff --git a/xmlbeans/src/store/org/apache/xmlbeans/impl/store/QNameFactory.java b/xmlbeans/src/store/org/apache/xmlbeans/impl/store/QNameFactory.java new file mode 100755 index 000000000..b0fca1780 --- /dev/null +++ b/xmlbeans/src/store/org/apache/xmlbeans/impl/store/QNameFactory.java @@ -0,0 +1,34 @@ +/* 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.store; + +import javax.xml.namespace.QName; + +public interface QNameFactory +{ + public QName getQName ( String uri, String local ); + + public QName getQName ( String uri, String local, String prefix ); + + public QName getQName ( + char[] uriSrc, int uriPos, int uriCch, + char[] localSrc, int localPos, int localCch ); + + public QName getQName ( + char[] uriSrc, int uriPos, int uriCch, + char[] localSrc, int localPos, int localCch, + char[] prefixSrc, int prefixPos, int prefixCch ); +} \ No newline at end of file diff --git a/xmlbeans/src/store/org/apache/xmlbeans/impl/store/Query.java b/xmlbeans/src/store/org/apache/xmlbeans/impl/store/Query.java new file mode 100644 index 000000000..8fef064ce --- /dev/null +++ b/xmlbeans/src/store/org/apache/xmlbeans/impl/store/Query.java @@ -0,0 +1,525 @@ +/* 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.store; + +import org.apache.xmlbeans.*; +import org.apache.xmlbeans.impl.common.XPath; +import org.w3c.dom.*; + +import javax.xml.namespace.QName; +import java.io.*; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Date; +import java.lang.reflect.Method; +import java.lang.reflect.InvocationTargetException; +import java.math.BigDecimal; + +public abstract class Query +{ + public static final String QUERY_DELEGATE_INTERFACE = "QUERY_DELEGATE_INTERFACE"; + public static String _useDelegateForXQuery = "use delegate for xquery"; + public static String _useXdkForXQuery = "use xdk for xquery"; + + private static String _delIntfName; + //private static HashMap _delegateQueryCache = new HashMap(); + + private static HashMap _xdkQueryCache = new HashMap(); + private static Method _xdkCompileQuery; + private static boolean _xdkAvailable = true; // at the beginning assume is available + + private static HashMap _xqrlQueryCache = new HashMap(); //todo check for memory leaks + private static Method _xqrlCompileQuery; + private static boolean _xqrlAvailable = true; // at the beginning assume is available + + private static HashMap _xqrl2002QueryCache = new HashMap(); + private static Method _xqrl2002CompileQuery; + private static boolean _xqrl2002Available = true; // at the beginning assume is available + + static + { + ClassLoader cl = Query.class.getClassLoader(); + String id = "META-INF/services/org.apache.xmlbeans.impl.store.QueryDelegate.QueryInterface"; + InputStream in = cl.getResourceAsStream(id); + try + { + BufferedReader br = new BufferedReader(new InputStreamReader(in)); + _delIntfName = br.readLine().trim(); + br.close(); + } + catch (Exception e) + { + _delIntfName = null; + } + } + + abstract XmlObject[] objectExecute(Cur c, XmlOptions options); + + abstract XmlCursor cursorExecute(Cur c, XmlOptions options); + + // + // Xqrl store specific implementation of compiled path/query + // + + static XmlObject[] objectExecQuery(Cur c, String queryExpr, XmlOptions options) + { + return getCompiledQuery(queryExpr, options).objectExecute(c, options); + } + + static XmlCursor cursorExecQuery(Cur c, String queryExpr, XmlOptions options) + { + return getCompiledQuery(queryExpr, options).cursorExecute(c, options); + } + + public static synchronized Query getCompiledQuery(String queryExpr, XmlOptions options) + { + return getCompiledQuery(queryExpr, Path.getCurrentNodeVar(options), options); + } + + static synchronized Query getCompiledQuery(String queryExpr, String currentVar, XmlOptions options) + { + assert queryExpr != null; + options = XmlOptions.maskNull(options); + Query query; + + if (options.hasOption(Path._forceXqrl2002ForXpathXQuery)) + { + query = (Query)_xqrl2002QueryCache.get(queryExpr); + if (query!=null) + return query; + + query = getXqrl2002CompiledQuery(queryExpr, currentVar); + if (query!=null) + { + _xqrl2002QueryCache.put(queryExpr, query); + return query; + } + throw new RuntimeException("No 2002 query engine found."); + } + + //Parse the query via XBeans: need to figure out end of prolog + //in order to bind $this...not good but... + Map boundary = new HashMap(); + int boundaryVal = 0; + try + { + XPath.compileXPath(queryExpr, currentVar, boundary); + } + catch (XPath.XPathCompileException e) + { + //don't care if it fails, just care about boundary + } + finally + { + boundaryVal = boundary.get(XPath._NS_BOUNDARY) == null ? 0 : + ((Integer) boundary.get(XPath._NS_BOUNDARY)).intValue(); + } + + if (options.hasOption(_useXdkForXQuery)) + { + //try XDK + query = (Query) _xdkQueryCache.get(queryExpr); + if (query != null) + return query; + + query = createXdkCompiledQuery(queryExpr, currentVar); + if (query != null) + { + _xdkQueryCache.put(queryExpr, query); + return query; + } + } + + if (!options.hasOption(_useDelegateForXQuery)) + { + //try XQRL + query = (Query) _xqrlQueryCache.get(queryExpr); + if (query != null) + return query; + + query = createXqrlCompiledQuery(queryExpr, currentVar); + if (query != null) + { + _xqrlQueryCache.put(queryExpr, query); + return query; + } + } + + //otherwise (if _useDelegateForXQuery option is set), + //or if xqrl is not found, try delegate + //query = (Query) _delegateQueryCache.get(queryExpr); + + //if (query != null) + // return query; + + String delIntfName = + options.hasOption(QUERY_DELEGATE_INTERFACE) ? + (String)options.get(QUERY_DELEGATE_INTERFACE) : _delIntfName; + query = DelegateQueryImpl.createDelegateCompiledQuery(delIntfName, queryExpr, currentVar, boundaryVal); + + if (query != null) + { + //_delegateQueryCache.put(queryExpr, query); + return query; + } + + throw new RuntimeException("No query engine found"); + } + + public static synchronized String compileQuery(String queryExpr, XmlOptions options) + { + getCompiledQuery(queryExpr, options); + return queryExpr; + } + + private static Query createXdkCompiledQuery(String queryExpr, String currentVar) + { + //if the XDK engine has been determined unavailable, return null + if ( !_xdkAvailable ) return null; + if ( _xdkCompileQuery == null) + { + try + { + Class xdkImpl = Class.forName("org.apache.xmlbeans.impl.store.OXQXBXqrlImpl"); + + _xdkCompileQuery = + xdkImpl.getDeclaredMethod("compileQuery", + new Class[]{String.class, String.class, Boolean.class}); + } + catch (ClassNotFoundException e) + { + _xdkAvailable = false; + return null; + } + catch (Exception e) + { + _xdkAvailable = false; + throw new RuntimeException(e.getMessage(), e); + } + } + + Object[] args = new Object[]{queryExpr, currentVar, new Boolean(true)}; + + try + { + return (Query) _xdkCompileQuery.invoke(null, args); + } + catch (InvocationTargetException e) + { + Throwable t = e.getCause(); + throw new RuntimeException(t.getMessage(), t); + } + catch (IllegalAccessException e) + { + throw new RuntimeException(e.getMessage(), e); + } + } + + private static Query createXqrlCompiledQuery(String queryExpr, String currentVar) + { + //if the XQRL engine has been determined unavailable, return null + if ( !_xqrlAvailable ) return null; + if ( _xqrlCompileQuery == null) + { + try + { + Class xqrlImpl = Class.forName("org.apache.xmlbeans.impl.store.XqrlImpl"); + + _xqrlCompileQuery = + xqrlImpl.getDeclaredMethod("compileQuery", + new Class[]{String.class, String.class, Boolean.class}); + } + catch (ClassNotFoundException e) + { + _xqrlAvailable = false; + return null; + } + catch (Exception e) + { + _xqrlAvailable = false; + throw new RuntimeException(e.getMessage(), e); + } + } + + Object[] args = new Object[]{queryExpr, currentVar, new Boolean(true)}; + + try + { + return (Query) _xqrlCompileQuery.invoke(null, args); + } + catch (InvocationTargetException e) + { + Throwable t = e.getCause(); + throw new RuntimeException(t.getMessage(), t); + } + catch (IllegalAccessException e) + { + throw new RuntimeException(e.getMessage(), e); + } + } + + private static Query getXqrl2002CompiledQuery(String queryExpr, String currentVar) + { + if (_xqrl2002Available && _xqrl2002CompileQuery == null) + { + try + { + Class xqrlImpl = Class.forName("org.apache.xmlbeans.impl.store.Xqrl2002Impl"); + + _xqrl2002CompileQuery = + xqrlImpl.getDeclaredMethod("compileQuery", + new Class[]{String.class, String.class, Boolean.class}); + } + catch (ClassNotFoundException e) + { + _xqrl2002Available = false; + return null; + } + catch (Exception e) + { + _xqrl2002Available = false; + throw new RuntimeException(e.getMessage(), e); + } + } + + Object[] args = new Object[]{queryExpr, currentVar, new Boolean(true)}; + + try + { + return (Query) _xqrl2002CompileQuery.invoke(null, args); + } + catch (InvocationTargetException e) + { + Throwable t = e.getCause(); + throw new RuntimeException(t.getMessage(), t); + } + catch (IllegalAccessException e) + { + throw new RuntimeException(e.getMessage(), e); + } + } + + private static final class DelegateQueryImpl extends Query + { + private DelegateQueryImpl(QueryDelegate.QueryInterface xqueryImpl) + { + _xqueryImpl = xqueryImpl; + } + + public static Query createDelegateCompiledQuery(String delIntfName, + String queryExpr, + String currentVar, + int boundary) + { + assert !(currentVar.startsWith(".") || currentVar.startsWith("..")); + QueryDelegate.QueryInterface impl = + QueryDelegate.createInstance(delIntfName, queryExpr, + currentVar, boundary); + if (impl == null) + return null; + + return new DelegateQueryImpl(impl); + } + + XmlObject[] objectExecute(Cur c, XmlOptions options) + { + return new DelegateQueryEngine(_xqueryImpl, c, options).objectExecute(); + } + + XmlCursor cursorExecute(Cur c, XmlOptions options) + { + return new DelegateQueryEngine(_xqueryImpl, c, options).cursorExecute(); + } + + + private static class DelegateQueryEngine + { + public DelegateQueryEngine(QueryDelegate.QueryInterface xqImpl, + Cur c, XmlOptions opt) + { + + _engine = xqImpl; + _version = c._locale.version(); + _cur = c.weakCur(this); + _options = opt; + + } + + public XmlObject[] objectExecute() + { + if (_cur != null && _version != _cur._locale.version()) + //throw new ConcurrentModificationException + // ("Document changed during select") + ; + + Map bindings = (Map) XmlOptions.maskNull(_options). + get(XmlOptions.XQUERY_VARIABLE_MAP); + List resultsList; + resultsList = _engine.execQuery(_cur.getDom(), bindings); + + assert resultsList.size() > -1; + + XmlObject[] result = new XmlObject[resultsList.size()]; + int i; + for (i = 0; i < resultsList.size(); i++) { + //copy objects into the locale + Locale l = Locale.getLocale(_cur._locale._schemaTypeLoader, + _options); + + l.enter(); + Object node = resultsList.get(i); + Cur res = null; + try { + //typed function results of XQuery + if (!(node instanceof Node)) { + //TODO: exact same code as Path.java + //make a common super-class and pull this--what to name that + //superclass??? + res = l.load("").tempCur(); + res.setValue(node.toString()); + SchemaType type=getType(node); + Locale.autoTypeDocument(res, type, null); + result[i] = res.getObject(); + } + else + res = loadNode(l, (Node) node); + result[i] = res.getObject(); + } + catch (XmlException e) { + throw new RuntimeException(e); + } + finally { + l.exit(); + } + res.release(); + } + release(); + _engine = null; + return result; + } + private SchemaType getType(Object node) + { + SchemaType type; + if (node instanceof Integer) + type = XmlInteger.type; + else if (node instanceof Double) + type = XmlDouble.type; + else if (node instanceof Long) + type = XmlLong.type; + else if (node instanceof Float) + type = XmlFloat.type; + else if (node instanceof BigDecimal) + type = XmlDecimal.type; + else if (node instanceof Boolean) + type = XmlBoolean.type; + else if (node instanceof String) + type = XmlString.type; + else if (node instanceof Date) + type = XmlDate.type; + else + type = XmlAnySimpleType.type; + return type; + } + public XmlCursor cursorExecute() + { + if (_cur != null && _version != _cur._locale.version()) + //throw new ConcurrentModificationException + // ("Document changed during select") + ; + + Map bindings = (Map) XmlOptions.maskNull(_options). + get(XmlOptions.XQUERY_VARIABLE_MAP); + List resultsList; + resultsList = _engine.execQuery(_cur.getDom(), bindings); + + assert resultsList.size() > -1; + + int i; + _engine = null; + + Locale locale = Locale.getLocale(_cur._locale._schemaTypeLoader, _options); + locale.enter(); + Locale.LoadContext _context = new Cur.CurLoadContext(locale, _options); + Cursor resultCur = null; + try { + for (i = 0; i < resultsList.size(); i++) { + loadNodeHelper(locale, (Node) resultsList.get(i), _context); + } + Cur c = _context.finish(); + Locale.associateSourceName(c, _options); + Locale.autoTypeDocument(c, null, _options); + resultCur = new Cursor(c); + } + catch (Exception e) { + } + finally { + locale.exit(); + } + release(); + return resultCur; + } + + + public void release() + { + if (_cur != null) { + _cur.release(); + _cur = null; + } + } + + + private Cur loadNode(Locale locale, Node node) + { + Locale.LoadContext context = new Cur.CurLoadContext(locale, _options); + + try { + loadNodeHelper(locale, node, context); + Cur c = context.finish(); + Locale.associateSourceName(c, _options); + Locale.autoTypeDocument(c, null, _options); + return c; + } + catch (Exception e) { + throw new XmlRuntimeException(e.getMessage(), e); + } + } + + private void loadNodeHelper(Locale locale, Node node, Locale.LoadContext context) + { + if (node.getNodeType() == Node.ATTRIBUTE_NODE) { + QName attName = new QName(node.getNamespaceURI(), + node.getLocalName(), + node.getPrefix()); + context.attr(attName, node.getNodeValue()); + } + else + locale.loadNode(node, context); + + } + + + private Cur _cur; + private QueryDelegate.QueryInterface _engine; + private long _version; + private XmlOptions _options; + } + + private QueryDelegate.QueryInterface _xqueryImpl; + } + +} diff --git a/xmlbeans/src/store/org/apache/xmlbeans/impl/store/QueryDelegate.java b/xmlbeans/src/store/org/apache/xmlbeans/impl/store/QueryDelegate.java new file mode 100644 index 000000000..8032a061b --- /dev/null +++ b/xmlbeans/src/store/org/apache/xmlbeans/impl/store/QueryDelegate.java @@ -0,0 +1,89 @@ +/* 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.store; + +import java.util.List; +import java.util.Map; +import java.util.HashMap; +import java.lang.reflect.Constructor; + +public final class QueryDelegate +{ + private static HashMap _constructors = new HashMap(); + + private QueryDelegate() + {} + + private static synchronized void init(String implClassName) + { + // default to Saxon + if (implClassName == null) + implClassName = "org.apache.xmlbeans.impl.xquery.saxon.XBeansXQuery"; + Class queryInterfaceImpl = null; + boolean engineAvailable = true; + try + { + queryInterfaceImpl = Class.forName(implClassName); + } + catch (ClassNotFoundException e) + { + engineAvailable = false; + } + catch (NoClassDefFoundError e) + { + engineAvailable = false; + } + + if (engineAvailable) + { + try + { + Constructor constructor = queryInterfaceImpl.getConstructor( + new Class[] {String.class, String.class, Integer.class}); + _constructors.put(implClassName, constructor); + } + catch (Exception e) + { + throw new RuntimeException(e); + } + } + } + + public static synchronized QueryInterface createInstance(String implClassName, + String query, String contextVar, int boundary) + { + if (_constructors.get(implClassName) == null) + init(implClassName); + + if (_constructors.get(implClassName) == null) + return null; + + Constructor constructor = (Constructor)_constructors.get(implClassName); + try + { + return (QueryInterface)constructor.newInstance( + new Object[] {query, contextVar, new Integer(boundary)}); + } + catch (Exception e) + { + throw new RuntimeException(e); + } + } + + public static interface QueryInterface + { + public List execQuery(Object node, Map variableBindings); + } +} diff --git a/xmlbeans/src/store/org/apache/xmlbeans/impl/store/Saaj.java b/xmlbeans/src/store/org/apache/xmlbeans/impl/store/Saaj.java new file mode 100755 index 000000000..a87956791 --- /dev/null +++ b/xmlbeans/src/store/org/apache/xmlbeans/impl/store/Saaj.java @@ -0,0 +1,150 @@ +/* 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.store; + +import javax.xml.namespace.QName; + +import java.util.Iterator; +import java.util.Locale; + + +import javax.xml.transform.Source; + +import org.apache.xmlbeans.impl.soap.Detail; +import org.apache.xmlbeans.impl.soap.DetailEntry; +import org.apache.xmlbeans.impl.soap.MimeHeaders; +import org.apache.xmlbeans.impl.soap.Name; +import org.apache.xmlbeans.impl.soap.SOAPBody; +import org.apache.xmlbeans.impl.soap.SOAPBodyElement; +import org.apache.xmlbeans.impl.soap.SOAPElement; +import org.apache.xmlbeans.impl.soap.SOAPEnvelope; +import org.apache.xmlbeans.impl.soap.SOAPException; +import org.apache.xmlbeans.impl.soap.SOAPFactory; +import org.apache.xmlbeans.impl.soap.SOAPFault; +import org.apache.xmlbeans.impl.soap.SOAPHeader; +import org.apache.xmlbeans.impl.soap.SOAPHeaderElement; +import org.apache.xmlbeans.impl.soap.SOAPPart; +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.Element; +import org.w3c.dom.Text; + +public interface Saaj +{ + // Use in XmlOptions to enable SAAJ support in store + + public static final String SAAJ_IMPL = "SAAJ_IMPL"; + + public interface SaajCallback + { + void setSaajData ( Node n, Object o ); + Object getSaajData ( Node n ); + + Element createSoapElement ( QName name, QName parentName ); + + Element importSoapElement ( Document doc, Element elem, boolean deep, QName parentName ); + } + + void setCallback ( SaajCallback callback ); + + Class identifyElement ( QName name, QName parentName ); + + void soapNode_detachNode ( org.apache.xmlbeans.impl.soap.Node soapNode ); + void soapNode_recycleNode ( org.apache.xmlbeans.impl.soap.Node node ); + String soapNode_getValue ( org.apache.xmlbeans.impl.soap.Node node ); + void soapNode_setValue ( org.apache.xmlbeans.impl.soap.Node node, String value ); + SOAPElement soapNode_getParentElement ( org.apache.xmlbeans.impl.soap.Node node ); + void soapNode_setParentElement ( org.apache.xmlbeans.impl.soap.Node node, SOAPElement soapElement ); + + void soapElement_removeContents ( SOAPElement soapElement ); + String soapElement_getEncodingStyle ( SOAPElement soapElement ); + void soapElement_setEncodingStyle ( SOAPElement soapElement, String encodingStyle ); + boolean soapElement_removeNamespaceDeclaration ( SOAPElement soapElement, String prefix ); + Iterator soapElement_getAllAttributes ( SOAPElement soapElement ); + Iterator soapElement_getChildElements ( SOAPElement parent ); + Iterator soapElement_getNamespacePrefixes ( SOAPElement soapElement ); + SOAPElement soapElement_addAttribute ( SOAPElement soapElement, Name name, String value ) throws SOAPException; + SOAPElement soapElement_addChildElement ( SOAPElement parent, SOAPElement oldChild ) throws SOAPException; + SOAPElement soapElement_addChildElement ( SOAPElement soapElement, Name name ) throws SOAPException; + SOAPElement soapElement_addChildElement ( SOAPElement soapElement, String localName ) throws SOAPException; + SOAPElement soapElement_addChildElement ( SOAPElement soapElement, String localName, String prefix ) throws SOAPException; + SOAPElement soapElement_addChildElement ( SOAPElement soapElement, String localName, String prefix, String uri ) throws SOAPException; + SOAPElement soapElement_addNamespaceDeclaration ( SOAPElement soapElement, String prefix, String uri ); + SOAPElement soapElement_addTextNode ( SOAPElement soapElement, String data ); + String soapElement_getAttributeValue ( SOAPElement soapElement, Name name ); + Iterator soapElement_getChildElements ( SOAPElement parent, Name name ); + Name soapElement_getElementName ( SOAPElement soapElement ); + String soapElement_getNamespaceURI ( SOAPElement soapElement, String prefix ); + Iterator soapElement_getVisibleNamespacePrefixes ( SOAPElement soapElement ); + boolean soapElement_removeAttribute ( SOAPElement soapElement, Name name ); + + SOAPBody soapEnvelope_addBody ( SOAPEnvelope soapEnvelope ) throws SOAPException; + SOAPBody soapEnvelope_getBody ( SOAPEnvelope soapEnvelope ) throws SOAPException; + SOAPHeader soapEnvelope_getHeader ( SOAPEnvelope soapEnvelope ) throws SOAPException; + SOAPHeader soapEnvelope_addHeader ( SOAPEnvelope soapEnvelope ) throws SOAPException; + Name soapEnvelope_createName ( SOAPEnvelope soapEnvelope, String localName ); + Name soapEnvelope_createName ( SOAPEnvelope soapEnvelope, String localName, String prefix, String namespaceURI ); + + Iterator soapHeader_examineAllHeaderElements ( SOAPHeader soapHeader ); + Iterator soapHeader_extractAllHeaderElements ( SOAPHeader soapHeader ); + Iterator soapHeader_examineHeaderElements ( SOAPHeader soapHeader, String actor ); + Iterator soapHeader_examineMustUnderstandHeaderElements ( SOAPHeader soapHeader, String mustUnderstandString ); + Iterator soapHeader_extractHeaderElements ( SOAPHeader soapHeader, String actor ); + SOAPHeaderElement soapHeader_addHeaderElement ( SOAPHeader soapHeader, Name name ); + + void soapPart_removeAllMimeHeaders ( SOAPPart soapPart ); + void soapPart_removeMimeHeader ( SOAPPart soapPart, String name ); + Iterator soapPart_getAllMimeHeaders ( SOAPPart soapPart ); + SOAPEnvelope soapPart_getEnvelope ( SOAPPart soapPart ); + Source soapPart_getContent ( SOAPPart soapPart ); + void soapPart_setContent ( SOAPPart soapPart, Source source ); + String[] soapPart_getMimeHeader ( SOAPPart soapPart, String name ); + void soapPart_addMimeHeader ( SOAPPart soapPart, String name, String value ); + void soapPart_setMimeHeader ( SOAPPart soapPart, String name, String value ); + Iterator soapPart_getMatchingMimeHeaders ( SOAPPart soapPart, String[] names ); + Iterator soapPart_getNonMatchingMimeHeaders ( SOAPPart soapPart, String[] names ); + + boolean soapBody_hasFault ( SOAPBody soapBody ); + SOAPFault soapBody_addFault ( SOAPBody soapBody ) throws SOAPException; + SOAPFault soapBody_getFault ( SOAPBody soapBody ); + SOAPBodyElement soapBody_addBodyElement ( SOAPBody soapBody, Name name ); + SOAPBodyElement soapBody_addDocument ( SOAPBody soapBody, Document document ); + SOAPFault soapBody_addFault ( SOAPBody soapBody, Name name, String s ) throws SOAPException; + SOAPFault soapBody_addFault ( SOAPBody soapBody, Name faultCode, String faultString, Locale locale ) throws SOAPException; + + Detail soapFault_addDetail ( SOAPFault soapFault ) throws SOAPException; + Detail soapFault_getDetail ( SOAPFault soapFault ); + String soapFault_getFaultActor ( SOAPFault soapFault ); + String soapFault_getFaultCode ( SOAPFault soapFault ); + Name soapFault_getFaultCodeAsName ( SOAPFault soapFault ); + String soapFault_getFaultString ( SOAPFault soapFault ); + Locale soapFault_getFaultStringLocale ( SOAPFault soapFault ); + void soapFault_setFaultActor ( SOAPFault soapFault, String faultActorString ); + void soapFault_setFaultCode ( SOAPFault soapFault, Name faultCodeName ) throws SOAPException; + void soapFault_setFaultCode ( SOAPFault soapFault, String faultCode ) throws SOAPException; + void soapFault_setFaultString ( SOAPFault soapFault, String faultString ); + void soapFault_setFaultString ( SOAPFault soapFault, String faultString, Locale locale ); + + void soapHeaderElement_setMustUnderstand ( SOAPHeaderElement soapHeaderElement, boolean mustUnderstand ); + boolean soapHeaderElement_getMustUnderstand ( SOAPHeaderElement soapHeaderElement ); + void soapHeaderElement_setActor ( SOAPHeaderElement soapHeaderElement, String actor ); + String soapHeaderElement_getActor ( SOAPHeaderElement soapHeaderElement ); + + boolean soapText_isComment ( org.apache.xmlbeans.impl.soap.Text text ); + + DetailEntry detail_addDetailEntry ( Detail detail, Name name ); + Iterator detail_getDetailEntries ( Detail detail ); +} \ No newline at end of file diff --git a/xmlbeans/src/store/org/apache/xmlbeans/impl/store/Saver.java b/xmlbeans/src/store/org/apache/xmlbeans/impl/store/Saver.java new file mode 100755 index 000000000..1344aaacf --- /dev/null +++ b/xmlbeans/src/store/org/apache/xmlbeans/impl/store/Saver.java @@ -0,0 +1,4432 @@ +/* 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.store; + +import javax.xml.namespace.QName; + +import org.apache.xmlbeans.SystemProperties; +import org.apache.xmlbeans.XmlDocumentProperties; +import org.apache.xmlbeans.XmlOptions; +import org.apache.xmlbeans.XmlOptionCharEscapeMap; +import org.apache.xmlbeans.xml.stream.*; + +import org.apache.xmlbeans.impl.common.*; + +import java.io.Writer; +import java.io.Reader; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.UnsupportedEncodingException; + +import org.xml.sax.ContentHandler; +import org.xml.sax.ext.LexicalHandler; +import org.xml.sax.SAXException; + +import org.xml.sax.helpers.AttributesImpl; + +import java.util.Iterator; +import java.util.ArrayList; +import java.util.List; +import java.util.HashMap; +import java.util.Map; +import java.util.LinkedHashMap; +import java.util.ConcurrentModificationException; + +abstract class Saver +{ + static final int ROOT = Cur.ROOT; + static final int ELEM = Cur.ELEM; + static final int ATTR = Cur.ATTR; + static final int COMMENT = Cur.COMMENT; + static final int PROCINST = Cur.PROCINST; + static final int TEXT = Cur.TEXT; + + protected abstract boolean emitElement ( SaveCur c, ArrayList attrNames, ArrayList attrValues ); + protected abstract void emitFinish ( SaveCur c ); + protected abstract void emitText ( SaveCur c ); + protected abstract void emitComment ( SaveCur c ); + protected abstract void emitProcinst ( SaveCur c ); + protected abstract void emitDocType ( String docTypeName, String publicId, String systemId ); + protected abstract void emitStartDoc ( SaveCur c ); + protected abstract void emitEndDoc ( SaveCur c ); + + protected void syntheticNamespace ( String prefix, String uri, boolean considerDefault ) { } + + Saver ( Cur c, XmlOptions options ) + { + assert c._locale.entered(); + + options = XmlOptions.maskNull( options ); + + _cur = createSaveCur( c, options ); + + _locale = c._locale; + _version = _locale.version(); + + _namespaceStack = new ArrayList(); + _uriMap = new HashMap(); + _prefixMap = new HashMap(); + + _attrNames = new ArrayList(); + _attrValues = new ArrayList (); + + // Define implicit xml prefixed namespace + + addMapping( "xml", Locale._xml1998Uri ); + + if (options.hasOption( XmlOptions.SAVE_IMPLICIT_NAMESPACES )) + { + Map m = (Map) options.get( XmlOptions.SAVE_IMPLICIT_NAMESPACES ); + + for ( Iterator i = m.keySet().iterator() ; i.hasNext() ; ) + { + String prefix = (String) i.next(); + addMapping( prefix, (String) m.get( prefix ) ); + } + } + + // define character map for escaped replacements + if (options.hasOption( XmlOptions.SAVE_SUBSTITUTE_CHARACTERS )) + { + _replaceChar = (XmlOptionCharEscapeMap) + options.get( XmlOptions.SAVE_SUBSTITUTE_CHARACTERS); + } + + // If the default prefix has not been mapped, do so now + + if (getNamespaceForPrefix( "" ) == null) + { + _initialDefaultUri = new String( "" ); + addMapping( "", _initialDefaultUri ); + } + + if (options.hasOption( XmlOptions.SAVE_AGGRESSIVE_NAMESPACES ) && + !(this instanceof SynthNamespaceSaver)) + { + SynthNamespaceSaver saver = new SynthNamespaceSaver( c, options ); + + while ( saver.process() ) + ; + + if (!saver._synthNamespaces.isEmpty()) + _preComputedNamespaces = saver._synthNamespaces; + } + + _useDefaultNamespace = + options.hasOption( XmlOptions.SAVE_USE_DEFAULT_NAMESPACE ); + + _saveNamespacesFirst = options.hasOption( XmlOptions.SAVE_NAMESPACES_FIRST ); + + if (options.hasOption( XmlOptions.SAVE_SUGGESTED_PREFIXES )) + _suggestedPrefixes = (Map) options.get( XmlOptions.SAVE_SUGGESTED_PREFIXES); + + _ancestorNamespaces = _cur.getAncestorNamespaces(); + } + + private static SaveCur createSaveCur ( Cur c, XmlOptions options ) + { + QName synthName = (QName) options.get( XmlOptions.SAVE_SYNTHETIC_DOCUMENT_ELEMENT ); + + QName fragName = synthName; + + if (fragName == null) + { + fragName = + options.hasOption( XmlOptions.SAVE_USE_OPEN_FRAGMENT ) + ? Locale._openuriFragment + : Locale._xmlFragment; + } + + boolean saveInner = + options.hasOption( XmlOptions.SAVE_INNER ) && + !options.hasOption( XmlOptions.SAVE_OUTER ); + + Cur start = c.tempCur(); + Cur end = c.tempCur(); + + SaveCur cur = null; + + int k = c.kind(); + + switch ( k ) + { + case ROOT : + { + positionToInner( c, start, end ); + + if (Locale.isFragment( start, end )) + cur = new FragSaveCur( start, end, fragName ); + else if (synthName != null) + cur = new FragSaveCur( start, end, synthName ); + else + cur = new DocSaveCur( c ); + + break; + } + + case ELEM : + { + if (saveInner) + { + positionToInner( c, start, end ); + + cur = + new FragSaveCur( + start, end, Locale.isFragment( start, end ) ? fragName : synthName ); + } + else if (synthName != null) + { + positionToInner( c, start, end ); + + cur = new FragSaveCur( start, end, synthName ); + } + else + { + start.moveToCur( c ); + end.moveToCur( c ); + end.skip(); + + cur = new FragSaveCur( start, end, null ); + } + + break; + } + } + + if (cur == null) + { + assert k < 0 || k == ATTR || k == COMMENT || k == PROCINST || k == TEXT; + + if (k < 0) + { + // Save out "" + start.moveToCur( c ); + end.moveToCur( c ); + } + else if (k == TEXT) + { + start.moveToCur( c ); + end.moveToCur( c ); + end.next(); + } + else if (saveInner) + { + start.moveToCur( c ); + start.next(); + + end.moveToCur( c ); + end.toEnd(); + } + else if (k == ATTR) + { + start.moveToCur( c ); + end.moveToCur( c ); + } + else + { + assert k == COMMENT || k == PROCINST; + + start.moveToCur( c ); + end.moveToCur( c ); + end.skip(); + } + + cur = new FragSaveCur( start, end, fragName ); + } + + String filterPI = (String) options.get( XmlOptions.SAVE_FILTER_PROCINST ); + + if (filterPI != null) + cur = new FilterPiSaveCur( cur, filterPI ); + + if (options.hasOption( XmlOptions.SAVE_PRETTY_PRINT )) + cur = new PrettySaveCur( cur, options ); + + start.release(); + end.release(); + + return cur; + } + + private static void positionToInner ( Cur c, Cur start, Cur end ) + { + assert c.isContainer(); + + start.moveToCur( c ); + + if (!start.toFirstAttr()) + start.next(); + + end.moveToCur( c ); + end.toEnd(); + } + + protected boolean saveNamespacesFirst ( ) + { + return _saveNamespacesFirst; + } + + protected void enterLocale() + { + _locale.enter(); + } + + protected void exitLocale() + { + _locale.exit(); + } + + protected final boolean process ( ) + { + assert _locale.entered(); + + if (_cur == null) + return false; + + if (_version != _locale.version()) + throw new ConcurrentModificationException( "Document changed during save" ); + + switch ( _cur.kind() ) + { + case ROOT : { processRoot(); break; } + case ELEM : { processElement(); break; } + case - ELEM : { processFinish (); break; } + case TEXT : { emitText ( _cur ); break; } + + case COMMENT : { emitComment ( _cur ); _cur.toEnd(); break; } + case PROCINST : { emitProcinst ( _cur ); _cur.toEnd(); break; } + + case - ROOT : + { + emitEndDoc(_cur); + _cur.release(); + _cur = null; + + return true; + } + + default : throw new RuntimeException( "Unexpected kind" ); + } + + _cur.next(); + + return true; + } + + private final void processFinish ( ) + { + emitFinish( _cur ); + popMappings(); + } + + private final void processRoot ( ) + { + assert _cur.isRoot(); + + XmlDocumentProperties props = _cur.getDocProps(); + String systemId = null; + String docTypeName = null; + if (props != null) + { + systemId = props.getDoctypeSystemId(); + docTypeName = props.getDoctypeName(); + } + + if (systemId != null || docTypeName != null) + { + if (docTypeName == null) + { + _cur.push(); + while (!_cur.isElem() && _cur.next()) + ; + if (_cur.isElem()) + docTypeName = _cur.getName().getLocalPart(); + _cur.pop(); + } + + String publicId = props.getDoctypePublicId(); + + if (docTypeName != null) + { + QName rootElemName = _cur.getName(); + + if ( rootElemName == null ) + { + _cur.push(); + while ( !_cur.isFinish() ) + { + if (_cur.isElem()) + { + rootElemName = _cur.getName(); + break; + } + _cur.next(); + } + _cur.pop(); + } + + if ( rootElemName!=null && docTypeName.equals(rootElemName.getLocalPart()) ) + { + emitDocType( docTypeName, publicId, systemId ); + return; + } + } + } + + emitStartDoc(_cur); + } + + private final void processElement ( ) + { + assert _cur.isElem() && _cur.getName() != null; + + QName name = _cur.getName(); + + // Add a new entry to the frontier. If this element has a name + // which has no namespace, then we must make sure that pushing + // the mappings causes the default namespace to be empty + + boolean ensureDefaultEmpty = name.getNamespaceURI().length() == 0; + + pushMappings( _cur, ensureDefaultEmpty ); + + // + // There are four things which use mappings: + // + // 1) The element name + // 2) The element value (qname based) + // 3) Attribute names + // 4) The attribute values (qname based) + // + + // 1) The element name (not for starts) + + ensureMapping( name.getNamespaceURI(), name.getPrefix(), !ensureDefaultEmpty, false ); + + // + // + // + + _attrNames.clear(); + _attrValues.clear(); + + _cur.push(); + + attrs: + for ( boolean A = _cur.toFirstAttr() ; A ; A = _cur.toNextAttr() ) + { + if (_cur.isNormalAttr()) + { + QName attrName = _cur.getName(); + + _attrNames.add( attrName ); + + for ( int i = _attrNames.size() - 2 ; i >= 0 ; i-- ) + { + if (_attrNames.get( i ).equals( attrName )) + { + _attrNames.remove( _attrNames.size() - 1 ); + continue attrs; + } + } + + _attrValues.add( _cur.getAttrValue() ); + + ensureMapping( attrName.getNamespaceURI(), attrName.getPrefix(), false, true ); + } + } + + _cur.pop(); + + // If I am doing aggressive namespaces and we're emitting a + // container which can contain content, add the namespaces + // we've computed. Basically, I'm making sure the pre-computed + // namespaces are mapped on the first container which has a name. + + if (_preComputedNamespaces != null) + { + for ( Iterator i = _preComputedNamespaces.keySet().iterator() ; i.hasNext() ; ) + { + String uri = (String) i.next(); + String prefix = (String) _preComputedNamespaces.get( uri ); + boolean considerDefault = prefix.length() == 0 && !ensureDefaultEmpty; + + ensureMapping( uri, prefix, considerDefault, false ); + } + + // Set to null so we do this once at the top + _preComputedNamespaces = null; + } + + if (emitElement( _cur, _attrNames, _attrValues )) + { + popMappings(); + _cur.toEnd(); + } + } + + // + // Layout of namespace stack: + // + // URI Undo + // URI Rename + // Prefix Undo + // Mapping + // + + boolean hasMappings ( ) + { + int i = _namespaceStack.size(); + + return i > 0 && _namespaceStack.get( i - 1 ) != null; + } + + void iterateMappings ( ) + { + _currentMapping = _namespaceStack.size(); + + while ( _currentMapping > 0 && _namespaceStack.get( _currentMapping - 1 ) != null ) + _currentMapping -= 8; + } + + boolean hasMapping ( ) + { + return _currentMapping < _namespaceStack.size(); + } + + void nextMapping ( ) + { + _currentMapping += 8; + } + + String mappingPrefix ( ) + { + assert hasMapping(); + return (String) _namespaceStack.get( _currentMapping + 6 ); + } + + String mappingUri ( ) + { + assert hasMapping(); + return (String) _namespaceStack.get( _currentMapping + 7 ); + } + + private final void pushMappings ( SaveCur c, boolean ensureDefaultEmpty ) + { + assert c.isContainer(); + + _namespaceStack.add( null ); + + c.push(); + + namespaces: + for ( boolean A = c.toFirstAttr() ; A ; A = c.toNextAttr() ) + if (c.isXmlns()) + addNewFrameMapping( c.getXmlnsPrefix(), c.getXmlnsUri(), ensureDefaultEmpty ); + + c.pop(); + + if (_ancestorNamespaces != null) + { + for ( int i = 0 ; i < _ancestorNamespaces.size() ; i += 2 ) + { + String prefix = (String) _ancestorNamespaces.get( i ); + String uri = (String) _ancestorNamespaces.get( i + 1 ); + + addNewFrameMapping( prefix, uri, ensureDefaultEmpty ); + } + + _ancestorNamespaces = null; + } + + if (ensureDefaultEmpty) + { + String defaultUri = (String) _prefixMap.get( "" ); + + // I map the default to "" at the very beginning + assert defaultUri != null; + + if (defaultUri.length() > 0) + addMapping( "", "" ); + } + } + + private final void addNewFrameMapping ( String prefix, String uri, boolean ensureDefaultEmpty ) + { + // If the prefix maps to "", this don't include this mapping 'cause it's not well formed. + // Also, if we want to make sure that the default namespace is always "", then check that + // here as well. + + if ((prefix.length() == 0 || uri.length() > 0) && + (!ensureDefaultEmpty || prefix.length() > 0 || uri.length() == 0)) + { + // Make sure the prefix is not already mapped in this frame + + for ( iterateMappings() ; hasMapping() ; nextMapping() ) + if (mappingPrefix().equals( prefix )) + return; + + // Also make sure that the prefix declaration is not redundant + // This has the side-effect of making it impossible to set a + // redundant prefix declaration, but seems that it's better + // to just never issue a duplicate prefix declaration. + if (uri.equals(getNamespaceForPrefix(prefix))) + return; + + addMapping( prefix, uri ); + } + } + + private final void addMapping ( String prefix, String uri ) + { + assert uri != null; + assert prefix != null; + + // If the prefix being mapped here is already mapped to a uri, + // that uri will either go out of scope or be mapped to another + // prefix. + + String renameUri = (String) _prefixMap.get( prefix ); + String renamePrefix = null; + + if (renameUri != null) + { + // See if this prefix is already mapped to this uri. If + // so, then add to the stack, but there is nothing to rename + + if (renameUri.equals( uri )) + renameUri = null; + else + { + int i = _namespaceStack.size(); + + while ( i > 0 ) + { + if (_namespaceStack.get( i - 1 ) == null) + { + i--; + continue; + } + + if (_namespaceStack.get( i - 7 ).equals( renameUri )) + { + renamePrefix = (String) _namespaceStack.get( i - 8 ); + + if (renamePrefix == null || !renamePrefix.equals( prefix )) + break; + } + + i -= 8; + } + + assert i > 0; + } + } + + _namespaceStack.add( _uriMap.get( uri ) ); + _namespaceStack.add( uri ); + + if (renameUri != null) + { + _namespaceStack.add( _uriMap.get( renameUri ) ); + _namespaceStack.add( renameUri ); + } + else + { + _namespaceStack.add( null ); + _namespaceStack.add( null ); + } + + _namespaceStack.add( prefix ); + _namespaceStack.add( _prefixMap.get( prefix ) ); + + _namespaceStack.add( prefix ); + _namespaceStack.add( uri ); + + _uriMap.put( uri, prefix ); + _prefixMap.put( prefix, uri ); + + if (renameUri != null) + _uriMap.put( renameUri, renamePrefix ); + } + + private final void popMappings ( ) + { + for ( ; ; ) + { + int i = _namespaceStack.size(); + + if (i == 0) + break; + + if (_namespaceStack.get( i - 1 ) == null) + { + _namespaceStack.remove( i - 1 ); + break; + } + + Object oldUri = _namespaceStack.get( i - 7 ); + Object oldPrefix = _namespaceStack.get( i - 8 ); + + if (oldPrefix == null) + _uriMap.remove( oldUri ); + else + _uriMap.put( oldUri, oldPrefix ); + + oldPrefix = _namespaceStack.get( i - 4 ); + oldUri = _namespaceStack.get( i - 3 ); + + if (oldUri == null) + _prefixMap.remove( oldPrefix ); + else + _prefixMap.put( oldPrefix, oldUri ); + + String uri = (String) _namespaceStack.get( i - 5 ); + + if (uri != null) + _uriMap.put( uri, _namespaceStack.get( i - 6 ) ); + + // Hahahahahaha -- :-( + _namespaceStack.remove( i - 1 ); + _namespaceStack.remove( i - 2 ); + _namespaceStack.remove( i - 3 ); + _namespaceStack.remove( i - 4 ); + _namespaceStack.remove( i - 5 ); + _namespaceStack.remove( i - 6 ); + _namespaceStack.remove( i - 7 ); + _namespaceStack.remove( i - 8 ); + } + } + + private final void dumpMappings ( ) + { + for ( int i = _namespaceStack.size() ; i > 0 ; ) + { + if (_namespaceStack.get( i - 1 ) == null) + { + System.out.println( "----------------" ); + i--; + continue; + } + + System.out.print( "Mapping: " ); + System.out.print( _namespaceStack.get( i - 2 ) ); + System.out.print( " -> " ); + System.out.print( _namespaceStack.get( i - 1 ) ); + System.out.println(); + + System.out.print( "Prefix Undo: " ); + System.out.print( _namespaceStack.get( i - 4 ) ); + System.out.print( " -> " ); + System.out.print( _namespaceStack.get( i - 3 ) ); + System.out.println(); + + System.out.print( "Uri Rename: " ); + System.out.print( _namespaceStack.get( i - 5 ) ); + System.out.print( " -> " ); + System.out.print( _namespaceStack.get( i - 6 ) ); + System.out.println(); + + System.out.print( "UriUndo: " ); + System.out.print( _namespaceStack.get( i - 7 ) ); + System.out.print( " -> " ); + System.out.print( _namespaceStack.get( i - 8 ) ); + System.out.println(); + + System.out.println(); + + i -= 8; + } + } + + private final String ensureMapping ( + String uri, String candidatePrefix, + boolean considerCreatingDefault, boolean mustHavePrefix ) + { + assert uri != null; + + // Can be called for no-namespaced things + + if (uri.length() == 0) + return null; + + String prefix = (String) _uriMap.get( uri ); + + if (prefix != null && (prefix.length() > 0 || !mustHavePrefix)) + return prefix; + + // + // I try prefixes from a number of places, in order: + // + // 1) What was passed in + // 2) The optional suggestions (for uri's) + // 3) The default mapping is allowed + // 4) ns#++ + // + + if (candidatePrefix != null && candidatePrefix.length() == 0) + candidatePrefix = null; + + if (candidatePrefix == null || !tryPrefix( candidatePrefix )) + { + if (_suggestedPrefixes != null && + _suggestedPrefixes.containsKey( uri ) && + tryPrefix( (String) _suggestedPrefixes.get( uri ) )) + { + candidatePrefix = (String) _suggestedPrefixes.get( uri ); + } + else if (considerCreatingDefault && _useDefaultNamespace && tryPrefix( "" )) + candidatePrefix = ""; + else + { + String basePrefix = QNameHelper.suggestPrefix( uri ); + candidatePrefix = basePrefix; + + for ( int i = 1 ; ; i++ ) + { + if (tryPrefix( candidatePrefix )) + break; + + candidatePrefix = basePrefix + i; + } + } + } + + assert candidatePrefix != null; + + syntheticNamespace( candidatePrefix, uri, considerCreatingDefault ); + + addMapping( candidatePrefix, uri ); + + return candidatePrefix; + } + + protected final String getUriMapping ( String uri ) + { + assert _uriMap.get( uri ) != null; + return (String) _uriMap.get( uri ); + } + + String getNonDefaultUriMapping ( String uri ) + { + String prefix = (String) _uriMap.get( uri ); + + if (prefix != null && prefix.length() > 0) + return prefix; + + for ( Iterator keys = _prefixMap.keySet().iterator() ; keys.hasNext() ; ) + { + prefix = (String) keys.next(); + + if (prefix.length() > 0 && _prefixMap.get( prefix ).equals( uri )) + return prefix; + } + + assert false : "Could not find non-default mapping"; + + return null; + } + + private final boolean tryPrefix ( String prefix ) + { + if (prefix == null || Locale.beginsWithXml( prefix )) + return false; + + String existingUri = (String) _prefixMap.get( prefix ); + + // If the prefix is currently mapped, then try another prefix. A + // special case is that of trying to map the default prefix (""). + // Here, there always exists a default mapping. If this is the + // mapping we found, then remap it anyways. I use != to compare + // strings because I want to test for the specific initial default + // uri I added when I initialized the saver. + + if (existingUri != null && (prefix.length() > 0 || existingUri != _initialDefaultUri)) + return false; + + return true; + } + + public final String getNamespaceForPrefix ( String prefix ) + { + assert !prefix.equals( "xml" ) || _prefixMap.get( prefix ).equals( Locale._xml1998Uri ); + + return (String) _prefixMap.get( prefix ); + } + + protected Map getPrefixMap() + { + return _prefixMap; + } + + // + // + // + + static final class SynthNamespaceSaver extends Saver + { + LinkedHashMap _synthNamespaces = new LinkedHashMap(); + + SynthNamespaceSaver ( Cur c, XmlOptions options ) + { + super( c, options ); + } + + protected void syntheticNamespace ( + String prefix, String uri, boolean considerCreatingDefault ) + { + _synthNamespaces.put( uri, considerCreatingDefault ? "" : prefix ); + } + + protected boolean emitElement ( + SaveCur c, ArrayList attrNames, ArrayList attrValues ) { return false; } + + protected void emitFinish ( SaveCur c ) { } + protected void emitText ( SaveCur c ) { } + protected void emitComment ( SaveCur c ) { } + protected void emitProcinst ( SaveCur c ) { } + protected void emitDocType ( String docTypeName, String publicId, String systemId ) { } + protected void emitStartDoc ( SaveCur c ) { } + protected void emitEndDoc ( SaveCur c ) { } + } + + // + // + // + + static final class TextSaver extends Saver + { + TextSaver ( Cur c, XmlOptions options, String encoding ) + { + super( c, options ); + + boolean noSaveDecl = + options != null && options.hasOption( XmlOptions.SAVE_NO_XML_DECL ); + + if (options != null && options.hasOption(XmlOptions.SAVE_CDATA_LENGTH_THRESHOLD)) + _cdataLengthThreshold = ((Integer)options.get(XmlOptions.SAVE_CDATA_LENGTH_THRESHOLD)).intValue(); + + if (options != null && options.hasOption(XmlOptions.SAVE_CDATA_ENTITY_COUNT_THRESHOLD)) + _cdataEntityCountThreshold = ((Integer)options.get(XmlOptions.SAVE_CDATA_ENTITY_COUNT_THRESHOLD)).intValue(); + + if (options != null && options.hasOption(XmlOptions.LOAD_SAVE_CDATA_BOOKMARKS) ) + _useCDataBookmarks = true; + + if (options != null && options.hasOption(XmlOptions.SAVE_PRETTY_PRINT) ) + _isPrettyPrint = true; + + _in = _out = 0; + _free = 0; + + assert _buf==null || + (_out<_in && _free == _buf.length - ( _in - _out ) ) || // data in the middle, free on the edges + (_out>_in && _free == _out - _in ) || // data on the edges, free in the middle + (_out==_in && _free == _buf.length) || // no data, all buffer free + (_out==_in && _free == 0) // buffer full + : "_buf.length:" + _buf.length + " _in:" + _in + " _out:" + _out + " _free:" + _free; + + if (encoding != null && !noSaveDecl) + { + XmlDocumentProperties props = Locale.getDocProps( c, false ); + + String version = props == null ? null : props.getVersion(); + + if (version == null) + version = "1.0"; + + emit( "" + _newLine ); + } + } + + protected boolean emitElement ( SaveCur c, ArrayList attrNames, ArrayList attrValues ) + { + assert c.isElem(); + + emit( '<' ); + emitName( c.getName(), false ); + + if (saveNamespacesFirst()) + emitNamespacesHelper(); + + for ( int i = 0 ; i < attrNames.size() ; i++ ) + emitAttrHelper( (QName) attrNames.get( i ), (String) attrValues.get( i ) ); + + if (!saveNamespacesFirst()) + emitNamespacesHelper(); + + if (!c.hasChildren() && !c.hasText()) + { + emit( '/', '>' ); + return true; + } + else + { + emit( '>' ); + return false; + } + } + + protected void emitFinish ( SaveCur c ) + { + emit( '<', '/' ); + emitName( c.getName(), false ); + emit( '>' ); + } + + protected void emitXmlns ( String prefix, String uri ) + { + assert prefix != null; + assert uri != null; + + emit( "xmlns" ); + + if (prefix.length() > 0) + { + emit( ':' ); + emit( prefix ); + } + + emit( '=', '\"' ); + + // TODO - must encode uri properly + + emit( uri ); + entitizeAttrValue(false); + + emit( '"' ); + } + + private void emitNamespacesHelper ( ) + { + for ( iterateMappings() ; hasMapping() ; nextMapping() ) + { + emit( ' ' ); + emitXmlns( mappingPrefix(), mappingUri() ); + } + } + + private void emitAttrHelper ( QName attrName, String attrValue ) + { + emit( ' ' ); + emitName( attrName, true ); + emit( '=', '\"' ); + emit( attrValue ); + entitizeAttrValue(true); + emit( '"' ); + } + + protected void emitText ( SaveCur c ) + { + assert c.isText(); + + // c.isTextCData() is expensive do it only if useCDataBookmarks option is enabled + boolean forceCData = _useCDataBookmarks && c.isTextCData(); + + emit( c ); + + entitizeContent( forceCData ); + } + + protected void emitComment ( SaveCur c ) + { + assert c.isComment(); + + emit( "" ); + } + + protected void emitProcinst ( SaveCur c ) + { + assert c.isProcinst(); + + emit( "" ); + } + + private void emitLiteral ( String literal ) + { + // TODO: systemId production http://www.w3.org/TR/REC-xml/#NT-SystemLiteral + // TODO: publicId production http://www.w3.org/TR/REC-xml/#NT-PubidLiteral + if (literal.indexOf( "\"" ) < 0) + { + emit( '\"' ); + emit( literal ); + emit( '\"' ); + } + else + { + emit( '\'' ); + emit( literal ); + emit( '\'' ); + } + } + + protected void emitDocType ( String docTypeName, String publicId, String systemId ) + { + assert docTypeName != null; + + emit( "" ); + emit( _newLine ); + } + + protected void emitStartDoc ( SaveCur c ) + { + } + + protected void emitEndDoc ( SaveCur c ) + { + } + + // + // + // + + private void emitName ( QName name, boolean needsPrefix ) + { + assert name != null; + + String uri = name.getNamespaceURI(); + + assert uri != null; + + if (uri.length() != 0) + { + String prefix = name.getPrefix(); + String mappedUri = getNamespaceForPrefix( prefix ); + + if (mappedUri == null || !mappedUri.equals( uri )) + prefix = getUriMapping( uri ); + + // Attrs need a prefix. If I have not found one, then there must be a default + // prefix obscuring the prefix needed for this attr. Find it manually. + + // NOTE - Consider keeping the currently mapped default URI separate fromn the + // _urpMap and _prefixMap. This way, I would not have to look it up manually + // here + + if (needsPrefix && prefix.length() == 0) + prefix = getNonDefaultUriMapping( uri ); + + if (prefix.length() > 0) + { + emit( prefix ); + emit( ':' ); + } + } + + assert name.getLocalPart().length() > 0; + + emit( name.getLocalPart() ); + } + + private void emit ( char ch ) + { + assert _buf==null || + (_out<_in && _free == _buf.length - ( _in - _out ) ) || // data in the middle, free on the edges + (_out>_in && _free == _out - _in ) || // data on the edges, free in the middle + (_out==_in && _free == _buf.length) || // no data, all buffer free + (_out==_in && _free == 0) // buffer full + : "_buf.length:" + _buf.length + " _in:" + _in + " _out:" + _out + " _free:" + _free; + + preEmit( 1 ); + + _buf[ _in ] = ch; + + _in = (_in + 1) % _buf.length; + + assert _buf==null || + (_out<_in && _free == _buf.length - ( _in - _out ) ) || // data in the middle, free on the edges + (_out>_in && _free == _out - _in ) || // data on the edges, free in the middle + (_out==_in && _free == _buf.length) || // no data, all buffer free + (_out==_in && _free == 0) // buffer full + : "_buf.length:" + _buf.length + " _in:" + _in + " _out:" + _out + " _free:" + _free; + } + + private void emit ( char ch1, char ch2 ) + { + if( preEmit( 2 ) ) + return; + + _buf[ _in ] = ch1; + _in = (_in + 1) % _buf.length; + + _buf[ _in ] = ch2; + _in = (_in + 1) % _buf.length; + + assert _buf==null || + (_out<_in && _free == _buf.length - ( _in - _out ) ) || // data in the middle, free on the edges + (_out>_in && _free == _out - _in ) || // data on the edges, free in the middle + (_out==_in && _free == _buf.length) || // no data, all buffer free + (_out==_in && _free == 0) // buffer full + : "_buf.length:" + _buf.length + " _in:" + _in + " _out:" + _out + " _free:" + _free; + } + + private void emit ( String s ) + { + assert _buf==null || + (_out<_in && _free == _buf.length - ( _in - _out ) ) || // data in the middle, free on the edges + (_out>_in && _free == _out - _in ) || // data on the edges, free in the middle + (_out==_in && _free == _buf.length) || // no data, all buffer free + (_out==_in && _free == 0) // buffer full + : "_buf.length:" + _buf.length + " _in:" + _in + " _out:" + _out + " _free:" + _free; + + int cch = s == null ? 0 : s.length(); + + if (preEmit( cch )) + return; + + int chunk; + + if (_in <= _out || cch < (chunk = _buf.length - _in)) + { + s.getChars( 0, cch, _buf, _in ); + _in += cch; + } + else + { + s.getChars( 0, chunk, _buf, _in ); + s.getChars( chunk, cch, _buf, 0 ); + _in = (_in + cch) % _buf.length; + } + + assert _buf==null || + (_out<_in && _free == _buf.length - ( _in - _out ) ) || // data in the middle, free on the edges + (_out>_in && _free == _out - _in ) || // data on the edges, free in the middle + (_out==_in && _free == _buf.length) || // no data, all buffer free + (_out==_in && _free == 0) // buffer full + : "_buf.length:" + _buf.length + " _in:" + _in + " _out:" + _out + " _free:" + _free; + } + + private void emit ( SaveCur c ) + { + if (c.isText()) + { + Object src = c.getChars(); + int cch = c._cchSrc; + + if (preEmit( cch )) + return; + + int chunk; + + if (_in <= _out || cch < (chunk = _buf.length - _in)) + { + CharUtil.getChars( _buf, _in, src, c._offSrc, cch ); + _in += cch; + } + else + { + CharUtil.getChars( _buf, _in, src, c._offSrc, chunk ); + CharUtil.getChars( _buf, 0, src, c._offSrc + chunk, cch - chunk ); + _in = (_in + cch) % _buf.length; + } + } + else + preEmit( 0 ); + } + + private boolean preEmit ( int cch ) + { + assert cch >= 0; + assert _buf==null || + (_out<_in && _free == _buf.length - ( _in - _out ) ) || // data in the middle, free on the edges + (_out>_in && _free == _out - _in ) || // data on the edges, free in the middle + (_out==_in && _free == _buf.length) || // no data, all buffer free + (_out==_in && _free == 0) // buffer full + : "_buf.length:" + _buf.length + " _in:" + _in + " _out:" + _out + " _free:" + _free; + + _lastEmitCch = cch; + + if (cch == 0) + return true; + + if (_free <= cch) + resize( cch, -1 ); + + assert cch <= _free; + + int used = getAvailable(); + + // if we are about to emit and there is noting in the buffer, reset + // the buffer to be at the beginning so as to not grow it anymore + // than needed. + + if (used == 0) + { + assert _in == _out; + assert _free == _buf.length; + _in = _out = 0; + } + + _lastEmitIn = _in; + + _free -= cch; + + assert _free >= 0; + assert _buf==null || _free == (_in>=_out ? _buf.length - (_in - _out) : _out - _in ) - cch : "_buf.length:" + _buf.length + " _in:" + _in + " _out:" + _out + " _free:" + _free; + assert _buf==null || + (_out<_in && _free == _buf.length - ( _in - _out ) - cch) || // data in the middle, free on the edges + (_out>_in && _free == _out - _in - cch ) || // data on the edges, free in the middle + (_out==_in && _free == _buf.length - cch) || // no data, all buffer free + (_out==_in && _free == 0) // buffer full + : "_buf.length:" + _buf.length + " _in:" + _in + " _out:" + _out + " _free:" + _free; + + return false; + } + + private void entitizeContent ( boolean forceCData ) + { + assert _free >=0; + + if (_lastEmitCch == 0) + return; + + int i = _lastEmitIn; + final int n = _buf.length; + + boolean hasCharToBeReplaced = false; + + int count = 0; + char prevChar = 0; + char prevPrevChar = 0; + for ( int cch = _lastEmitCch ; cch > 0 ; cch-- ) + { + char ch = _buf[ i ]; + + if (ch == '<' || ch == '&') + count++; + else if (prevPrevChar == ']' && prevChar == ']' && ch == '>' ) + hasCharToBeReplaced = true; + else if (isBadChar( ch ) || isEscapedChar( ch ) || (!_isPrettyPrint && ch == '\r') ) + hasCharToBeReplaced = true; + + if (++i == n) + i = 0; + + prevPrevChar = prevChar; + prevChar = ch; + } + + if (!forceCData && count == 0 && !hasCharToBeReplaced && count<_cdataEntityCountThreshold) + return; + + i = _lastEmitIn; + + // + // Heuristic for knowing when to save out stuff as a CDATA. + // + if (forceCData || (_lastEmitCch > _cdataLengthThreshold && count > _cdataEntityCountThreshold) ) + { + boolean lastWasBracket = _buf[ i ] == ']'; + + i = replace( i, " 0 ; cch-- ) + { + char ch = _buf[ i ]; + + if (ch == '>' && secondToLastWasBracket && lastWasBracket) + i = replace( i, "]]>>" ); + } + else + { + char ch = 0, ch_1 = 0, ch_2; + for ( int cch = _lastEmitCch ; cch > 0 ; cch-- ) + { + ch_2 = ch_1; + ch_1 = ch; + ch = _buf[ i ]; + + if (ch == '<') + i = replace( i, "<" ); + else if (ch == '&') + i = replace( i, "&" ); + else if (ch == '>' && ch_1 == ']' && ch_2 == ']') + i = replace( i, ">" ); + else if (isBadChar( ch )) + i = replace( i, "?" ); + else if (!_isPrettyPrint && ch == '\r') + i = replace( i, " " ); + else if (isEscapedChar( ch )) + i = replace( i, _replaceChar.getEscapedString( ch ) ); + else + i++; + + if (i == _buf.length) + i = 0; + } + } + } + + private void entitizeAttrValue ( boolean replaceEscapedChar ) + { + if (_lastEmitCch == 0) + return; + + int i = _lastEmitIn; + + for ( int cch = _lastEmitCch ; cch > 0 ; cch-- ) + { + char ch = _buf[ i ]; + + if (ch == '<') + i = replace( i, "<" ); + else if (ch == '&') + i = replace( i, "&" ); + else if (ch == '"') + i = replace( i, """ ); + else if (isEscapedChar( ch )) + { + if (replaceEscapedChar) + i = replace( i, _replaceChar.getEscapedString( ch ) ); + } + else + i++; + + if (i == _buf.length) + i = 0; + } + } + + private void entitizeComment ( ) + { + if (_lastEmitCch == 0) + return; + + int i = _lastEmitIn; + + boolean lastWasDash = false; + + for ( int cch = _lastEmitCch ; cch > 0 ; cch-- ) + { + char ch = _buf[ i ]; + + if (isBadChar( ch )) + i = replace( i, "?" ); + else if (ch == '-') + { + if (lastWasDash) + { + // Replace "--" with "- " to make well formed + i = replace( i, " " ); + lastWasDash = false; + } + else + { + lastWasDash = true; + i++; + } + } + else + { + lastWasDash = false; + i++; + } + + if (i == _buf.length) + i = 0; + } + + // Because I have only replaced chars with single chars, + // _lastEmitIn will still be ok + + int offset = (_lastEmitIn + _lastEmitCch - 1) % _buf.length; + if (_buf[ offset ] == '-') + i = replace( offset, " " ); + } + + private void entitizeProcinst ( ) + { + if (_lastEmitCch == 0) + return; + + int i = _lastEmitIn; + + boolean lastWasQuestion = false; + + for ( int cch = _lastEmitCch ; cch > 0 ; cch-- ) + { + char ch = _buf[ i ]; + + if (isBadChar( ch )) + i = replace( i, "?" ); + + if (ch == '>') + { + // TODO - Had to convert to a space here ... imples not well formed XML + if (lastWasQuestion) + i = replace( i, " " ); + else + i++; + + lastWasQuestion = false; + } + else + { + lastWasQuestion = ch == '?'; + i++; + } + + if (i == _buf.length) + i = 0; + } + } + + /** + * Test if a character is valid in xml character content. See + * http://www.w3.org/TR/REC-xml#NT-Char + */ + + private boolean isBadChar ( char ch ) + { + return ! ( + (ch >= 0x20 && ch <= 0xD7FF ) || + (ch >= 0xE000 && ch <= 0xFFFD) || + (ch >= 0x10000 && ch <= 0x10FFFF) || + (ch == 0x9) || (ch == 0xA) || (ch == 0xD) + ); + } + + /** + * Test if a character is to be replaced with an escaped value + */ + private boolean isEscapedChar ( char ch ) + { + return ( null != _replaceChar && _replaceChar.containsChar( ch ) ); + } + + private int replace ( int i, String replacement ) + { + assert replacement.length() > 0; + + int dCch = replacement.length() - 1; + + if (dCch == 0) + { + _buf[ i ] = replacement.charAt( 0 ); + return i + 1; + } + + assert _free >= 0; + + if (dCch > _free) + i = resize( dCch, i ); + + assert _free >= 0; + + assert _free >= dCch; + assert getAvailable() > 0; + + int charsToCopy = dCch + 1; + + if (_out > _in && i >= _out) + { + System.arraycopy( _buf, _out, _buf, _out - dCch, i - _out ); + _out -= dCch; + i -= dCch; + } + else + { + assert i < _in; + int availableEndChunk = _buf.length - _in; + if ( dCch <= availableEndChunk ) + { + System.arraycopy( _buf, i, _buf, i + dCch, _in - i ); + _in = ( _in + dCch) % _buf.length; + } + else if ( dCch <= availableEndChunk + _in - i - 1 ) + { + int numToCopyToStart = dCch - availableEndChunk; + System.arraycopy( _buf, _in-numToCopyToStart, _buf, 0, numToCopyToStart ); + System.arraycopy( _buf, i+1, _buf, i+1+dCch, _in-i-1-numToCopyToStart); + + _in = numToCopyToStart; + } + else + { + int numToCopyToStart = _in - i - 1; + charsToCopy = availableEndChunk + _in - i; + + System.arraycopy( _buf, _in-numToCopyToStart, _buf, dCch-charsToCopy+1, numToCopyToStart ); + replacement.getChars( charsToCopy, dCch + 1, _buf, 0); + + _in = numToCopyToStart + dCch - charsToCopy + 1; + } + } + + replacement.getChars( 0, charsToCopy, _buf, i ); + + _free -= dCch; + + assert _free >= 0; + assert _buf==null || + (_out<_in && _free == _buf.length - ( _in - _out ) ) || // data in the middle, free on the edges + (_out>_in && _free == _out - _in ) || // data on the edges, free in the middle + (_out==_in && _free == _buf.length) || // no data, all buffer free + (_out==_in && _free == 0) // buffer full + : "_buf.length:" + _buf.length + " _in:" + _in + " _out:" + _out + " _free:" + _free; + + return (i + dCch + 1) % _buf.length; + } + // + // + // + + private int ensure ( int cch ) + { + // Even if we're asked to ensure nothing, still try to ensure + // atleast one character so we can determine if we're at the + // end of the stream. + + if (cch <= 0) + cch = 1; + + int available = getAvailable(); + + for ( ; available < cch ; available = getAvailable() ) + if (!process()) + break; + + assert available == getAvailable(); + +// if (available == 0) +// return 0; + + return available; + } + + int getAvailable ( ) + { + return _buf == null ? 0 : _buf.length - _free; + } + + private int resize ( int cch, int i ) + { + assert _free >= 0; + assert cch > 0; + assert cch >= _free; + assert _buf==null || + (_out<_in && _free == _buf.length - ( _in - _out ) ) || // data in the middle, free on the edges + (_out>_in && _free == _out - _in ) || // data on the edges, free in the middle + (_out==_in && _free == _buf.length) || // no data, all buffer free + (_out==_in && _free == 0) // buffer full + : "_buf.length:" + _buf.length + " _in:" + _in + " _out:" + _out + " _free:" + _free; + + int newLen = _buf == null ? _initialBufSize : _buf.length * 2; + int used = getAvailable(); + + while ( newLen - used < cch ) + newLen *= 2; + + char[] newBuf = new char [ newLen ]; + + if (used > 0) + { + if (_in > _out) + { + assert i == -1 || (i >= _out && i < _in); + System.arraycopy( _buf, _out, newBuf, 0, used ); + i -= _out; + } + else + { + assert i == -1 || (i >= _out || i < _in); + System.arraycopy( _buf, _out, newBuf, 0, used - _in ); + System.arraycopy( _buf, 0, newBuf, used - _in, _in ); + i = i >= _out ? i - _out : i + _out; + } + + _out = 0; + _in = used; + _free += newBuf.length - _buf.length; + } + else + { + _free = newBuf.length; + assert _in == 0 && _out == 0; + assert i == -1; + } + + _buf = newBuf; + + assert _free >= 0; + assert _buf==null || + (_out<_in && _free == _buf.length - ( _in - _out ) ) || // data in the middle, free on the edges + (_out>_in && _free == _out - _in ) || // data on the edges, free in the middle + (_out==_in && _free == _buf.length) || // no data, all buffer free + (_out==_in && _free == 0) // buffer full + : "_buf.length:" + _buf.length + " _in:" + _in + " _out:" + _out + " _free:" + _free; + + return i; + } + + public int read ( ) + { + if (ensure( 1 ) == 0) + return -1; + + assert getAvailable() > 0; + + int ch = _buf[ _out ]; + + _out = (_out + 1) % _buf.length; + _free++; + + assert _buf==null || + (_out<_in && _free == _buf.length - ( _in - _out ) ) || // data in the middle, free on the edges + (_out>_in && _free == _out - _in ) || // data on the edges, free in the middle + (_out==_in && _free == _buf.length) || // no data, all buffer free + (_out==_in && _free == 0) // buffer full + : "_buf.length:" + _buf.length + " _in:" + _in + " _out:" + _out + " _free:" + _free; + + return ch; + } + + public int read ( char[] cbuf, int off, int len ) + { + // Check for end of stream even if there is no way to return + // characters because the Reader doc says to return -1 at end of + // stream. + + int n; + + if ((n = ensure( len )) == 0) + return -1; + + if (cbuf == null || len <= 0) + return 0; + + if (n < len) + len = n; + + if (_out < _in) + { + System.arraycopy( _buf, _out, cbuf, off, len ); + } + else + { + int chunk = _buf.length - _out; + + if (chunk >= len) + System.arraycopy( _buf, _out, cbuf, off, len ); + else + { + System.arraycopy( _buf, _out, cbuf, off, chunk ); + System.arraycopy( _buf, 0, cbuf, off + chunk, len - chunk ); + } + } + + _out = (_out + len) % _buf.length; + _free += len; + + assert _buf==null || + (_out<_in && _free == _buf.length - ( _in - _out ) ) || // data in the middle, free on the edges + (_out>_in && _free == _out - _in ) || // data on the edges, free in the middle + (_out==_in && _free == _buf.length) || // no data, all buffer free + (_out==_in && _free == 0) // buffer full + : "_buf.length:" + _buf.length + " _in:" + _in + " _out:" + _out + " _free:" + _free; + + assert _free >= 0; + + return len; + } + + public int write ( Writer writer, int cchMin ) + { + while ( getAvailable() < cchMin) + { + if (!process()) + break; + } + + int charsAvailable = getAvailable(); + + if (charsAvailable > 0) + { + // I don't want to deal with the circular cases + + assert _out == 0; + assert _in >= _out : "_in:" + _in + " < _out:" + _out; + assert _free == _buf.length - _in; + + try + { +//System.out.println("-------------\nWriting in corverter: TextSaver.write():1703 " + charsAvailable + " chars\n" + new String(_buf, 0, charsAvailable)); + writer.write( _buf, 0, charsAvailable ); + writer.flush(); + } + catch ( IOException e ) + { + throw new RuntimeException( e ); + } + + _free += charsAvailable; + + assert _free >= 0; + + _in = 0; + } + assert _buf==null || + (_out<_in && _free == _buf.length - ( _in - _out ) ) || // data in the middle, free on the edges + (_out>_in && _free == _out - _in ) || // data on the edges, free in the middle + (_out==_in && _free == _buf.length) || // no data, all buffer free + (_out==_in && _free == 0) // buffer full + : "_buf.length:" + _buf.length + " _in:" + _in + " _out:" + _out + " _free:" + _free; + + return charsAvailable; + } + + public String saveToString ( ) + { + // We're gonna build a string. Instead of using StringBuffer, may + // as well use my buffer here. Fill the whole sucker up and + // create a String! + + while ( process() ) + ; + + assert _out == 0; + + int available = getAvailable(); + + return available == 0 ? "" : new String( _buf, _out, available ); + } + + // + // + // + + private static final int _initialBufSize = 4096; + private int _cdataLengthThreshold = 32; + private int _cdataEntityCountThreshold = 5; + private boolean _useCDataBookmarks = false; + private boolean _isPrettyPrint = false; + + private int _lastEmitIn; + private int _lastEmitCch; + + private int _free; + private int _in; + private int _out; + private char[] _buf; + /* + _buf is a circular buffer, useful data is before _in up to _out, there are 2 posible configurations: + 1: _in<=_out |data|_in empty _out|data| + 2: _out<_in |empty _out|data|_in empty| + _free is used to keep around the remaining empty space in the bufer so assert _buf==null || _free == (_in>=_out ? _buf.length - (_in - _out) : _out - _in ) ; + */ + } + + static final class OptimizedForSpeedSaver + extends Saver + { + Writer _w; + private char[] _buf = new char[1024]; + + + static private class SaverIOException + extends RuntimeException + { + SaverIOException(IOException e) + { + super(e); + } + } + + + OptimizedForSpeedSaver(Cur cur, Writer writer) + { + super(cur, XmlOptions.maskNull(null)); + _w = writer; + } + + static void save(Cur cur, Writer writer) + throws IOException + { + try + { + Saver saver = new OptimizedForSpeedSaver(cur, writer); + while(saver.process()) + {} + } + catch (SaverIOException e) + { + throw (IOException)e.getCause(); + } + } + + private void emit(String s) + { + try + { + _w.write(s); + } + catch (IOException e) + { + throw new SaverIOException(e); + } + } + + private void emit(char c) + { + try + { + _buf[0] = c; + _w.write(_buf, 0, 1); + } + catch (IOException e) + { + throw new SaverIOException(e); + } + } + + private void emit(char c1, char c2) + { + try + { + _buf[0] = c1; + _buf[1] = c2; + _w.write(_buf, 0 , 2); + } + catch (IOException e) + { + throw new SaverIOException(e); + } + } + + private void emit(char[] buf, int start, int len) + { + try + { + _w.write(buf, start, len); + } + catch (IOException e) + { + throw new SaverIOException(e); + } + } + + protected boolean emitElement ( SaveCur c, ArrayList attrNames, ArrayList attrValues ) + { + assert c.isElem(); + + emit( '<' ); + emitName( c.getName(), false ); + + for ( int i = 0 ; i < attrNames.size() ; i++ ) + emitAttrHelper( (QName) attrNames.get( i ), (String) attrValues.get( i ) ); + + if (!saveNamespacesFirst()) + emitNamespacesHelper(); + + if (!c.hasChildren() && !c.hasText()) + { + emit( '/', '>' ); + return true; + } + else + { + emit( '>' ); + return false; + } + } + + protected void emitFinish ( SaveCur c ) + { + emit( '<', '/' ); + emitName( c.getName(), false ); + emit( '>' ); + } + + protected void emitXmlns ( String prefix, String uri ) + { + assert prefix != null; + assert uri != null; + + emit( "xmlns" ); + + if (prefix.length() > 0) + { + emit( ':' ); + emit( prefix ); + } + + emit( '=', '\"' ); + + // TODO - must encode uri properly + emitAttrValue(uri); + + emit( '"' ); + } + + private void emitNamespacesHelper ( ) + { + for ( iterateMappings() ; hasMapping() ; nextMapping() ) + { + emit( ' ' ); + emitXmlns( mappingPrefix(), mappingUri() ); + } + } + + private void emitAttrHelper ( QName attrName, String attrValue ) + { + emit( ' ' ); + emitName( attrName, true ); + emit( '=', '\"' ); + emitAttrValue(attrValue); + + emit( '"' ); + } + + protected void emitComment ( SaveCur c ) + { + assert c.isComment(); + + emit( "" ); + } + + protected void emitProcinst ( SaveCur c ) + { + assert c.isProcinst(); + + emit( "" ); + } + + protected void emitDocType ( String docTypeName, String publicId, String systemId ) + { + assert docTypeName != null; + + emit( "' ); + emit( _newLine ); + } + + protected void emitStartDoc ( SaveCur c ) + { + } + + protected void emitEndDoc ( SaveCur c ) + { + } + + // + // + // + + private void emitName ( QName name, boolean needsPrefix ) + { + assert name != null; + + String uri = name.getNamespaceURI(); + + assert uri != null; + + if (uri.length() != 0) + { + String prefix = name.getPrefix(); + String mappedUri = getNamespaceForPrefix( prefix ); + + if (mappedUri == null || !mappedUri.equals( uri )) + prefix = getUriMapping( uri ); + + // Attrs need a prefix. If I have not found one, then there must be a default + // prefix obscuring the prefix needed for this attr. Find it manually. + + // NOTE - Consider keeping the currently mapped default URI separate fromn the + // _urpMap and _prefixMap. This way, I would not have to look it up manually + // here + + if (needsPrefix && prefix.length() == 0) + prefix = getNonDefaultUriMapping( uri ); + + if (prefix.length() > 0) + { + emit( prefix ); + emit( ':' ); + } + } + + assert name.getLocalPart().length() > 0; + + emit( name.getLocalPart() ); + } + + private void emitAttrValue ( CharSequence attVal) + { + int len = attVal.length(); + + for ( int i = 0; i= 0x20 && ch <= 0xD7FF ) || + (ch >= 0xE000 && ch <= 0xFFFD) || + (ch >= 0x10000 && ch <= 0x10FFFF) || + (ch == 0x9) || (ch == 0xA) || (ch == 0xD) + ); + } + + private void emitLiteral ( String literal ) + { + // TODO: systemId production http://www.w3.org/TR/REC-xml/#NT-SystemLiteral + // TODO: publicId production http://www.w3.org/TR/REC-xml/#NT-PubidLiteral + if (literal.indexOf( "\"" ) < 0) + { + emit( '\"' ); + emit( literal ); + emit( '\"' ); + } + else + { + emit( '\'' ); + emit( literal ); + emit( '\'' ); + } + } + + protected void emitText ( SaveCur c ) + { + assert c.isText(); + + Object src = c.getChars(); + int cch = c._cchSrc; + int off = c._offSrc; + int index = 0; + int indexLimit = 0; + while( index cch ? cch : index + 512; + CharUtil.getChars( _buf, 0, src, off+index, indexLimit-index ); + entitizeAndWriteText(indexLimit-index); + index = indexLimit; + } + } + + protected void emitPiText ( SaveCur c ) + { + assert c.isText(); + + Object src = c.getChars(); + int cch = c._cchSrc; + int off = c._offSrc; + int index = 0; + int indexLimit = 0; + while( index cch ? cch : 512; + CharUtil.getChars( _buf, 0, src, off+index, indexLimit ); + entitizeAndWritePIText(indexLimit-index); + index = indexLimit; + } + } + + protected void emitCommentText ( SaveCur c ) + { + assert c.isText(); + + Object src = c.getChars(); + int cch = c._cchSrc; + int off = c._offSrc; + int index = 0; + int indexLimit = 0; + while( index cch ? cch : 512; + CharUtil.getChars( _buf, 0, src, off+index, indexLimit ); + entitizeAndWriteCommentText(indexLimit-index); + index = indexLimit; + } + } + + private void entitizeAndWriteText(int bufLimit) + { + int index = 0; + for (int i = 0; i < bufLimit; i++) + { + char c = _buf[i]; + switch(c) + { + case '<': + emit(_buf, index, i-index); + emit("<"); + index = i+1; + break; + case '&': + emit(_buf, index, i-index); + emit("&"); + index = i+1; + break; + } + } + emit(_buf, index, bufLimit-index); + } + + private void entitizeAndWriteCommentText ( int bufLimit ) + { + boolean lastWasDash = false; + + for ( int i=0 ; i') + { + // Had to convert to a space here ... imples not well formed XML + if (lastWasQuestion) + _buf[i] = ' '; + + lastWasQuestion = false; + } + else + { + lastWasQuestion = ch == '?'; + } + } + emit(_buf, 0, bufLimit); + } + } + + static final class TextReader extends Reader + { + TextReader ( Cur c, XmlOptions options ) + { + _textSaver = new TextSaver( c, options, null ); + _locale = c._locale; + _closed = false; + } + + public void close ( ) throws IOException { _closed = true; } + + public boolean ready ( ) throws IOException { return !_closed; } + + public int read ( ) throws IOException + { + checkClosed(); + + if (_locale.noSync()) { _locale.enter(); try { return _textSaver.read(); } finally { _locale.exit(); } } + else synchronized ( _locale ) { _locale.enter(); try { return _textSaver.read(); } finally { _locale.exit(); } } + } + + public int read ( char[] cbuf ) throws IOException + { + checkClosed(); + + if (_locale.noSync()) { _locale.enter(); try { return _textSaver.read( cbuf, 0, cbuf == null ? 0 : cbuf.length ); } finally { _locale.exit(); } } + else synchronized ( _locale ) { _locale.enter(); try { return _textSaver.read( cbuf, 0, cbuf == null ? 0 : cbuf.length ); } finally { _locale.exit(); } } + } + + public int read ( char[] cbuf, int off, int len ) throws IOException + { + checkClosed(); + + if (_locale.noSync()) { _locale.enter(); try { return _textSaver.read( cbuf, off, len ); } finally { _locale.exit(); } } + else synchronized ( _locale ) { _locale.enter(); try { return _textSaver.read( cbuf, off, len ); } finally { _locale.exit(); } } + } + + private void checkClosed ( ) throws IOException + { + if (_closed) + throw new IOException( "Reader has been closed" ); + } + + private Locale _locale; + private TextSaver _textSaver; + private boolean _closed; + } + + static final class InputStreamSaver extends InputStream + { + InputStreamSaver ( Cur c, XmlOptions options ) + { + _locale = c._locale; + + _closed = false; + + assert _locale.entered(); + + options = XmlOptions.maskNull( options ); + + _outStreamImpl = new OutputStreamImpl(); + + String encoding = null; + + XmlDocumentProperties props = Locale.getDocProps( c, false ); + + if (props != null && props.getEncoding() != null) + encoding = EncodingMap.getIANA2JavaMapping( props.getEncoding() ); + + if (options.hasOption( XmlOptions.CHARACTER_ENCODING )) + encoding = (String) options.get( XmlOptions.CHARACTER_ENCODING ); + + if (encoding != null) + { + String ianaEncoding = EncodingMap.getJava2IANAMapping( encoding ); + + if (ianaEncoding != null) + encoding = ianaEncoding; + } + + if (encoding == null) + encoding = EncodingMap.getJava2IANAMapping( "UTF8" ); + + String javaEncoding = EncodingMap.getIANA2JavaMapping( encoding ); + + if (javaEncoding == null) + throw new IllegalStateException( "Unknown encoding: " + encoding ); + + try + { + _converter = new OutputStreamWriter( _outStreamImpl, javaEncoding ); + } + catch ( UnsupportedEncodingException e ) + { + throw new RuntimeException( e ); + } + + _textSaver = new TextSaver( c, options, encoding ); + } + + public void close ( ) throws IOException + { + _closed = true; + } + + private void checkClosed ( ) throws IOException + { + if (_closed) + throw new IOException( "Stream closed" ); + } + + // Having the gateway here is kinda slow for the single character case. It may be possible + // to only enter the gate when there are no chars in the buffer. + + public int read ( ) throws IOException + { + checkClosed(); + + if (_locale.noSync()) { _locale.enter(); try { return _outStreamImpl.read(); } finally { _locale.exit(); } } + else synchronized ( _locale ) { _locale.enter(); try { return _outStreamImpl.read(); } finally { _locale.exit(); } } + } + + public int read ( byte[] bbuf, int off, int len ) throws IOException + { + checkClosed(); + + if (bbuf == null) + throw new NullPointerException( "buf to read into is null" ); + + if (off < 0 || off > bbuf.length) + throw new IndexOutOfBoundsException( "Offset is not within buf" ); + + if (_locale.noSync()) { _locale.enter(); try { return _outStreamImpl.read( bbuf, off, len ); } finally { _locale.exit(); } } + else synchronized ( _locale ) { _locale.enter(); try { return _outStreamImpl.read( bbuf, off, len ); } finally { _locale.exit(); } } + } + + private int ensure ( int cbyte ) + { + // Even if we're asked to ensure nothing, still try to ensure + // atleast one byte so we can determine if we're at the + // end of the stream. + + if (cbyte <= 0) + cbyte = 1; + + int bytesAvailable = _outStreamImpl.getAvailable(); + + for ( ; bytesAvailable < cbyte ; + bytesAvailable = _outStreamImpl.getAvailable() ) + { + if (_textSaver.write( _converter, 2048 ) < 2048) + break; + } + + bytesAvailable = _outStreamImpl.getAvailable(); + +// if (bytesAvailable == 0) +// return 0; + + return bytesAvailable; + } + + public int available() + throws IOException + { + if (_locale.noSync()) + { _locale.enter(); try { + return ensure(1024); + } finally { _locale.exit(); } } + else + synchronized ( _locale ) + { _locale.enter(); try { return ensure(1024); } finally { _locale.exit(); } } + } + + private final class OutputStreamImpl extends OutputStream + { + int read ( ) + { + if (InputStreamSaver.this.ensure( 1 ) == 0) + return -1; + + assert getAvailable() > 0; + + int bite = _buf[ _out ]; + + _out = (_out + 1) % _buf.length; + _free++; + + return bite; + } + + int read ( byte[] bbuf, int off, int len ) + { + // Check for end of stream even if there is no way to return + // characters because the Reader doc says to return -1 at end of + // stream. + + int n; + + if ((n = ensure( len )) == 0) + return -1; + + if (bbuf == null || len <= 0) + return 0; + + if (n < len) + len = n; + + if (_out < _in) + { + System.arraycopy( _buf, _out, bbuf, off, len ); + } + else + { + int chunk = _buf.length - _out; + + if (chunk >= len) + System.arraycopy( _buf, _out, bbuf, off, len ); + else + { + System.arraycopy( _buf, _out, bbuf, off, chunk ); + + System.arraycopy( + _buf, 0, bbuf, off + chunk, len - chunk ); + } + } + _out = (_out + len) % _buf.length; + _free += len; + +//System.out.println("------------------------\nRead out of queue: Saver:2440 InputStreamSaver.read() bbuf " + len + " bytes :\n" + new String(bbuf, off, len)); + return len; + } + + int getAvailable ( ) + { + return _buf == null ? 0 : _buf.length - _free; + } + + public void write ( int bite ) + { + if (_free == 0) + resize( 1 ); + + assert _free > 0; + + _buf[ _in ] = (byte) bite; + + _in = (_in + 1) % _buf.length; + _free--; + } + + public void write ( byte[] buf, int off, int cbyte ) + { + assert cbyte >= 0; +//System.out.println("---------\nAfter converter, write in queue: OutputStreamImpl.write():Saver:2469 " + cbyte + " bytes \n" + new String(buf, off, cbyte)); + if (cbyte == 0) + return; + + if (_free < cbyte) + resize( cbyte ); + + if (_in == _out) + { + assert getAvailable() == 0; + assert _free == _buf.length - getAvailable(); + _in = _out = 0; + } + + int chunk = _buf.length - _in; + + if (_in <= _out || cbyte < chunk) + { + System.arraycopy( buf, off, _buf, _in, cbyte ); + _in += cbyte; + } + else + { + System.arraycopy( buf, off, _buf, _in, chunk ); + + System.arraycopy( + buf, off + chunk, _buf, 0, cbyte - chunk ); + + _in = (_in + cbyte) % _buf.length; + } + + _free -= cbyte; + } + + void resize ( int cbyte ) + { + assert cbyte > _free : cbyte + " !> " + _free; + + int newLen = _buf == null ? _initialBufSize : _buf.length * 2; + int used = getAvailable(); + + while ( newLen - used < cbyte ) + newLen *= 2; + + byte[] newBuf = new byte [ newLen ]; + + if (used > 0) + { + if (_in > _out) + System.arraycopy( _buf, _out, newBuf, 0, used ); + else + { + System.arraycopy( + _buf, _out, newBuf, 0, used - _in ); + + System.arraycopy( + _buf, 0, newBuf, used - _in, _in ); + } + + _out = 0; + _in = used; + _free += newBuf.length - _buf.length; + } + else + { + _free = newBuf.length; + assert _in == _out; + } + + _buf = newBuf; + } + + private static final int _initialBufSize = 4096; + + private int _free; + private int _in; + private int _out; + private byte[] _buf; + } + + private Locale _locale; + private boolean _closed; + private OutputStreamImpl _outStreamImpl; + private TextSaver _textSaver; + private OutputStreamWriter _converter; + } + + static final class XmlInputStreamSaver extends Saver + { + XmlInputStreamSaver ( Cur c, XmlOptions options ) + { + super( c, options ); + } + + protected boolean emitElement(SaveCur c, ArrayList attrNames, ArrayList attrValues) + { + assert c.isElem(); + + for ( iterateMappings() ; hasMapping() ; nextMapping() ) + { + enqueue( new StartPrefixMappingImpl( mappingPrefix(), mappingUri() ) ); + } + + StartElementImpl.AttributeImpl lastAttr = null; + StartElementImpl.AttributeImpl attributes = null; + StartElementImpl.AttributeImpl namespaces = null; + + for ( int i=0; i 0; + + String prefix = null; + + if (uri!=null && uri.length() != 0) + { + prefix = name.getPrefix(); + String mappedUri = saver.getNamespaceForPrefix( prefix ); + + if (mappedUri == null || !mappedUri.equals( uri )) + prefix = saver.getUriMapping( uri ); + + // Attrs need a prefix. If I have not found one, then there must be a default + // prefix obscuring the prefix needed for this attr. Find it manually. + + // NOTE - Consider keeping the currently mapped default URI separate fromn the + // _urpMap and _prefixMap. This way, I would not have to look it up manually + // here + + if (needsPrefix && prefix.length() == 0) + prefix = saver.getNonDefaultUriMapping( uri ); + + } + + return new XmlNameImpl( uri, local, prefix ); + } + + private static abstract class XmlEventImpl extends XmlEventBase + { + XmlEventImpl ( int type ) + { + super( type ); + } + + public XMLName getName ( ) + { + return null; + } + + public XMLName getSchemaType ( ) + { + throw new RuntimeException( "NYI" ); + } + + public boolean hasName ( ) + { + return false; + } + + public final Location getLocation ( ) + { + // (orig v1 comment)TODO - perhaps I can save a location goober sometimes? + return null; + } + + XmlEventImpl _next; + } + + private static class StartDocumentImpl + extends XmlEventImpl implements StartDocument + { + StartDocumentImpl ( String systemID, String encoding, boolean isStandAlone, String version ) + { + super( XMLEvent.START_DOCUMENT ); + _systemID = systemID; + _encoding = encoding; + _standAlone = isStandAlone; + _version = version; + } + + public String getSystemId ( ) + { + return _systemID; + } + + public String getCharacterEncodingScheme ( ) + { + return _encoding; + } + + public boolean isStandalone ( ) + { + return _standAlone; + } + + public String getVersion ( ) + { + return _version; + } + + String _systemID; + String _encoding; + boolean _standAlone; + String _version; + } + + private static class StartElementImpl + extends XmlEventImpl implements StartElement + { + StartElementImpl ( XMLName name, AttributeImpl attributes, AttributeImpl namespaces, Map prefixMap ) + { + super( XMLEvent.START_ELEMENT ); + + _name = name; + _attributes = attributes; + _namespaces = namespaces; + _prefixMap = prefixMap; + } + + public boolean hasName() + { + return true; + } + + public XMLName getName ( ) + { + return _name; + } + + public AttributeIterator getAttributes ( ) + { + return new AttributeIteratorImpl( _attributes, null ); + } + + public AttributeIterator getNamespaces ( ) + { + return new AttributeIteratorImpl( null, _namespaces ); + } + + public AttributeIterator getAttributesAndNamespaces ( ) + { + return new AttributeIteratorImpl( _attributes, _namespaces ); + } + + public Attribute getAttributeByName ( XMLName xmlName ) + { + for ( AttributeImpl a = _attributes ; a != null ; a = a._next ) + { + if (xmlName.equals( a.getName() )) + return a; + } + + return null; + } + + public String getNamespaceUri ( String prefix ) + { + return (String) _prefixMap.get( prefix == null ? "" : prefix ); + } + + public Map getNamespaceMap ( ) + { + return _prefixMap; + } + + private static class AttributeIteratorImpl + implements AttributeIterator + { + AttributeIteratorImpl( AttributeImpl attributes, AttributeImpl namespaces ) + { + _attributes = attributes; + _namespaces = namespaces; + } + + public Object monitor() + { + return this; + } + + public Attribute next ( ) + { + synchronized (monitor()) + { + checkVersion(); + + AttributeImpl attr = null; + + if (_attributes != null) + { + attr = _attributes; + _attributes = attr._next; + } + else if (_namespaces != null) + { + attr = _namespaces; + _namespaces = attr._next; + } + + return attr; + } + } + + public boolean hasNext ( ) + { + synchronized (monitor()) + { + checkVersion(); + + return _attributes != null || _namespaces != null; + } + } + + public Attribute peek ( ) + { + synchronized (monitor()) + { + checkVersion(); + + if (_attributes != null) + return _attributes; + else if (_namespaces != null) + return _namespaces; + + return null; + } + } + + public void skip ( ) + { + synchronized (monitor()) + { + checkVersion(); + + if (_attributes != null) + _attributes = _attributes._next; + else if (_namespaces != null) + _namespaces = _namespaces._next; + } + } + + private final void checkVersion ( ) + { +// if (_version != _root.getVersion()) +// throw new IllegalStateException( "Document changed" ); + } + +// private long _version; + private AttributeImpl _attributes; + private AttributeImpl _namespaces; + } + + private static abstract class AttributeImpl implements Attribute + { + /** + * Don't forget to set _name + */ + AttributeImpl () + { + } + + public XMLName getName ( ) + { + return _name; + } + + public String getType ( ) + { + // (from v1 impl) TODO - Make sure throwing away this DTD info is ok. + // (from v1 impl) Is there schema info which can return more useful info? + return "CDATA"; + } + + public XMLName getSchemaType ( ) + { + // (from v1 impl) TODO - Can I return something reasonable here? + return null; + } + + AttributeImpl _next; + + protected XMLName _name; + } + + private static class XmlnsAttributeImpl extends AttributeImpl + { + XmlnsAttributeImpl ( String prefix, String uri ) + { + super(); + _uri = uri; + + String local; + + if (prefix.length() == 0) + { + prefix = null; + local = "xmlns"; + } + else + { + local = prefix; + prefix = "xmlns"; + } + + _name = new XmlNameImpl( null, local, prefix ); + } + + public String getValue ( ) + { + return _uri; + } + + private String _uri; + } + + private static class NormalAttributeImpl extends AttributeImpl + { + NormalAttributeImpl (XMLName name, String value) + { + _name = name; + _value = value; + } + + public String getValue ( ) + { + return _value; + } + + private String _value; // If invalid in the store + } + + private XMLName _name; + private Map _prefixMap; + + private AttributeImpl _attributes; + private AttributeImpl _namespaces; + } + + private static class StartPrefixMappingImpl + extends XmlEventImpl implements StartPrefixMapping + { + StartPrefixMappingImpl ( String prefix, String uri ) + { + super( XMLEvent.START_PREFIX_MAPPING ); + + _prefix = prefix; + _uri = uri; + } + + public String getNamespaceUri ( ) + { + return _uri; + } + + public String getPrefix ( ) + { + return _prefix; + } + + private String _prefix, _uri; + } + + private static class ChangePrefixMappingImpl + extends XmlEventImpl implements ChangePrefixMapping + { + ChangePrefixMappingImpl ( String prefix, String oldUri, String newUri ) + { + super( XMLEvent.CHANGE_PREFIX_MAPPING ); + + _oldUri = oldUri; + _newUri = newUri; + _prefix = prefix; + } + + public String getOldNamespaceUri ( ) + { + return _oldUri; + } + + public String getNewNamespaceUri ( ) + { + return _newUri; + } + + public String getPrefix ( ) + { + return _prefix; + } + + private String _oldUri, _newUri, _prefix; + } + + private static class EndPrefixMappingImpl + extends XmlEventImpl implements EndPrefixMapping + { + EndPrefixMappingImpl ( String prefix ) + { + super( XMLEvent.END_PREFIX_MAPPING ); + _prefix = prefix; + } + + public String getPrefix ( ) + { + return _prefix; + } + + private String _prefix; + } + + private static class EndElementImpl + extends XmlEventImpl implements EndElement + { + EndElementImpl ( XMLName name ) + { + super( XMLEvent.END_ELEMENT ); + + _name = name; + } + + public boolean hasName ( ) + { + return true; + } + + public XMLName getName ( ) + { + return _name; + } + + private XMLName _name; + } + + private static class EndDocumentImpl + extends XmlEventImpl implements EndDocument + { + EndDocumentImpl ( ) + { + super( XMLEvent.END_DOCUMENT ); + } + } + + private static class TripletEventImpl + extends XmlEventImpl implements CharacterData + { + TripletEventImpl ( int eventType, Object obj, int cch, int off ) + { + super(eventType); + _obj = obj; + _cch = cch; + _off = off; + } + + public String getContent ( ) + { + return CharUtil.getString(_obj, _off, _cch); + } + + public boolean hasContent ( ) + { + return _cch > 0; + } + + private Object _obj; + private int _cch; + private int _off; + } + + private static class CharacterDataImpl + extends TripletEventImpl implements CharacterData + { + CharacterDataImpl ( Object obj, int cch, int off ) + { + super(XMLEvent.CHARACTER_DATA, obj, cch, off); + } + } + + private static class CommentImpl + extends TripletEventImpl implements Comment + { + CommentImpl ( Object obj, int cch, int off ) + { + super( XMLEvent.COMMENT, obj, cch, off); + } + } + + private static class ProcessingInstructionImpl + extends TripletEventImpl implements ProcessingInstruction + { + ProcessingInstructionImpl ( String target, Object obj, int cch, int off) + { + super( XMLEvent.PROCESSING_INSTRUCTION, obj, cch, off); + _target = target; + } + + public String getTarget ( ) + { + return _target; + } + + public String getData ( ) + { + return getContent(); + } + + private String _target; + } + + private XmlEventImpl _in, _out; + } + + static final class XmlInputStreamImpl extends GenericXmlInputStream + { + XmlInputStreamImpl ( Cur cur, XmlOptions options ) + { + _xmlInputStreamSaver = + new XmlInputStreamSaver( cur, options ); + + // Make the saver grind away just a bit to throw any exceptions + // related to the inability to create a stream on this xml + + _xmlInputStreamSaver.process(); + } + + protected XMLEvent nextEvent ( ) throws XMLStreamException + { + return _xmlInputStreamSaver.dequeue(); + } + + private XmlInputStreamSaver _xmlInputStreamSaver; + } + + static final class SaxSaver extends Saver + { + SaxSaver ( Cur c, XmlOptions options, ContentHandler ch, LexicalHandler lh ) + throws SAXException + { + super( c, options ); + + _contentHandler = ch; + _lexicalHandler = lh; + + _attributes = new AttributesImpl(); + _nsAsAttrs = !options.hasOption( XmlOptions.SAVE_SAX_NO_NSDECLS_IN_ATTRIBUTES ); + + _contentHandler.startDocument(); + + try + { + while ( process() ) + ; + } + catch ( SaverSAXException e ) + { + throw e._saxException; + } + + _contentHandler.endDocument(); + } + + private class SaverSAXException extends RuntimeException + { + SaverSAXException ( SAXException e ) + { + _saxException = e; + } + + SAXException _saxException; + } + + private String getPrefixedName ( QName name ) + { + String uri = name.getNamespaceURI(); + String local = name.getLocalPart(); + + if (uri.length() == 0) + return local; + + String prefix = getUriMapping( uri ); + + if (prefix.length() == 0) + return local; + + return prefix + ":" + local; + } + + private void emitNamespacesHelper ( ) + { + for ( iterateMappings() ; hasMapping() ; nextMapping() ) + { + String prefix = mappingPrefix(); + String uri = mappingUri(); + + try + { + _contentHandler.startPrefixMapping( prefix, uri ); + } + catch ( SAXException e ) + { + throw new SaverSAXException( e ); + } + + if (_nsAsAttrs) + if (prefix == null || prefix.length() == 0) + _attributes.addAttribute( "http://www.w3.org/2000/xmlns/", "xmlns", "xmlns", "CDATA", uri ); + else + _attributes.addAttribute( "http://www.w3.org/2000/xmlns/", prefix, "xmlns:" + prefix, "CDATA", uri ); + } + } + + protected boolean emitElement ( SaveCur c, ArrayList attrNames, ArrayList attrValues ) + { + _attributes.clear(); + + if (saveNamespacesFirst()) + emitNamespacesHelper(); + + for ( int i = 0 ; i < attrNames.size() ; i++ ) + { + QName name = (QName) attrNames.get( i ); + + _attributes.addAttribute( + name.getNamespaceURI(), name.getLocalPart(), getPrefixedName( name ), + "CDATA", (String) attrValues.get( i ) ); + } + + if (!saveNamespacesFirst()) + emitNamespacesHelper(); + + QName elemName = c.getName(); + + try + { + _contentHandler.startElement( + elemName.getNamespaceURI(), elemName.getLocalPart(), + getPrefixedName( elemName ), _attributes ); + } + catch ( SAXException e ) + { + throw new SaverSAXException( e ); + } + + return false; + } + + protected void emitFinish ( SaveCur c ) + { + QName name = c.getName(); + + try + { + _contentHandler.endElement( + name.getNamespaceURI(), name.getLocalPart(), getPrefixedName( name ) ); + + for ( iterateMappings() ; hasMapping() ; nextMapping() ) + _contentHandler.endPrefixMapping( mappingPrefix() ); + } + catch ( SAXException e ) + { + throw new SaverSAXException( e ); + } + } + + protected void emitText ( SaveCur c ) + { + assert c.isText(); + + Object src = c.getChars(); + + try + { + if (src instanceof char[]) + { + // Pray the user does not modify the buffer .... + _contentHandler.characters( (char[]) src, c._offSrc, c._cchSrc ); + } + else + { + if (_buf == null) + _buf = new char [ 1024 ]; + + while ( c._cchSrc > 0 ) + { + int cch = java.lang.Math.min( _buf.length, c._cchSrc ); + + CharUtil.getChars( _buf, 0, src, c._offSrc, cch ); + + _contentHandler.characters( _buf, 0, cch ); + + c._offSrc += cch; + c._cchSrc -= cch; + } + } + } + catch ( SAXException e ) + { + throw new SaverSAXException( e ); + } + } + + protected void emitComment ( SaveCur c ) + { + if (_lexicalHandler != null) + { + c.push(); + + c.next(); + + try + { + if (!c.isText()) + _lexicalHandler.comment( null, 0, 0 ); + else + { + Object src = c.getChars(); + + if (src instanceof char[]) + { + // Pray the user does not modify the buffer .... + _lexicalHandler.comment( (char[]) src, c._offSrc, c._cchSrc ); + } + else + { + if (_buf == null || _buf.length < c._cchSrc) + _buf = new char [ java.lang.Math.max( 1024, c._cchSrc ) ]; + + CharUtil.getChars( _buf, 0, src, c._offSrc, c._cchSrc ); + + _lexicalHandler.comment( _buf, 0, c._cchSrc ); + } + } + } + catch ( SAXException e ) + { + throw new SaverSAXException( e ); + } + + c.pop(); + } + } + + protected void emitProcinst ( SaveCur c ) + { + String target = c.getName().getLocalPart(); + + c.push(); + + c.next(); + + String value = CharUtil.getString( c.getChars(), c._offSrc, c._cchSrc ); + + c.pop(); + + try + { + _contentHandler.processingInstruction( c.getName().getLocalPart(), value ); + } + catch ( SAXException e ) + { + throw new SaverSAXException( e ); + } + } + + protected void emitDocType ( String docTypeName, String publicId, String systemId ) + { + if (_lexicalHandler != null) + { + try + { + _lexicalHandler.startDTD( docTypeName, publicId, systemId ); + _lexicalHandler.endDTD(); + } + catch ( SAXException e ) + { + throw new SaverSAXException( e ); + } + } + } + + protected void emitStartDoc ( SaveCur c ) + { + } + + protected void emitEndDoc ( SaveCur c ) + { + } + + private ContentHandler _contentHandler; + private LexicalHandler _lexicalHandler; + + private AttributesImpl _attributes; + + private char[] _buf; + private boolean _nsAsAttrs; + } + + // + // + // + + static abstract class SaveCur + { + final boolean isRoot ( ) { return kind() == ROOT; } + final boolean isElem ( ) { return kind() == ELEM; } + final boolean isAttr ( ) { return kind() == ATTR; } + final boolean isText ( ) { return kind() == TEXT; } + final boolean isComment ( ) { return kind() == COMMENT; } + final boolean isProcinst ( ) { return kind() == PROCINST; } + final boolean isFinish ( ) { return Cur.kindIsFinish( kind() ); } + final boolean isContainer ( ) { return Cur.kindIsContainer( kind() ); } + final boolean isNormalAttr ( ) { return kind() == ATTR && !isXmlns(); } + + final boolean skip ( ) { toEnd(); return next(); } + + abstract void release ( ); + + abstract int kind ( ); + + abstract QName getName ( ); + abstract String getXmlnsPrefix ( ); + abstract String getXmlnsUri ( ); + + abstract boolean isXmlns ( ); + + abstract boolean hasChildren ( ); + abstract boolean hasText ( ); + abstract boolean isTextCData ( ); + + abstract boolean toFirstAttr ( ); + abstract boolean toNextAttr ( ); + abstract String getAttrValue ( ); + + abstract boolean next ( ); + abstract void toEnd ( ); + + abstract void push ( ); + abstract void pop ( ); + + abstract Object getChars ( ); + abstract List getAncestorNamespaces ( ); + abstract XmlDocumentProperties getDocProps ( ); + + int _offSrc; + int _cchSrc; + } + + // TODO - saving a fragment need to take namesapces from root and + // reflect them on the document element + + private static final class DocSaveCur extends SaveCur + { + DocSaveCur ( Cur c ) + { + assert c.isRoot(); + _cur = c.weakCur( this ); + } + + void release ( ) + { + _cur.release(); + _cur = null; + } + + int kind ( ) { return _cur.kind(); } + + QName getName ( ) { return _cur.getName(); } + String getXmlnsPrefix ( ) { return _cur.getXmlnsPrefix(); } + String getXmlnsUri ( ) { return _cur.getXmlnsUri(); } + + boolean isXmlns ( ) { return _cur.isXmlns(); } + + boolean hasChildren ( ) { return _cur.hasChildren(); } + boolean hasText ( ) { return _cur.hasText(); } + boolean isTextCData ( ) { return _cur.isTextCData(); } + + boolean toFirstAttr ( ) { return _cur.toFirstAttr(); } + boolean toNextAttr ( ) { return _cur.toNextAttr(); } + String getAttrValue ( ) { assert _cur.isAttr(); return _cur.getValueAsString(); } + + void toEnd ( ) { _cur.toEnd(); } + boolean next ( ) { return _cur.next(); } + + void push ( ) { _cur.push(); } + void pop ( ) { _cur.pop(); } + + List getAncestorNamespaces ( ) { return null; } + + Object getChars ( ) + { + Object o = _cur.getChars( -1 ); + + _offSrc = _cur._offSrc; + _cchSrc = _cur._cchSrc; + + return o; + } + + XmlDocumentProperties getDocProps ( ) { return Locale.getDocProps(_cur, false); } + + private Cur _cur; + } + + private static abstract class FilterSaveCur extends SaveCur + { + FilterSaveCur ( SaveCur c ) + { + assert c.isRoot(); + _cur = c; + } + + // Can filter anything by root and attributes and text + protected abstract boolean filter ( ); + + void release ( ) + { + _cur.release(); + _cur = null; + } + + int kind ( ) { return _cur.kind(); } + + QName getName ( ) { return _cur.getName(); } + String getXmlnsPrefix ( ) { return _cur.getXmlnsPrefix(); } + String getXmlnsUri ( ) { return _cur.getXmlnsUri(); } + + boolean isXmlns ( ) { return _cur.isXmlns(); } + + boolean hasChildren ( ) { return _cur.hasChildren(); } + boolean hasText ( ) { return _cur.hasText(); } + boolean isTextCData ( ) { return _cur.isTextCData(); } + + boolean toFirstAttr ( ) { return _cur.toFirstAttr(); } + boolean toNextAttr ( ) { return _cur.toNextAttr(); } + String getAttrValue ( ) { return _cur.getAttrValue(); } + + void toEnd ( ) { _cur.toEnd(); } + + boolean next ( ) + { + if (!_cur.next()) + return false; + + if (!filter()) + return true; + + assert !isRoot() && !isText() && !isAttr(); + + toEnd(); + + return next(); + } + + void push ( ) { _cur.push(); } + void pop ( ) { _cur.pop(); } + + List getAncestorNamespaces ( ) { return _cur.getAncestorNamespaces(); } + + Object getChars ( ) + { + Object o = _cur.getChars(); + + _offSrc = _cur._offSrc; + _cchSrc = _cur._cchSrc; + + return o; + } + + XmlDocumentProperties getDocProps ( ) { return _cur.getDocProps(); } + + private SaveCur _cur; + } + + private static final class FilterPiSaveCur extends FilterSaveCur + { + FilterPiSaveCur ( SaveCur c, String target ) + { + super( c ); + + _piTarget = target; + } + + protected boolean filter ( ) + { + return kind() == PROCINST && getName().getLocalPart().equals( _piTarget ); + } + + private String _piTarget; + } + + private static final class FragSaveCur extends SaveCur + { + FragSaveCur ( Cur start, Cur end, QName synthElem ) + { + _saveAttr = start.isAttr() && start.isSamePos( end ); + + _cur = start.weakCur( this ); + _end = end.weakCur( this ); + + _elem = synthElem; + + _state = ROOT_START; + + _stateStack = new int [ 8 ]; + + start.push(); + computeAncestorNamespaces( start ); + start.pop(); + } + + List getAncestorNamespaces ( ) + { + return _ancestorNamespaces; + } + + private void computeAncestorNamespaces ( Cur c ) + { + _ancestorNamespaces = new ArrayList(); + + while ( c.toParentRaw() ) + { + if (c.toFirstAttr()) + { + do + { + if (c.isXmlns()) + { + String prefix = c.getXmlnsPrefix(); + String uri = c.getXmlnsUri(); + + // Don't let xmlns:foo="" get used + + if (uri.length() > 0 || prefix.length() == 0) + { + _ancestorNamespaces.add( c.getXmlnsPrefix() ); + _ancestorNamespaces.add( c.getXmlnsUri() ); + } + } + } + while ( c.toNextAttr() ); + + c.toParent(); + } + } + } + + // + // + // + + void release ( ) + { + _cur.release(); + _cur = null; + + _end.release(); + _end = null; + } + + int kind ( ) + { + switch ( _state ) + { + case ROOT_START : return ROOT; + case ELEM_START : return ELEM; + case ELEM_END : return -ELEM; + case ROOT_END : return -ROOT; + } + + assert _state == CUR; + + return _cur.kind(); + } + + QName getName ( ) + { + switch ( _state ) + { + case ROOT_START : + case ROOT_END : return null; + case ELEM_START : + case ELEM_END : return _elem; + } + + assert _state == CUR; + + return _cur.getName(); + } + + String getXmlnsPrefix ( ) + { + assert _state == CUR && _cur.isAttr(); + return _cur.getXmlnsPrefix(); + } + + String getXmlnsUri ( ) + { + assert _state == CUR && _cur.isAttr(); + return _cur.getXmlnsUri(); + } + + boolean isXmlns ( ) + { + assert _state == CUR && _cur.isAttr(); + return _cur.isXmlns(); + } + + boolean hasChildren ( ) + { + boolean hasChildren = false; + + if (isContainer()) + { // is there a faster way to do this? + push(); + next(); + + if (!isText() && !isFinish()) + hasChildren = true; + + pop(); + } + + return hasChildren; + } + + boolean hasText ( ) + { + boolean hasText = false; + + if (isContainer()) + { + push(); + next(); + + if (isText()) + hasText = true; + + pop(); + } + + return hasText; + } + + boolean isTextCData ( ) + { + return _cur.isTextCData(); + } + + Object getChars ( ) + { + assert _state == CUR && _cur.isText(); + + Object src = _cur.getChars( -1 ); + + _offSrc = _cur._offSrc; + _cchSrc = _cur._cchSrc; + + return src; + } + + boolean next ( ) + { + switch ( _state ) + { + case ROOT_START : + { + _state = _elem == null ? CUR : ELEM_START; + break; + } + + case ELEM_START : + { + if (_saveAttr) + _state = ELEM_END; + else + { + if (_cur.isAttr()) + { + _cur.toParent(); + _cur.next(); + } + + if (_cur.isSamePos( _end )) + _state = ELEM_END; + else + _state = CUR; + } + + break; + } + + case CUR : + { + assert !_cur.isAttr(); + + _cur.next(); + + if (_cur.isSamePos( _end )) + _state = _elem == null ? ROOT_END : ELEM_END; + + break; + } + + case ELEM_END : + { + _state = ROOT_END; + break; + } + case ROOT_END : + return false; + } + + return true; + } + + void toEnd ( ) + { + switch ( _state ) + { + case ROOT_START : _state = ROOT_END; return; + case ELEM_START : _state = ELEM_END; return; + case ROOT_END : + case ELEM_END : return; + } + + assert _state == CUR && !_cur.isAttr() && !_cur.isText(); + + _cur.toEnd(); + } + + boolean toFirstAttr ( ) + { + switch ( _state ) + { + case ROOT_END : + case ELEM_END : + case ROOT_START : return false; + case CUR : return _cur.toFirstAttr(); + } + + assert _state == ELEM_START; + + if (!_cur.isAttr()) + return false; + + _state = CUR; + + return true; + } + + boolean toNextAttr ( ) + { + assert _state == CUR; + return !_saveAttr && _cur.toNextAttr(); + } + + String getAttrValue ( ) + { + assert _state == CUR && _cur.isAttr(); + return _cur.getValueAsString(); + } + + void push ( ) + { + if (_stateStackSize == _stateStack.length) + { + int[] newStateStack = new int [ _stateStackSize * 2 ]; + System.arraycopy( _stateStack, 0, newStateStack, 0, _stateStackSize ); + _stateStack = newStateStack; + } + + _stateStack [ _stateStackSize++ ] = _state; + _cur.push(); + } + + void pop () + { + _cur.pop(); + _state = _stateStack [ --_stateStackSize ]; + } + + XmlDocumentProperties getDocProps ( ) { return Locale.getDocProps(_cur, false); } + + // + // + // + + private Cur _cur; + private Cur _end; + + private ArrayList _ancestorNamespaces; + + private QName _elem; + + private boolean _saveAttr; + + private static final int ROOT_START = 1; + private static final int ELEM_START = 2; + private static final int ROOT_END = 3; + private static final int ELEM_END = 4; + private static final int CUR = 5; + + private int _state; + + private int[] _stateStack; + private int _stateStackSize; + } + + private static final class PrettySaveCur extends SaveCur + { + PrettySaveCur ( SaveCur c, XmlOptions options ) + { + _sb = new StringBuffer(); + _stack = new ArrayList(); + + _cur = c; + + assert options != null; + + _prettyIndent = 2; + + if (options.hasOption( XmlOptions.SAVE_PRETTY_PRINT_INDENT )) + { + _prettyIndent = + ((Integer) options.get( XmlOptions.SAVE_PRETTY_PRINT_INDENT )).intValue(); + } + + if (options.hasOption( XmlOptions.SAVE_PRETTY_PRINT_OFFSET )) + { + _prettyOffset = + ((Integer) options.get( XmlOptions.SAVE_PRETTY_PRINT_OFFSET )).intValue(); + } + + if (options.hasOption( XmlOptions.LOAD_SAVE_CDATA_BOOKMARKS )) + { + _useCDataBookmarks = true; + } + } + + List getAncestorNamespaces ( ) { return _cur.getAncestorNamespaces(); } + + void release ( ) { _cur.release(); } + + int kind ( ) { return _txt == null ? _cur.kind() : TEXT; } + + QName getName ( ) { assert _txt == null; return _cur.getName(); } + String getXmlnsPrefix ( ) { assert _txt == null; return _cur.getXmlnsPrefix(); } + String getXmlnsUri ( ) { assert _txt == null; return _cur.getXmlnsUri(); } + + boolean isXmlns ( ) { return _txt == null ? _cur.isXmlns() : false; } + + boolean hasChildren ( ) { return _txt == null ? _cur.hasChildren() : false; } + boolean hasText ( ) { return _txt == null ? _cur.hasText() : false; } + + // _cur.isTextCData() is expensive do it only if useCDataBookmarks option is enabled + boolean isTextCData ( ) { return _txt == null ? (_useCDataBookmarks && _cur.isTextCData()) + : _isTextCData; } + + boolean toFirstAttr ( ) { assert _txt == null; return _cur.toFirstAttr(); } + boolean toNextAttr ( ) { assert _txt == null; return _cur.toNextAttr(); } + String getAttrValue ( ) { assert _txt == null; return _cur.getAttrValue(); } + + void toEnd ( ) + { + assert _txt == null; + _cur.toEnd(); + + if (_cur.kind() == -ELEM) + _depth--; + } + + boolean next ( ) + { + int k; + + if (_txt != null) + { + assert _txt.length() > 0; + assert !_cur.isText(); + _txt = null; + _isTextCData = false; + k = _cur.kind(); + } + else + { + int prevKind = k = _cur.kind(); + + if (!_cur.next()) + return false; + + _sb.delete( 0, _sb.length() ); + + assert _txt == null; + + // place any text encountered in the buffer + if (_cur.isText()) + { + // _cur.isTextCData() is expensive do it only if useCDataBookmarks option is enabled + _isTextCData = _useCDataBookmarks && _cur.isTextCData(); + CharUtil.getString( _sb, _cur.getChars(), _cur._offSrc, _cur._cchSrc ); + _cur.next(); + trim( _sb ); + } + + k = _cur.kind(); + + // Check for non leaf, _prettyIndent < 0 means that the save is all on one line + + if (_prettyIndent >= 0 && + prevKind != COMMENT && prevKind != PROCINST && (prevKind != ELEM || k != -ELEM)) +// if (prevKind != COMMENT && prevKind != PROCINST && (prevKind != ELEM || k != -ELEM)) + { + if (_sb.length() > 0) + { + _sb.insert( 0, _newLine ); + spaces( _sb, _newLine.length(), _prettyOffset + _prettyIndent * _depth ); + } + + if (k != -ROOT) + { + if (prevKind != ROOT) + _sb.append( _newLine ); + + int d = k < 0 ? _depth - 1 : _depth; + spaces( _sb, _sb.length(), _prettyOffset + _prettyIndent * d ); + } + } + + if (_sb.length() > 0) + { + _txt = _sb.toString(); + k = TEXT; + } + } + + if (k == ELEM) + _depth++; + else if (k == -ELEM) + _depth--; + + return true; + } + + void push ( ) + { + _cur.push(); + _stack.add( _txt ); + _stack.add( new Integer( _depth ) ); + _isTextCData = false; + } + + void pop ( ) + { + _cur.pop(); + _depth = ((Integer) _stack.remove( _stack.size() - 1 )).intValue(); + _txt = (String) _stack.remove( _stack.size() - 1 ); + _isTextCData = false; + } + + Object getChars ( ) + { + if (_txt != null) + { + _offSrc = 0; + _cchSrc = _txt.length(); + return _txt; + } + + Object o = _cur.getChars(); + + _offSrc = _cur._offSrc; + _cchSrc = _cur._cchSrc; + + return o; + } + + XmlDocumentProperties getDocProps ( ) { return _cur.getDocProps(); } + + static void spaces ( StringBuffer sb, int offset, int count ) + { + while ( count-- > 0 ) + sb.insert( offset, ' ' ); + } + + static void trim ( StringBuffer sb ) + { + int i; + + for ( i = 0 ; i < sb.length() ; i++ ) + if (!CharUtil.isWhiteSpace( sb.charAt( i ) )) + break; + + sb.delete( 0, i ); + + for ( i = sb.length() ; i > 0 ; i-- ) + if (!CharUtil.isWhiteSpace( sb.charAt( i - 1 ) )) + break; + + sb.delete( i, sb.length() ); + } + + private SaveCur _cur; + + private int _prettyIndent; + private int _prettyOffset; + + private String _txt; + private StringBuffer _sb; + + private int _depth; + + private ArrayList _stack; + private boolean _isTextCData = false; + private boolean _useCDataBookmarks = false; + } + + + // + // + // + + private final Locale _locale; + private final long _version; + + private SaveCur _cur; + + private List _ancestorNamespaces; + private Map _suggestedPrefixes; + protected XmlOptionCharEscapeMap _replaceChar; + private boolean _useDefaultNamespace; + private Map _preComputedNamespaces; + private boolean _saveNamespacesFirst; + + private ArrayList _attrNames; + private ArrayList _attrValues; + + private ArrayList _namespaceStack; + private int _currentMapping; + private HashMap _uriMap; + private HashMap _prefixMap; + private String _initialDefaultUri; + + static final String _newLine = + SystemProperties.getProperty( "line.separator" ) == null + ? "\n" + : SystemProperties.getProperty( "line.separator" ); +} diff --git a/xmlbeans/src/store/org/apache/xmlbeans/impl/store/Validate.java b/xmlbeans/src/store/org/apache/xmlbeans/impl/store/Validate.java new file mode 100644 index 000000000..fadfa2b2c --- /dev/null +++ b/xmlbeans/src/store/org/apache/xmlbeans/impl/store/Validate.java @@ -0,0 +1,284 @@ +/* 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.store; + +import org.apache.xmlbeans.impl.common.ValidatorListener; +import javax.xml.stream.Location; +import org.apache.xmlbeans.XmlCursor; +import javax.xml.namespace.QName; + +final class Validate implements ValidatorListener.Event +{ + Validate ( Cur c, ValidatorListener sink ) + { + if (!c.isUserNode()) + throw new IllegalStateException( "Inappropriate location to validate" ); + + _sink = sink; + _cur = c; + _textCur = c.tempCur(); + _hasText = false; + + _cur.push(); + + try + { + process(); + } + finally + { + _cur.pop(); + _cur = null; + + _sink = null; + + _textCur.release(); + } + } + + private void process ( ) + { + emitEvent( ValidatorListener.BEGIN ); + + if (_cur.isAttr()) + { + // If validating an attr, I'm really validating the contents of that attr. So, go to + // any text value and shove it thru the validator. + + _cur.next(); + + if (_cur.isText()) + emitText(); + } + else + { + assert _cur.isContainer(); + + // Do the attrs of the top container + + doAttrs(); + + for ( _cur.next() ; ! _cur.isAtEndOfLastPush() ; _cur.next() ) + { + switch ( _cur.kind() ) + { + case Cur.ELEM : + emitEvent( ValidatorListener.BEGIN ); + doAttrs(); + break; + + case - Cur.ELEM : + emitEvent( ValidatorListener.END ); + break; + + case Cur.TEXT : + emitText(); + break; + + case Cur.COMMENT : + case Cur.PROCINST : + _cur.toEnd(); + break; + + default : + throw new RuntimeException( "Unexpected kind: " + _cur.kind() ); + } + } + } + + emitEvent( ValidatorListener.END ); + } + + private void doAttrs ( ) + { + // When processing attrs, there can be no accumulated text because there would have been + // a preceeding event which would have flushged the text. + + assert !_hasText; + + if (_cur.toFirstAttr()) + { + do + { + if (_cur.isNormalAttr() && !_cur.getUri().equals( Locale._xsi )) + _sink.nextEvent( ValidatorListener.ATTR, this ); + } + while ( _cur.toNextAttr() ); + + _cur.toParent(); + } + + _sink.nextEvent( ValidatorListener.ENDATTRS, this ); + } + + private void emitText ( ) + { + assert _cur.isText(); + + if (_hasText) + { + if (_oneChunk) + { + if (_textSb == null) + _textSb = new StringBuffer(); + else + _textSb.delete( 0, _textSb.length() ); + + assert _textCur.isText(); + + CharUtil.getString( + _textSb, _textCur.getChars( -1 ), _textCur._offSrc, _textCur._cchSrc ); + + _oneChunk = false; + } + + assert _textSb != null && _textSb.length() > 0; + + CharUtil.getString( _textSb, _cur.getChars( -1 ), _cur._offSrc, _cur._cchSrc ); + } + else + { + _hasText = true; + _oneChunk = true; + _textCur.moveToCur( _cur ); + } + } + + private void emitEvent ( int kind ) + { + assert kind != ValidatorListener.TEXT; + assert kind != ValidatorListener.ATTR || !_hasText; + assert kind != ValidatorListener.ENDATTRS || !_hasText; + + if (_hasText) + { + _sink.nextEvent( ValidatorListener.TEXT, this ); + _hasText = false; + } + + _sink.nextEvent( kind, this ); + } + + public String getText ( ) + { + if (_cur.isAttr()) + return _cur.getValueAsString(); + + assert _hasText; + assert _oneChunk || (_textSb != null && _textSb.length() > 0); + assert !_oneChunk || _textCur.isText(); + + return _oneChunk ? _textCur.getCharsAsString( -1 ) : _textSb.toString(); + } + + public String getText ( int wsr ) + { + if (_cur.isAttr()) + return _cur.getValueAsString( wsr ); + + assert _hasText; + assert _oneChunk || (_textSb != null && _textSb.length() > 0); + assert !_oneChunk || _textCur.isText(); + + if (_oneChunk) + return _textCur.getCharsAsString( -1, wsr ); + + return Locale.applyWhiteSpaceRule( _textSb.toString(), wsr ); + } + + public boolean textIsWhitespace ( ) + { + if (_cur.isAttr()) + { + return + _cur._locale.getCharUtil().isWhiteSpace( + _cur.getFirstChars(), _cur._offSrc, _cur._cchSrc ); + } + + assert _hasText; + + if (_oneChunk) + { + return + _cur._locale.getCharUtil().isWhiteSpace( + _textCur.getChars( -1 ), _textCur._offSrc, _textCur._cchSrc ); + } + + String s = _textSb.toString(); + + return _cur._locale.getCharUtil().isWhiteSpace( s, 0, s.length() ); + } + + public String getNamespaceForPrefix ( String prefix ) + { + return _cur.namespaceForPrefix( prefix, true ); + } + + public XmlCursor getLocationAsCursor ( ) + { + return new Cursor( _cur ); + } + + public Location getLocation ( ) + { + return null; + } + + public String getXsiType ( ) + { + return _cur.getAttrValue( Locale._xsiType ); + } + + public String getXsiNil ( ) + { + return _cur.getAttrValue( Locale._xsiNil ); + } + + public String getXsiLoc ( ) + { + return _cur.getAttrValue( Locale._xsiLoc ); + } + + public String getXsiNoLoc ( ) + { + return _cur.getAttrValue( Locale._xsiNoLoc ); + } + + public QName getName ( ) + { + return _cur.isAtLastPush() ? null : _cur.getName(); + } + + // + // + // + + private ValidatorListener _sink; + + private Cur _cur; + + // Two ways to accumulate text. First, I can have a Cur positioned at the text. I do this + // instead of getting the there there because white space rules are applied at a later point. + // This way, when I turn the text into a String, I can cache the string. If multiple chunks + // of text exists for one event, then I accumulate all the text into a string buffer and I, + // then, don't care about caching Strings. + + private boolean _hasText; + private boolean _oneChunk; + + private Cur _textCur; + private StringBuffer _textSb; +} \ No newline at end of file diff --git a/xmlbeans/src/store/org/apache/xmlbeans/impl/store/Xobj.java b/xmlbeans/src/store/org/apache/xmlbeans/impl/store/Xobj.java new file mode 100644 index 000000000..6cbfa84c6 --- /dev/null +++ b/xmlbeans/src/store/org/apache/xmlbeans/impl/store/Xobj.java @@ -0,0 +1,3251 @@ +/* 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.store; + +import org.apache.xmlbeans.CDataBookmark; +import org.w3c.dom.Attr; +import org.w3c.dom.CDATASection; +import org.w3c.dom.CharacterData; +import org.w3c.dom.Comment; +import org.w3c.dom.Document; +import org.w3c.dom.DocumentFragment; +import org.w3c.dom.DocumentType; +import org.w3c.dom.DOMException; +import org.w3c.dom.DOMImplementation; +import org.w3c.dom.Element; +import org.w3c.dom.EntityReference; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.w3c.dom.ProcessingInstruction; +import org.w3c.dom.Text; +import org.w3c.dom.DOMImplementation; + +// DOM Level 3 +import org.w3c.dom.UserDataHandler; +import org.w3c.dom.DOMConfiguration; +import org.w3c.dom.TypeInfo; + + +import javax.xml.transform.Source; + +import java.io.PrintStream; + +import java.util.Iterator; +import java.util.Map; +import java.util.ArrayList; +import java.util.List; +import java.util.Vector; + +import org.apache.xmlbeans.impl.soap.Detail; +import org.apache.xmlbeans.impl.soap.DetailEntry; +import org.apache.xmlbeans.impl.soap.MimeHeaders; +import org.apache.xmlbeans.impl.soap.Name; +import org.apache.xmlbeans.impl.soap.SOAPBody; +import org.apache.xmlbeans.impl.soap.SOAPBodyElement; +import org.apache.xmlbeans.impl.soap.SOAPElement; +import org.apache.xmlbeans.impl.soap.SOAPEnvelope; +import org.apache.xmlbeans.impl.soap.SOAPException; +import org.apache.xmlbeans.impl.soap.SOAPFactory; +import org.apache.xmlbeans.impl.soap.SOAPFault; +import org.apache.xmlbeans.impl.soap.SOAPFaultElement; +import org.apache.xmlbeans.impl.soap.SOAPHeader; +import org.apache.xmlbeans.impl.soap.SOAPHeaderElement; +import org.apache.xmlbeans.impl.soap.SOAPPart; +import org.apache.xmlbeans.impl.store.Locale.LoadContext; + +import org.apache.xmlbeans.impl.store.DomImpl.Dom; +import org.apache.xmlbeans.impl.store.DomImpl.CharNode; +import org.apache.xmlbeans.impl.store.DomImpl.TextNode; +import org.apache.xmlbeans.impl.store.DomImpl.CdataNode; +import org.apache.xmlbeans.impl.store.DomImpl.SaajTextNode; +import org.apache.xmlbeans.impl.store.DomImpl.SaajCdataNode; + +import org.apache.xmlbeans.XmlBeans; +import org.apache.xmlbeans.SchemaField; +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.SchemaTypeLoader; +import org.apache.xmlbeans.XmlCursor; +import org.apache.xmlbeans.XmlCursor.XmlMark; +import org.apache.xmlbeans.XmlOptions; +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.XmlException; +import org.apache.xmlbeans.QNameSet; + +import org.apache.xmlbeans.impl.values.TypeStore; +import org.apache.xmlbeans.impl.values.TypeStoreUser; +import org.apache.xmlbeans.impl.values.TypeStoreVisitor; +import org.apache.xmlbeans.impl.values.TypeStoreUserFactory; + +import javax.xml.namespace.QName; + +import org.apache.xmlbeans.impl.common.ValidatorListener; +import org.apache.xmlbeans.impl.common.XmlLocale; +import org.apache.xmlbeans.impl.common.QNameHelper; + +abstract class Xobj implements TypeStore +{ + static final int TEXT = Cur.TEXT; + static final int ROOT = Cur.ROOT; + static final int ELEM = Cur.ELEM; + static final int ATTR = Cur.ATTR; + static final int COMMENT = Cur.COMMENT; + static final int PROCINST = Cur.PROCINST; + + static final int END_POS = Cur.END_POS; + static final int NO_POS = Cur.NO_POS; + + Xobj ( Locale l, int kind, int domType ) + { + assert kind == ROOT || kind == ELEM || kind == ATTR || kind == COMMENT || kind == PROCINST; + + _locale = l; + _bits = (domType << 4) + kind; + } + + final boolean entered ( ) { return _locale.entered(); } + + final int kind ( ) { return _bits & 0xF; } + final int domType ( ) { return (_bits & 0xF0) >> 4; } + + final boolean isRoot ( ) { return kind() == ROOT; } + final boolean isAttr ( ) { return kind() == ATTR; } + final boolean isElem ( ) { return kind() == ELEM; } + final boolean isProcinst ( ) { return kind() == PROCINST; } + final boolean isComment ( ) { return kind() == COMMENT; } + final boolean isContainer ( ) { return Cur.kindIsContainer( kind() ); } + final boolean isUserNode ( ) { int k = kind(); return k == ELEM || k == ROOT || (k == ATTR && !isXmlns()); } + + final boolean isNormalAttr ( ) { return isAttr() && !Locale.isXmlns( _name ); } + final boolean isXmlns ( ) { return isAttr() && Locale.isXmlns( _name ); } + + final int cchValue ( ) { return _cchValue; } + final int cchAfter ( ) { return _cchAfter; } + + final int posAfter ( ) { return 2 + _cchValue; } + final int posMax ( ) { return 2 + _cchValue + _cchAfter; } + + final String getXmlnsPrefix ( ) { return Locale.xmlnsPrefix( _name ); } + final String getXmlnsUri ( ) { return getValueAsString(); } + + final boolean hasTextEnsureOccupancy ( ) + { + ensureOccupancy(); + return hasTextNoEnsureOccupancy(); + } + + final boolean hasTextNoEnsureOccupancy ( ) + { + if (_cchValue > 0) + return true; + + Xobj lastAttr = lastAttr(); + + return lastAttr != null && lastAttr._cchAfter > 0; + } + + final boolean hasAttrs ( ) { return _firstChild != null && _firstChild.isAttr(); } + final boolean hasChildren ( ) { return _lastChild != null && !_lastChild .isAttr(); } + + + /** + * this method is to speed up DomImpl + * when underlying obj is an Xobj + * + * @return 0 or 1 dom children; val 2 indicates that DomImpl needs to + * compute the result itself + */ + final protected int getDomZeroOneChildren() + { + if (_firstChild == null && + _srcValue == null && + _charNodesValue == null) + return 0; + + if (_lastChild != null && + _lastChild.isAttr() && + _lastChild._charNodesAfter == null && + _lastChild._srcAfter == null && + _srcValue == null && + _charNodesValue == null + ) + return 0; + + if (_firstChild == _lastChild && + _firstChild != null && + !_firstChild.isAttr() && + _srcValue == null && + _charNodesValue == null && + _firstChild._srcAfter == null + ) + return 1; + + if (_firstChild == null && + _srcValue != null && + ( _charNodesValue == null || + (_charNodesValue._next == null && + _charNodesValue._cch == _cchValue)) + ) + return 1; + //single elem after an attr + Xobj lastAttr = lastAttr(); + Xobj node = lastAttr == null ? + null : lastAttr._nextSibling; + if (lastAttr != null && + lastAttr._srcAfter == null && + node != null && + node._srcAfter == null && + node._nextSibling == null) + return 1; + + return 2; + } + + /** + * can one use the _firstChild pointer to retrieve + * the first DOM child + * + * @return + */ + final protected boolean isFirstChildPtrDomUsable() + { + if (_firstChild == null && + _srcValue == null && + _charNodesValue == null) + return true; + + if (_firstChild != null && + !_firstChild.isAttr() && + _srcValue == null && + _charNodesValue == null) + { + assert (_firstChild instanceof Xobj.NodeXobj): + "wrong node type"; + return true; + } + return false; + } + + /** + * can one use the _nextSibling pointer to retrieve + * the next DOM sibling + * @return + */ + final protected boolean isNextSiblingPtrDomUsable() + { + if (_charNodesAfter == null && + _srcAfter == null) + { + assert (_nextSibling == null || + _nextSibling instanceof Xobj.NodeXobj): + "wrong node type"; + return true; + } + return false; + } + /** + * can one use the _charNodesValue pointer to retrieve + * the next DOM sibling + * + * @return + */ + final protected boolean isExistingCharNodesValueUsable() + { + if (_srcValue == null) return false; + if (_charNodesValue != null && _charNodesValue._next == null + && _charNodesValue._cch == _cchValue) + return true; + return false; + } + final protected boolean isCharNodesValueUsable() + { + return isExistingCharNodesValueUsable() || + (_charNodesValue = + Cur.updateCharNodes(_locale, this, + _charNodesValue, _cchValue)) != null; + } + + /** + * can one use the _charNodesAfter pointer to retrieve + * the next DOM sibling + * + * @return + */ + final protected boolean isCharNodesAfterUsable() + { + if (_srcAfter == null) return false; + if (_charNodesAfter != null && _charNodesAfter._next == null + && _charNodesAfter._cch == this._cchAfter) + return true; + return (_charNodesAfter = + Cur.updateCharNodes(_locale, this, + _charNodesAfter, _cchAfter)) != null; + } + + + final Xobj lastAttr ( ) + { + if (_firstChild == null || !_firstChild.isAttr()) + return null; + + Xobj lastAttr = _firstChild; + + while ( lastAttr._nextSibling != null && lastAttr._nextSibling.isAttr() ) + lastAttr = lastAttr._nextSibling; + + return lastAttr; + } + + abstract Dom getDom ( ); + + abstract Xobj newNode ( Locale l ); + + final int cchLeft ( int p ) + { + if (isRoot() && p == 0) + return 0; + + Xobj x = getDenormal( p ); + + p = posTemp(); + int pa = x.posAfter(); + + return p - (p < pa ? 1 : pa); + } + + final int cchRight ( int p ) + { + assert p < posMax(); + + if (p <= 0) + return 0; + + int pa = posAfter(); + + return p < pa ? pa - p - 1 : posMax() - p; + } + + // + // Dom interface + // + + public final Locale locale ( ) { return _locale; } + public final int nodeType ( ) { return domType(); } + public final QName getQName ( ) { return _name; } + + public final Cur tempCur ( ) { Cur c = _locale.tempCur(); c.moveTo( this ); return c; } + + public void dump ( PrintStream o, Object ref ) { Cur.dump( o, (Xobj) this, ref ); } + public void dump ( PrintStream o ) { Cur.dump( o, this, this ); } + public void dump ( ) { dump( System.out ); } + + // + // + // + + final Cur getEmbedded ( ) + { + _locale.embedCurs(); + + return _embedded; + } + + // Incoming p must be at text (implicitly denormalized) + + final boolean inChars ( int p, Xobj xIn, int pIn, int cch, boolean includeEnd ) + { + assert p > 0 && p < posMax() && p != posAfter() - 1 && cch > 0; + assert xIn.isNormal( pIn ); + + // No need to denormalize "in" if the right hand side is excluded. Denormalizing deals + // with the case where p is END_POS. + + int offset; + + if (includeEnd) + { + // Can't denormalize at the beginning of the document + + if (xIn.isRoot() && pIn == 0) + return false; + + xIn = xIn.getDenormal( pIn ); + pIn = xIn.posTemp(); + + offset = 1; + } + else + offset = 0; + + return xIn == this && pIn >= p && pIn < p + (cch < 0 ? cchRight( p ) : cch) + offset; + } + + // Is x/p just after the end of this + + final boolean isJustAfterEnd ( Xobj x, int p ) + { + assert x.isNormal( p ); + + // Get denormalize at the beginning of the doc + + if (x.isRoot() && p == 0) + return false; + + return + x == this + ? p == posAfter() + : x.getDenormal( p ) == this && x.posTemp() == posAfter(); + } + + final boolean isInSameTree ( Xobj x ) + { + if (_locale != x._locale) + return false; + + for ( Xobj y = this ; ; y = y._parent ) + { + if (y == x) + return true; + + if (y._parent == null) + { + for ( ; ; x = x._parent ) + { + if (x == this) + return true; + + if (x._parent == null) + return x == y; + } + } + } + } + + final boolean contains ( Cur c ) + { + assert c.isNormal(); + + return contains( c._xobj, c._pos ); + } + + final boolean contains ( Xobj x, int p ) + { + assert x.isNormal( p ); + + if (this == x) + return p == END_POS || (p > 0 && p < posAfter()); + + if (_firstChild == null) + return false; + + for ( ; x != null ; x = x._parent ) + if (x == this) + return true; + + return false; + } + + final Bookmark setBookmark ( int p, Object key, Object value ) + { + assert isNormal( p ); + + for ( Bookmark b = _bookmarks ; b != null ; b = b._next ) + { + if (p == b._pos && key == b._key) + { + if (value == null) + { + _bookmarks = b.listRemove( _bookmarks ); + return null; + } + + b._value = value; + + return b; + } + } + + if (value == null) + return null; + + Bookmark b = new Bookmark(); + + b._xobj = this; + b._pos = p; + b._key = key; + b._value = value; + + _bookmarks = b.listInsert( _bookmarks ); + + return b; + } + + final boolean hasBookmark(Object key, int pos) + { + for ( Bookmark b = _bookmarks ; b != null ; b = b._next ) + if ( b._pos == pos && key == b._key ) + { + //System.out.println("hasCDataBookmark pos: " + pos + " xobj: " + getQName() + " b._pos: " + _bookmarks._pos); + return true; + } + + return false; + } + + final Xobj findXmlnsForPrefix ( String prefix ) + { + assert isContainer() && prefix != null; + + for ( Xobj c = this ; c != null ; c = c._parent ) + for ( Xobj a = c.firstAttr() ; a != null ; a = a.nextAttr() ) + if (a.isXmlns() && a.getXmlnsPrefix().equals( prefix )) + return a; + + return null; + } + + final boolean removeAttr ( QName name ) + { + assert isContainer(); + + Xobj a = getAttr( name ); + + if (a == null) + return false; + + Cur c = a.tempCur(); + + for ( ; ; ) + { + c.moveNode( null ); + + a = getAttr( name ); + + if (a == null) + break; + + c.moveTo( a ); + } + + c.release(); + + return true; + } + + final Xobj setAttr ( QName name, String value ) + { + assert isContainer(); + + Cur c = tempCur(); + + if (c.toAttr( name )) + c.removeFollowingAttrs(); + else + { + c.next(); + c.createAttr( name ); + } + + c.setValue( value ); + + Xobj a = c._xobj; + + c.release(); + + return a; + } + + final void setName ( QName newName ) + { + assert isAttr() || isElem() || isProcinst(); + assert newName != null; + + if (!_name.equals( newName ) || !_name.getPrefix().equals( newName.getPrefix() )) + { +// TODO - this is not a structural change .... perhaps should not issue a change here? + _locale.notifyChange(); + + QName oldName = _name; + + _name = newName; + if (this instanceof Xobj.NamedNodeXobj) + { + NamedNodeXobj me = (NamedNodeXobj)this; + me._canHavePrefixUri = true; + } + + if (!isProcinst()) + { + Xobj disconnectFromHere = this; + + if (isAttr() && _parent != null) + { + if (oldName.equals( Locale._xsiType ) || newName.equals( Locale._xsiType )) + disconnectFromHere = _parent; + + if (oldName.equals( Locale._xsiNil ) || newName.equals( Locale._xsiNil )) + _parent.invalidateNil(); + } + + disconnectFromHere.disconnectNonRootUsers(); + } + + _locale._versionAll++; + _locale._versionSansText++; + } + } + + final Xobj ensureParent ( ) + { + assert _parent != null || (!isRoot() && cchAfter() == 0); + return _parent == null ? new DocumentFragXobj( _locale ).appendXobj( this ) : _parent; + } + + final Xobj firstAttr ( ) + { + return _firstChild == null || !_firstChild.isAttr() ? null : _firstChild; + } + + final Xobj nextAttr ( ) + { + if (_firstChild != null && _firstChild.isAttr()) + return _firstChild; + + if (_nextSibling != null && _nextSibling.isAttr()) + return _nextSibling; + + return null; + } + + final boolean isValid ( ) + { + if (isVacant() && (_cchValue != 0 || _user == null)) + return false; + + return true; + } + + final int posTemp ( ) + { + return _locale._posTemp; + } + + final Xobj getNormal ( int p ) + { + assert p == END_POS || (p >= 0 && p <= posMax()); + + Xobj x = this; + + if (p == x.posMax()) + { + if (x._nextSibling != null) + { + x = x._nextSibling; + p = 0; + } + else + { + x = x.ensureParent(); + p = END_POS; + } + } + else if (p == x.posAfter() - 1) + p = END_POS; + + _locale._posTemp = p; + + return x; + } + + // Can't denormalize a position at the very beginning of the document. No where to go to the + // left! + + final Xobj getDenormal ( int p ) + { + assert END_POS == -1; + assert !isRoot() || p == END_POS || p > 0; + + Xobj x = this; + + if (p == 0) + { + if (x._prevSibling == null) + { + x = x.ensureParent(); + p = x.posAfter() - 1; + } + else + { + x = x._prevSibling; + p = x.posMax(); + } + } + else if (p == END_POS) + { + if (x._lastChild == null) + p = x.posAfter() - 1; + else + { + x = x._lastChild; + p = x.posMax(); + } + } + + _locale._posTemp = p; + + return x; + } + + final boolean isNormal ( int p ) + { + if (!isValid()) + return false; + + if (p == END_POS || p == 0) + return true; + + if (p < 0 || p >= posMax()) + return false; + + if (p >= posAfter()) + { + if (isRoot()) + return false; + + if (_nextSibling != null && _nextSibling.isAttr()) + return false; + + if (_parent == null || !_parent.isContainer()) + return false; + } + + if (p == posAfter() - 1) + return false; + + return true; + } + + final Xobj walk ( Xobj root, boolean walkChildren ) + { + if (_firstChild != null && walkChildren) + return _firstChild; + + for ( Xobj x = this ; x != root ; x = x._parent ) + if (x._nextSibling != null) + return x._nextSibling; + + return null; + } + + final Xobj removeXobj ( ) + { + if (_parent != null) + { + if (_parent._firstChild == this) + _parent._firstChild = _nextSibling; + + if (_parent._lastChild == this) + _parent._lastChild = _prevSibling; + + if (_prevSibling != null) + _prevSibling._nextSibling = _nextSibling; + + if (_nextSibling != null) + _nextSibling._prevSibling = _prevSibling; + + _parent = null; + _prevSibling = null; + _nextSibling = null; + } + + return this; + } + + final Xobj insertXobj ( Xobj s ) + { + assert _locale == s._locale; + assert !s.isRoot() && !isRoot(); + assert s._parent == null; + assert s._prevSibling == null; + assert s._nextSibling == null; + + ensureParent(); + + s._parent = _parent; + s._prevSibling = _prevSibling; + s._nextSibling = this; + + if (_prevSibling != null) + _prevSibling._nextSibling = s; + else + _parent._firstChild = s; + + _prevSibling = s; + + return this; + } + + final Xobj appendXobj ( Xobj c ) + { + assert _locale == c._locale; + assert !c.isRoot(); + assert c._parent == null; + assert c._prevSibling == null; + assert c._nextSibling == null; + assert _lastChild == null || _firstChild != null; + + c._parent = this; + c._prevSibling = _lastChild; + + if (_lastChild == null) + _firstChild = c; + else + _lastChild._nextSibling = c; + + _lastChild = c; + + return this; + } + + final void removeXobjs ( Xobj first, Xobj last ) + { + assert last._locale == first._locale; + assert first._parent == this; + assert last._parent == this; + + if (_firstChild == first) + _firstChild = last._nextSibling; + + if (_lastChild == last) + _lastChild = first._prevSibling; + + if (first._prevSibling != null) + first._prevSibling._nextSibling = last._nextSibling; + + if (last._nextSibling != null) + last._nextSibling._prevSibling = first._prevSibling; + + // Leave the children linked together + + first._prevSibling = null; + last._nextSibling = null; + + for ( ; first != null ; first = first._nextSibling ) + first._parent = null; + } + + final void insertXobjs ( Xobj first, Xobj last ) + { + assert _locale == first._locale; + assert last._locale == first._locale; + assert first._parent == null && last._parent == null; + assert first._prevSibling == null; + assert last._nextSibling == null; + + first._prevSibling = _prevSibling; + last._nextSibling = this; + + if (_prevSibling != null) + _prevSibling._nextSibling = first; + else + _parent._firstChild = first; + + _prevSibling = last; + + for ( ; first != this ; first = first._nextSibling ) + first._parent = _parent; + } + + final void appendXobjs ( Xobj first, Xobj last ) + { + assert _locale == first._locale; + assert last._locale == first._locale; + assert first._parent == null && last._parent == null; + assert first._prevSibling == null; + assert last._nextSibling == null; + assert !first.isRoot(); + + first._prevSibling = _lastChild; + + if (_lastChild == null) + _firstChild = first; + else + _lastChild._nextSibling = first; + + _lastChild = last; + + for ( ; first != null ; first = first._nextSibling ) + first._parent = this; + } + + static final void disbandXobjs ( Xobj first, Xobj last ) + { + assert last._locale == first._locale; + assert first._parent == null && last._parent == null; + assert first._prevSibling == null; + assert last._nextSibling == null; + assert !first.isRoot(); + + while ( first != null ) + { + Xobj next = first._nextSibling; + first._nextSibling = first._prevSibling = null; + first = next; + } + } + + // Potential attr is going to be moved/removed, invalidate parent if it is a special attr + + final void invalidateSpecialAttr ( Xobj newParent ) + { + if (isAttr()) + { + if (_name.equals( Locale._xsiType )) + { + if (_parent != null) + _parent.disconnectNonRootUsers(); + + if (newParent != null) + newParent.disconnectNonRootUsers(); + } + + if (_name.equals( Locale._xsiNil )) + { + if (_parent != null) + _parent.invalidateNil(); + + if (newParent != null) + newParent.invalidateNil(); + } + } + } + + // Move or remove chars. Incoming p is denormalized. Incoming xTo and pTo are denormalized. + // Option to move curs with text. Option to perform invalidations. + // + // Important note: this fcn must operate under the assumption that the tree may be in an + // invalid state. Most likely, there may be text on two different nodes which should belong + // on the same node. Assertion of cursor normalization usually detects this problem. Any of + // the fcns it calls must also deal with these invalid conditions. Try not to call so many + // fcns from here. + + final void removeCharsHelper ( + int p, int cchRemove, Xobj xTo, int pTo, boolean moveCurs, boolean invalidate ) + { + assert p > 0 && p < posMax() && p != posAfter() - 1; + assert cchRemove > 0; + assert cchRight( p ) >= cchRemove; + assert !moveCurs || xTo != null; + + // Here I check the span of text to be removed for cursors. If xTo/pTo is not specified, + // then the caller wants these cursors to collapse to be after the text being removed. If + // the caller specifies moveCurs, then the caller has arranged for the text being removed + // to have been copied to xTp/pTo and wants the cursors to be moved there as well. + // Note that I call nextChars here. I do this because trying to shift the cursor to the + // end of the text to be removed with a moveTo could cause the improper placement of the + // cursor just before an end tag, instead of placing it just before the first child. Also, + // I adjust all positions of curs after the text to be removed to account for the removal. + + for ( Cur c = getEmbedded() ; c != null ; ) + { + Cur next = c._next; + + // Here I test to see if the Cur c is in the range of chars to be removed. Normally + // I would call inChars, but it can't handle the invalidity of the tree, so I heve + // inlined the inChars logic here (includeEnd is false, makes it much simpler). + // Note that I also call moveToNoCheck because the destination may have afterText + // and no parent which will cause normaliztion checks in MoveTo to fail. I don't think + // that nextChars will be called under such circumstnaces. + + assert c._xobj == this; + + if (c._pos >= p && c._pos < p + cchRemove) + { + if (moveCurs) + c.moveToNoCheck( xTo, pTo + c._pos - p ); + else + c.nextChars( cchRemove - c._pos + p ); + } + + // If c is still on this Xobj and it's to the right of the chars to remove, adjust + // it to adapt to the removal of the cars. I don't have to worry about END_POS + // here, just curs in text. + + if (c._xobj == this && c._pos >= p + cchRemove) + c._pos -= cchRemove; + + c = next; + } + + // Here I move bookmarks in this text to the span of text at xTo/pTo. The text at this/p + // is going away, but a caller of this fcn who specifies xTo/pTo has copied the text to + // xTo/pTo. The caller has to make sure that if xTo/pTo is not specified, then there are + // no bookmarks in the span of text to be removed. + + for ( Bookmark b = _bookmarks ; b != null ; ) + { + Bookmark next = b._next; + + // Similarly, as above, I can't call inChars here + + assert b._xobj == this; + + if (b._pos >= p && b._pos < p + cchRemove) + { + assert xTo != null; + b.moveTo( xTo, pTo + b._pos - p ); + } + + if (b._xobj == this && b._pos >= p + cchRemove) + b._pos -= cchRemove; + + b = b._next; + } + + // Now, remove the actual chars + + int pa = posAfter(); + CharUtil cu = _locale.getCharUtil(); + + if (p < pa) + { + _srcValue = cu.removeChars( p - 1, cchRemove, _srcValue, _offValue, _cchValue ); + _offValue = cu._offSrc; + _cchValue = cu._cchSrc; + + if (invalidate) + { + invalidateUser(); + invalidateSpecialAttr( null ); + } + } + else + { + _srcAfter = cu.removeChars( p - pa, cchRemove, _srcAfter, _offAfter, _cchAfter ); + _offAfter = cu._offSrc; + _cchAfter = cu._cchSrc; + + if (invalidate && _parent != null) + _parent.invalidateUser(); + } + } + + // Insert chars into this xobj. Incoming p is denormalized. Update bookmarks and cursors. + // This fcn does not deal with occupation of the value, this needs to be handled by the + // caller. + + final void insertCharsHelper ( int p, Object src, int off, int cch, boolean invalidate ) + { + assert p > 0; + assert p >= posAfter() || isOccupied(); + + int pa = posAfter(); + + // Here I shuffle bookmarks and cursors affected by the insertion of the new text. Because + // getting the embedded cursors is non-trivial, I avoid getting them if I don't need to. + // Basically, I need to know if p is before any text in the node as a whole. If it is, + // then there may be cursors/marks I need to shift right. + + if (p - (p < pa ? 1 : 2) < _cchValue + _cchAfter) + { + for ( Cur c = getEmbedded() ; c != null ; c = c._next ) + if (c._pos >= p) + c._pos += cch; + + for ( Bookmark b = _bookmarks ; b != null ; b = b._next ) + if (b._pos >= p) + b._pos += cch; + } + + // Now, stuff the new characters in! Also invalidate the proper container and if the + // value of an attribute is changing, check for special attr invalidation. Note that + // I do not assume that inserting after text will have a parent. There are use cases + // from moveNodesContents which excersize this. + + CharUtil cu = _locale.getCharUtil(); + + if (p < pa) + { + _srcValue = cu.insertChars( p - 1, _srcValue, _offValue, _cchValue, src, off, cch ); + _offValue = cu._offSrc; + _cchValue = cu._cchSrc; + + if (invalidate) + { + invalidateUser(); + invalidateSpecialAttr( null ); + } + } + else + { + _srcAfter = cu.insertChars( p - pa, _srcAfter, _offAfter, _cchAfter, src, off, cch ); + _offAfter = cu._offSrc; + _cchAfter = cu._cchSrc; + + if (invalidate && _parent != null) + _parent.invalidateUser(); + } + } + + Xobj copyNode ( Locale toLocale ) + { + Xobj newParent = null; + Xobj copy = null; + + for ( Xobj x = this ; ; ) + { + x.ensureOccupancy(); + + Xobj newX = x.newNode( toLocale ); + + newX._srcValue = x._srcValue; + newX._offValue = x._offValue; + newX._cchValue = x._cchValue; + + newX._srcAfter = x._srcAfter; + newX._offAfter = x._offAfter; + newX._cchAfter = x._cchAfter; + + for ( Bookmark b = x._bookmarks; b != null ; b = b._next ) + { + if ( x.hasBookmark( CDataBookmark.CDATA_BOOKMARK.getKey(), b._pos) ) + newX.setBookmark(b._pos, CDataBookmark.CDATA_BOOKMARK.getKey(), CDataBookmark.CDATA_BOOKMARK); + } + // TODO - strange to have charNode stuff inside here ..... + // newX._charNodesValue = CharNode.copyNodes( x._charNodesValue, newX._srcValue ); + // newX._charNodesAfter = CharNode.copyNodes( x._charNodesAfter, newX._srcAfter ); + + if (newParent == null) + copy = newX; + else + newParent.appendXobj( newX ); + + // Walk to the next in-order xobj. Record the current (y) to compute newParent + + Xobj y = x; + + if ((x = x.walk( this, true )) == null) + break; + + if (y == x._parent) + newParent = newX; + else + for ( ; y._parent != x._parent ; y = y._parent ) + newParent = newParent._parent; + } + + copy._srcAfter = null; + copy._offAfter = 0; + copy._cchAfter = 0; + + return copy; + } + + // Rturns all the chars, even if there is text intermixed with children + + String getCharsAsString ( int p, int cch, int wsr ) + { + if (cchRight( p ) == 0) + return ""; + + Object src = getChars( p, cch ); + + if (wsr == Locale.WS_PRESERVE) + return CharUtil.getString( src, _locale._offSrc, _locale._cchSrc ); + + Locale.ScrubBuffer scrub = Locale.getScrubBuffer( wsr ); + + scrub.scrub( src, _locale._offSrc, _locale._cchSrc ); + + return scrub.getResultAsString(); + } + String getCharsAfterAsString ( int off, int cch ) + { + int offset = off + _cchValue + 2; + if (offset == posMax()) + offset = -1; + return getCharsAsString(offset, cch, + Locale.WS_PRESERVE); + } + String getCharsValueAsString ( int off, int cch ) + { + return getCharsAsString(off + 1, cch, + Locale.WS_PRESERVE); + } + String getValueAsString ( int wsr ) + { + if (!hasChildren()) + { + Object src = getFirstChars(); + + if (wsr == Locale.WS_PRESERVE) + { + String s = CharUtil.getString( src, _locale._offSrc, _locale._cchSrc ); + + // Cache string to be able to use it later again + + int cch = s.length(); + + if (cch > 0) + { + Xobj lastAttr = lastAttr(); + + assert (lastAttr == null ? _cchValue : lastAttr._cchAfter) == cch; + + if (lastAttr != null) + { + lastAttr._srcAfter = s; + lastAttr._offAfter = 0; + } + else + { + _srcValue = s; + _offValue = 0; + } + } + + return s; + } + + Locale.ScrubBuffer scrub = Locale.getScrubBuffer( wsr ); + + scrub.scrub( src, _locale._offSrc, _locale._cchSrc ); + + return scrub.getResultAsString(); + } + + Locale.ScrubBuffer scrub = Locale.getScrubBuffer( wsr ); + + Cur c = tempCur(); + + c.push(); + + for ( c.next() ; !c.isAtEndOfLastPush() ; ) + { + if (c.isText()) + scrub.scrub( c.getChars( -1 ), c._offSrc, c._cchSrc ); + + if (c.isComment() || c.isProcinst()) + c.skip(); + else + c.next(); + } + + String s = scrub.getResultAsString(); + + c.release(); + + return s; + } + + String getValueAsString ( ) + { + return getValueAsString( Locale.WS_PRESERVE ); + } + + String getString ( int p, int cch ) + { + int cchRight = cchRight( p ); + + if (cchRight == 0) + return ""; + + if (cch < 0 || cch > cchRight) + cch = cchRight; + + int pa = posAfter(); + + assert p > 0; + + String s; + + if (p >= pa) + { + s = CharUtil.getString( _srcAfter, _offAfter + p - pa, cch ); + + if (p == pa && cch == _cchAfter) + { + _srcAfter = s; + _offAfter = 0; + } + } + else + { + s = CharUtil.getString( _srcValue, _offValue + p - 1, cch ); + + if (p == 1 && cch == _cchValue) + { + _srcValue = s; + _offValue = 0; + } + } + + return s; + } + + // Returns just chars just after the begin tag ... does not get all the text if there are + // children + + Object getFirstChars ( ) + { + ensureOccupancy(); + + if (_cchValue > 0) + return getChars( 1, -1 ); + + Xobj lastAttr = lastAttr(); + + if (lastAttr == null || lastAttr._cchAfter <= 0) + { + _locale._offSrc = 0; + _locale._cchSrc = 0; + + return null; + } + + return lastAttr.getChars( lastAttr.posAfter(), -1 ); + } + + Object getChars ( int pos, int cch, Cur c ) + { + Object src = getChars( pos, cch ); + + c._offSrc = _locale._offSrc; + c._cchSrc = _locale._cchSrc; + + return src; + } + + // These return the remainder of the char triple that getChars starts + + Object getChars ( int pos, int cch ) + { + assert isNormal( pos ); + + int cchRight = cchRight( pos ); + + if (cch < 0 || cch > cchRight) + cch = cchRight; + + if (cch == 0) + { + _locale._offSrc = 0; + _locale._cchSrc = 0; + + return null; + } + + return getCharsHelper( pos, cch ); + } + + // Assumes that there are chars to return, does not assume normal x/p + + Object getCharsHelper ( int pos, int cch ) + { + assert cch > 0 && cchRight( pos ) >= cch; + + int pa = posAfter(); + + Object src; + + if (pos >= pa) + { + src = _srcAfter; + _locale._offSrc = _offAfter + pos - pa; + } + else + { + src = _srcValue; + _locale._offSrc = _offValue + pos - 1; + } + + _locale._cchSrc = cch; + + return src; + } + + // + // + // + + final void setBit ( int mask ) { _bits |= mask; } + final void clearBit ( int mask ) { _bits &= ~mask; } + + final boolean bitIsSet ( int mask ) { return (_bits & mask) != 0; } + final boolean bitIsClear ( int mask ) { return (_bits & mask) == 0; } + + static final int VACANT = 0x100; + static final int STABLE_USER = 0x200; + static final int INHIBIT_DISCONNECT = 0x400; + + final boolean isVacant ( ) { return bitIsSet ( VACANT ); } + final boolean isOccupied ( ) { return bitIsClear ( VACANT ); } + final boolean inhibitDisconnect ( ) { return bitIsSet ( INHIBIT_DISCONNECT ); } + + final boolean isStableUser ( ) { return bitIsSet( STABLE_USER ); } + + void invalidateNil ( ) + { + if (_user != null) + _user.invalidate_nilvalue(); + } + + void setStableType ( SchemaType type ) + { + setStableUser( ((TypeStoreUserFactory) type).createTypeStoreUser() ); + } + + void setStableUser ( TypeStoreUser user ) + { + disconnectNonRootUsers(); + disconnectUser(); + + assert _user == null; + + _user = user; + + _user.attach_store( this ); + + setBit( STABLE_USER ); + } + + void disconnectUser ( ) + { + if (_user != null && !inhibitDisconnect()) + { + ensureOccupancy(); + _user.disconnect_store(); + _user = null; + } + } + + // If a node does not have a user, then I don't need to walk its descendents. NOte that + // the doconnect happens in document order. This may be a problem ... not sure ... May want + // to disconnect in a bottom up manner. + + void disconnectNonRootUsers ( ) + { + Xobj next; + + for ( Xobj x = this ; x != null ; x = next ) + { + next = x.walk( this, x._user != null ); + + if (!x.isRoot()) + x.disconnectUser(); + } + } + + void disconnectChildrenUsers ( ) + { + Xobj next; + + for ( Xobj x = walk( this, _user == null ) ; x != null ; x = next ) + { + next = x.walk( this, x._user != null ); + + x.disconnectUser(); + } + } + + /** + * Given a prefix, returns the namespace corresponding to + * the prefix at this location, or null if there is no mapping + * for this prefix. + *

    + * prefix="" indicates the absence of a prefix. A return value + * of "" indicates the no-namespace, and should not be confused + * with a return value of null, which indicates an illegal + * state, where there is no mapping for the given prefix. + *

    + * If the the default namespace is not explicitly mapped in the xml, + * the xml spec says that it should be mapped to the no-namespace. + * When the 'defaultAlwaysMapped' parameter is true, the default namepsace + * will return the no-namespace even if it is not explicity + * mapped, otherwise the default namespace will return null. + *

    + * This function intercepts the built-in prefixes "xml" and + * "xmlns" and returns their well-known namespace URIs. + * + * @param prefix The prefix to look up. + * @param defaultAlwaysMapped If true, return the no-namespace for the default namespace if not set. + * @return The mapped namespace URI ("" if no-namespace), or null if no mapping. + */ + + final String namespaceForPrefix ( String prefix, boolean defaultAlwaysMapped ) + { + if (prefix == null) + prefix = ""; + + // handle built-in prefixes + + if (prefix.equals( "xml" )) + return Locale._xml1998Uri; + + if (prefix.equals( "xmlns" )) + return Locale._xmlnsUri; + + for ( Xobj x = this ; x != null ; x = x._parent ) + for ( Xobj a = x._firstChild ; a != null && a.isAttr() ; a = a._nextSibling ) + if (a.isXmlns() && a.getXmlnsPrefix().equals( prefix )) + return a.getXmlnsUri(); + + return defaultAlwaysMapped && prefix.length() == 0 ? "" : null; + } + + final String prefixForNamespace ( String ns, String suggestion, boolean createIfMissing ) + { + if (ns == null) + ns = ""; + + // special cases + + if (ns.equals( Locale._xml1998Uri )) + return "xml"; + + if (ns.equals( Locale._xmlnsUri )) + return "xmlns"; + + // Get the closest container for the spot we're on + + Xobj base = this; + + while ( !base.isContainer() ) + base = base.ensureParent(); + + // Special handling for the no-namespace case + + if (ns.length() == 0) + { + // Search for a namespace decl which defines the default namespace + + Xobj a = base.findXmlnsForPrefix( "" ); + + // If I did not find a default decl or the decl maps to the no namespace, then + // the default namespace is mapped to "" + + if (a == null || a.getXmlnsUri().length() == 0) + return ""; + + // At this point, I've found a default namespace which is *not* the no-namespace. + // If I can't modify the document to mape the desired no-namespace, I must fail. + + if (!createIfMissing) + return null; + + // Ok, I need to make the default namespace on the nearest container map to "" + + base.setAttr( _locale.createXmlns( null ), "" ); + + return ""; + } + + // Look for an exisiting mapping for the desired uri which has a visible prefix + + for ( Xobj c = base ; c != null ; c = c._parent ) + for ( Xobj a = c.firstAttr() ; a != null ; a = a.nextAttr() ) + if (a.isXmlns() && a.getXmlnsUri().equals( ns )) + if (base.findXmlnsForPrefix( a.getXmlnsPrefix() ) == a) + return a.getXmlnsPrefix(); + + // No exisiting xmlns I can use, need to create one. See if I can first + + if (!createIfMissing) + return null; + + // Sanitize the suggestion. + + if (suggestion != null && + (suggestion.length() == 0 || suggestion.toLowerCase().startsWith( "xml" ) || + base.findXmlnsForPrefix( suggestion ) != null)) + { + suggestion = null; + } + + // If no suggestion, make one up + + if (suggestion == null) + { + String prefixBase = QNameHelper.suggestPrefix( ns ); + + suggestion = prefixBase; + + for ( int i = 1 ; ; suggestion = prefixBase + i++ ) + if (base.findXmlnsForPrefix( suggestion ) == null) + break; + } + + // Add a new namespace decl at the top elem if one exists, otherwise at root + + Xobj c = base; + + while ( !c.isRoot() && !c.ensureParent().isRoot() ) + c = c._parent; + + base.setAttr( _locale.createXmlns( suggestion ), ns ); + + return suggestion; + } + + final QName getValueAsQName ( ) + { + assert !hasChildren(); + + // TODO - + // caching the QName value in this object would prevent one from having + // to repeat all this string arithmatic over and over again. Perhaps + // when I make the store capable of handling strong simple types this + // can be done ... + + String value = getValueAsString( Locale.WS_COLLAPSE ); + + String prefix, localname; + + int firstcolon = value.indexOf( ':' ); + + if (firstcolon >= 0) + { + prefix = value.substring( 0, firstcolon ); + localname = value.substring( firstcolon + 1 ); + } + else + { + prefix = ""; + localname = value; + } + + String uri = namespaceForPrefix( prefix, true ); + + if (uri == null) + return null; // no prefix definition found - that's illegal + + return new QName( uri, localname ); + } + + final Xobj getAttr ( QName name ) + { + for ( Xobj x = _firstChild ; x != null && x.isAttr() ; x = x._nextSibling ) + if (x._name.equals( name )) + return x; + + return null; + } + + final QName getXsiTypeName ( ) + { + assert isContainer(); + + Xobj a = getAttr( Locale._xsiType ); + + return a == null ? null : a.getValueAsQName(); + } + + final XmlObject getObject ( ) + { + return isUserNode() ? (XmlObject) getUser() : null; + } + + final TypeStoreUser getUser ( ) + { + assert isUserNode(); + assert _user != null || (!isRoot() && !isStableUser()); + + if (_user == null) + { + // BUGBUG - this is recursive + + TypeStoreUser parentUser = + _parent == null + ? ((TypeStoreUserFactory) XmlBeans.NO_TYPE).createTypeStoreUser() + : _parent.getUser(); + + _user = + isElem() + ? parentUser.create_element_user( _name, getXsiTypeName() ) + : parentUser.create_attribute_user( _name ); + + _user.attach_store( this ); + } + + return _user; + } + + final void invalidateUser ( ) + { + assert isValid(); + assert _user == null || isUserNode(); + + if (_user != null) + _user.invalidate_value(); + } + + final void ensureOccupancy ( ) + { + assert isValid(); + + if (isVacant()) + { + assert isUserNode(); + + // In order to use Cur to set the value, I mark the + // value as occupied and remove the user to prohibit + // further user invalidations + + clearBit( VACANT ); + + TypeStoreUser user = _user; + _user = null; + + String value = user.build_text( this ); + + + long saveVersion = _locale._versionAll; + long saveVersionSansText = _locale._versionSansText; + + + setValue( value ); + assert saveVersionSansText == _locale._versionSansText; + + _locale._versionAll = saveVersion; + + + assert _user == null; + _user = user; + } + } + private void setValue(String val) + { + assert CharUtil.isValid(val, 0, val.length()); + + // Check for nothing to insert + + if (val.length() <= 0) + return; + + _locale.notifyChange(); + Xobj lastAttr = lastAttr(); + int startPos = 1; + Xobj charOwner = this; + if (lastAttr != null) + { + charOwner = lastAttr; + startPos = charOwner.posAfter(); + } + charOwner.insertCharsHelper(startPos, val, 0, val.length(), true); + } + // + // TypeStore + // + + public SchemaTypeLoader get_schematypeloader ( ) + { + return _locale._schemaTypeLoader; + } + + public XmlLocale get_locale ( ) + { + return _locale; + } + + // TODO - remove this when I've replaced the old store + public Object get_root_object ( ) + { + return _locale; + } + + public boolean is_attribute ( ) { assert isValid(); return isAttr(); } + public boolean validate_on_set ( ) { assert isValid(); return _locale._validateOnSet; } + + public void invalidate_text ( ) + { + _locale.enter(); + + try + { + assert isValid(); + + if (isOccupied()) + { + if (hasTextNoEnsureOccupancy() || hasChildren()) + { + TypeStoreUser user = _user; + _user = null; + + Cur c = tempCur(); + c.moveNodeContents( null, false ); + c.release(); + + assert _user == null; + _user = user; + } + + setBit( VACANT ); + } + + assert isValid(); + } + finally + { + _locale.exit(); + } + } + + public String fetch_text ( int wsr ) + { + _locale.enter(); + + try + { + assert isValid() && isOccupied(); + + return getValueAsString( wsr ); + } + finally + { + _locale.exit(); + } + } + + public XmlCursor new_cursor ( ) + { + _locale.enter(); + + try + { + Cur c = tempCur(); + XmlCursor xc = new Cursor( c ); + c.release(); + return xc; + + } + finally + { + _locale.exit(); + } + } + + public SchemaField get_schema_field ( ) + { + assert isValid(); + + if (isRoot()) + return null; + + TypeStoreUser parentUser = ensureParent().getUser(); + + if (isAttr()) + return parentUser.get_attribute_field( _name ); + + assert isElem(); + + TypeStoreVisitor visitor = parentUser.new_visitor(); + + if (visitor == null) + return null; + + for ( Xobj x = _parent._firstChild ; ; x = x._nextSibling ) + { + if (x.isElem()) + { + visitor.visit( x._name ); + + if (x == this) + return visitor.get_schema_field(); + } + } + } + + public void validate ( ValidatorListener eventSink ) + { + _locale.enter(); + + try + { + Cur c = tempCur(); + Validate validate = new Validate( c, eventSink ); + c.release(); + } + finally + { + _locale.exit(); + } + } + + public TypeStoreUser change_type ( SchemaType type ) + { + _locale.enter(); + + try + { + Cur c = tempCur(); + c.setType( type, false ); + c.release(); + } + finally + { + _locale.exit(); + } + + return getUser(); + } + + public TypeStoreUser substitute ( QName name, SchemaType type ) + { + _locale.enter(); + + try + { + Cur c = tempCur(); + c.setSubstitution( name, type, false ); + c.release(); + } + finally + { + _locale.exit(); + } + + return getUser(); + } + + public QName get_xsi_type ( ) + { + return getXsiTypeName(); + } + + public void store_text ( String text ) + { + _locale.enter(); + + TypeStoreUser user = _user; + _user = null; + + try + { + Cur c = tempCur(); + + c.moveNodeContents( null, false ); + + if (text != null && text.length() > 0) + { + c.next(); + c.insertString( text ); + } + + c.release(); + } + finally + { + assert _user == null; + _user = user; + + _locale.exit(); + } + } + + public int compute_flags ( ) + { + if (isRoot()) + return 0; + + TypeStoreUser parentUser = ensureParent().getUser(); + + if (isAttr()) + return parentUser.get_attributeflags( _name ); + + int f = parentUser.get_elementflags( _name ); + + if (f != -1) + return f; + + TypeStoreVisitor visitor = parentUser.new_visitor(); + + if (visitor == null) + return 0; + + for ( Xobj x = _parent._firstChild ; ; x = x._nextSibling ) + { + if (x.isElem()) + { + visitor.visit( x._name ); + + if (x == this) + return visitor.get_elementflags(); + } + } + } + + public String compute_default_text ( ) + { + if (isRoot()) + return null; + + TypeStoreUser parentUser = ensureParent().getUser(); + + if (isAttr()) + return parentUser.get_default_attribute_text( _name ); + + String result = parentUser.get_default_element_text( _name ); + + if (result != null) + return result; + + TypeStoreVisitor visitor = parentUser.new_visitor(); + + if (visitor == null) + return null; + + for ( Xobj x = _parent._firstChild ; ; x = x._nextSibling ) + { + if (x.isElem()) + { + visitor.visit( x._name ); + + if (x == this) + return visitor.get_default_text(); + } + } + } + + public boolean find_nil ( ) + { + if (isAttr()) + return false; + + _locale.enter(); + + try + { + Xobj a = getAttr( Locale._xsiNil ); + + if (a == null) + return false; + + String value = a.getValueAsString( Locale.WS_COLLAPSE ); + + return value.equals( "true" ) || value.equals( "1" ); + } + finally + { + _locale.exit(); + } + } + + public void invalidate_nil ( ) + { + if (isAttr()) + return; + + _locale.enter(); + + try + { + if (!_user.build_nil()) + removeAttr( Locale._xsiNil ); + else + setAttr( Locale._xsiNil, "true" ); + } + finally + { + _locale.exit(); + } + } + + public int count_elements ( QName name ) + { + return _locale.count( this, name, null ); + } + + public int count_elements ( QNameSet names ) + { + return _locale.count( this, null, names ); + } + + public TypeStoreUser find_element_user ( QName name, int i ) + { + for ( Xobj x = _firstChild ; x != null ; x = x._nextSibling ) + if (x.isElem() && x._name.equals( name ) && --i < 0) + return x.getUser(); + + return null; + } + + public TypeStoreUser find_element_user ( QNameSet names, int i ) + { + for ( Xobj x = _firstChild ; x != null ; x = x._nextSibling ) + if (x.isElem() && names.contains( x._name ) && --i < 0) + return x.getUser(); + + return null; + } + + public void find_all_element_users ( QName name, List fillMeUp ) + { + for ( Xobj x = _firstChild ; x != null ; x = x._nextSibling ) + if (x.isElem() && x._name.equals( name )) + fillMeUp.add( x.getUser() ); + } + + public void find_all_element_users ( QNameSet names, List fillMeUp ) + { + for ( Xobj x = _firstChild ; x != null ; x = x._nextSibling ) + if (x.isElem() && names.contains( x._name )) + fillMeUp.add( x.getUser() ); + } + + private static TypeStoreUser insertElement ( QName name, Xobj x, int pos ) + { + x._locale.enter(); + + try + { + Cur c = x._locale.tempCur(); + c.moveTo( x, pos ); + c.createElement( name ); + TypeStoreUser user = c.getUser(); + c.release(); + return user; + } + finally + { + x._locale.exit(); + } + } + + public TypeStoreUser insert_element_user ( QName name, int i ) + { + if (i < 0) + throw new IndexOutOfBoundsException(); + + if (!isContainer()) + throw new IllegalStateException(); + + Xobj x = _locale.findNthChildElem( this, name, null, i ); + + if (x == null) + { + if (i > _locale.count( this, name, null ) + 1) + throw new IndexOutOfBoundsException(); + + return add_element_user( name ); + } + + return insertElement( name, x, 0 ); + } + + public TypeStoreUser insert_element_user ( QNameSet names, QName name, int i ) + { + if (i < 0) + throw new IndexOutOfBoundsException(); + + if (!isContainer()) + throw new IllegalStateException(); + + Xobj x = _locale.findNthChildElem( this, null, names, i ); + + if (x == null) + { + if (i > _locale.count( this, null, names ) + 1) + throw new IndexOutOfBoundsException(); + + return add_element_user( name ); + } + + return insertElement( name, x, 0 ); + } + + public TypeStoreUser add_element_user ( QName name ) + { + if (!isContainer()) + throw new IllegalStateException(); + + QNameSet endSet = null; + boolean gotEndSet = false; + + Xobj candidate = null; + + for ( Xobj x = _lastChild ; x != null ; x = x._prevSibling ) + { + if (x.isContainer()) + { + if (x._name.equals( name )) + break; + + if (!gotEndSet) + { + endSet = _user.get_element_ending_delimiters( name ); + gotEndSet = true; + } + + if (endSet == null || endSet.contains( x._name )) + candidate = x; + } + } + + return + candidate == null + ? insertElement( name, this, END_POS ) + : insertElement( name, candidate, 0 ); + } + + private static void removeElement ( Xobj x ) + { + if (x == null) + throw new IndexOutOfBoundsException(); + + x._locale.enter(); + + try + { + Cur c = x.tempCur(); + c.moveNode( null ); + c.release(); + } + finally + { + x._locale.exit(); + } + } + + public void remove_element ( QName name, int i ) + { + if (i < 0) + throw new IndexOutOfBoundsException(); + + if (!isContainer()) + throw new IllegalStateException(); + + Xobj x; + + for ( x = _firstChild ; x != null ; x = x._nextSibling ) + if (x.isElem() && x._name.equals( name ) && --i < 0) + break; + + removeElement( x ); + } + + public void remove_element ( QNameSet names, int i ) + { + if (i < 0) + throw new IndexOutOfBoundsException(); + + if (!isContainer()) + throw new IllegalStateException(); + + Xobj x; + + for ( x = _firstChild ; x != null ; x = x._nextSibling ) + if (x.isElem() && names.contains( x._name ) && --i < 0) + break; + + removeElement( x ); + } + + public TypeStoreUser find_attribute_user ( QName name ) + { + Xobj a = getAttr( name ); + + return a == null ? null : a.getUser(); + } + + public TypeStoreUser add_attribute_user ( QName name ) + { + if (getAttr( name ) != null) + throw new IndexOutOfBoundsException(); + + _locale.enter(); + + try + { + return setAttr( name, "" ).getUser(); + } + finally + { + _locale.exit(); + } + } + + public void remove_attribute ( QName name ) + { + _locale.enter(); + + try + { + if (!removeAttr( name )) + throw new IndexOutOfBoundsException(); + } + finally + { + _locale.exit(); + } + } + + public TypeStoreUser copy_contents_from ( TypeStore source ) + { + Xobj xSrc = (Xobj) source; + + if (xSrc == this) + return getUser(); + + _locale.enter(); + + try + { + xSrc._locale.enter(); + + Cur c = tempCur(); + + try + { + Cur cSrc1 = xSrc.tempCur(); + Map sourceNamespaces = Locale.getAllNamespaces( cSrc1, null ); + cSrc1.release(); + + if (isAttr()) + { + Cur cSrc = xSrc.tempCur(); + String value = Locale.getTextValue( cSrc ); + cSrc.release(); + + c.setValue( value ); + } + else + { + // Here I save away the user of this node so that it does not get whacked + // in the following operations. + + disconnectChildrenUsers(); + + assert !inhibitDisconnect(); + + setBit( INHIBIT_DISCONNECT ); + + QName xsiType = isContainer() ? getXsiTypeName() : null; + + Xobj copy = xSrc.copyNode( _locale ); + + Cur.moveNodeContents( this, null, true ); + + c.next(); + + Cur.moveNodeContents( copy, c, true ); + + c.moveTo( this ); + + if (xsiType != null) + c.setXsiType( xsiType ); + + assert inhibitDisconnect(); + clearBit( INHIBIT_DISCONNECT ); + } + + if (sourceNamespaces != null) + { + if (!c.isContainer()) + c.toParent(); + + Locale.applyNamespaces( c, sourceNamespaces ); + } + + } + finally + { + c.release(); + + xSrc._locale.exit(); + } + } + finally + { + _locale.exit(); + } + + return getUser(); + } + + public TypeStoreUser copy(SchemaTypeLoader stl, SchemaType type, XmlOptions options) + { + //do not use a user's Factory method for copying. + //XmlFactoryHook hook = XmlFactoryHook.ThreadContext.getHook(); + Xobj destination = null; + options = XmlOptions.maskNull(options); + SchemaType sType = (SchemaType) options.get(XmlOptions.DOCUMENT_TYPE); + + if (sType == null) + sType = type == null ? XmlObject.type : type; + + Locale locale = this.locale(); + if ( Boolean.TRUE.equals(options.get(XmlOptions.COPY_USE_NEW_SYNC_DOMAIN)) ) + locale = Locale.getLocale(stl, options); + + if (sType.isDocumentType() || (sType.isNoType() && (this instanceof Xobj.DocumentXobj))) + destination = Cur.createDomDocumentRootXobj(locale, false); + else + destination = Cur.createDomDocumentRootXobj(locale, true); + + + locale.enter(); + try + { + Cur c = destination.tempCur(); + c.setType(type); + c.release(); + } + finally + { + locale.exit(); + } + + TypeStoreUser tsu = destination.copy_contents_from(this); + return tsu; + } + + public void array_setter ( XmlObject[] sources, QName elementName ) + { + _locale.enter(); + + try + { + // TODO - this is the quick and dirty implementation, make this faster + + int m = sources.length; + + ArrayList copies = new ArrayList(); + ArrayList types = new ArrayList(); + + for ( int i = 0 ; i < m ; i++ ) + { + // TODO - deal with null sources[ i ] here -- what to do? + + if (sources[ i ] == null) + throw new IllegalArgumentException( "Array element null" ); + + else if (sources[ i ].isImmutable()) + { + copies.add( null ); + types.add( null ); + } + else + { + Xobj x = ((Xobj) ((TypeStoreUser) sources[ i ]).get_store()); + + if (x._locale == _locale) + copies.add( x.copyNode( _locale ) ); + else + { + x._locale.enter(); + + try + { + copies.add( x.copyNode( _locale ) ); + } + finally + { + x._locale.exit(); + } + } + + types.add( sources[ i ].schemaType() ); + } + } + + int n = count_elements( elementName ); + + for ( ; n > m ; n-- ) + remove_element( elementName, m ); + + for ( ; m > n ; n++ ) + add_element_user( elementName ); + + assert m == n; + + ArrayList elements = new ArrayList(); + + find_all_element_users( elementName, elements ); + + for ( int i = 0 ; i < elements.size() ; i++ ) + elements.set( i, (Xobj) ((TypeStoreUser) elements.get( i )).get_store() ); + + assert elements.size() == n; + + Cur c = tempCur(); + + for ( int i = 0 ; i < n ; i++ ) + { + Xobj x = (Xobj) elements.get( i ); + + if (sources[ i ].isImmutable()) + x.getObject().set( sources[ i ] ); + else + { + Cur.moveNodeContents( x, null, true ); + + c.moveTo( x ); + c.next(); + + Cur.moveNodeContents( (Xobj) copies.get( i ), c, true ); + + x.change_type( (SchemaType) types.get( i ) ); + } + } + + c.release(); + } + finally + { + _locale.exit(); + } + } + + public void visit_elements ( TypeStoreVisitor visitor ) + { + throw new RuntimeException( "Not implemeneted" ); + } + + public XmlObject[] exec_query ( String queryExpr, XmlOptions options ) throws XmlException + { + _locale.enter(); + + try + { + Cur c = tempCur(); + + XmlObject[] result = Query.objectExecQuery( c, queryExpr, options ); + + c.release(); + + return result; + } + finally + { + _locale.exit(); + } + } + + public String find_prefix_for_nsuri ( String nsuri, String suggested_prefix ) + { + _locale.enter(); + + try + { + return prefixForNamespace( nsuri, suggested_prefix, true ); + } + finally + { + _locale.exit(); + } + } + + public String getNamespaceForPrefix ( String prefix ) + { + return namespaceForPrefix( prefix, true ); + } + + // + // + // + + abstract static class NodeXobj extends Xobj implements Dom, Node, NodeList + { + NodeXobj ( Locale l, int kind, int domType ) + { + super( l, kind, domType ); + } + + Dom getDom ( ) { return this; } + + // + // + // + + public int getLength ( ) { return DomImpl._childNodes_getLength( this ); } + public Node item ( int i ) { return DomImpl._childNodes_item( this, i ); } + + public Node appendChild ( Node newChild ) { return DomImpl._node_appendChild( this, newChild ); } + public Node cloneNode ( boolean deep ) { return DomImpl._node_cloneNode( this, deep ); } + public NamedNodeMap getAttributes ( ) { return null; } + public NodeList getChildNodes ( ) { return this; } + public Node getParentNode ( ) { return DomImpl._node_getParentNode( this ); } + public Node removeChild ( Node oldChild ) { return DomImpl._node_removeChild( this, oldChild ); } + public Node getFirstChild ( ) { return DomImpl._node_getFirstChild( this ); } + public Node getLastChild ( ) { return DomImpl._node_getLastChild( this ); } + public String getLocalName ( ) { return DomImpl._node_getLocalName( this ); } + public String getNamespaceURI ( ) { return DomImpl._node_getNamespaceURI( this ); } + public Node getNextSibling ( ) { return DomImpl._node_getNextSibling( this ); } + public String getNodeName ( ) { return DomImpl._node_getNodeName( this ); } + public short getNodeType ( ) { return DomImpl._node_getNodeType( this ); } + public String getNodeValue ( ) { return DomImpl._node_getNodeValue( this ); } + public Document getOwnerDocument ( ) { return DomImpl._node_getOwnerDocument( this ); } + public String getPrefix ( ) { return DomImpl._node_getPrefix( this ); } + public Node getPreviousSibling ( ) { return DomImpl._node_getPreviousSibling( this ); } + public boolean hasAttributes ( ) { return DomImpl._node_hasAttributes( this ); } + public boolean hasChildNodes ( ) { return DomImpl._node_hasChildNodes( this ); } + public Node insertBefore ( Node newChild, Node refChild ) { return DomImpl._node_insertBefore( this, newChild, refChild ); } + public boolean isSupported ( String feature, String version ) { return DomImpl._node_isSupported( this, feature, version ); } + public void normalize ( ) { DomImpl._node_normalize( this ); } + public Node replaceChild ( Node newChild, Node oldChild ) { return DomImpl._node_replaceChild( this, newChild, oldChild ); } + public void setNodeValue ( String nodeValue ) { DomImpl._node_setNodeValue( this, nodeValue ); } + public void setPrefix ( String prefix ) { DomImpl._node_setPrefix( this, prefix ); } + public boolean nodeCanHavePrefixUri( ){ return false; } + + // DOM Level 3 + public Object getUserData ( String key ) { return DomImpl._node_getUserData( this, key ); } + public Object setUserData ( String key, Object data, UserDataHandler handler ) { return DomImpl._node_setUserData( this, key, data, handler ); } + public Object getFeature ( String feature, String version ) { return DomImpl._node_getFeature( this, feature, version ); } + public boolean isEqualNode ( Node arg ) { return DomImpl._node_isEqualNode( this, arg ); } + public boolean isSameNode ( Node arg ) { return DomImpl._node_isSameNode( this, arg ); } + public String lookupNamespaceURI ( String prefix ) { return DomImpl._node_lookupNamespaceURI( this, prefix ); } + public String lookupPrefix ( String namespaceURI ) { return DomImpl._node_lookupPrefix( this, namespaceURI ); } + public boolean isDefaultNamespace ( String namespaceURI ) { return DomImpl._node_isDefaultNamespace( this, namespaceURI ); } + public void setTextContent ( String textContent ) { DomImpl._node_setTextContent( this, textContent ); } + public String getTextContent ( ) { return DomImpl._node_getTextContent( this ); } + public short compareDocumentPosition ( Node other ) { return DomImpl._node_compareDocumentPosition( this, other ); } + public String getBaseURI ( ) { return DomImpl._node_getBaseURI( this ); } + } + + static class DocumentXobj extends NodeXobj implements Document + { + DocumentXobj ( Locale l ) + { + super( l, ROOT, DomImpl.DOCUMENT ); + } + + Xobj newNode ( Locale l ) { return new DocumentXobj( l ); } + + // + // + // + + public Attr createAttribute ( String name ) { return DomImpl._document_createAttribute( this, name ); } + public Attr createAttributeNS ( String namespaceURI, String qualifiedName ) { return DomImpl._document_createAttributeNS( this, namespaceURI, qualifiedName ); } + public CDATASection createCDATASection ( String data ) { return DomImpl._document_createCDATASection( this, data ); } + public Comment createComment ( String data ) { return DomImpl._document_createComment( this, data ); } + public DocumentFragment createDocumentFragment ( ) { return DomImpl._document_createDocumentFragment( this ); } + public Element createElement ( String tagName ) { return DomImpl._document_createElement( this, tagName ); } + public Element createElementNS ( String namespaceURI, String qualifiedName ) { return DomImpl._document_createElementNS( this, namespaceURI, qualifiedName ); } + public EntityReference createEntityReference ( String name ) { return DomImpl._document_createEntityReference( this, name ); } + public ProcessingInstruction createProcessingInstruction ( String target, String data ) { return DomImpl._document_createProcessingInstruction( this, target, data ); } + public Text createTextNode ( String data ) { return DomImpl._document_createTextNode( this, data ); } + public DocumentType getDoctype ( ) { return DomImpl._document_getDoctype( this ); } + public Element getDocumentElement ( ) { return DomImpl._document_getDocumentElement( this ); } + public Element getElementById ( String elementId ) { + if ( _idToElement == null )return null; + Xobj o = (Xobj) _idToElement.get(elementId); + if (o == null) return null; + if (!isInSameTree(o)) + { + _idToElement.remove(elementId); + } + return (Element)o; + } + public NodeList getElementsByTagName ( String tagname ) { return DomImpl._document_getElementsByTagName( this, tagname ); } + public NodeList getElementsByTagNameNS ( String namespaceURI, String localName ) { return DomImpl._document_getElementsByTagNameNS( this, namespaceURI, localName ); } + public DOMImplementation getImplementation ( ) { return DomImpl._document_getImplementation( this ); } + public Node importNode ( Node importedNode, boolean deep ) { return DomImpl._document_importNode( this, importedNode, deep ); } + + // DOM Level 3 + public Node adoptNode ( Node source ) { throw new RuntimeException( "DOM Level 3 Not implemented" ); } + public String getDocumentURI ( ) { throw new RuntimeException( "DOM Level 3 Not implemented" ); } + public DOMConfiguration getDomConfig ( ) { throw new RuntimeException( "DOM Level 3 Not implemented" ); } + public String getInputEncoding ( ) { throw new RuntimeException( "DOM Level 3 Not implemented" ); } + public boolean getStrictErrorChecking ( ) { throw new RuntimeException( "DOM Level 3 Not implemented" ); } + public String getXmlEncoding ( ) { throw new RuntimeException( "DOM Level 3 Not implemented" ); } + public boolean getXmlStandalone ( ) { throw new RuntimeException( "DOM Level 3 Not implemented" ); } + public String getXmlVersion ( ) { throw new RuntimeException( "DOM Level 3 Not implemented" ); } + public void normalizeDocument ( ) { throw new RuntimeException( "DOM Level 3 Not implemented" ); } + public Node renameNode ( Node n, String namespaceURI, String qualifiedName ) { throw new RuntimeException( "DOM Level 3 Not implemented" ); } + public void setDocumentURI ( String documentURI ) { throw new RuntimeException( "DOM Level 3 Not implemented" ); } + public void setStrictErrorChecking ( boolean strictErrorChecking ) { throw new RuntimeException( "DOM Level 3 Not implemented" ); } + public void setXmlStandalone ( boolean xmlStandalone ) { throw new RuntimeException( "DOM Level 3 Not implemented" ); } + public void setXmlVersion ( String xmlVersion ) { throw new RuntimeException( "DOM Level 3 Not implemented" ); } + + protected void addIdElement( String idVal, Dom e){ + if ( _idToElement == null) + _idToElement = new java.util.Hashtable(); + _idToElement.put(idVal,e); + } + void removeIdElement( String idVal ){ + if (_idToElement != null) + _idToElement.remove(idVal); + } + private java.util.Hashtable _idToElement; + } + static class DocumentFragXobj extends NodeXobj implements DocumentFragment + { + DocumentFragXobj ( Locale l ) { super( l, ROOT, DomImpl.DOCFRAG ); } + + Xobj newNode ( Locale l ) { return new DocumentFragXobj( l ); } + } + + final static class ElementAttributes implements NamedNodeMap + { + ElementAttributes ( ElementXobj elementXobj ) + { + _elementXobj = elementXobj; + } + + public int getLength ( ) { return DomImpl._attributes_getLength( _elementXobj ); } + public Node getNamedItem ( String name ) { return DomImpl._attributes_getNamedItem ( _elementXobj, name ); } + public Node getNamedItemNS ( String namespaceURI, String localName ) { return DomImpl._attributes_getNamedItemNS ( _elementXobj, namespaceURI, localName ); } + public Node item ( int index ) { return DomImpl._attributes_item ( _elementXobj, index ); } + public Node removeNamedItem ( String name ) { return DomImpl._attributes_removeNamedItem ( _elementXobj, name ); } + public Node removeNamedItemNS ( String namespaceURI, String localName ) { return DomImpl._attributes_removeNamedItemNS ( _elementXobj, namespaceURI, localName ); } + public Node setNamedItem ( Node arg ) { return DomImpl._attributes_setNamedItem ( _elementXobj, arg ); } + public Node setNamedItemNS ( Node arg ) { return DomImpl._attributes_setNamedItemNS ( _elementXobj, arg ); } + + private ElementXobj _elementXobj; + } + + static abstract class NamedNodeXobj extends NodeXobj + { + NamedNodeXobj ( Locale l, int kind, int domType ) + { + super( l, kind, domType ); + _canHavePrefixUri = true; + } + + public boolean nodeCanHavePrefixUri( ){ return _canHavePrefixUri; } + + boolean _canHavePrefixUri; + } + + static class ElementXobj extends NamedNodeXobj implements Element + { + ElementXobj ( Locale l, QName name ) + { + super( l, ELEM, DomImpl.ELEMENT ); + _name = name; + } + + Xobj newNode ( Locale l ) { return new ElementXobj( l, _name ); } + + // + // + // + + public NamedNodeMap getAttributes ( ) + { + if (_attributes == null) + _attributes = new ElementAttributes( this ); + + return _attributes; + } + + public String getAttribute ( String name ) { return DomImpl._element_getAttribute( this, name ); } + public Attr getAttributeNode ( String name ) { return DomImpl._element_getAttributeNode( this, name ); } + public Attr getAttributeNodeNS ( String namespaceURI, String localName ) { return DomImpl._element_getAttributeNodeNS( this, namespaceURI, localName ); } + public String getAttributeNS ( String namespaceURI, String localName ) { return DomImpl._element_getAttributeNS( this, namespaceURI, localName ); } + public NodeList getElementsByTagName ( String name ) { return DomImpl._element_getElementsByTagName( this, name ); } + public NodeList getElementsByTagNameNS ( String namespaceURI, String localName ) { return DomImpl._element_getElementsByTagNameNS( this, namespaceURI, localName ); } + public String getTagName ( ) { return DomImpl._element_getTagName( this ); } + public boolean hasAttribute ( String name ) { return DomImpl._element_hasAttribute( this, name ); } + public boolean hasAttributeNS ( String namespaceURI, String localName ) { return DomImpl._element_hasAttributeNS( this, namespaceURI, localName ); } + public void removeAttribute ( String name ) { DomImpl._element_removeAttribute( this, name ); } + public Attr removeAttributeNode ( Attr oldAttr ) { return DomImpl._element_removeAttributeNode( this, oldAttr ); } + public void removeAttributeNS ( String namespaceURI, String localName ) { DomImpl._element_removeAttributeNS( this, namespaceURI, localName ); } + public void setAttribute ( String name, String value ) { DomImpl._element_setAttribute( this, name, value ); } + public Attr setAttributeNode ( Attr newAttr ) { return DomImpl._element_setAttributeNode( this, newAttr ); } + public Attr setAttributeNodeNS ( Attr newAttr ) { return DomImpl._element_setAttributeNodeNS( this, newAttr ); } + public void setAttributeNS ( String namespaceURI, String qualifiedName, String value ) { DomImpl._element_setAttributeNS( this, namespaceURI, qualifiedName, value ); } + + // DOM Level 3 + public TypeInfo getSchemaTypeInfo ( ) { throw new RuntimeException( "DOM Level 3 Not implemented" ); } + public void setIdAttribute ( String name, boolean isId ) { throw new RuntimeException( "DOM Level 3 Not implemented" ); } + public void setIdAttributeNS ( String namespaceURI, String localName, boolean isId ) { throw new RuntimeException( "DOM Level 3 Not implemented" ); } + public void setIdAttributeNode ( Attr idAttr, boolean isId ) { throw new RuntimeException( "DOM Level 3 Not implemented" ); } + + private ElementAttributes _attributes; + } + + static class AttrXobj extends NamedNodeXobj implements Attr + { + AttrXobj ( Locale l, QName name ) + { + super( l, ATTR, DomImpl.ATTR ); + _name = name; + } + + Xobj newNode ( Locale l ) { return new AttrXobj( l, _name ); } + + // + public Node getNextSibling ( ) { return null; } + // + + public String getName ( ) { return DomImpl._node_getNodeName( this ); } + public Element getOwnerElement ( ) { return DomImpl._attr_getOwnerElement( this ); } + public boolean getSpecified ( ) { return DomImpl._attr_getSpecified( this ); } + public String getValue ( ) { return DomImpl._node_getNodeValue( this ); } + public void setValue ( String value ) { DomImpl._node_setNodeValue( this, value ); } + + // DOM Level 3 + public TypeInfo getSchemaTypeInfo ( ) { throw new RuntimeException( "DOM Level 3 Not implemented" ); } + public boolean isId ( ) { return false; } + } + + static class AttrIdXobj + extends AttrXobj + { + AttrIdXobj ( Locale l, QName name ) + { + super( l, name ); + } + public boolean isId() + { + return true; + } + } + static class CommentXobj extends NodeXobj implements Comment + { + CommentXobj ( Locale l ) { super( l, COMMENT, DomImpl.COMMENT ); } + + Xobj newNode ( Locale l ) { return new CommentXobj( l ); } + + public NodeList getChildNodes ( ) { return DomImpl._emptyNodeList; } + + public void appendData ( String arg ) { DomImpl._characterData_appendData( this, arg ); } + public void deleteData ( int offset, int count ) { DomImpl._characterData_deleteData( this, offset, count ); } + public String getData ( ) { return DomImpl._characterData_getData( this ); } + public int getLength ( ) { return DomImpl._characterData_getLength( this ); } + public Node getFirstChild ( ) { return null; } + public void insertData ( int offset, String arg ) { DomImpl._characterData_insertData( this, offset, arg ); } + public void replaceData ( int offset, int count, String arg ) { DomImpl._characterData_replaceData( this, offset, count, arg ); } + public void setData ( String data ) { DomImpl._characterData_setData( this, data ); } + public String substringData ( int offset, int count ) { return DomImpl._characterData_substringData( this, offset, count ); } + } + + static class ProcInstXobj extends NodeXobj implements ProcessingInstruction + { + ProcInstXobj ( Locale l, String target ) + { + super( l, PROCINST, DomImpl.PROCINST ); + _name = _locale.makeQName( null, target ); + } + + Xobj newNode ( Locale l ) { return new ProcInstXobj( l, _name.getLocalPart() ); } + + public int getLength ( ) { return 0; } + public Node getFirstChild ( ) { return null; } + + public String getData ( ) { return DomImpl._processingInstruction_getData( this ); } + public String getTarget ( ) { return DomImpl._processingInstruction_getTarget( this ); } + public void setData ( String data ) { DomImpl._processingInstruction_setData( this, data ); } + } + + // + // SAAJ objects + // + + static class SoapPartDocXobj extends DocumentXobj + { + SoapPartDocXobj ( Locale l ) + { + super(l); + //super( l, ROOT, DomImpl.DOCUMENT ); + _soapPartDom = new SoapPartDom( this ); + } + + Dom getDom ( ) { return _soapPartDom; } + + Xobj newNode ( Locale l ) { return new SoapPartDocXobj( l ); } + + SoapPartDom _soapPartDom; + } + + static class SoapPartDom extends SOAPPart implements Dom, Document, NodeList + { + SoapPartDom ( SoapPartDocXobj docXobj ) + { + _docXobj = docXobj; + } + + public int nodeType ( ) { return DomImpl.DOCUMENT; } + public Locale locale ( ) { return _docXobj._locale; } + public Cur tempCur ( ) { return _docXobj.tempCur(); } + public QName getQName ( ) { return _docXobj._name; } + + public void dump ( ) { dump( System.out ); } + public void dump ( PrintStream o ) { _docXobj.dump( o ); } + public void dump ( PrintStream o, Object ref ) { _docXobj.dump( o, ref ); } + + public String name ( ) { return "#document"; } + + public Node appendChild ( Node newChild ) { return DomImpl._node_appendChild( this, newChild ); } + public Node cloneNode ( boolean deep ) { return DomImpl._node_cloneNode( this, deep ); } + public NamedNodeMap getAttributes ( ) { return null; } + public NodeList getChildNodes ( ) { return this; } + public Node getParentNode ( ) { return DomImpl._node_getParentNode( this ); } + public Node removeChild ( Node oldChild ) { return DomImpl._node_removeChild( this, oldChild ); } + public Node getFirstChild ( ) { return DomImpl._node_getFirstChild( this ); } + public Node getLastChild ( ) { return DomImpl._node_getLastChild( this ); } + public String getLocalName ( ) { return DomImpl._node_getLocalName( this ); } + public String getNamespaceURI ( ) { return DomImpl._node_getNamespaceURI( this ); } + public Node getNextSibling ( ) { return DomImpl._node_getNextSibling( this ); } + public String getNodeName ( ) { return DomImpl._node_getNodeName( this ); } + public short getNodeType ( ) { return DomImpl._node_getNodeType( this ); } + public String getNodeValue ( ) { return DomImpl._node_getNodeValue( this ); } + public Document getOwnerDocument ( ) { return DomImpl._node_getOwnerDocument( this ); } + public String getPrefix ( ) { return DomImpl._node_getPrefix( this ); } + public Node getPreviousSibling ( ) { return DomImpl._node_getPreviousSibling( this ); } + public boolean hasAttributes ( ) { return DomImpl._node_hasAttributes( this ); } + public boolean hasChildNodes ( ) { return DomImpl._node_hasChildNodes( this ); } + public Node insertBefore ( Node newChild, Node refChild ) { return DomImpl._node_insertBefore( this, newChild, refChild ); } + public boolean isSupported ( String feature, String version ) { return DomImpl._node_isSupported( this, feature, version ); } + public void normalize ( ) { DomImpl._node_normalize( this ); } + public Node replaceChild ( Node newChild, Node oldChild ) { return DomImpl._node_replaceChild( this, newChild, oldChild ); } + public void setNodeValue ( String nodeValue ) { DomImpl._node_setNodeValue( this, nodeValue ); } + public void setPrefix ( String prefix ) { DomImpl._node_setPrefix( this, prefix ); } + + // DOM Level 3 + public Object getUserData ( String key ) { return DomImpl._node_getUserData( this, key ); } + public Object setUserData ( String key, Object data, UserDataHandler handler ) { return DomImpl._node_setUserData( this, key, data, handler ); } + public Object getFeature ( String feature, String version ) { return DomImpl._node_getFeature( this, feature, version ); } + public boolean isEqualNode ( Node arg ) { return DomImpl._node_isEqualNode( this, arg ); } + public boolean isSameNode ( Node arg ) { return DomImpl._node_isSameNode( this, arg ); } + public String lookupNamespaceURI ( String prefix ) { return DomImpl._node_lookupNamespaceURI( this, prefix ); } + public String lookupPrefix ( String namespaceURI ) { return DomImpl._node_lookupPrefix( this, namespaceURI ); } + public boolean isDefaultNamespace ( String namespaceURI ) { return DomImpl._node_isDefaultNamespace( this, namespaceURI ); } + public void setTextContent ( String textContent ) { DomImpl._node_setTextContent( this, textContent ); } + public String getTextContent ( ) { return DomImpl._node_getTextContent( this ); } + public short compareDocumentPosition ( Node other ) { return DomImpl._node_compareDocumentPosition( this, other ); } + public String getBaseURI ( ) { return DomImpl._node_getBaseURI( this ); } + public Node adoptNode ( Node source ) { throw new RuntimeException( "DOM Level 3 Not implemented" ); } + public String getDocumentURI ( ) { throw new RuntimeException( "DOM Level 3 Not implemented" ); } + public DOMConfiguration getDomConfig ( ) { throw new RuntimeException( "DOM Level 3 Not implemented" ); } + public String getInputEncoding ( ) { throw new RuntimeException( "DOM Level 3 Not implemented" ); } + public boolean getStrictErrorChecking ( ) { throw new RuntimeException( "DOM Level 3 Not implemented" ); } + public String getXmlEncoding ( ) { throw new RuntimeException( "DOM Level 3 Not implemented" ); } + public boolean getXmlStandalone ( ) { throw new RuntimeException( "DOM Level 3 Not implemented" ); } + public String getXmlVersion ( ) { throw new RuntimeException( "DOM Level 3 Not implemented" ); } + public void normalizeDocument ( ) { throw new RuntimeException( "DOM Level 3 Not implemented" ); } + public Node renameNode ( Node n, String namespaceURI, String qualifiedName ) { throw new RuntimeException( "DOM Level 3 Not implemented" ); } + public void setDocumentURI ( String documentURI ) { throw new RuntimeException( "DOM Level 3 Not implemented" ); } + public void setStrictErrorChecking ( boolean strictErrorChecking ) { throw new RuntimeException( "DOM Level 3 Not implemented" ); } + public void setXmlStandalone ( boolean xmlStandalone ) { throw new RuntimeException( "DOM Level 3 Not implemented" ); } + public void setXmlVersion ( String xmlVersion ) { throw new RuntimeException( "DOM Level 3 Not implemented" ); } + + public Attr createAttribute ( String name ) { return DomImpl._document_createAttribute( this, name ); } + public Attr createAttributeNS ( String namespaceURI, String qualifiedName ) { return DomImpl._document_createAttributeNS( this, namespaceURI, qualifiedName ); } + public CDATASection createCDATASection ( String data ) { return DomImpl._document_createCDATASection( this, data ); } + public Comment createComment ( String data ) { return DomImpl._document_createComment( this, data ); } + public DocumentFragment createDocumentFragment ( ) { return DomImpl._document_createDocumentFragment( this ); } + public Element createElement ( String tagName ) { return DomImpl._document_createElement( this, tagName ); } + public Element createElementNS ( String namespaceURI, String qualifiedName ) { return DomImpl._document_createElementNS( this, namespaceURI, qualifiedName ); } + public EntityReference createEntityReference ( String name ) { return DomImpl._document_createEntityReference( this, name ); } + public ProcessingInstruction createProcessingInstruction ( String target, String data ) { return DomImpl._document_createProcessingInstruction( this, target, data ); } + public Text createTextNode ( String data ) { return DomImpl._document_createTextNode( this, data ); } + public DocumentType getDoctype ( ) { return DomImpl._document_getDoctype( this ); } + public Element getDocumentElement ( ) { return DomImpl._document_getDocumentElement( this ); } + public Element getElementById ( String elementId ) { return DomImpl._document_getElementById( this, elementId ); } + public NodeList getElementsByTagName ( String tagname ) { return DomImpl._document_getElementsByTagName( this, tagname ); } + public NodeList getElementsByTagNameNS ( String namespaceURI, String localName ) { return DomImpl._document_getElementsByTagNameNS( this, namespaceURI, localName ); } + public DOMImplementation getImplementation ( ) { return DomImpl._document_getImplementation( this ); } + public Node importNode ( Node importedNode, boolean deep ) { return DomImpl._document_importNode( this, importedNode, deep ); } + + public int getLength ( ) { return DomImpl._childNodes_getLength( this ); } + public Node item ( int i ) { return DomImpl._childNodes_item( this, i ); } + + public void removeAllMimeHeaders ( ) { DomImpl._soapPart_removeAllMimeHeaders( this ); } + public void removeMimeHeader ( String name ) { DomImpl._soapPart_removeMimeHeader( this, name ); } + public Iterator getAllMimeHeaders ( ) { return DomImpl._soapPart_getAllMimeHeaders( this ); } + public SOAPEnvelope getEnvelope ( ) { return DomImpl._soapPart_getEnvelope( this ); } + public Source getContent ( ) { return DomImpl._soapPart_getContent( this ); } + public void setContent ( Source source ) { DomImpl._soapPart_setContent( this, source ); } + public String[] getMimeHeader ( String name ) { return DomImpl._soapPart_getMimeHeader( this, name ); } + public void addMimeHeader ( String name, String value ) { DomImpl._soapPart_addMimeHeader( this, name,value ); } + public void setMimeHeader ( String name, String value ) { DomImpl._soapPart_setMimeHeader( this, name, value ); } + public Iterator getMatchingMimeHeaders ( String[] names ) { return DomImpl._soapPart_getMatchingMimeHeaders( this, names ); } + public Iterator getNonMatchingMimeHeaders ( String[] names ) { return DomImpl._soapPart_getNonMatchingMimeHeaders( this, names ); } + + public boolean nodeCanHavePrefixUri( ){ return true; } + + SoapPartDocXobj _docXobj; + } + + static class SoapElementXobj + extends ElementXobj implements SOAPElement, org.apache.xmlbeans.impl.soap.Node + { + SoapElementXobj ( Locale l, QName name ) { super( l, name ); } + + Xobj newNode ( Locale l ) { return new SoapElementXobj( l, _name ); } + + public void detachNode ( ) { DomImpl._soapNode_detachNode( this ); } + public void recycleNode ( ) { DomImpl._soapNode_recycleNode( this ); } + public String getValue ( ) { return DomImpl._soapNode_getValue( this ); } + public void setValue ( String value ) { DomImpl._soapNode_setValue( this, value ); } + public SOAPElement getParentElement ( ) { return DomImpl._soapNode_getParentElement( this ); } + public void setParentElement ( SOAPElement p ) { DomImpl._soapNode_setParentElement( this, p ); } + + public void removeContents ( ) { DomImpl._soapElement_removeContents( this ); } + public String getEncodingStyle ( ) { return DomImpl._soapElement_getEncodingStyle( this ); } + public void setEncodingStyle ( String encodingStyle ) { DomImpl._soapElement_setEncodingStyle( this, encodingStyle ); } + public boolean removeNamespaceDeclaration ( String prefix ) { return DomImpl._soapElement_removeNamespaceDeclaration( this, prefix ); } + public Iterator getAllAttributes ( ) { return DomImpl._soapElement_getAllAttributes( this ); } + public Iterator getChildElements ( ) { return DomImpl._soapElement_getChildElements( this ); } + public Iterator getNamespacePrefixes ( ) { return DomImpl._soapElement_getNamespacePrefixes( this ); } + public SOAPElement addAttribute ( Name name, String value ) throws SOAPException { return DomImpl._soapElement_addAttribute( this, name, value ); } + public SOAPElement addChildElement ( SOAPElement oldChild ) throws SOAPException { return DomImpl._soapElement_addChildElement( this, oldChild ); } + public SOAPElement addChildElement ( Name name ) throws SOAPException { return DomImpl._soapElement_addChildElement( this, name ); } + public SOAPElement addChildElement ( String localName ) throws SOAPException { return DomImpl._soapElement_addChildElement( this, localName ); } + public SOAPElement addChildElement ( String localName, String prefix ) throws SOAPException { return DomImpl._soapElement_addChildElement( this, localName, prefix ); } + public SOAPElement addChildElement ( String localName, String prefix, String uri ) throws SOAPException { return DomImpl._soapElement_addChildElement( this, localName, prefix, uri ); } + public SOAPElement addNamespaceDeclaration ( String prefix, String uri ) { return DomImpl._soapElement_addNamespaceDeclaration( this, prefix, uri ); } + public SOAPElement addTextNode ( String data ) { return DomImpl._soapElement_addTextNode( this, data ); } + public String getAttributeValue ( Name name ) { return DomImpl._soapElement_getAttributeValue( this, name ); } + public Iterator getChildElements ( Name name ) { return DomImpl._soapElement_getChildElements( this, name ); } + public Name getElementName ( ) { return DomImpl._soapElement_getElementName( this ); } + public String getNamespaceURI ( String prefix ) { return DomImpl._soapElement_getNamespaceURI( this, prefix ); } + public Iterator getVisibleNamespacePrefixes ( ) { return DomImpl._soapElement_getVisibleNamespacePrefixes( this ); } + public boolean removeAttribute ( Name name ) { return DomImpl._soapElement_removeAttribute( this, name ); } + } + + static class SoapBodyXobj extends SoapElementXobj implements SOAPBody + { + SoapBodyXobj ( Locale l, QName name ) { super( l, name ); } + + Xobj newNode ( Locale l ) { return new SoapBodyXobj( l, _name ); } + + public boolean hasFault ( ) { return DomImpl.soapBody_hasFault( this ); } + public SOAPFault addFault ( ) throws SOAPException { return DomImpl.soapBody_addFault( this ); } + public SOAPFault getFault ( ) { return DomImpl.soapBody_getFault( this ); } + public SOAPBodyElement addBodyElement ( Name name ) { return DomImpl.soapBody_addBodyElement( this, name ); } + public SOAPBodyElement addDocument ( Document document ) { return DomImpl.soapBody_addDocument( this, document ); } + public SOAPFault addFault ( Name name, String s ) throws SOAPException { return DomImpl.soapBody_addFault( this, name, s ); } + public SOAPFault addFault ( Name faultCode, String faultString, java.util.Locale locale ) throws SOAPException { return DomImpl.soapBody_addFault( this, faultCode, faultString, locale ); } + } + + static class SoapBodyElementXobj extends SoapElementXobj implements SOAPBodyElement + { + SoapBodyElementXobj ( Locale l, QName name ) { super( l, name ); } + + Xobj newNode ( Locale l ) { return new SoapBodyElementXobj( l, _name ); } + } + + static class SoapEnvelopeXobj extends SoapElementXobj implements SOAPEnvelope + { + SoapEnvelopeXobj ( Locale l, QName name ) { super( l, name ); } + + Xobj newNode ( Locale l ) { return new SoapEnvelopeXobj( l, _name ); } + + public SOAPBody addBody ( ) throws SOAPException { return DomImpl._soapEnvelope_addBody( this ); } + public SOAPBody getBody ( ) throws SOAPException { return DomImpl._soapEnvelope_getBody( this ); } + public SOAPHeader getHeader ( ) throws SOAPException { return DomImpl._soapEnvelope_getHeader( this ); } + public SOAPHeader addHeader ( ) throws SOAPException { return DomImpl._soapEnvelope_addHeader( this ); } + public Name createName ( String localName ) { return DomImpl._soapEnvelope_createName( this, localName ); } + public Name createName ( String localName, String prefix, String namespaceURI ) { return DomImpl._soapEnvelope_createName( this, localName, prefix, namespaceURI ); } + } + + static class SoapHeaderXobj extends SoapElementXobj implements SOAPHeader + { + SoapHeaderXobj ( Locale l, QName name ) { super( l, name ); } + + Xobj newNode ( Locale l ) { return new SoapHeaderXobj( l, _name ); } + + public Iterator examineAllHeaderElements ( ) { return DomImpl.soapHeader_examineAllHeaderElements( this ); } + public Iterator extractAllHeaderElements ( ) { return DomImpl.soapHeader_extractAllHeaderElements( this ); } + public Iterator examineHeaderElements ( String actor ) { return DomImpl.soapHeader_examineHeaderElements( this, actor ); } + public Iterator examineMustUnderstandHeaderElements ( String mustUnderstandString ) { return DomImpl.soapHeader_examineMustUnderstandHeaderElements( this, mustUnderstandString ); } + public Iterator extractHeaderElements ( String actor ) { return DomImpl.soapHeader_extractHeaderElements( this, actor ); } + public SOAPHeaderElement addHeaderElement ( Name name ) { return DomImpl.soapHeader_addHeaderElement( this, name ); } + } + + static class SoapHeaderElementXobj extends SoapElementXobj implements SOAPHeaderElement + { + SoapHeaderElementXobj ( Locale l, QName name ) { super( l, name ); } + + Xobj newNode ( Locale l ) { return new SoapHeaderElementXobj( l, _name ); } + + public void setMustUnderstand ( boolean mustUnderstand ) { DomImpl.soapHeaderElement_setMustUnderstand( this, mustUnderstand ); } + public boolean getMustUnderstand ( ) { return DomImpl.soapHeaderElement_getMustUnderstand( this ); } + public void setActor ( String actor ) { DomImpl.soapHeaderElement_setActor( this, actor ); } + public String getActor ( ) { return DomImpl.soapHeaderElement_getActor( this ); } + } + + static class SoapFaultXobj extends SoapBodyElementXobj implements SOAPFault + { + SoapFaultXobj ( Locale l, QName name ) { super( l, name ); } + + Xobj newNode ( Locale l ) { return new SoapFaultXobj( l, _name ); } + + public void setFaultString ( String faultString ) { DomImpl.soapFault_setFaultString( this, faultString ); } + public void setFaultString ( String faultString, java.util.Locale locale ) { DomImpl.soapFault_setFaultString( this, faultString, locale ); } + public void setFaultCode ( Name faultCodeName ) throws SOAPException { DomImpl.soapFault_setFaultCode( this, faultCodeName ); } + public void setFaultActor ( String faultActorString ) { DomImpl.soapFault_setFaultActor( this, faultActorString ); } + public String getFaultActor ( ) { return DomImpl.soapFault_getFaultActor( this ); } + public String getFaultCode ( ) { return DomImpl.soapFault_getFaultCode( this ); } + public void setFaultCode ( String faultCode ) throws SOAPException { DomImpl.soapFault_setFaultCode( this, faultCode ); } + public java.util.Locale getFaultStringLocale ( ) { return DomImpl.soapFault_getFaultStringLocale( this ); } + public Name getFaultCodeAsName ( ) { return DomImpl.soapFault_getFaultCodeAsName( this ); } + public String getFaultString ( ) { return DomImpl.soapFault_getFaultString( this ); } + public Detail addDetail ( ) throws SOAPException { return DomImpl.soapFault_addDetail( this ); } + public Detail getDetail ( ) { return DomImpl.soapFault_getDetail( this ); } + } + + static class SoapFaultElementXobj extends SoapElementXobj implements SOAPFaultElement + { + SoapFaultElementXobj ( Locale l, QName name ) { super( l, name ); } + + Xobj newNode ( Locale l ) { return new SoapFaultElementXobj( l, _name ); } + } + + static class DetailXobj extends SoapFaultElementXobj implements Detail + { + DetailXobj ( Locale l, QName name ) { super( l, name ); } + + Xobj newNode ( Locale l ) { return new DetailXobj( l, _name ); } + + public DetailEntry addDetailEntry ( Name name ) { return DomImpl.detail_addDetailEntry( this, name ); } + public Iterator getDetailEntries ( ) { return DomImpl.detail_getDetailEntries( this ); } + } + + static class DetailEntryXobj extends SoapElementXobj implements DetailEntry + { + Xobj newNode ( Locale l ) { return new DetailEntryXobj( l, _name ); } + + DetailEntryXobj ( Locale l, QName name ) { super( l, name ); } + } + + // + // + // + + static class Bookmark implements XmlMark + { + boolean isOnList ( Bookmark head ) + { + for ( ; head != null ; head = head._next ) + if (head == this) + return true; + + return false; + } + + Bookmark listInsert ( Bookmark head ) + { + assert _next == null && _prev == null; + + if (head == null) + head = _prev = this; + else + { + _prev = head._prev; + head._prev = head._prev._next = this; + } + + return head; + } + + Bookmark listRemove ( Bookmark head ) + { + assert _prev != null && isOnList( head ); + + if (_prev == this) + head = null; + else + { + if (head == this) + head = _next; + else + _prev._next = _next; + + if (_next == null) + head._prev = _prev; + else + { + _next._prev = _prev; + _next = null; + } + } + + _prev = null; + assert _next == null; + + return head; + } + + void moveTo ( Xobj x, int p ) + { + assert isOnList( _xobj._bookmarks ); + + if (_xobj != x) + { + _xobj._bookmarks = listRemove( _xobj._bookmarks ); + x._bookmarks = listInsert( x._bookmarks ); + + _xobj = x; + } + + _pos = p; + } + + // + // XmlCursor.XmlMark method + // + + public XmlCursor createCursor ( ) + { + if (_xobj == null) + { + throw new IllegalStateException( + "Attempting to create a cursor on a bookmark that " + + "has been cleared or replaced."); + } + + return Cursor.newCursor( _xobj, _pos ); + } + + // + // + // + + Xobj _xobj; + int _pos; + + Bookmark _next; + Bookmark _prev; + + Object _key; + Object _value; + } + + // + // + // + + Locale _locale; + QName _name; + + Cur _embedded; + + Bookmark _bookmarks; + + int _bits; + + Xobj _parent; + Xobj _nextSibling; + Xobj _prevSibling; + Xobj _firstChild; + Xobj _lastChild; + + Object _srcValue, _srcAfter; + int _offValue, _offAfter; + int _cchValue, _cchAfter; + + // TODO - put this in a ptr off this node + CharNode _charNodesValue; + CharNode _charNodesAfter; + + // TODO - put this in a ptr off this node + TypeStoreUser _user; +} diff --git a/xmlbeans/src/store/org/w3c/dom/DOMConfiguration.java b/xmlbeans/src/store/org/w3c/dom/DOMConfiguration.java new file mode 100755 index 000000000..df99c994b --- /dev/null +++ b/xmlbeans/src/store/org/w3c/dom/DOMConfiguration.java @@ -0,0 +1,27 @@ +/* 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.w3c.dom; + +public interface DOMConfiguration +{ + public boolean canSetParameter ( String name, Object value ); + + public Object getParameter ( String name ); + + public DOMStringList getParameterNames ( ); + + public void setParameter ( String name, Object value ); +} \ No newline at end of file diff --git a/xmlbeans/src/store/org/w3c/dom/DOMStringList.java b/xmlbeans/src/store/org/w3c/dom/DOMStringList.java new file mode 100755 index 000000000..95d4a3287 --- /dev/null +++ b/xmlbeans/src/store/org/w3c/dom/DOMStringList.java @@ -0,0 +1,25 @@ +/* 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.w3c.dom; + +public interface DOMStringList +{ + public boolean contains ( String str ); + + public int getLength ( ); + + public String item ( int index ); +} \ No newline at end of file diff --git a/xmlbeans/src/store/org/w3c/dom/TypeInfo.java b/xmlbeans/src/store/org/w3c/dom/TypeInfo.java new file mode 100755 index 000000000..74df1deb7 --- /dev/null +++ b/xmlbeans/src/store/org/w3c/dom/TypeInfo.java @@ -0,0 +1,31 @@ +/* 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.w3c.dom; + +public interface TypeInfo +{ + public static final int DERIVATION_EXTENSION = 2; + public static final int DERIVATION_LIST = 8; + public static final int DERIVATION_RESTRICTION = 1; + public static final int DERIVATION_UNION = 4; + + public String getTypeName ( ); + + public String getTypeNamespace ( ); + + public boolean isDerivedFrom ( + String typeNamespaceArg, String typeNameArg, int derivationMethod ); +} \ No newline at end of file diff --git a/xmlbeans/src/store/org/w3c/dom/UserDataHandler.java b/xmlbeans/src/store/org/w3c/dom/UserDataHandler.java new file mode 100755 index 000000000..a44bdeb01 --- /dev/null +++ b/xmlbeans/src/store/org/w3c/dom/UserDataHandler.java @@ -0,0 +1,27 @@ +/* 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.w3c.dom; + +public interface UserDataHandler +{ + public static final short NODE_ADOPTED = 5; + public static final short NODE_CLONED = 1; + public static final short NODE_DELETED = 3; + public static final short NODE_IMPORTED = 2; + public static final short NODE_RENAMED = 4; + + public void handle ( short operation, String key, Object data, Node src, Node dst ); +} \ No newline at end of file diff --git a/xmlbeans/src/tools/org/apache/xmlbeans/impl/inst2xsd/Inst2Xsd.java b/xmlbeans/src/tools/org/apache/xmlbeans/impl/inst2xsd/Inst2Xsd.java new file mode 100644 index 000000000..985b36759 --- /dev/null +++ b/xmlbeans/src/tools/org/apache/xmlbeans/impl/inst2xsd/Inst2Xsd.java @@ -0,0 +1,377 @@ +/* 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.inst2xsd; + +import org.apache.xmlbeans.SchemaTypeLoader; +import org.apache.xmlbeans.XmlBeans; +import org.apache.xmlbeans.XmlException; +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.XmlOptions; +import org.apache.xmlbeans.XmlError; +import org.apache.xmlbeans.impl.xb.xsdschema.SchemaDocument; +import org.apache.xmlbeans.impl.inst2xsd.util.TypeSystemHolder; +import org.apache.xmlbeans.impl.tool.CommandLine; + +import java.io.File; +import java.io.IOException; +import java.io.Reader; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.Set; +import java.util.HashSet; + +/** + * @author Cezar Andrei (cezar.andrei at bea.com) Date: Jul 16, 2004 + * + * This class generates a set of XMLSchemas from an instance XML document. + * + * How it works: + * - first: pass through all the instances, building a TypeSystemHolder structure + * - second: serialize the TypeSystemHolder structure into SchemaDocuments + */ +public class Inst2Xsd +{ + public static void main(String[] args) + { + if (args==null || args.length == 0) + { + printHelp(); + System.exit(0); + return; + } + + Set flags = new HashSet(); + flags.add("h"); + flags.add("help"); + flags.add("usage"); + flags.add("license"); + flags.add("version"); + flags.add("verbose"); + flags.add("validate"); + + Set opts = new HashSet(); + opts.add("design"); + opts.add("simple-content-types"); + opts.add("enumerations"); + opts.add("outDir"); + opts.add("outPrefix"); + + CommandLine cl = new CommandLine(args, flags, opts); + Inst2XsdOptions inst2XsdOptions = new Inst2XsdOptions(); + + if (cl.getOpt("license") != null) + { + CommandLine.printLicense(); + System.exit(0); + return; + } + + if (cl.getOpt("version") != null) + { + CommandLine.printVersion(); + System.exit(0); + return; + } + + if (cl.getOpt("h") != null || cl.getOpt("help") != null || cl.getOpt("usage") != null) + { + printHelp(); + System.exit(0); + return; + } + + String[] badopts = cl.getBadOpts(); + if (badopts.length > 0) + { + for (int i = 0; i < badopts.length; i++) + System.out.println("Unrecognized option: " + badopts[i]); + printHelp(); + System.exit(0); + return; + } + + String design = cl.getOpt("design"); + if (design==null) + { + // default + } + else if (design.equals("vb")) + { + inst2XsdOptions.setDesign(Inst2XsdOptions.DESIGN_VENETIAN_BLIND); + } + else if (design.equals("rd")) + { + inst2XsdOptions.setDesign(Inst2XsdOptions.DESIGN_RUSSIAN_DOLL); + } + else if (design.equals("ss")) + { + inst2XsdOptions.setDesign(Inst2XsdOptions.DESIGN_SALAMI_SLICE); + } + else + { + printHelp(); + System.exit(0); + return; + } + + String simpleContent = cl.getOpt("simple-content-types"); + if (simpleContent==null) + { + //default + } + else if (simpleContent.equals("smart")) + { + inst2XsdOptions.setSimpleContentTypes(Inst2XsdOptions.SIMPLE_CONTENT_TYPES_SMART); + } + else if (simpleContent.equals("string")) + { + inst2XsdOptions.setSimpleContentTypes(Inst2XsdOptions.SIMPLE_CONTENT_TYPES_STRING); + } + else + { + printHelp(); + System.exit(0); + return; + } + + String enumerations = cl.getOpt("enumerations"); + if (enumerations==null) + { + // default + } + else if (enumerations.equals("never")) + { + inst2XsdOptions.setUseEnumerations(Inst2XsdOptions.ENUMERATION_NEVER); + } + else + { + try + { + int intVal = Integer.parseInt(enumerations); + inst2XsdOptions.setUseEnumerations(intVal); + } + catch (NumberFormatException e) + { + printHelp(); + System.exit(0); + return; + } + } + + File outDir = new File( cl.getOpt("outDir")==null ? "." : cl.getOpt("outDir")); + + String outPrefix = cl.getOpt("outPrefix"); + if (outPrefix==null) + outPrefix = "schema"; + + inst2XsdOptions.setVerbose((cl.getOpt("verbose") != null)); + boolean validate = cl.getOpt("validate")!=null; + + File[] xmlFiles = cl.filesEndingWith(".xml"); + XmlObject[] xmlInstances = new XmlObject[xmlFiles.length]; + + if ( xmlInstances.length==0 ) + { + printHelp(); + System.exit(0); + return; + } + + int i = 0; + try + { + for (i = 0; i < xmlFiles.length; i++) + { + xmlInstances[i] = XmlObject.Factory.parse(xmlFiles[i]); + } + } + catch (XmlException e) + { + System.err.println("Invalid xml file: '" + xmlFiles[i].getName() + "'. " + e.getMessage()); + return; + } + catch (IOException e) + { + System.err.println("Could not read file: '" + xmlFiles[i].getName() + "'. " + e.getMessage()); + return; + } + + SchemaDocument[] schemaDocs = inst2xsd(xmlInstances, inst2XsdOptions); + + try + { + for (i = 0; i < schemaDocs.length; i++) + { + SchemaDocument schema = schemaDocs[i]; + + if (inst2XsdOptions.isVerbose()) + System.out.println("----------------------\n\n" + schema); + + schema.save(new File(outDir, outPrefix + i + ".xsd"), new XmlOptions().setSavePrettyPrint()); + } + } + catch (IOException e) + { + System.err.println("Could not write file: '" + outDir + File.pathSeparator + outPrefix + i + ".xsd" + "'. " + e.getMessage()); + return; + } + + if (validate) + { + validateInstances(schemaDocs, xmlInstances); + } + } + + private static void printHelp() + { + System.out.println("Generates XMLSchema from instance xml documents."); + System.out.println("Usage: inst2xsd [opts] [instance.xml]*"); + System.out.println("Options include:"); + System.out.println(" -design [rd|ss|vb] - XMLSchema design type"); + System.out.println(" rd - Russian Doll Design - local elements and local types"); + System.out.println(" ss - Salami Slice Design - global elements and local types"); + System.out.println(" vb - Venetian Blind Design (default) - local elements and global complex types"); + System.out.println(" -simple-content-types [smart|string] - Simple content types detection (leaf text). Smart is the default"); + System.out.println(" -enumerations [never|NUMBER] - Use enumerations. Default value is " + Inst2XsdOptions.ENUMERATION_NOT_MORE_THAN_DEFAULT + "."); + System.out.println(" -outDir [dir] - Directory for output files. Default is '.'"); + System.out.println(" -outPrefix [file_name_prefix] - Prefix for output file names. Default is 'schema'"); + System.out.println(" -validate - Validates input instances agaist generated schemas."); + System.out.println(" -verbose - print more informational messages"); + System.out.println(" -license - print license information"); + System.out.println(" -help - help imformation"); + } + + private Inst2Xsd() {} + + // public entry points + + public static SchemaDocument[] inst2xsd(Reader[] instReaders, Inst2XsdOptions options) + throws IOException, XmlException + { + XmlObject[] instances = new XmlObject[ instReaders.length ]; + for (int i = 0; i < instReaders.length; i++) + { + instances[i] = XmlObject.Factory.parse(instReaders[i]); + } + return inst2xsd(instances, options); + } + + public static SchemaDocument[] inst2xsd(XmlObject[] instances, Inst2XsdOptions options) + { + if (options==null) + options = new Inst2XsdOptions(); + + // create structure + TypeSystemHolder typeSystemHolder = new TypeSystemHolder(); + + XsdGenStrategy strategy; + switch (options.getDesign()) + { + case Inst2XsdOptions.DESIGN_RUSSIAN_DOLL: + strategy = new RussianDollStrategy(); + break; + + case Inst2XsdOptions.DESIGN_SALAMI_SLICE: + strategy = new SalamiSliceStrategy(); + break; + + case Inst2XsdOptions.DESIGN_VENETIAN_BLIND: + strategy = new VenetianBlindStrategy(); + break; + + default: + throw new IllegalArgumentException("Unknown design."); + } + // processDoc the instance + strategy.processDoc(instances, options, typeSystemHolder); + + if (options.isVerbose()) + System.out.println("typeSystemHolder.toString(): " + typeSystemHolder); + + SchemaDocument[] sDocs = typeSystemHolder.getSchemaDocuments(); + + return sDocs; + } + + private static boolean validateInstances(SchemaDocument[] sDocs, XmlObject[] instances) + { + SchemaTypeLoader sLoader; + Collection compErrors = new ArrayList(); + XmlOptions schemaOptions = new XmlOptions(); + schemaOptions.setErrorListener(compErrors); + try + { + sLoader = XmlBeans.loadXsd(sDocs, schemaOptions); + } + catch (Exception e) + { + if (compErrors.isEmpty() || !(e instanceof XmlException)) + { + e.printStackTrace(System.out); + } + System.out.println("\n-------------------\n\nInvalid schemas."); + for (Iterator errors = compErrors.iterator(); errors.hasNext(); ) + { + XmlError xe = (XmlError)errors.next(); + System.out.println(xe.getLine() + ":" + xe.getColumn() + " " + xe.getMessage()); + } + return false; + } + + System.out.println("\n-------------------"); + boolean result = true; + + for (int i = 0; i < instances.length; i++) + { + XmlObject xobj; + + try + { + xobj = sLoader.parse( instances[i].newXMLStreamReader(), null, new XmlOptions().setLoadLineNumbers() ); + } + catch (XmlException e) + { + System.out.println("Error:\n" + instances[i].documentProperties().getSourceName() + " not loadable: " + e); + e.printStackTrace(System.out); + result = false; + continue; + } + + Collection errors = new ArrayList(); + + if (xobj.schemaType() == XmlObject.type) + { + System.out.println(instances[i].documentProperties().getSourceName() + " NOT valid. "); + System.out.println(" Document type not found." ); + result = false; + } + else if (xobj.validate(new XmlOptions().setErrorListener(errors))) + System.out.println("Instance[" + i + "] valid - " + instances[i].documentProperties().getSourceName()); + else + { + System.out.println("Instance[" + i + "] NOT valid - " + instances[i].documentProperties().getSourceName()); + for (Iterator it = errors.iterator(); it.hasNext(); ) + { + XmlError xe = (XmlError)it.next(); + System.out.println(xe.getLine() + ":" + xe.getColumn() + " " + xe.getMessage()); + } + result = false; + } + } + + return result; + } +} diff --git a/xmlbeans/src/tools/org/apache/xmlbeans/impl/inst2xsd/Inst2XsdOptions.java b/xmlbeans/src/tools/org/apache/xmlbeans/impl/inst2xsd/Inst2XsdOptions.java new file mode 100644 index 000000000..166e58948 --- /dev/null +++ b/xmlbeans/src/tools/org/apache/xmlbeans/impl/inst2xsd/Inst2XsdOptions.java @@ -0,0 +1,116 @@ +/* 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.inst2xsd; + +/** + * @author Cezar Andrei (cezar.andrei at bea.com) Date: Jul 19, 2004 + + Options: + * Design + o Russian Doll Design - local elements and local types + o Salami Slice Design - global elements and local types + o Venetian Blind Design (default)- local elements and global complex types + * Simple content types (leafs) + o smart (default) - try to find out the right simple shema type + o always xsd:string + * Use enumeration - when there are multiple valid values in a list + o never + o only if not more than the value (default 10)- number option + */ +public class Inst2XsdOptions +{ + // design + public static final int DESIGN_RUSSIAN_DOLL = 1; + public static final int DESIGN_SALAMI_SLICE = 2; + public static final int DESIGN_VENETIAN_BLIND = 3; + + private int _design = DESIGN_VENETIAN_BLIND; + + // schema type for simple content values + public static final int SIMPLE_CONTENT_TYPES_SMART = 1; + public static final int SIMPLE_CONTENT_TYPES_STRING = 2; + + private int _simpleContentTypes = SIMPLE_CONTENT_TYPES_SMART; + + // use enumeration + public static final int ENUMERATION_NEVER = 1; + public static final int ENUMERATION_NOT_MORE_THAN_DEFAULT = 10; + + private int _enumerations = ENUMERATION_NOT_MORE_THAN_DEFAULT; + + private boolean _verbose = false; + + + public int getDesign() + { + return _design; + } + + /** + * Design + o Russian Doll Design + o Salami Slice Design + o Venetian Blind Design + * @param designType + * @see #DESIGN_RUSSIAN_DOLL + * @see #DESIGN_SALAMI_SLICE + * @see #DESIGN_VENETIAN_BLIND + */ + public void setDesign(int designType) + { + if (designType!=DESIGN_RUSSIAN_DOLL && designType!=DESIGN_SALAMI_SLICE && designType!=DESIGN_VENETIAN_BLIND) + throw new IllegalArgumentException("Unknown value for design type."); + _design = designType; + } + + public boolean isUseEnumerations() + { + return _enumerations>ENUMERATION_NEVER; + } + + public int getUseEnumerations() + { + return _enumerations; + } + + public void setUseEnumerations(int useEnumerations) + { + if (useEnumerations0) + { + // complex content + if (collapsedText.length()>0) + { + elemType.setContentType(Type.COMPLEX_TYPE_MIXED_CONTENT); + } + else + { + elemType.setContentType(Type.COMPLEX_TYPE_COMPLEX_CONTENT); + } + processElementsInComplexType(elemType, children, element.getName().getNamespaceURI(), typeSystemHolder, options); + processAttributesInComplexType(elemType, attributes); + } + else + { + // simple content + // hack workaround for being able to call xc.getNamespaceForPrefix() + XmlCursor xcForNamespaces = xc.newCursor(); + xcForNamespaces.toParent(); + + if (attributes.size()>0) + { + elemType.setContentType(Type.COMPLEX_TYPE_SIMPLE_CONTENT); + + Type extendedType = Type.createNamedType( + processSimpleContentType(textBuff.toString(), options, xcForNamespaces), Type.SIMPLE_TYPE_SIMPLE_CONTENT); + elemType.setExtensionType(extendedType); + + processAttributesInComplexType(elemType, attributes); + } + else + { + elemType.setContentType(Type.SIMPLE_TYPE_SIMPLE_CONTENT); + elemType.setName(processSimpleContentType(textBuff.toString(), options, xcForNamespaces)); + + // add enumeration value + String enumValue = XmlString.type.getName().equals(elemType.getName()) ? textBuff.toString() : collapsedText; + elemType.addEnumerationValue(enumValue, xcForNamespaces); + } + + xcForNamespaces.dispose(); // end hack + } + + checkIfReferenceToGlobalTypeIsNeeded( element, typeSystemHolder, options); + + return element; + } + + protected void processElementsInComplexType(Type elemType, List children, String parentNamespace, + TypeSystemHolder typeSystemHolder, Inst2XsdOptions options) + { + Map elemNamesToElements = new HashMap(); + Element currentElem = null; + + for (Iterator iterator = children.iterator(); iterator.hasNext();) + { + Element child = (Element) iterator.next(); + + if (currentElem==null) + { // first element in this type + checkIfElementReferenceIsNeeded(child, parentNamespace, typeSystemHolder, options); + elemType.addElement(child); + elemNamesToElements.put(child.getName(), child); + currentElem = child; + continue; + } + + if (currentElem.getName()==child.getName()) + { // same contiguos element + combineTypes(currentElem.getType(), child.getType(), options); // unify types + combineElementComments(currentElem, child); + // minOcc=0 maxOcc=unbounded + currentElem.setMinOccurs(0); + currentElem.setMaxOccurs(Element.UNBOUNDED); + } + else + { + Element sameElem = (Element)elemNamesToElements.get(child.getName()); + if (sameElem==null) + { // new element name + checkIfElementReferenceIsNeeded(child, parentNamespace, typeSystemHolder, options); + elemType.addElement(child); + elemNamesToElements.put(child.getName(), child); + } + else + { //same non contiguos + combineTypes(currentElem.getType(), child.getType(), options); + combineElementComments(currentElem, child); + elemType.setTopParticleForComplexOrMixedContent(Type.PARTICLE_CHOICE_UNBOUNDED); + } + currentElem = child; + } + } + } + + protected void checkIfElementReferenceIsNeeded(Element child, String parentNamespace, + TypeSystemHolder typeSystemHolder, Inst2XsdOptions options) + { + if (!child.getName().getNamespaceURI().equals(parentNamespace)) + { + Element referencedElem = new Element(); + referencedElem.setGlobal(true); + referencedElem.setName(child.getName()); + referencedElem.setType(child.getType()); + + if (child.isNillable()) + { + referencedElem.setNillable(true); + child.setNillable(false); + } + + referencedElem = addGlobalElement(referencedElem, typeSystemHolder, options); + + child.setRef(referencedElem); // clears child's type + } + } + + protected void checkIfReferenceToGlobalTypeIsNeeded(Element elem, TypeSystemHolder typeSystemHolder, + Inst2XsdOptions options) + { + // RussianDollDesign doesn't define global types + } + + protected void processAttributesInComplexType(Type elemType, List attributes) + { + assert elemType.isComplexType(); + for (Iterator iterator = attributes.iterator(); iterator.hasNext();) + { + Attribute att = (Attribute) iterator.next(); + elemType.addAttribute(att); + } + } + + protected Attribute processAttribute(XmlCursor xc, Inst2XsdOptions options, String parentNamespace, + TypeSystemHolder typeSystemHolder) + { + assert xc.isAttr() : "xc not on attribute"; + Attribute attribute = new Attribute(); + QName attName = xc.getName(); + + attribute.setName(attName); + + XmlCursor parent = xc.newCursor(); + parent.toParent(); + + Type simpleContentType = Type.createNamedType( + processSimpleContentType(xc.getTextValue(), options, parent), Type.SIMPLE_TYPE_SIMPLE_CONTENT); + + parent.dispose(); + + attribute.setType(simpleContentType); + + checkIfAttributeReferenceIsNeeded(attribute, parentNamespace, typeSystemHolder); + + return attribute; + } + + protected void checkIfAttributeReferenceIsNeeded(Attribute attribute, String parentNamespace, TypeSystemHolder typeSystemHolder) + { + if (!attribute.getName().getNamespaceURI().equals("") && + !attribute.getName().getNamespaceURI().equals(parentNamespace)) + { + // make attribute be a reference to a top level attribute in a different targetNamespace + Attribute referencedAtt = new Attribute(); + referencedAtt.setGlobal(true); + referencedAtt.setName(attribute.getName()); + referencedAtt.setType(attribute.getType()); + + typeSystemHolder.addGlobalAttribute(referencedAtt); + + attribute.setRef(referencedAtt); + } + } + + protected class SCTValidationContext + implements ValidationContext + { + protected boolean valid = true; + + public boolean isValid() + { + return valid; + } + + public void resetToValid() + { + valid = true; + } + + public void invalid(String message) + { + valid = false; + } + + public void invalid(String code, Object[] args) + { + valid = false; + } + } + + private SCTValidationContext _validationContext = new SCTValidationContext(); + + + // List of precedence for smart simple primitive type determination + // byte, short, int, long, integer, float, double, decimal, + // boolean + // date, dateTime, time, gDuration, + // QName ?, + // anyUri ? - triggered only for http:// or www. constructs, + // list types ? + // string + protected QName processSimpleContentType(String lexicalValue, Inst2XsdOptions options, final XmlCursor xc) + { + // check options and return xsd:string or if smart is enabled, look for a better type + if (options.getSimpleContentTypes()==Inst2XsdOptions.SIMPLE_CONTENT_TYPES_STRING) + return XmlString.type.getName(); + + if (options.getSimpleContentTypes()!=Inst2XsdOptions.SIMPLE_CONTENT_TYPES_SMART) + throw new IllegalArgumentException("Unknown value for Inst2XsdOptions.getSimpleContentTypes() :" + options.getSimpleContentTypes()); + + // Inst2XsdOptions.SIMPLE_CONTENT_TYPES_SMART case + + + try + { + XsTypeConverter.lexByte(lexicalValue); + return XmlByte.type.getName(); + } + catch (Exception e) {} + + try + { + XsTypeConverter.lexShort(lexicalValue); + return XmlShort.type.getName(); + } + catch (Exception e) {} + + try + { + XsTypeConverter.lexInt(lexicalValue); + return XmlInt.type.getName(); + } + catch (Exception e) {} + + try + { + XsTypeConverter.lexLong(lexicalValue); + return XmlLong.type.getName(); + } + catch (Exception e) {} + + try + { + XsTypeConverter.lexInteger(lexicalValue); + return XmlInteger.type.getName(); + } + catch (Exception e) {} + + try + { + XsTypeConverter.lexFloat(lexicalValue); + return XmlFloat.type.getName(); + } + catch (Exception e) {} + +// // this not needed because it's lexical space is covered by float +// try +// { +// XsTypeConverter.lexDouble(lexicalValue); +// return XmlDouble.type.getName(); +// } +// catch (Exception e) {} +// +// try +// { +// XsTypeConverter.lexDecimal(lexicalValue); +// return XmlDecimal.type.getName(); +// } +// catch (Exception e) {} + + XmlDateImpl.validateLexical(lexicalValue, XmlDate.type, _validationContext); + if (_validationContext.isValid()) + return XmlDate.type.getName(); + _validationContext.resetToValid(); + + XmlDateTimeImpl.validateLexical(lexicalValue, XmlDateTime.type, _validationContext); + if (_validationContext.isValid()) + return XmlDateTime.type.getName(); + _validationContext.resetToValid(); + + XmlTimeImpl.validateLexical(lexicalValue, XmlTime.type, _validationContext); + if (_validationContext.isValid()) + return XmlTime.type.getName(); + _validationContext.resetToValid(); + + XmlDurationImpl.validateLexical(lexicalValue, XmlDuration.type, _validationContext); + if (_validationContext.isValid()) + return XmlDuration.type.getName(); + _validationContext.resetToValid(); + + // check for uri + if (lexicalValue.startsWith("http://") || lexicalValue.startsWith("www.")) + { + XmlAnyUriImpl.validateLexical(lexicalValue, _validationContext); + if (_validationContext.isValid()) + return XmlAnyURI.type.getName(); + _validationContext.resetToValid(); + } + + // check for QName + int idx = lexicalValue.indexOf(':'); + if (idx>=0 && idx==lexicalValue.lastIndexOf(':') && idx+1options.getUseEnumerations()) + { + into.closeEnumeration(); + } + } + } + + protected QName combineToMoreGeneralSimpleType(QName t1, QName t2) + { + if (t1.equals(t2)) + return t1; + + if (t2.equals(XmlShort.type.getName()) && t1.equals(XmlByte.type.getName())) + return t2; + if (t1.equals(XmlShort.type.getName()) && t2.equals(XmlByte.type.getName())) + return t1; + + if (t2.equals(XmlInt.type.getName()) && + (t1.equals(XmlShort.type.getName()) || t1.equals(XmlByte.type.getName())) ) + return t2; + if (t1.equals(XmlInt.type.getName()) && + (t2.equals(XmlShort.type.getName()) || t2.equals(XmlByte.type.getName())) ) + return t1; + + if (t2.equals(XmlLong.type.getName()) && + (t1.equals(XmlInt.type.getName()) || t1.equals(XmlShort.type.getName()) || t1.equals(XmlByte.type.getName())) ) + return t2; + if (t1.equals(XmlLong.type.getName()) && + (t2.equals(XmlInt.type.getName()) || t2.equals(XmlShort.type.getName()) || t2.equals(XmlByte.type.getName())) ) + return t1; + + if (t2.equals(XmlInteger.type.getName()) && + (t1.equals(XmlLong.type.getName()) || t1.equals(XmlInt.type.getName()) || + t1.equals(XmlShort.type.getName()) || t1.equals(XmlByte.type.getName())) ) + return t2; + if (t1.equals(XmlInteger.type.getName()) && + (t2.equals(XmlLong.type.getName()) || t2.equals(XmlInt.type.getName()) || + t2.equals(XmlShort.type.getName()) || t2.equals(XmlByte.type.getName())) ) + return t1; + + if (t2.equals(XmlFloat.type.getName()) && + (t1.equals(XmlInteger.type.getName()) || + t1.equals(XmlLong.type.getName()) || t1.equals(XmlInt.type.getName()) || + t1.equals(XmlShort.type.getName()) || t1.equals(XmlByte.type.getName())) ) + return t2; + if (t1.equals(XmlFloat.type.getName()) && + (t2.equals(XmlInteger.type.getName()) || + t2.equals(XmlLong.type.getName()) || t2.equals(XmlInt.type.getName()) || + t2.equals(XmlShort.type.getName()) || t2.equals(XmlByte.type.getName())) ) + return t1; + + //double, decimal will never get here since they don't get generated + + //the rest of the combinations are not compatible, so they will combine in xsd:string + return XmlString.type.getName(); + } + + protected void combineAttributesOfTypes(Type into, Type from) + { + // loop through attributes: add fromAtt if they don't exist, combine them if they exist + outterLoop: + for (int i = 0; i < from.getAttributes().size(); i++) + { + Attribute fromAtt = (Attribute)from.getAttributes().get(i); + for (int j = 0; j < into.getAttributes().size(); j++) + { + Attribute intoAtt = (Attribute)into.getAttributes().get(j); + if (intoAtt.getName().equals(fromAtt.getName())) + { + intoAtt.getType().setName( + combineToMoreGeneralSimpleType(intoAtt.getType().getName(), fromAtt.getType().getName())); + continue outterLoop; + } + } + // fromAtt doesn't exist in into type, will add it right now + into.addAttribute(fromAtt); + } + + //optional attributes: if there are atts in into that are not in from, make them optional + outterLoop: + for (int i = 0; i < into.getAttributes().size(); i++) + { + Attribute intoAtt = (Attribute)into.getAttributes().get(i); + for (int j = 0; j < from.getAttributes().size(); j++) + { + Attribute fromAtt = (Attribute)from.getAttributes().get(j); + if (fromAtt.getName().equals(intoAtt.getName())) + { + continue; + } + } + // intoAtt doesn't exist in into type, will add it right now + intoAtt.setOptional(true); + } + } + + protected void combineElementsOfTypes(Type into, Type from, boolean makeElementsOptional, Inst2XsdOptions options) + { + boolean needsUnboundedChoice = false; + + if (into.getTopParticleForComplexOrMixedContent()!=Type.PARTICLE_SEQUENCE || + from.getTopParticleForComplexOrMixedContent()!=Type.PARTICLE_SEQUENCE) + needsUnboundedChoice = true; + + List res = new ArrayList(); + + int fromStartingIndex = 0; + int fromMatchedIndex = -1; + int intoMatchedIndex = -1; + + // for each element in into + for (int i = 0; !needsUnboundedChoice && i < into.getElements().size(); i++) + { + // try to find one with same name in from + Element intoElement = (Element) into.getElements().get(i); + for (int j = fromStartingIndex; j < from.getElements().size(); j++) + { + Element fromElement = (Element) from.getElements().get(j); + if (intoElement.getName().equals(fromElement.getName())) + { + fromMatchedIndex = j; + break; + } + } + + // if not found, it's safe to add this one to result 'res' (as optional) and continue + if ( fromMatchedIndex < fromStartingIndex ) + { + res.add(intoElement); + intoElement.setMinOccurs(0); + continue; + } + + // else try out all from elemens between fromStartingIndex to fromMatchedIndex + // to see if they match one of the into elements + intoMatchingLoop: + for (int j2 = fromStartingIndex; j2 < fromMatchedIndex; j2++) + { + Element fromCandidate = (Element) from.getElements().get(j2); + + for (int i2 = i+1; i2 < into.getElements().size(); i2++) + { + Element intoCandidate = (Element) into.getElements().get(i2); + if (fromCandidate.getName().equals(intoCandidate.getName())) + { + intoMatchedIndex = i2; + break intoMatchingLoop; + } + } + } + + if (intoMatchedIndex0) + { + if (into.getComment()==null) + into.setComment(with.getComment()); + else + into.setComment(into.getComment() + with.getComment()); + } + } +} diff --git a/xmlbeans/src/tools/org/apache/xmlbeans/impl/inst2xsd/SalamiSliceStrategy.java b/xmlbeans/src/tools/org/apache/xmlbeans/impl/inst2xsd/SalamiSliceStrategy.java new file mode 100644 index 000000000..be2645045 --- /dev/null +++ b/xmlbeans/src/tools/org/apache/xmlbeans/impl/inst2xsd/SalamiSliceStrategy.java @@ -0,0 +1,47 @@ +/* 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.inst2xsd; + +import org.apache.xmlbeans.impl.inst2xsd.util.Element; +import org.apache.xmlbeans.impl.inst2xsd.util.TypeSystemHolder; + +/** + * @author Cezar Andrei ( cezar.andrei at bea.com ) + * Date: Jul 26, 2004 + */ +public class SalamiSliceStrategy + extends RussianDollStrategy + implements XsdGenStrategy +{ + protected void checkIfElementReferenceIsNeeded(Element child, String parentNamespace, + TypeSystemHolder typeSystemHolder, Inst2XsdOptions options) + { + // always add element references + Element referencedElem = new Element(); + referencedElem.setGlobal(true); + referencedElem.setName(child.getName()); + referencedElem.setType(child.getType()); + + if (child.isNillable()) + { + referencedElem.setNillable(true); + child.setNillable(false); + } + + referencedElem = addGlobalElement(referencedElem, typeSystemHolder, options); + + child.setRef(referencedElem); // clears child's type + } +} diff --git a/xmlbeans/src/tools/org/apache/xmlbeans/impl/inst2xsd/VenetianBlindStrategy.java b/xmlbeans/src/tools/org/apache/xmlbeans/impl/inst2xsd/VenetianBlindStrategy.java new file mode 100644 index 000000000..79257e620 --- /dev/null +++ b/xmlbeans/src/tools/org/apache/xmlbeans/impl/inst2xsd/VenetianBlindStrategy.java @@ -0,0 +1,116 @@ +/* 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.inst2xsd; + +import org.apache.xmlbeans.impl.inst2xsd.util.Element; +import org.apache.xmlbeans.impl.inst2xsd.util.TypeSystemHolder; +import org.apache.xmlbeans.impl.inst2xsd.util.Type; + +import javax.xml.namespace.QName; + +/** + * @author Cezar Andrei ( cezar.andrei at bea.com ) + * Date: Jul 26, 2004 + */ +public class VenetianBlindStrategy + extends RussianDollStrategy + implements XsdGenStrategy +{ + protected void checkIfReferenceToGlobalTypeIsNeeded(Element elem, + TypeSystemHolder typeSystemHolder, Inst2XsdOptions options) + { + // VenetianBlindDesign defines global complex types + Type elemType = elem.getType(); + QName elemName = elem.getName(); + + if (elemType.isGlobal()) + // is already global, do nothing + return; + + if (elemType.isComplexType()) + { + for (int i = 0; ; i++) + { + elemType.setName(new QName(elemName.getNamespaceURI(), elemName.getLocalPart() + "Type" + (i==0 ? "" : "" + i))); + + Type candidate = typeSystemHolder.getGlobalType(elemType.getName()); + if (candidate==null) + { + elemType.setGlobal(true); + typeSystemHolder.addGlobalType(elemType); + break; + } + else + { + if (compatibleTypes(candidate, elemType)) + { + combineTypes(candidate, elemType, options); + elem.setType(candidate); + break; + } + } + } + } + } + + private boolean compatibleTypes(Type elemType, Type candidate) + { + // when two types look like they are the same ? + + if (elemType==candidate) + return true; + +// if (typeIsReferencedInside(elemType, candidate) || typeIsReferencedInside(candidate, elemType)) +// return false; +// +// if (!elemType.isComplexType() && !candidate.isComplexType()) +// return true; +// +// if (elemType.isComplexType() && !candidate.isComplexType()) +// return false; +// if (!elemType.isComplexType() && candidate.isComplexType()) +// return false; +// +// // both complex after this point +// +// //todo: be smarter: look at att and elem names and types - compute a difference index + + return true; + } + +// private boolean typeIsReferencedInside(Type entity, Type container) +// { +// for (int i = 0; i < container.getElements().size(); i++) +// { +// Element element = (Element) container.getElements().get(i); +// if (entity==element.getType()) +// return true; +// +// if (typeIsReferencedInside(entity, element.getType())) +// return true; +// } +// +// for (int i = 0; i < container.getAttributes().size(); i++) +// { +// Attribute attribute = (Attribute) container.getAttributes().get(i); +// if (entity==attribute.getType()) +// return true; +// +// if (typeIsReferencedInside(entity, attribute.getType())) +// return true; +// } +// return false; +// } +} \ No newline at end of file diff --git a/xmlbeans/src/tools/org/apache/xmlbeans/impl/inst2xsd/XsdGenStrategy.java b/xmlbeans/src/tools/org/apache/xmlbeans/impl/inst2xsd/XsdGenStrategy.java new file mode 100644 index 000000000..066fdbd98 --- /dev/null +++ b/xmlbeans/src/tools/org/apache/xmlbeans/impl/inst2xsd/XsdGenStrategy.java @@ -0,0 +1,28 @@ +/* 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.inst2xsd; + +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.impl.inst2xsd.util.TypeSystemHolder; +import org.apache.xmlbeans.impl.inst2xsd.Inst2XsdOptions; + +/** + * Author: Cezar Andrei ( cezar.andrei at bea.com ) + * Date: Jul 26, 2004 + */ +public interface XsdGenStrategy +{ + void processDoc(XmlObject[] instances, Inst2XsdOptions options, TypeSystemHolder typeSystemHolder); +} diff --git a/xmlbeans/src/tools/org/apache/xmlbeans/impl/inst2xsd/util/Attribute.java b/xmlbeans/src/tools/org/apache/xmlbeans/impl/inst2xsd/util/Attribute.java new file mode 100644 index 000000000..0d230bcc5 --- /dev/null +++ b/xmlbeans/src/tools/org/apache/xmlbeans/impl/inst2xsd/util/Attribute.java @@ -0,0 +1,99 @@ +/* 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.inst2xsd.util; + +import javax.xml.namespace.QName; + +/** + * @author Cezar Andrei (cezar.andrei at bea.com) Date: Jul 18, 2004 + */ +public class Attribute +{ + private QName _name; + private Type _type; + private Attribute _ref = null; + private boolean _isGlobal = false; + private boolean _isOptional = false; + + public QName getName() + { + return _name; + } + + public void setName(QName name) + { + _name = name; + } + + public Type getType() + { + return isRef() ? getRef().getType() : _type; + } + + public void setType(Type type) + { + assert !isRef(); + _type = type; + } + + public boolean isRef() + { + return _ref!=null; + } + + public Attribute getRef() + { + return _ref; + } + + public void setRef(Attribute ref) + { + assert !isGlobal(); + _ref = ref; + _type = null; + } + + public boolean isGlobal() + { + return _isGlobal; + } + + public void setGlobal(boolean isGlobal) + { + _isGlobal = isGlobal; + } + + public boolean isOptional() + { + return _isOptional; + } + + public void setOptional(boolean isOptional) + { + assert isOptional && !isGlobal() : "Global attributes cannot be optional."; + _isOptional = isOptional; + } + + public String toString() + { + return "\n Attribute{" + + "_name=" + _name + + ", _type=" + _type + + ", _ref=" + (_ref!=null) + + ", _isGlobal=" + _isGlobal + + ", _isOptional=" + _isOptional + + "}"; + } +} diff --git a/xmlbeans/src/tools/org/apache/xmlbeans/impl/inst2xsd/util/Element.java b/xmlbeans/src/tools/org/apache/xmlbeans/impl/inst2xsd/util/Element.java new file mode 100644 index 000000000..2b37c70db --- /dev/null +++ b/xmlbeans/src/tools/org/apache/xmlbeans/impl/inst2xsd/util/Element.java @@ -0,0 +1,138 @@ +/* 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.inst2xsd.util; + +import javax.xml.namespace.QName; + +/** + * @author Cezar Andrei (cezar.andrei at bea.com) Date: Jul 16, 2004 + */ +public class Element +{ + private QName _name = null; // if isRef is true is the name of the referenced name + private Element _ref = null; + private boolean _isGlobal = false; + private int _minOccurs = 1; + private int _maxOccurs = 1; + public static final int UNBOUNDED = -1; + private boolean _isNillable = false; + private Type _type = null; + private String _comment = null; + + public QName getName() + { + return _name; + } + + public void setName(QName name) + { + _name = name; + } + + public boolean isRef() + { + return _ref!=null; + } + + public Element getRef() + { + return _ref; + } + + public void setRef(Element ref) + { + assert _isGlobal==false; + _ref = ref; + _type = null; + } + + public boolean isGlobal() + { + return _isGlobal; + } + + public void setGlobal(boolean isGlobal) + { + _isGlobal = isGlobal; + _minOccurs = 1; + _maxOccurs = 1; + } + + public int getMinOccurs() + { + return _minOccurs; + } + + public void setMinOccurs(int minOccurs) + { + _minOccurs = minOccurs; + } + + public int getMaxOccurs() + { + return _maxOccurs; + } + + public void setMaxOccurs(int maxOccurs) + { + _maxOccurs = maxOccurs; + } + + public boolean isNillable() + { + return _isNillable; + } + + public void setNillable(boolean isNillable) + { + _isNillable = isNillable; + } + + public Type getType() + { + return isRef() ? getRef().getType() : _type; + } + + public void setType(Type type) + { + assert !isRef(); + _type = type; + } + + public String getComment() + { + return _comment; + } + + public void setComment(String comment) + { + _comment = comment; + } + + public String toString() + { + return "\n Element{" + + " _name = " + _name + + ", _ref = " + (_ref!=null) + + ", _isGlobal = " + _isGlobal + + ", _minOccurs = " + _minOccurs + + ", _maxOccurs = " + _maxOccurs + + ", _isNillable = " + _isNillable + + ", _comment = " + _comment + + ",\n _type = " + ( _type==null ? "null" : + (_type.isGlobal() ? _type.getName().toString() : _type.toString())) + + "\n }"; + } +} diff --git a/xmlbeans/src/tools/org/apache/xmlbeans/impl/inst2xsd/util/Type.java b/xmlbeans/src/tools/org/apache/xmlbeans/impl/inst2xsd/util/Type.java new file mode 100644 index 000000000..b06762439 --- /dev/null +++ b/xmlbeans/src/tools/org/apache/xmlbeans/impl/inst2xsd/util/Type.java @@ -0,0 +1,326 @@ +/* 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.inst2xsd.util; + +import org.apache.xmlbeans.XmlQName; +import org.apache.xmlbeans.XmlCursor; +import org.apache.xmlbeans.impl.common.PrefixResolver; +import org.apache.xmlbeans.impl.values.XmlQNameImpl; + +import javax.xml.namespace.QName; +import java.util.List; +import java.util.ArrayList; + +/** + * @author Cezar Andrei (cezar.andrei at bea.com) Date: Jul 16, 2004 + */ +public class Type +{ + private QName _name; + + private int _kind = SIMPLE_TYPE_SIMPLE_CONTENT; + // _kind value space + public static final int SIMPLE_TYPE_SIMPLE_CONTENT = 1; // ie no atts, no elems, just text + public static final int COMPLEX_TYPE_SIMPLE_CONTENT = 2; // ie atts*, no elems, text* - simple type extension + public static final int COMPLEX_TYPE_COMPLEX_CONTENT = 3; // ie atts*, elems, no text + public static final int COMPLEX_TYPE_MIXED_CONTENT = 4; // ie atts*, elems, text + public static final int COMPLEX_TYPE_EMPTY_CONTENT = 5; // no elems, no text, just atts + + private int _topParticleForComplexOrMixedContent = PARTICLE_SEQUENCE; + // _topParticleForComplexOrMixedContent + public static final int PARTICLE_SEQUENCE = 1; + public static final int PARTICLE_CHOICE_UNBOUNDED = 2; + + private List _elements; // size>0 COMPLEX + private List _attributes; // size>0 COMPLEX + + private Type _extensionType; + private boolean _isGlobal = false; + + private List _enumerationValues; + private boolean _acceptsEnumerationValue = true; + private List _enumerationQNames; // This is a special case where the lexical representation + // is not enough for a value, the QNames need to be remembered + // in case the _extensionType is QName + + protected Type() + {} + + public static Type createNamedType(QName name, int contentType) + { + assert name!=null; + Type type = new Type(); + type.setName(name); + type.setContentType(contentType); + return type; + } + + public static Type createUnnamedType(int contentType) + { + assert contentType==SIMPLE_TYPE_SIMPLE_CONTENT || + contentType==COMPLEX_TYPE_SIMPLE_CONTENT || + contentType==COMPLEX_TYPE_COMPLEX_CONTENT || + contentType==COMPLEX_TYPE_MIXED_CONTENT || + contentType==COMPLEX_TYPE_EMPTY_CONTENT: "Unknown contentType: " + contentType; + Type type = new Type(); + type.setContentType(contentType); + return type; + } + + + public QName getName() + { + return _name; + } + + public void setName(QName name) + { + this._name = name; + } + + /** + * @return + * SIMPLE_TYPE_SIMPLE_CONTENT // ie no atts, no elems, just text + * COMPLEX_TYPE_SIMPLE_CONTENT // ie atts*, no elems, text* - simple type extension + * COMPLEX_TYPE_COMPLEX_CONTENT // ie atts*, elems, no text + * COMPLEX_TYPE_MIXED_CONTENT // ie atts*, elems, text + * COMPLEX_TYPE_EMPTY_CONTENT // no elems, no text, just atts + */ + public int getContentType() + { + return _kind; + } + + /** + * @param kind 4 kinds: + * SIMPLE_TYPE_SIMPLE_CONTENT // ie no atts, no elems, just text + * COMPLEX_TYPE_SIMPLE_CONTENT // ie atts*, no elems, text* - simple type extension + * COMPLEX_TYPE_COMPLEX_CONTENT // ie atts*, elems, no text + * COMPLEX_TYPE_MIXED_CONTENT // ie atts*, elems, text + * COMPLEX_TYPE_EMPTY_CONTENT // no elems, no text, just atts + */ + public void setContentType(int kind) + { + this._kind = kind; + } + + public List getElements() + { + ensureElements(); + return _elements; + } + + public void addElement(Element element) + { + ensureElements(); + _elements.add(element); + } + + public void setElements(List elements) + { + ensureElements(); + _elements.clear(); + _elements.addAll(elements); + } + + private void ensureElements() + { + if (_elements==null) + _elements = new ArrayList(); + } + + public List getAttributes() + { + ensureAttributes(); + return _attributes; + } + + public void addAttribute(Attribute attribute) + { + ensureAttributes(); + _attributes.add(attribute); + } + + public Attribute getAttribute(QName name) + { + for (int i = 0; i < _attributes.size(); i++) + { + Attribute attribute = (Attribute) _attributes.get(i); + if (attribute.getName().equals(name)) + return attribute; + } + return null; + } + + private void ensureAttributes() + { + if (_attributes==null) + _attributes = new ArrayList(); + } + + public boolean isComplexType() + { + return (_kind==COMPLEX_TYPE_COMPLEX_CONTENT || + _kind==COMPLEX_TYPE_MIXED_CONTENT|| + _kind==COMPLEX_TYPE_SIMPLE_CONTENT); + } + + public boolean hasSimpleContent() + { + return (_kind==SIMPLE_TYPE_SIMPLE_CONTENT || + _kind==COMPLEX_TYPE_SIMPLE_CONTENT); + } + + /** + * @return PARTICLE_SEQUENCE or PARTICLE_CHOICE_UNBOUNDED + */ + public int getTopParticleForComplexOrMixedContent() + { + return _topParticleForComplexOrMixedContent; + } + + /** + * @param topParticleForComplexOrMixedContent PARTICLE_SEQUENCE or PARTICLE_CHOICE_UNBOUNDED + */ + public void setTopParticleForComplexOrMixedContent(int topParticleForComplexOrMixedContent) + { + this._topParticleForComplexOrMixedContent = topParticleForComplexOrMixedContent; + } + + public boolean isGlobal() + { + return _isGlobal; + } + + public void setGlobal(boolean isGlobal) + { + assert isGlobal && getName()!=null; + _isGlobal = isGlobal; + } + + public Type getExtensionType() + { + return _extensionType; + } + + public void setExtensionType(Type extendedType) + { + assert _kind == COMPLEX_TYPE_SIMPLE_CONTENT : "Extension used only for type which are COMPLEX_TYPE_SIMPLE_CONTENT"; + assert extendedType!=null && extendedType.getName()!=null : "Extended type must be a named type."; + _extensionType = extendedType; + } + + public List getEnumerationValues() + { + ensureEnumerationValues(); + return _enumerationValues; + } + + public List getEnumerationQNames() + { + ensureEnumerationValues(); + return _enumerationQNames; + } + + public void addEnumerationValue(String enumerationValue, final XmlCursor xc) + { + assert _kind==SIMPLE_TYPE_SIMPLE_CONTENT || _kind==COMPLEX_TYPE_SIMPLE_CONTENT : "Enumerations possible only on simple content"; + ensureEnumerationValues(); + if (_acceptsEnumerationValue && !_enumerationValues.contains(enumerationValue)) + { + _enumerationValues.add(enumerationValue); + if (_name.equals(XmlQName.type.getName())) + { + // check for QName + PrefixResolver prefixResolver = new PrefixResolver() + { + public String getNamespaceForPrefix(String prefix) + { return xc.namespaceForPrefix(prefix); } + }; + + QName qname = XmlQNameImpl.validateLexical(enumerationValue, null, prefixResolver); + + assert qname!=null : "The check for QName should allready have happened."; + _enumerationQNames.add(qname); + } + } + } + + private void ensureEnumerationValues() + { + if (_enumerationValues==null) + { + _enumerationValues = new ArrayList(); + _enumerationQNames = new ArrayList(); + } + } + + public boolean isEnumeration() + { + return _acceptsEnumerationValue && _enumerationValues!=null && _enumerationValues.size()>1; + } + + public boolean isQNameEnumeration() + { + return isEnumeration() && _name.equals(XmlQName.type.getName()) && _enumerationQNames!=null && _enumerationQNames.size()>1; + } + + public void closeEnumeration() + { + _acceptsEnumerationValue=false; + } + + public String toString() + { + return "Type{" + + "_name = " + _name + + ", _extensionType = " + _extensionType + + ", _kind = " + _kind + + ", _elements = " + _elements + + ", _attributes = " + _attributes + + "}"; + } + + public void addAllEnumerationsFrom(Type from) + { + assert _kind==SIMPLE_TYPE_SIMPLE_CONTENT || _kind==COMPLEX_TYPE_SIMPLE_CONTENT : "Enumerations possible only on simple content"; + ensureEnumerationValues(); + + if (_name.equals(XmlQName.type.getName()) && from._name.equals(XmlQName.type.getName())) + { + for (int i = 0; i < from.getEnumerationValues().size(); i++) + { + String enumValue = (String) from.getEnumerationValues().get(i); + QName enumQNameValue = (QName) from.getEnumerationQNames().get(i); + if (_acceptsEnumerationValue && !_enumerationQNames.contains(enumQNameValue)) + { + _enumerationValues.add(enumValue); + _enumerationQNames.add(enumQNameValue); + } + } + } + else + { + for (int i = 0; i < from.getEnumerationValues().size(); i++) + { + String enumValue = (String) from.getEnumerationValues().get(i); + if (_acceptsEnumerationValue && !_enumerationValues.contains(enumValue)) + { + _enumerationValues.add(enumValue); + } + } + } + } +} diff --git a/xmlbeans/src/tools/org/apache/xmlbeans/impl/inst2xsd/util/TypeSystemHolder.java b/xmlbeans/src/tools/org/apache/xmlbeans/impl/inst2xsd/util/TypeSystemHolder.java new file mode 100644 index 000000000..b79b06862 --- /dev/null +++ b/xmlbeans/src/tools/org/apache/xmlbeans/impl/inst2xsd/util/TypeSystemHolder.java @@ -0,0 +1,396 @@ +/* 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.inst2xsd.util; + +import org.apache.xmlbeans.impl.xb.xsdschema.SchemaDocument; +import org.apache.xmlbeans.XmlString; +import org.apache.xmlbeans.XmlQName; +import org.apache.xmlbeans.XmlCursor; + +import javax.xml.namespace.QName; +import java.math.BigInteger; +import java.util.Collection; +import java.util.Iterator; +import java.util.Map; +import java.util.LinkedHashMap; +import java.util.HashMap; + +/** + * @author Cezar Andrei (cezar.andrei at bea.com) Date: Jul 16, 2004 + */ +public class TypeSystemHolder +{ + Map _globalElements; // QName -> Element + Map _globalAttributes; // QName -> Attribute + Map _globalTypes; // QName -> Type + + public TypeSystemHolder() + { + _globalElements = new LinkedHashMap(); + _globalAttributes = new LinkedHashMap(); + _globalTypes = new LinkedHashMap(); + } + + public void addGlobalElement(Element element) + { + assert element.isGlobal() && !element.isRef(); + _globalElements.put(element.getName(), element); + } + + public Element getGlobalElement(QName name) + { + return (Element)_globalElements.get(name); + } + + public Element[] getGlobalElements() + { + Collection col = _globalElements.values(); + return (Element[])col.toArray(new Element[col.size()]); + } + + public void addGlobalAttribute(Attribute attribute) + { + assert attribute.isGlobal() && !attribute.isRef(); + _globalAttributes.put(attribute.getName(), attribute); + } + + public Attribute getGlobalAttribute(QName name) + { + return (Attribute)_globalAttributes.get(name); + } + + public Attribute[] getGlobalAttributes() + { + Collection col = _globalAttributes.values(); + return (Attribute[])col.toArray(new Attribute[col.size()]); + } + + public void addGlobalType(Type type) + { + assert type.isGlobal() && type.getName()!=null : "type must be a global type before being added."; + _globalTypes.put(type.getName(), type); + } + + public Type getGlobalType(QName name) + { + return (Type)_globalTypes.get(name); + } + + public Type[] getGlobalTypes() + { + Collection col = _globalTypes.values(); + return (Type[])col.toArray(new Type[col.size()]); + } + + public SchemaDocument[] getSchemaDocuments() + { + // recompute everything, should cache it and track changes + Map nsToSchemaDocs = new LinkedHashMap(); + + for (Iterator iterator = _globalElements.keySet().iterator(); iterator.hasNext();) + { + QName globalElemName = (QName) iterator.next(); + String tns = globalElemName.getNamespaceURI(); + SchemaDocument schDoc = getSchemaDocumentForTNS(nsToSchemaDocs, tns); + + fillUpGlobalElement((Element)_globalElements.get(globalElemName), schDoc, tns); + } + + for (Iterator iterator = _globalAttributes.keySet().iterator(); iterator.hasNext();) + { + QName globalAttName = (QName) iterator.next(); + String tns = globalAttName.getNamespaceURI(); + SchemaDocument schDoc = getSchemaDocumentForTNS(nsToSchemaDocs, tns); + + fillUpGlobalAttribute((Attribute)_globalAttributes.get(globalAttName), schDoc, tns); + } + + for (Iterator iterator = _globalTypes.keySet().iterator(); iterator.hasNext();) + { + QName globalTypeName = (QName) iterator.next(); + String tns = globalTypeName.getNamespaceURI(); + SchemaDocument schDoc = getSchemaDocumentForTNS(nsToSchemaDocs, tns); + + fillUpGlobalType((Type)_globalTypes.get(globalTypeName), schDoc, tns); + } + + Collection schDocColl = nsToSchemaDocs.values(); + return (SchemaDocument[])schDocColl.toArray(new SchemaDocument[schDocColl.size()]); + } + + private static SchemaDocument getSchemaDocumentForTNS(Map nsToSchemaDocs, String tns) + { + SchemaDocument schDoc = (SchemaDocument)nsToSchemaDocs.get(tns); + if (schDoc==null) + { + schDoc = SchemaDocument.Factory.newInstance(); + nsToSchemaDocs.put(tns, schDoc); + } + return schDoc; + } + + private static org.apache.xmlbeans.impl.xb.xsdschema.SchemaDocument.Schema getTopLevelSchemaElement(SchemaDocument schDoc, + String tns) + { + org.apache.xmlbeans.impl.xb.xsdschema.SchemaDocument.Schema sch = schDoc.getSchema(); + if (sch==null) + { + sch = schDoc.addNewSchema(); + sch.setAttributeFormDefault(org.apache.xmlbeans.impl.xb.xsdschema.FormChoice.Enum.forString("unqualified")); + sch.setElementFormDefault(org.apache.xmlbeans.impl.xb.xsdschema.FormChoice.Enum.forString("qualified")); + if (!tns.equals("")) + sch.setTargetNamespace(tns); + } + return sch; + } + + // Global Elements + private void fillUpGlobalElement(Element globalElement, SchemaDocument schDoc, String tns) + { + assert tns.equals(globalElement.getName().getNamespaceURI()); + + org.apache.xmlbeans.impl.xb.xsdschema.SchemaDocument.Schema sch = getTopLevelSchemaElement(schDoc, tns); + + org.apache.xmlbeans.impl.xb.xsdschema.TopLevelElement topLevelElem = sch.addNewElement(); + topLevelElem.setName(globalElement.getName().getLocalPart()); + + if (globalElement.isNillable()) + topLevelElem.setNillable(globalElement.isNillable()); + + fillUpElementDocumentation(topLevelElem, globalElement.getComment()); + + Type elemType = globalElement.getType(); + fillUpTypeOnElement(elemType, topLevelElem, tns); + } + + protected void fillUpLocalElement(Element element, org.apache.xmlbeans.impl.xb.xsdschema.LocalElement localSElement, String tns) + { + fillUpElementDocumentation(localSElement, element.getComment()); + if (!element.isRef()) + { + assert element.getName().getNamespaceURI().equals(tns) || + element.getName().getNamespaceURI().length() == 0; + fillUpTypeOnElement(element.getType(), localSElement, tns); + localSElement.setName(element.getName().getLocalPart()); + } + else + { + localSElement.setRef(element.getName()); + assert !element.isNillable(); + } + + if (element.getMaxOccurs()==Element.UNBOUNDED) + { + localSElement.setMaxOccurs("unbounded"); + } + if (element.getMinOccurs()!=1) + { + localSElement.setMinOccurs(new BigInteger("" + element.getMinOccurs())); + } + + if (element.isNillable()) + localSElement.setNillable(element.isNillable()); + } + + private void fillUpTypeOnElement(Type elemType, org.apache.xmlbeans.impl.xb.xsdschema.Element parentSElement, String tns) + { + if (elemType.isGlobal()) + { + assert elemType.getName()!=null : "Global type must have a name."; + parentSElement.setType(elemType.getName()); + } + else if (elemType.getContentType()==Type.SIMPLE_TYPE_SIMPLE_CONTENT) + { + if (elemType.isEnumeration()) + fillUpEnumeration(elemType, parentSElement); + else + parentSElement.setType(elemType.getName()); + } + else + { + org.apache.xmlbeans.impl.xb.xsdschema.LocalComplexType localComplexType = parentSElement.addNewComplexType(); + fillUpContentForComplexType(elemType, localComplexType, tns); + } + } + + private void fillUpEnumeration(Type type, org.apache.xmlbeans.impl.xb.xsdschema.Element parentSElement) + { + assert type.isEnumeration() && !type.isComplexType() : "Enumerations must be on simple types only."; + org.apache.xmlbeans.impl.xb.xsdschema.RestrictionDocument.Restriction restriction = parentSElement.addNewSimpleType().addNewRestriction(); + restriction.setBase(type.getName()); + if (type.isQNameEnumeration()) + { + for (int i = 0; i < type.getEnumerationQNames().size(); i++) + { + QName value = (QName) type.getEnumerationQNames().get(i); + XmlQName xqname = XmlQName.Factory.newValue(value); + + org.apache.xmlbeans.impl.xb.xsdschema.NoFixedFacet enumSElem = restriction.addNewEnumeration(); + XmlCursor xc = enumSElem.newCursor(); + + String newPrefix = xc.prefixForNamespace(value.getNamespaceURI()); + xc.dispose(); + + enumSElem.setValue( XmlQName.Factory.newValue( + new QName(value.getNamespaceURI(), value.getLocalPart(), newPrefix))); + } + } + else + { + for (int i = 0; i < type.getEnumerationValues().size(); i++) + { + String value = (String) type.getEnumerationValues().get(i); + restriction.addNewEnumeration().setValue(XmlString.Factory.newValue(value)); + } + } + } + + private void fillUpAttributesInComplexTypesSimpleContent(Type elemType, + org.apache.xmlbeans.impl.xb.xsdschema.SimpleExtensionType sExtension, String tns) + { + for (int i = 0; i < elemType.getAttributes().size(); i++) + { + Attribute att = (Attribute) elemType.getAttributes().get(i); + org.apache.xmlbeans.impl.xb.xsdschema.Attribute sAttribute = sExtension.addNewAttribute(); + fillUpLocalAttribute(att, sAttribute, tns); + } + } + + private void fillUpAttributesInComplexTypesComplexContent(Type elemType, + org.apache.xmlbeans.impl.xb.xsdschema.ComplexType localSComplexType, String tns) + { + for (int i = 0; i < elemType.getAttributes().size(); i++) + { + Attribute att = (Attribute) elemType.getAttributes().get(i); + org.apache.xmlbeans.impl.xb.xsdschema.Attribute sAttribute = localSComplexType.addNewAttribute(); + fillUpLocalAttribute(att, sAttribute, tns); + } + } + + protected void fillUpLocalAttribute(Attribute att, org.apache.xmlbeans.impl.xb.xsdschema.Attribute sAttribute, String tns) + { + if (att.isRef()) + { + sAttribute.setRef(att.getRef().getName()); + } + else + { + assert att.getName().getNamespaceURI()==tns || att.getName().getNamespaceURI().equals(""); + sAttribute.setType(att.getType().getName()); + sAttribute.setName(att.getName().getLocalPart()); + if (att.isOptional()) + sAttribute.setUse(org.apache.xmlbeans.impl.xb.xsdschema.Attribute.Use.OPTIONAL); + } + } + + protected void fillUpContentForComplexType(Type type, org.apache.xmlbeans.impl.xb.xsdschema.ComplexType sComplexType, String tns) + { + if (type.getContentType()==Type.COMPLEX_TYPE_SIMPLE_CONTENT) + { + org.apache.xmlbeans.impl.xb.xsdschema.SimpleContentDocument.SimpleContent simpleContent = sComplexType.addNewSimpleContent(); + + assert type.getExtensionType()!=null && type.getExtensionType().getName()!=null : "Extension type must exist and be named for a COMPLEX_TYPE_SIMPLE_CONTENT"; + + org.apache.xmlbeans.impl.xb.xsdschema.SimpleExtensionType ext = simpleContent.addNewExtension(); + ext.setBase(type.getExtensionType().getName()); + + fillUpAttributesInComplexTypesSimpleContent(type, ext, tns); + } + else + { + if (type.getContentType()==Type.COMPLEX_TYPE_MIXED_CONTENT) + { + sComplexType.setMixed(true); + } + + org.apache.xmlbeans.impl.xb.xsdschema.ExplicitGroup explicitGroup; + if (type.getContentType()==Type.COMPLEX_TYPE_EMPTY_CONTENT) + explicitGroup = null; + else if (type.getTopParticleForComplexOrMixedContent()==Type.PARTICLE_SEQUENCE) + { + explicitGroup = sComplexType.addNewSequence(); + } + else if (type.getTopParticleForComplexOrMixedContent()==Type.PARTICLE_CHOICE_UNBOUNDED) + { + explicitGroup = sComplexType.addNewChoice(); + explicitGroup.setMaxOccurs("unbounded"); + explicitGroup.setMinOccurs(new BigInteger("0")); + } + else { throw new IllegalStateException("Unknown particle type in complex and mixed content"); } + + for (int i = 0; i < type.getElements().size(); i++) + { + Element child = (Element) type.getElements().get(i); + assert !child.isGlobal(); + org.apache.xmlbeans.impl.xb.xsdschema.LocalElement childLocalElement = explicitGroup.addNewElement(); + fillUpLocalElement(child, childLocalElement, tns); + } + + fillUpAttributesInComplexTypesComplexContent(type, sComplexType, tns); + } + } + + // Global Attributes + private void fillUpGlobalAttribute(Attribute globalAttribute, SchemaDocument schDoc, String tns) + { + assert tns.equals(globalAttribute.getName().getNamespaceURI()); + org.apache.xmlbeans.impl.xb.xsdschema.SchemaDocument.Schema sch = getTopLevelSchemaElement(schDoc, tns); + + org.apache.xmlbeans.impl.xb.xsdschema.TopLevelAttribute topLevelAtt = sch.addNewAttribute(); + topLevelAtt.setName(globalAttribute.getName().getLocalPart()); + + Type elemType = globalAttribute.getType(); + + if (elemType.getContentType()==Type.SIMPLE_TYPE_SIMPLE_CONTENT) + { + topLevelAtt.setType(elemType.getName()); + } + else + { + //org.apache.xmlbeans.impl.xb.xsdschema.LocalSimpleType localSimpleType = topLevelAtt.addNewSimpleType(); + throw new IllegalStateException(); + } + } + + private static void fillUpElementDocumentation(org.apache.xmlbeans.impl.xb.xsdschema.Element element, String comment) + { + if (comment!=null && comment.length()>0) + { + org.apache.xmlbeans.impl.xb.xsdschema.DocumentationDocument.Documentation documentation = element.addNewAnnotation().addNewDocumentation(); + documentation.set(org.apache.xmlbeans.XmlString.Factory.newValue(comment)); + } + } + + // Global Types + private void fillUpGlobalType(Type globalType, SchemaDocument schDoc, String tns) + { + assert tns.equals(globalType.getName().getNamespaceURI()); + org.apache.xmlbeans.impl.xb.xsdschema.SchemaDocument.Schema sch = getTopLevelSchemaElement(schDoc, tns); + + org.apache.xmlbeans.impl.xb.xsdschema.TopLevelComplexType topLevelComplexType = sch.addNewComplexType(); + topLevelComplexType.setName(globalType.getName().getLocalPart()); + + fillUpContentForComplexType(globalType, topLevelComplexType, tns); + } + + public String toString() + { + return "TypeSystemHolder{" + + "\n\n_globalElements=" + _globalElements + + "\n\n_globalAttributes=" + _globalAttributes + + "\n\n_globalTypes=" + _globalTypes + + "\n}"; + } +} diff --git a/xmlbeans/src/tools/org/apache/xmlbeans/impl/xpathgen/XPathGenerationException.java b/xmlbeans/src/tools/org/apache/xmlbeans/impl/xpathgen/XPathGenerationException.java new file mode 100644 index 000000000..8a977da69 --- /dev/null +++ b/xmlbeans/src/tools/org/apache/xmlbeans/impl/xpathgen/XPathGenerationException.java @@ -0,0 +1,14 @@ +package org.apache.xmlbeans.impl.xpathgen; + +import org.apache.xmlbeans.XmlException; + +/** + * An exception thrown if the XPath generation process can't complete + */ +public class XPathGenerationException extends XmlException +{ + public XPathGenerationException(String m) + { + super(m); + } +} diff --git a/xmlbeans/src/tools/org/apache/xmlbeans/impl/xpathgen/XPathGenerator.java b/xmlbeans/src/tools/org/apache/xmlbeans/impl/xpathgen/XPathGenerator.java new file mode 100644 index 000000000..430afb3ce --- /dev/null +++ b/xmlbeans/src/tools/org/apache/xmlbeans/impl/xpathgen/XPathGenerator.java @@ -0,0 +1,208 @@ +package org.apache.xmlbeans.impl.xpathgen; + +import org.apache.xmlbeans.XmlCursor; +import org.apache.xmlbeans.XmlCursor.TokenType; + +import javax.xml.namespace.QName; +import javax.xml.namespace.NamespaceContext; + +/** + * Generates an XPath String that points to a given position in an XML document + */ +public class XPathGenerator +{ + /** + * Generates an XPath pointing to the position in the document indicated by node. + *

    If the context parameter is null, the XPath is absolute, otherwise the + * XPath will be relative to the position indicated by context.

    + *

    Note: the cursor position for the node parameter is not preserved

    + * @param node the position in the document that the generated path will point to + * @param context the context node; the generated path will be relative to it if not null and if + * pointing to an element on the path from the document root to node + * @param nsctx a namespace context that will be used to obtain prefixes; a (non-default) + * namespace mapping must be available for all required namespace URIs + * @return the generated path as a String + * @throws XPathGenerationException if the path could not be generated: the cursor is in a bad + * position (like over a comment) or no prefix mapping was found for one of the namespace URIs + */ + public static String generateXPath(XmlCursor node, XmlCursor context, NamespaceContext nsctx) + throws XPathGenerationException + { + if (node == null) + throw new IllegalArgumentException("Null node"); + if (nsctx == null) + throw new IllegalArgumentException("Null namespace context"); + TokenType tt = node.currentTokenType(); + if (context != null && node.isAtSamePositionAs(context)) + return "."; + switch (tt.intValue()) + { + case TokenType.INT_ATTR: + QName name = node.getName(); + node.toParent(); + String pathToParent = generateInternal(node, context, nsctx); + return pathToParent + '/' + '@' + qnameToString(name, nsctx); + case TokenType.INT_NAMESPACE: + name = node.getName(); + node.toParent(); + pathToParent = generateInternal(node, context, nsctx); + String prefix = name.getLocalPart(); + if (prefix.length() == 0) + return pathToParent + "/@xmlns"; + else + return pathToParent + "/@xmlns:" + prefix; + case TokenType.INT_START: + case TokenType.INT_STARTDOC: + return generateInternal(node, context, nsctx); + case TokenType.INT_TEXT: + int nrOfTextTokens = countTextTokens(node); + node.toParent(); + pathToParent = generateInternal(node, context, nsctx); + if (nrOfTextTokens == 0) + return pathToParent + "/text()"; + else + return pathToParent + "/text()[position()=" + nrOfTextTokens + ']'; + default: + throw new XPathGenerationException("Cannot generate XPath for cursor position: " + + tt.toString()); + } + } + + private static String generateInternal(XmlCursor node, XmlCursor context, NamespaceContext nsctx) + throws XPathGenerationException + { + if (node.isStartdoc()) + return ""; + if (context != null && node.isAtSamePositionAs(context)) + return "."; + assert node.isStart(); + QName name = node.getName(); + XmlCursor d = node.newCursor(); + if (!node.toParent()) + return "/" + name; + int elemIndex = 0, i = 1; + node.push(); + if (!node.toChild(name)) + throw new IllegalStateException("Must have at least one child with name: " + name); + do + { + if (node.isAtSamePositionAs(d)) + elemIndex = i; + else + i++; + } while (node.toNextSibling(name)); + node.pop(); + d.dispose(); + String pathToParent = generateInternal(node, context, nsctx); + return i == 1 ? pathToParent + '/' + qnameToString(name, nsctx) : + pathToParent + '/' + qnameToString(name, nsctx) + '[' + elemIndex + ']'; + } + + private static String qnameToString(QName qname, NamespaceContext ctx) + throws XPathGenerationException + { + String localName = qname.getLocalPart(); + String uri = qname.getNamespaceURI(); + if (uri.length() == 0) + return localName; + String prefix = qname.getPrefix(); + if (prefix != null && prefix.length() > 0) + { + // Try to use the same prefix if it maps to the right URI + String mappedUri = ctx.getNamespaceURI(prefix); + if (uri.equals(mappedUri)) + return prefix + ':' + localName; + } + // The prefix is not specified, or it is not mapped to the right URI + prefix = ctx.getPrefix(uri); + if (prefix == null) + throw new XPathGenerationException("Could not obtain a prefix for URI: " + uri); + if (prefix.length() == 0) + throw new XPathGenerationException("Can not use default prefix in XPath for URI: " + uri); + return prefix + ':' + localName; + } + + /** + * Computes how many text nodes the + * @param c the position in the document + * @return how many text nodes occur before the position determined by c + */ + private static int countTextTokens(XmlCursor c) + { + int k = 0; + int l = 0; + XmlCursor d = c.newCursor(); + c.push(); + c.toParent(); + TokenType tt = c.toFirstContentToken(); + while (!tt.isEnd()) + { + if (tt.isText()) + { + if (c.comparePosition(d) > 0) + // We have moved after the initial position + l++; + else + k++; + } + else if (tt.isStart()) + c.toEndToken(); + tt = c.toNextToken(); + } + c.pop(); + return l == 0 ? 0 : k; + } + + public static void main(String[] args) throws org.apache.xmlbeans.XmlException + { + String xml = + "\n" + + "text1text2text3texttext4\n" + + ""; + NamespaceContext ns = new NamespaceContext() { + public String getNamespaceURI(String prefix) + { + if ("ns".equals(prefix)) + return "http://a.com"; + else + return null; + } + public String getPrefix(String namespaceUri) + { + return null; + } + public java.util.Iterator getPrefixes(String namespaceUri) + { + return null; + } + }; + XmlCursor c = org.apache.xmlbeans.XmlObject.Factory.parse(xml).newCursor(); + c.toFirstContentToken(); // on + c.toFirstContentToken(); // on + c.toFirstChild(); // on + c.toFirstChild(); // on + c.push(); System.out.println(generateXPath(c, null, ns)); c.pop(); + c.toNextSibling(); + c.toNextSibling(); // on the last + c.push(); System.out.println(generateXPath(c, null, ns)); c.pop(); + XmlCursor d = c.newCursor(); + d.toParent(); + c.push(); System.out.println(generateXPath(c, d, ns)); c.pop(); + d.toParent(); + c.push(); System.out.println(generateXPath(c, d, ns)); c.pop(); + c.toFirstContentToken(); // on text content of the last + c.push(); System.out.println(generateXPath(c, d, ns)); c.pop(); + c.toParent(); + c.toPrevToken(); // on text content before the last + c.push(); System.out.println(generateXPath(c, d, ns)); c.pop(); + c.toParent(); // on + c.push(); System.out.println(generateXPath(c, d, ns)); c.pop(); + c.toFirstAttribute(); // on the "foo" attribute + c.push(); System.out.println(generateXPath(c, d, ns)); c.pop(); + c.toParent(); + c.toParent(); + c.toNextToken(); // on the "xmlns:ns" attribute + c.push(); System.out.println(generateXPath(c, d, ns)); c.pop(); + c.push(); System.out.println(generateXPath(c, null, ns)); c.pop(); + } +} diff --git a/xmlbeans/src/tools/org/apache/xmlbeans/impl/xsd2inst/SampleXmlUtil.java b/xmlbeans/src/tools/org/apache/xmlbeans/impl/xsd2inst/SampleXmlUtil.java new file mode 100644 index 000000000..210646d03 --- /dev/null +++ b/xmlbeans/src/tools/org/apache/xmlbeans/impl/xsd2inst/SampleXmlUtil.java @@ -0,0 +1,1189 @@ +/* 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.xsd2inst; + +/* + * TODO: +* Comment on enumerations? +* Comment on facets? +* Have a verbose option? +* Have a sample data option, would create valid instance with sample data? +* Add the pattern facet; this is tricky, considering the relationship with length +*/ + +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.XmlCursor; +import org.apache.xmlbeans.SchemaParticle; +import org.apache.xmlbeans.SchemaLocalElement; +import org.apache.xmlbeans.SchemaProperty; +import org.apache.xmlbeans.GDuration; +import org.apache.xmlbeans.GDurationBuilder; +import org.apache.xmlbeans.GDate; +import org.apache.xmlbeans.GDateBuilder; +import org.apache.xmlbeans.XmlAnySimpleType; +import org.apache.xmlbeans.SimpleValue; +import org.apache.xmlbeans.XmlOptions; +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.XmlInteger; +import org.apache.xmlbeans.XmlDate; +import org.apache.xmlbeans.XmlDateTime; +import org.apache.xmlbeans.XmlTime; +import org.apache.xmlbeans.XmlGYear; +import org.apache.xmlbeans.XmlGYearMonth; +import org.apache.xmlbeans.XmlGMonth; +import org.apache.xmlbeans.XmlGMonthDay; +import org.apache.xmlbeans.XmlGDay; +import org.apache.xmlbeans.XmlDecimal; +import org.apache.xmlbeans.XmlDuration; +import org.apache.xmlbeans.soap.SchemaWSDLArrayType; +import org.apache.xmlbeans.soap.SOAPArrayType; +import org.apache.xmlbeans.impl.util.Base64; +import org.apache.xmlbeans.impl.util.HexBin; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.Random; +import java.util.Set; +import java.util.HashSet; +import java.util.Arrays; + +import javax.xml.namespace.QName; + +public class SampleXmlUtil +{ + private boolean _soapEnc; + private static final int MAX_ELEMENTS = 1000; + private int _nElements; + + private SampleXmlUtil(boolean soapEnc) + { + _soapEnc = soapEnc; + } + + public static String createSampleForType(SchemaType sType) + { + XmlObject object = XmlObject.Factory.newInstance(); + XmlCursor cursor = object.newCursor(); + // Skip the document node + cursor.toNextToken(); + // Using the type and the cursor, call the utility method to get a + // sample XML payload for that Schema element + new SampleXmlUtil(false).createSampleForType(sType, cursor); + // Cursor now contains the sample payload + // Pretty print the result. Note that the cursor is positioned at the + // end of the doc so we use the original xml object that the cursor was + // created upon to do the xmlText() against. + XmlOptions options = new XmlOptions(); + options.put(XmlOptions.SAVE_PRETTY_PRINT); + options.put(XmlOptions.SAVE_PRETTY_PRINT_INDENT, 2); + options.put(XmlOptions.SAVE_AGGRESSIVE_NAMESPACES); + String result = object.xmlText(options); + return result; + } + + Random _picker = new Random(1); + + /** + * Cursor position + * Before: + * ^ + * After: + * ^ + */ + private void createSampleForType(SchemaType stype, XmlCursor xmlc) + { + if (_typeStack.contains( stype )) + return; + + _typeStack.add( stype ); + + try + { + if (stype.isSimpleType() || stype.isURType()) + { + processSimpleType(stype, xmlc); + return; + } + + // complex Type + // ^ + processAttributes(stype, xmlc); + + // ^ + switch (stype.getContentType()) + { + case SchemaType.NOT_COMPLEX_TYPE : + case SchemaType.EMPTY_CONTENT : + // noop + break; + case SchemaType.SIMPLE_CONTENT : + { + processSimpleType(stype, xmlc); + } + break; + case SchemaType.MIXED_CONTENT : + xmlc.insertChars(pick(WORDS) + " "); + if (stype.getContentModel() != null) + { + processParticle(stype.getContentModel(), xmlc, true); + } + xmlc.insertChars(pick(WORDS)); + break; + case SchemaType.ELEMENT_CONTENT : + if (stype.getContentModel() != null) + { + processParticle(stype.getContentModel(), xmlc, false); + } + break; + } + } + finally + { + _typeStack.remove( _typeStack.size() - 1 ); + } + } + + private void processSimpleType(SchemaType stype, XmlCursor xmlc) + { + String sample = sampleDataForSimpleType(stype); + xmlc.insertChars(sample); + } + + private String sampleDataForSimpleType(SchemaType sType) + { + if (XmlObject.type.equals(sType)) + return "anyType"; + + if (XmlAnySimpleType.type.equals(sType)) + return "anySimpleType"; + + if (sType.getSimpleVariety() == SchemaType.LIST) + { + SchemaType itemType = sType.getListItemType(); + StringBuffer sb = new StringBuffer(); + int length = pickLength(sType); + if (length > 0) + sb.append(sampleDataForSimpleType(itemType)); + for (int i = 1; i < length; i += 1) + { + sb.append(' '); + sb.append(sampleDataForSimpleType(itemType)); + } + return sb.toString(); + } + + if (sType.getSimpleVariety() == SchemaType.UNION) + { + SchemaType[] possibleTypes = sType.getUnionConstituentTypes(); + if (possibleTypes.length == 0) + return ""; + return sampleDataForSimpleType(possibleTypes[pick(possibleTypes.length)]); + } + + XmlAnySimpleType[] enumValues = sType.getEnumerationValues(); + if (enumValues != null && enumValues.length > 0) + { + return enumValues[pick(enumValues.length)].getStringValue(); + } + + switch (sType.getPrimitiveType().getBuiltinTypeCode()) + { + default: + case SchemaType.BTC_NOT_BUILTIN: + return ""; + + case SchemaType.BTC_ANY_TYPE: + case SchemaType.BTC_ANY_SIMPLE: + return "anything"; + + case SchemaType.BTC_BOOLEAN: + return pick(2) == 0 ? "true" : "false"; + + case SchemaType.BTC_BASE_64_BINARY: + { + String result = null; + try + { result = new String(Base64.encode(formatToLength(pick(WORDS), sType).getBytes("utf-8"))); } + catch (java.io.UnsupportedEncodingException e) + { /* Can't possibly happen */ } + return result; + } + + case SchemaType.BTC_HEX_BINARY: + return HexBin.encode(formatToLength(pick(WORDS), sType)); + + case SchemaType.BTC_ANY_URI: + return formatToLength("http://www." + pick(DNS1) + "." + pick(DNS2) + "/" + pick(WORDS) + "/" + pick(WORDS), sType); + + case SchemaType.BTC_QNAME: + return formatToLength("qname", sType); + + case SchemaType.BTC_NOTATION: + return formatToLength("notation", sType); + + case SchemaType.BTC_FLOAT: + return "1.5E2"; + case SchemaType.BTC_DOUBLE: + return "1.051732E7"; + case SchemaType.BTC_DECIMAL: + switch (closestBuiltin(sType).getBuiltinTypeCode()) + { + case SchemaType.BTC_SHORT: + return formatDecimal("1", sType); + case SchemaType.BTC_UNSIGNED_SHORT: + return formatDecimal("5", sType); + case SchemaType.BTC_BYTE: + return formatDecimal("2", sType); + case SchemaType.BTC_UNSIGNED_BYTE: + return formatDecimal("6", sType); + case SchemaType.BTC_INT: + return formatDecimal("3", sType); + case SchemaType.BTC_UNSIGNED_INT: + return formatDecimal("7", sType); + case SchemaType.BTC_LONG: + return formatDecimal("10", sType); + case SchemaType.BTC_UNSIGNED_LONG: + return formatDecimal("11", sType); + case SchemaType.BTC_INTEGER: + return formatDecimal("100", sType); + case SchemaType.BTC_NON_POSITIVE_INTEGER: + return formatDecimal("-200", sType); + case SchemaType.BTC_NEGATIVE_INTEGER: + return formatDecimal("-201", sType); + case SchemaType.BTC_NON_NEGATIVE_INTEGER: + return formatDecimal("200", sType); + case SchemaType.BTC_POSITIVE_INTEGER: + return formatDecimal("201", sType); + default: + case SchemaType.BTC_DECIMAL: + return formatDecimal("1000.00", sType); + } + + case SchemaType.BTC_STRING: + { + String result; + switch (closestBuiltin(sType).getBuiltinTypeCode()) + { + case SchemaType.BTC_STRING: + case SchemaType.BTC_NORMALIZED_STRING: + result = "string"; + break; + + case SchemaType.BTC_TOKEN: + result = "token"; + break; + + default: + result = "string"; + break; + } + + return formatToLength(result, sType); + } + + case SchemaType.BTC_DURATION: + return formatDuration(sType); + + 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: + return formatDate(sType); + } + } + + // a bit from the Aenid + public static final String[] WORDS = new String[] + { + "ipsa", "iovis", "rapidum", "iaculata", "e", "nubibus", "ignem", + "disiecitque", "rates", "evertitque", "aequora", "ventis", + "illum", "exspirantem", "transfixo", "pectore", "flammas", + "turbine", "corripuit", "scopuloque", "infixit", "acuto", + "ast", "ego", "quae", "divum", "incedo", "regina", "iovisque", + "et", "soror", "et", "coniunx", "una", "cum", "gente", "tot", "annos", + "bella", "gero", "et", "quisquam", "numen", "iunonis", "adorat", + "praeterea", "aut", "supplex", "aris", "imponet", "honorem", + "talia", "flammato", "secum", "dea", "corde", "volutans", + "nimborum", "in", "patriam", "loca", "feta", "furentibus", "austris", + "aeoliam", "venit", "hic", "vasto", "rex", "aeolus", "antro", + "luctantis", "ventos", "tempestatesque", "sonoras", + "imperio", "premit", "ac", "vinclis", "et", "carcere", "frenat", + "illi", "indignantes", "magno", "cum", "murmure", "montis", + "circum", "claustra", "fremunt", "celsa", "sedet", "aeolus", "arce", + "sceptra", "tenens", "mollitque", "animos", "et", "temperat", "iras", + "ni", "faciat", "maria", "ac", "terras", "caelumque", "profundum", + "quippe", "ferant", "rapidi", "secum", "verrantque", "per", "auras", + "sed", "pater", "omnipotens", "speluncis", "abdidit", "atris", + "hoc", "metuens", "molemque", "et", "montis", "insuper", "altos", + "imposuit", "regemque", "dedit", "qui", "foedere", "certo", + "et", "premere", "et", "laxas", "sciret", "dare", "iussus", "habenas", + }; + + + + private static final String[] DNS1 = new String[] { "corp", "your", "my", "sample", "company", "test", "any" }; + private static final String[] DNS2 = new String[] { "com", "org", "com", "gov", "org", "com", "org", "com", "edu" }; + + private int pick(int n) + { + return _picker.nextInt(n); + } + + private String pick(String[] a) + { + return a[pick(a.length)]; + } + + private String pick(String[] a, int count) + { + if (count <= 0) + return ""; + + int i = pick(a.length); + StringBuffer sb = new StringBuffer(a[i]); + while (count-- > 0) + { + i += 1; + if (i >= a.length) + i = 0; + sb.append(' '); + sb.append(a[i]); + } + return sb.toString(); + } + + private String pickDigits(int digits) + { + StringBuffer sb = new StringBuffer(); + while (digits-- > 0) + sb.append(Integer.toString(pick(10))); + return sb.toString(); + } + + private int pickLength(SchemaType sType) + { + XmlInteger length = (XmlInteger) sType.getFacet(SchemaType.FACET_LENGTH); + if (length != null) + return length.getBigIntegerValue().intValue(); + XmlInteger min = (XmlInteger) sType.getFacet(SchemaType.FACET_MIN_LENGTH); + XmlInteger max = (XmlInteger) sType.getFacet(SchemaType.FACET_MAX_LENGTH); + int minInt, maxInt; + if (min == null) + minInt = 0; + else + minInt = min.getBigIntegerValue().intValue(); + if (max == null) + maxInt = Integer.MAX_VALUE; + else + maxInt = max.getBigIntegerValue().intValue(); + // We try to keep the length of the array within reasonable limits, + // at least 1 item and at most 3 if possible + if (minInt == 0 && maxInt >= 1) + minInt = 1; + if (maxInt > minInt + 2) + maxInt = minInt + 2; + if (maxInt < minInt) + maxInt = minInt; + return minInt + pick(maxInt-minInt); + } + + /** + * Formats a given string to the required length, using the following operations: + * - append the source string to itself as necessary to pass the minLength; + * - truncate the result of previous step, if necessary, to keep it within minLength. + */ + private String formatToLength(String s, SchemaType sType) + { + String result = s; + try + { + SimpleValue min = (SimpleValue)sType.getFacet(SchemaType.FACET_LENGTH); + if (min == null) + min = (SimpleValue)sType.getFacet(SchemaType.FACET_MIN_LENGTH); + if (min != null) + { + int len = min.getIntValue(); + while (result.length() < len) + result = result + result; + } + SimpleValue max = (SimpleValue)sType.getFacet(SchemaType.FACET_LENGTH); + if (max == null) + max = (SimpleValue)sType.getFacet(SchemaType.FACET_MAX_LENGTH); + if (max != null) + { + int len = max.getIntValue(); + if (result.length() > len) + result = result.substring(0, len); + } + } + catch (Exception e) // intValue can be out of range + { + } + return result; + } + + private String formatDecimal(String start, SchemaType sType) + { + BigDecimal result = new BigDecimal(start); + XmlDecimal xmlD; + xmlD = (XmlDecimal) sType.getFacet(SchemaType.FACET_MIN_INCLUSIVE); + BigDecimal min = xmlD != null ? xmlD.getBigDecimalValue() : null; + xmlD = (XmlDecimal) sType.getFacet(SchemaType.FACET_MAX_INCLUSIVE); + BigDecimal max = xmlD != null ? xmlD.getBigDecimalValue() : null; + boolean minInclusive = true, maxInclusive = true; + xmlD = (XmlDecimal) sType.getFacet(SchemaType.FACET_MIN_EXCLUSIVE); + if (xmlD != null) + { + BigDecimal minExcl = xmlD.getBigDecimalValue(); + if (min == null || min.compareTo(minExcl) < 0) + { + min = minExcl; + minInclusive = false; + } + } + xmlD = (XmlDecimal) sType.getFacet(SchemaType.FACET_MAX_EXCLUSIVE); + if (xmlD != null) + { + BigDecimal maxExcl = xmlD.getBigDecimalValue(); + if (max == null || max.compareTo(maxExcl) > 0) + { + max = maxExcl; + maxInclusive = false; + } + } + xmlD = (XmlDecimal) sType.getFacet(SchemaType.FACET_TOTAL_DIGITS); + int totalDigits = -1; + if (xmlD != null) + { + totalDigits = xmlD.getBigDecimalValue().intValue(); + + StringBuffer sb = new StringBuffer(totalDigits); + for (int i = 0; i < totalDigits; i++) + sb.append('9'); + BigDecimal digitsLimit = new BigDecimal(sb.toString()); + if (max != null && max.compareTo(digitsLimit) > 0) + { + max = digitsLimit; + maxInclusive = true; + } + digitsLimit = digitsLimit.negate(); + if (min != null && min.compareTo(digitsLimit) < 0) + { + min = digitsLimit; + minInclusive = true; + } + } + + int sigMin = min == null ? 1 : result.compareTo(min); + int sigMax = max == null ? -1 : result.compareTo(max); + boolean minOk = sigMin > 0 || sigMin == 0 && minInclusive; + boolean maxOk = sigMax < 0 || sigMax == 0 && maxInclusive; + + // Compute the minimum increment + xmlD = (XmlDecimal) sType.getFacet(SchemaType.FACET_FRACTION_DIGITS); + int fractionDigits = -1; + BigDecimal increment; + if (xmlD == null) + increment = new BigDecimal(1); + else + { + fractionDigits = xmlD.getBigDecimalValue().intValue(); + if (fractionDigits > 0) + { + StringBuffer sb = new StringBuffer("0."); + for (int i = 1; i < fractionDigits; i++) + sb.append('0'); + sb.append('1'); + increment = new BigDecimal(sb.toString()); + } + else + increment = new BigDecimal(1.0); + } + + if (minOk && maxOk) + { + // OK + } + else if (minOk && !maxOk) + { + // TOO BIG + if (maxInclusive) + result = max; + else + result = max.subtract(increment); + } + else if (!minOk && maxOk) + { + // TOO SMALL + if (minInclusive) + result = min; + else + result = min.add(increment); + } + else + { + // MIN > MAX!! + } + + // We have the number + // Adjust the scale according to the totalDigits and fractionDigits + int digits = 0; + BigDecimal ONE = new BigDecimal(BigInteger.ONE); + for (BigDecimal n = result; n.abs().compareTo(ONE) >= 0; digits++) + n = n.movePointLeft(1); + + if (fractionDigits > 0) + if (totalDigits >= 0) + result = result.setScale(Math.max(fractionDigits, totalDigits - digits)); + else + result = result.setScale(fractionDigits); + else if (fractionDigits == 0) + result = result.setScale(0); + + return result.toString(); + } + + private String formatDuration(SchemaType sType) + { + XmlDuration d = + (XmlDuration) sType.getFacet(SchemaType.FACET_MIN_INCLUSIVE); + GDuration minInclusive = null; + if (d != null) + minInclusive = d.getGDurationValue(); + + d = (XmlDuration) sType.getFacet(SchemaType.FACET_MAX_INCLUSIVE); + GDuration maxInclusive = null; + if (d != null) + maxInclusive = d.getGDurationValue(); + + d = (XmlDuration) sType.getFacet(SchemaType.FACET_MIN_EXCLUSIVE); + GDuration minExclusive = null; + if (d != null) + minExclusive = d.getGDurationValue(); + + d = (XmlDuration) sType.getFacet(SchemaType.FACET_MAX_EXCLUSIVE); + GDuration maxExclusive = null; + if (d != null) + maxExclusive = d.getGDurationValue(); + + GDurationBuilder gdurb = new GDurationBuilder(); + BigInteger min, max; + + gdurb.setSecond(pick(800000)); + gdurb.setMonth(pick(20)); + + // Years + // Months + // Days + // Hours + // Minutes + // Seconds + // Fractions + if (minInclusive != null) + { + if (gdurb.getYear() < minInclusive.getYear()) + gdurb.setYear(minInclusive.getYear()); + if (gdurb.getMonth() < minInclusive.getMonth()) + gdurb.setMonth(minInclusive.getMonth()); + if (gdurb.getDay() < minInclusive.getDay()) + gdurb.setDay(minInclusive.getDay()); + if (gdurb.getHour() < minInclusive.getHour()) + gdurb.setHour(minInclusive.getHour()); + if (gdurb.getMinute() < minInclusive.getMinute()) + gdurb.setMinute(minInclusive.getMinute()); + if (gdurb.getSecond() < minInclusive.getSecond()) + gdurb.setSecond(minInclusive.getSecond()); + if (gdurb.getFraction().compareTo(minInclusive.getFraction()) < 0) + gdurb.setFraction(minInclusive.getFraction()); + } + + if (maxInclusive != null) + { + if (gdurb.getYear() > maxInclusive.getYear()) + gdurb.setYear(maxInclusive.getYear()); + if (gdurb.getMonth() > maxInclusive.getMonth()) + gdurb.setMonth(maxInclusive.getMonth()); + if (gdurb.getDay() > maxInclusive.getDay()) + gdurb.setDay(maxInclusive.getDay()); + if (gdurb.getHour() > maxInclusive.getHour()) + gdurb.setHour(maxInclusive.getHour()); + if (gdurb.getMinute() > maxInclusive.getMinute()) + gdurb.setMinute(maxInclusive.getMinute()); + if (gdurb.getSecond() > maxInclusive.getSecond()) + gdurb.setSecond(maxInclusive.getSecond()); + if (gdurb.getFraction().compareTo(maxInclusive.getFraction()) > 0) + gdurb.setFraction(maxInclusive.getFraction()); + } + + if (minExclusive != null) + { + if (gdurb.getYear() <= minExclusive.getYear()) + gdurb.setYear(minExclusive.getYear()+1); + if (gdurb.getMonth() <= minExclusive.getMonth()) + gdurb.setMonth(minExclusive.getMonth()+1); + if (gdurb.getDay() <= minExclusive.getDay()) + gdurb.setDay(minExclusive.getDay()+1); + if (gdurb.getHour() <= minExclusive.getHour()) + gdurb.setHour(minExclusive.getHour()+1); + if (gdurb.getMinute() <= minExclusive.getMinute()) + gdurb.setMinute(minExclusive.getMinute()+1); + if (gdurb.getSecond() <= minExclusive.getSecond()) + gdurb.setSecond(minExclusive.getSecond()+1); + if (gdurb.getFraction().compareTo(minExclusive.getFraction()) <= 0) + gdurb.setFraction(minExclusive.getFraction().add(new BigDecimal(0.001))); + } + + if (maxExclusive != null) + { + if (gdurb.getYear() > maxExclusive.getYear()) + gdurb.setYear(maxExclusive.getYear()); + if (gdurb.getMonth() > maxExclusive.getMonth()) + gdurb.setMonth(maxExclusive.getMonth()); + if (gdurb.getDay() > maxExclusive.getDay()) + gdurb.setDay(maxExclusive.getDay()); + if (gdurb.getHour() > maxExclusive.getHour()) + gdurb.setHour(maxExclusive.getHour()); + if (gdurb.getMinute() > maxExclusive.getMinute()) + gdurb.setMinute(maxExclusive.getMinute()); + if (gdurb.getSecond() > maxExclusive.getSecond()) + gdurb.setSecond(maxExclusive.getSecond()); + if (gdurb.getFraction().compareTo(maxExclusive.getFraction()) > 0) + gdurb.setFraction(maxExclusive.getFraction()); + } + + gdurb.normalize(); + return gdurb.toString(); + } + + private String formatDate(SchemaType sType) + { + GDateBuilder gdateb = new GDateBuilder(new Date(1000L * pick(365 * 24 * 60 * 60) + (30L + pick(20)) * 365 * 24 * 60 * 60 * 1000)); + GDate min = null, max = null; + GDate temp; + + // Find the min and the max according to the type + switch (sType.getPrimitiveType().getBuiltinTypeCode()) + { + case SchemaType.BTC_DATE_TIME: + { + XmlDateTime x = (XmlDateTime) sType.getFacet(SchemaType.FACET_MIN_INCLUSIVE); + if (x != null) + min = x.getGDateValue(); + x = (XmlDateTime) sType.getFacet(SchemaType.FACET_MIN_EXCLUSIVE); + if (x != null) + if (min == null || min.compareToGDate(x.getGDateValue()) <= 0) + min = x.getGDateValue(); + + x = (XmlDateTime) sType.getFacet(SchemaType.FACET_MAX_INCLUSIVE); + if (x != null) + max = x.getGDateValue(); + x = (XmlDateTime) sType.getFacet(SchemaType.FACET_MAX_EXCLUSIVE); + if (x != null) + if (max == null || max.compareToGDate(x.getGDateValue()) >= 0) + max = x.getGDateValue(); + break; + } + case SchemaType.BTC_TIME: + { + XmlTime x = (XmlTime) sType.getFacet(SchemaType.FACET_MIN_INCLUSIVE); + if (x != null) + min = x.getGDateValue(); + x = (XmlTime) sType.getFacet(SchemaType.FACET_MIN_EXCLUSIVE); + if (x != null) + if (min == null || min.compareToGDate(x.getGDateValue()) <= 0) + min = x.getGDateValue(); + + x = (XmlTime) sType.getFacet(SchemaType.FACET_MAX_INCLUSIVE); + if (x != null) + max = x.getGDateValue(); + x = (XmlTime) sType.getFacet(SchemaType.FACET_MAX_EXCLUSIVE); + if (x != null) + if (max == null || max.compareToGDate(x.getGDateValue()) >= 0) + max = x.getGDateValue(); + break; + } + case SchemaType.BTC_DATE: + { + XmlDate x = (XmlDate) sType.getFacet(SchemaType.FACET_MIN_INCLUSIVE); + if (x != null) + min = x.getGDateValue(); + x = (XmlDate) sType.getFacet(SchemaType.FACET_MIN_EXCLUSIVE); + if (x != null) + if (min == null || min.compareToGDate(x.getGDateValue()) <= 0) + min = x.getGDateValue(); + + x = (XmlDate) sType.getFacet(SchemaType.FACET_MAX_INCLUSIVE); + if (x != null) + max = x.getGDateValue(); + x = (XmlDate) sType.getFacet(SchemaType.FACET_MAX_EXCLUSIVE); + if (x != null) + if (max == null || max.compareToGDate(x.getGDateValue()) >= 0) + max = x.getGDateValue(); + break; + } + case SchemaType.BTC_G_YEAR_MONTH: + { + XmlGYearMonth x = (XmlGYearMonth) sType.getFacet(SchemaType.FACET_MIN_INCLUSIVE); + if (x != null) + min = x.getGDateValue(); + x = (XmlGYearMonth) sType.getFacet(SchemaType.FACET_MIN_EXCLUSIVE); + if (x != null) + if (min == null || min.compareToGDate(x.getGDateValue()) <= 0) + min = x.getGDateValue(); + + x = (XmlGYearMonth) sType.getFacet(SchemaType.FACET_MAX_INCLUSIVE); + if (x != null) + max = x.getGDateValue(); + x = (XmlGYearMonth) sType.getFacet(SchemaType.FACET_MAX_EXCLUSIVE); + if (x != null) + if (max == null || max.compareToGDate(x.getGDateValue()) >= 0) + max = x.getGDateValue(); + break; + } + case SchemaType.BTC_G_YEAR: + { + XmlGYear x = (XmlGYear) sType.getFacet(SchemaType.FACET_MIN_INCLUSIVE); + if (x != null) + min = x.getGDateValue(); + x = (XmlGYear) sType.getFacet(SchemaType.FACET_MIN_EXCLUSIVE); + if (x != null) + if (min == null || min.compareToGDate(x.getGDateValue()) <= 0) + min = x.getGDateValue(); + + x = (XmlGYear) sType.getFacet(SchemaType.FACET_MAX_INCLUSIVE); + if (x != null) + max = x.getGDateValue(); + x = (XmlGYear) sType.getFacet(SchemaType.FACET_MAX_EXCLUSIVE); + if (x != null) + if (max == null || max.compareToGDate(x.getGDateValue()) >= 0) + max = x.getGDateValue(); + break; + } + case SchemaType.BTC_G_MONTH_DAY: + { + XmlGMonthDay x = (XmlGMonthDay) sType.getFacet(SchemaType.FACET_MIN_INCLUSIVE); + if (x != null) + min = x.getGDateValue(); + x = (XmlGMonthDay) sType.getFacet(SchemaType.FACET_MIN_EXCLUSIVE); + if (x != null) + if (min == null || min.compareToGDate(x.getGDateValue()) <= 0) + min = x.getGDateValue(); + + x = (XmlGMonthDay) sType.getFacet(SchemaType.FACET_MAX_INCLUSIVE); + if (x != null) + max = x.getGDateValue(); + x = (XmlGMonthDay) sType.getFacet(SchemaType.FACET_MAX_EXCLUSIVE); + if (x != null) + if (max == null || max.compareToGDate(x.getGDateValue()) >= 0) + max = x.getGDateValue(); + break; + } + case SchemaType.BTC_G_DAY: + { + XmlGDay x = (XmlGDay) sType.getFacet(SchemaType.FACET_MIN_INCLUSIVE); + if (x != null) + min = x.getGDateValue(); + x = (XmlGDay) sType.getFacet(SchemaType.FACET_MIN_EXCLUSIVE); + if (x != null) + if (min == null || min.compareToGDate(x.getGDateValue()) <= 0) + min = x.getGDateValue(); + + x = (XmlGDay) sType.getFacet(SchemaType.FACET_MAX_INCLUSIVE); + if (x != null) + max = x.getGDateValue(); + x = (XmlGDay) sType.getFacet(SchemaType.FACET_MAX_EXCLUSIVE); + if (x != null) + if (max == null || max.compareToGDate(x.getGDateValue()) >= 0) + max = x.getGDateValue(); + break; + } + case SchemaType.BTC_G_MONTH: + { + XmlGMonth x = (XmlGMonth) sType.getFacet(SchemaType.FACET_MIN_INCLUSIVE); + if (x != null) + min = x.getGDateValue(); + x = (XmlGMonth) sType.getFacet(SchemaType.FACET_MIN_EXCLUSIVE); + if (x != null) + if (min == null || min.compareToGDate(x.getGDateValue()) <= 0) + min = x.getGDateValue(); + + x = (XmlGMonth) sType.getFacet(SchemaType.FACET_MAX_INCLUSIVE); + if (x != null) + max = x.getGDateValue(); + x = (XmlGMonth) sType.getFacet(SchemaType.FACET_MAX_EXCLUSIVE); + if (x != null) + if (max == null || max.compareToGDate(x.getGDateValue()) >= 0) + max = x.getGDateValue(); + break; + } + } + + if (min != null && max == null) + { + if (min.compareToGDate(gdateb) >= 0) + { + // Reset the date to min + (1-8) hours + Calendar c = gdateb.getCalendar(); + c.add(Calendar.HOUR_OF_DAY, pick(8)); + gdateb = new GDateBuilder(c); + } + } + else if (min == null && max != null) + { + if (max.compareToGDate(gdateb) <= 0) + { + // Reset the date to max - (1-8) hours + Calendar c = gdateb.getCalendar(); + c.add(Calendar.HOUR_OF_DAY, 0-pick(8)); + gdateb = new GDateBuilder(c); + } + } + else if (min != null && max != null) + { + if (min.compareToGDate(gdateb) >= 0 || max.compareToGDate(gdateb) <= 0) + { + // Find a date between the two + Calendar c = min.getCalendar(); + Calendar cmax = max.getCalendar(); + c.add(Calendar.HOUR_OF_DAY, 1); + if (c.after(cmax)) + { + c.add(Calendar.HOUR_OF_DAY, -1); + c.add(Calendar.MINUTE, 1); + if (c.after(cmax)) + { + c.add(Calendar.MINUTE, -1); + c.add(Calendar.SECOND, 1); + if (c.after(cmax)) + { + c.add(Calendar.SECOND, -1); + c.add(Calendar.MILLISECOND, 1); + if (c.after(cmax)) + c.add(Calendar.MILLISECOND, -1); + } + } + } + gdateb = new GDateBuilder(c); + } + } + + gdateb.setBuiltinTypeCode(sType.getPrimitiveType().getBuiltinTypeCode()); + if (pick(2) == 0) + gdateb.clearTimeZone(); + return gdateb.toString(); + } + + private SchemaType closestBuiltin(SchemaType sType) + { + while (!sType.isBuiltinType()) + sType = sType.getBaseType(); + return sType; + } + + /** + * Cracks a combined QName of the form URL:localname + */ + public static QName crackQName(String qName) + { + String ns; + String name; + + int index = qName.lastIndexOf( ':' ); + if (index >= 0) + { + ns = qName.substring( 0, index ); + name = qName.substring( index + 1); + } + else + { + ns = ""; + name = qName; + } + + return new QName(ns, name); + } + + + /** + * Cursor position: + * Before this call: + * ^ (cursor at the ^) + * After this call: + * <som text^ + */ + private void processParticle(SchemaParticle sp, XmlCursor xmlc, boolean mixed) + { + int loop = determineMinMaxForSample(sp, xmlc); + + while (loop-- > 0) + { + switch (sp.getParticleType()) + { + case (SchemaParticle.ELEMENT) : + processElement(sp, xmlc, mixed); + break; + case (SchemaParticle.SEQUENCE) : + processSequence(sp, xmlc, mixed); + break; + case (SchemaParticle.CHOICE) : + processChoice(sp, xmlc, mixed); + break; + case (SchemaParticle.ALL) : + processAll(sp, xmlc, mixed); + break; + case (SchemaParticle.WILDCARD) : + processWildCard(sp, xmlc, mixed); + break; + default : + // throw new Exception("No Match on Schema Particle Type: " + String.valueOf(sp.getParticleType())); + } + } + } + + private int determineMinMaxForSample(SchemaParticle sp, XmlCursor xmlc) + { + int minOccurs = sp.getIntMinOccurs(); + int maxOccurs = sp.getIntMaxOccurs(); + + if (minOccurs == maxOccurs) + return minOccurs; + + int result = minOccurs; + if (result == 0 && _nElements < MAX_ELEMENTS) + result = 1; + + if (sp.getParticleType() != SchemaParticle.ELEMENT) + return result; + + // it probably only makes sense to put comments in front of individual elements that repeat + + if (sp.getMaxOccurs() == null) + { + // xmlc.insertComment("The next " + getItemNameOrType(sp, xmlc) + " may be repeated " + minOccurs + " or more times"); + if (minOccurs == 0) + xmlc.insertComment("Zero or more repetitions:"); + else + xmlc.insertComment(minOccurs + " or more repetitions:"); + } + else if (sp.getIntMaxOccurs() > 1) + { + xmlc.insertComment(minOccurs + " to " + String.valueOf(sp.getMaxOccurs()) + " repetitions:"); + } + else + { + xmlc.insertComment("Optional:"); + } + return result; + } + + /* + Return a name for the element or the particle type to use in the comment for minoccurs, max occurs + */ + private String getItemNameOrType(SchemaParticle sp, XmlCursor xmlc) + { + String elementOrTypeName = null; + if (sp.getParticleType() == SchemaParticle.ELEMENT) + { + elementOrTypeName = "Element (" + sp.getName().getLocalPart() + ")"; + } + else + { + elementOrTypeName = printParticleType(sp.getParticleType()); + } + return elementOrTypeName; + } + + private void processElement(SchemaParticle sp, XmlCursor xmlc, boolean mixed) + { + // cast as schema local element + SchemaLocalElement element = (SchemaLocalElement) sp; + /// ^ -> ^ + if (_soapEnc) + xmlc.insertElement(element.getName().getLocalPart()); // soap encoded? drop namespaces. + else + xmlc.insertElement(element.getName().getLocalPart(), element.getName().getNamespaceURI()); + _nElements++; + /// -> ^ + xmlc.toPrevToken(); + // -> stuff^ + + createSampleForType(element.getType(), xmlc); + // -> stuff^ + xmlc.toNextToken(); + + } + + private void moveToken(int numToMove, XmlCursor xmlc) + { + for (int i = 0; i < Math.abs(numToMove); i++) + { + if (numToMove < 0) + { + xmlc.toPrevToken(); + } + else + { + xmlc.toNextToken(); + } + } + } + + private static final String formatQName(XmlCursor xmlc, QName qName) + { + XmlCursor parent = xmlc.newCursor(); + parent.toParent(); + String prefix = parent.prefixForNamespace(qName.getNamespaceURI()); + parent.dispose(); + String name; + if (prefix == null || prefix.length() == 0) + name = qName.getLocalPart(); + else + name = prefix + ":" + qName.getLocalPart(); + return name; + } + + private static final QName HREF = new QName("href"); + private static final QName ID = new QName("id"); + private static final QName XSI_TYPE = new QName("http://www.w3.org/2001/XMLSchema-instance", "type"); + private static final QName ENC_ARRAYTYPE = new QName("http://schemas.xmlsoap.org/soap/encoding/", "arrayType"); + private static final QName ENC_OFFSET = new QName("http://schemas.xmlsoap.org/soap/encoding/", "offset"); + + private static final Set SKIPPED_SOAP_ATTRS = new HashSet(Arrays.asList(new QName[] { HREF, ID, ENC_OFFSET})); + private void processAttributes(SchemaType stype, XmlCursor xmlc) + { + if (_soapEnc) + { + QName typeName = stype.getName(); + if (typeName != null) + { + xmlc.insertAttributeWithValue(XSI_TYPE, formatQName(xmlc, typeName)); + } + } + + SchemaProperty[] attrProps = stype.getAttributeProperties(); + for (int i = 0; i < attrProps.length; i++) + { + SchemaProperty attr = attrProps[i]; + if (_soapEnc) + { + if (SKIPPED_SOAP_ATTRS.contains(attr.getName())) + continue; + if (ENC_ARRAYTYPE.equals(attr.getName())) + { + SOAPArrayType arrayType = ((SchemaWSDLArrayType)stype.getAttributeModel().getAttribute(attr.getName())).getWSDLArrayType(); + if (arrayType != null) + xmlc.insertAttributeWithValue(attr.getName(), formatQName(xmlc, arrayType.getQName()) + arrayType.soap11DimensionString()); + continue; + } + } + String defaultValue = attr.getDefaultText(); + xmlc.insertAttributeWithValue(attr.getName(), defaultValue == null ? + sampleDataForSimpleType(attr.getType()) : defaultValue); + } + } + + private void processSequence(SchemaParticle sp, XmlCursor xmlc, boolean mixed) + { + SchemaParticle[] spc = sp.getParticleChildren(); + for (int i=0; i < spc.length; i++) + { + /// maybestuff^ + processParticle(spc[i], xmlc, mixed); + //maybestuff...morestuff^ + if (mixed && i < spc.length-1) + xmlc.insertChars(pick(WORDS)); + } + } + + private void processChoice(SchemaParticle sp, XmlCursor xmlc, boolean mixed) + { + SchemaParticle[] spc = sp.getParticleChildren(); + xmlc.insertComment("You have a CHOICE of the next " + String.valueOf(spc.length) + " items at this level"); + for (int i=0; i < spc.length; i++) + { + processParticle(spc[i], xmlc, mixed); + } + } + + private void processAll(SchemaParticle sp, XmlCursor xmlc, boolean mixed) + { + SchemaParticle[] spc = sp.getParticleChildren(); + // xmlc.insertComment("You may enter the following " + String.valueOf(spc.length) + " items in any order"); + for (int i=0; i < spc.length; i++) + { + processParticle(spc[i], xmlc, mixed); + if (mixed && i < spc.length-1) + xmlc.insertChars(pick(WORDS)); + } + } + + private void processWildCard(SchemaParticle sp, XmlCursor xmlc, boolean mixed) + { + xmlc.insertComment("You may enter ANY elements at this point"); + xmlc.insertElement("AnyElement"); + } + + /** + * This method will get the base type for the schema type + */ + + private static QName getClosestName(SchemaType sType) + { + while (sType.getName() == null) + sType = sType.getBaseType(); + + return sType.getName(); + } + + private String printParticleType(int particleType) + { + StringBuffer returnParticleType = new StringBuffer(); + returnParticleType.append("Schema Particle Type: "); + + switch (particleType) + { + case SchemaParticle.ALL : + returnParticleType.append("ALL\n"); + break; + case SchemaParticle.CHOICE : + returnParticleType.append("CHOICE\n"); + break; + case SchemaParticle.ELEMENT : + returnParticleType.append("ELEMENT\n"); + break; + case SchemaParticle.SEQUENCE : + returnParticleType.append("SEQUENCE\n"); + break; + case SchemaParticle.WILDCARD : + returnParticleType.append("WILDCARD\n"); + break; + default : + returnParticleType.append("Schema Particle Type Unknown"); + break; + } + + return returnParticleType.toString(); + } + + private ArrayList _typeStack = new ArrayList(); +} diff --git a/xmlbeans/src/tools/org/apache/xmlbeans/impl/xsd2inst/SchemaInstanceGenerator.java b/xmlbeans/src/tools/org/apache/xmlbeans/impl/xsd2inst/SchemaInstanceGenerator.java new file mode 100644 index 000000000..f7d2c1f93 --- /dev/null +++ b/xmlbeans/src/tools/org/apache/xmlbeans/impl/xsd2inst/SchemaInstanceGenerator.java @@ -0,0 +1,353 @@ +/* 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.xsd2inst; + +import org.apache.xmlbeans.XmlObject; + +import java.io.IOException; +import java.io.Reader; +import java.io.StringReader; +import java.util.ArrayList; +import java.io.File; +import java.util.HashSet; +import org.apache.xmlbeans.XmlOptions; +import org.apache.xmlbeans.XmlBeans; +import org.apache.xmlbeans.SchemaTypeSystem; +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.impl.xsd2inst.SampleXmlUtil; +import java.util.Set; +import org.apache.xmlbeans.XmlException; +import java.util.Iterator; +import java.util.List; +import java.util.Collection; +import org.apache.xmlbeans.impl.tool.CommandLine; + +public class SchemaInstanceGenerator +{ + public static class Xsd2InstOptions + { + private boolean _downloads = false; + private boolean _nopvr = false; + private boolean _noupa = false; + + /** + * @return true if network downloads are allowed, false othervise + * Default is false. + */ + public boolean isNetworkDownloads() + { + return _downloads; + } + + /** + * set true to allow network downloads, false othervise + */ + public void setNetworkDownloads(boolean downloads) + { + this._downloads = downloads; + } + + /** + * @return true to disable particle valid (restriction) rule, false othervise + * Default is false. + */ + public boolean isNopvr() + { + return _nopvr; + } + + /** + * set true to disable particle valid (restriction) rule, false othervise + */ + public void setNopvr(boolean nopvr) + { + this._nopvr = nopvr; + } + + /** + * @return true to disable unique particle attribution rule, false othervise + * Default is false. + */ + public boolean isNoupa() + { + return _noupa; + } + + /** + * set true to disable unique particle attribution rule, false othervise + */ + public void setNoupa(boolean noupa) + { + this._noupa = noupa; + } + } + + + public static void printUsage() + { + System.out.println("Generates a document based on the given Schema file"); + System.out.println("having the given element as root."); + System.out.println("The tool makes reasonable attempts to create a valid document,"); + System.out.println("but this is not always possible since, for example, "); + System.out.println("there are schemas for which no valid instance document "); + System.out.println("can be produced."); + System.out.println("Usage: xsd2inst [flags] schema.xsd -name element_name"); + System.out.println("Flags:"); + System.out.println(" -name the name of the root element"); + System.out.println(" -dl enable network downloads for imports and includes"); + System.out.println(" -nopvr disable particle valid (restriction) rule"); + System.out.println(" -noupa disable unique particle attribution rule"); + System.out.println(" -license prints license information"); + System.out.println(" -version prints version information"); + } + + public static void main(String[] args) + { + Set flags = new HashSet(); + Set opts = new HashSet(); + flags.add("h"); + flags.add("help"); + flags.add("usage"); + flags.add("license"); + flags.add("version"); + flags.add("dl"); + flags.add("noupa"); + flags.add("nopvr"); + flags.add("partial"); + opts.add("name"); + + CommandLine cl = new CommandLine(args, flags, opts); + + if (cl.getOpt("h") != null || cl.getOpt("help") != null || cl.getOpt("usage") != null) + { + printUsage(); + return; + } + + String[] badOpts = cl.getBadOpts(); + if (badOpts.length > 0) + { + for (int i = 0; i < badOpts.length; i++) + System.out.println("Unrecognized option: " + badOpts[i]); + printUsage(); + return; + } + + if (cl.getOpt("license") != null) + { + CommandLine.printLicense(); + System.exit(0); + return; + } + + if (cl.getOpt("version") != null) + { + CommandLine.printVersion(); + System.exit(0); + return; + } + + boolean dl = (cl.getOpt("dl") != null); + boolean nopvr = (cl.getOpt("nopvr") != null); + boolean noupa = (cl.getOpt("noupa") != null); + + File[] schemaFiles = cl.filesEndingWith(".xsd"); + String rootName = cl.getOpt("name"); + + if (rootName == null) + { + System.out.println("Required option \"-name\" must be present"); + return; + } + + // Process Schema files + List sdocs = new ArrayList(); + for (int i = 0; i < schemaFiles.length; i++) + { + try + { + sdocs.add(XmlObject.Factory.parse(schemaFiles[i], + (new XmlOptions()).setLoadLineNumbers().setLoadMessageDigest())); + } + catch (Exception e) + { + System.err.println("Can not load schema file: " + schemaFiles[i] + ": "); + e.printStackTrace(); + } + } + + XmlObject[] schemas = (XmlObject[]) sdocs.toArray(new XmlObject[sdocs.size()]); + + Xsd2InstOptions options = new Xsd2InstOptions(); + options.setNetworkDownloads(dl); + options.setNopvr(nopvr); + options.setNoupa(noupa); + + String result = xsd2inst(schemas, rootName, options); + +/* SchemaTypeSystem sts = null; + if (schemas.length > 0) + { + Collection errors = new ArrayList(); + XmlOptions compileOptions = new XmlOptions(); + if (dl) + compileOptions.setCompileDownloadUrls(); + if (nopvr) + compileOptions.setCompileNoPvrRule(); + if (noupa) + compileOptions.setCompileNoUpaRule(); + + try + { + sts = XmlBeans.compileXsd(schemas, XmlBeans.getBuiltinTypeSystem(), compileOptions); + } + catch (Exception e) + { + if (errors.isEmpty() || !(e instanceof XmlException)) + e.printStackTrace(); + + System.out.println("Schema compilation errors: "); + for (Iterator i = errors.iterator(); i.hasNext(); ) + System.out.println(i.next()); + } + } + + if (sts == null) + { + System.out.println("No Schemas to process."); + return; + } + SchemaType[] globalElems = sts.documentTypes(); + SchemaType elem = null; + for (int i = 0; i < globalElems.length; i++) + { + if (rootName.equals(globalElems[i].getDocumentElementName().getLocalPart())) + { + elem = globalElems[i]; + break; + } + } + + if (elem == null) + { + System.out.println("Could not find a global element with name \"" + rootName + "\""); + return; + } + + // Now generate it + String result = SampleXmlUtil.createSampleForType(elem); +*/ + + System.out.println(result); + + return; + } + + + public static String xsd2inst(String[] xsds, String rootName, Xsd2InstOptions options) + throws XmlException, IOException + { + Reader[] instReaders = new Reader[xsds.length]; + for (int i=0; i< xsds.length; i++) + { + instReaders[i] = new StringReader(xsds[i]); + } + + String res = xsd2inst(instReaders, rootName, options); + + return res; + } + + + public static String xsd2inst(Reader[] schemaReaders, String rootName, Xsd2InstOptions options) + { + // Process Schema files + List sdocs = new ArrayList(); + for (int i = 0; i < schemaReaders.length; i++) + { + try + { + sdocs.add(XmlObject.Factory.parse(schemaReaders[i], + (new XmlOptions()).setLoadLineNumbers().setLoadMessageDigest())); + } + catch (Exception e) + { + System.err.println("Can not load schema reader: " + i + " " + schemaReaders[i] + ": "); + e.printStackTrace(); + } + } + + XmlObject[] schemas = (XmlObject[]) sdocs.toArray(new XmlObject[sdocs.size()]); + + return xsd2inst(schemas, rootName, options); + } + + + public static String xsd2inst(XmlObject[] schemas, String rootName, Xsd2InstOptions options) + { + SchemaTypeSystem sts = null; + if (schemas.length > 0) + { + Collection errors = new ArrayList(); + XmlOptions compileOptions = new XmlOptions(); + if (options.isNetworkDownloads()) + compileOptions.setCompileDownloadUrls(); + if (options.isNopvr()) + compileOptions.setCompileNoPvrRule(); + if (options.isNoupa()) + compileOptions.setCompileNoUpaRule(); + + try + { + sts = XmlBeans.compileXsd(schemas, XmlBeans.getBuiltinTypeSystem(), compileOptions); + } + catch (Exception e) + { + if (errors.isEmpty() || !(e instanceof XmlException)) + e.printStackTrace(); + + System.out.println("Schema compilation errors: "); + for (Iterator i = errors.iterator(); i.hasNext(); ) + System.out.println(i.next()); + } + } + + if (sts == null) + { + throw new RuntimeException("No Schemas to process."); + } + SchemaType[] globalElems = sts.documentTypes(); + SchemaType elem = null; + for (int i = 0; i < globalElems.length; i++) + { + if (rootName.equals(globalElems[i].getDocumentElementName().getLocalPart())) + { + elem = globalElems[i]; + break; + } + } + + if (elem == null) + { + throw new RuntimeException("Could not find a global element with name \"" + rootName + "\""); + } + + // Now generate it + String result = SampleXmlUtil.createSampleForType(elem); + + return result; + } +} diff --git a/xmlbeans/src/toolschema/ltgfmt.xsd b/xmlbeans/src/toolschema/ltgfmt.xsd new file mode 100644 index 000000000..42b4bc509 --- /dev/null +++ b/xmlbeans/src/toolschema/ltgfmt.xsd @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/xmlbeans/src/toolschema/ltgfmt.xsdconfig b/xmlbeans/src/toolschema/ltgfmt.xsdconfig new file mode 100644 index 000000000..e4314151c --- /dev/null +++ b/xmlbeans/src/toolschema/ltgfmt.xsdconfig @@ -0,0 +1,17 @@ + + + + + org.apache.xmlbeans.impl.xb.ltgfmt + + + diff --git a/xmlbeans/src/toolschema/substwsdl.xsd b/xmlbeans/src/toolschema/substwsdl.xsd new file mode 100644 index 000000000..c9e4c72f5 --- /dev/null +++ b/xmlbeans/src/toolschema/substwsdl.xsd @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/xmlbeans/src/toolschema/substwsdl.xsdconfig b/xmlbeans/src/toolschema/substwsdl.xsdconfig new file mode 100644 index 000000000..bd475993a --- /dev/null +++ b/xmlbeans/src/toolschema/substwsdl.xsdconfig @@ -0,0 +1,17 @@ + + + + + org.apache.xmlbeans.impl.xb.substwsdl + + + diff --git a/xmlbeans/src/toolschema/xsdownload.xsd b/xmlbeans/src/toolschema/xsdownload.xsd new file mode 100644 index 000000000..c12d8e3a4 --- /dev/null +++ b/xmlbeans/src/toolschema/xsdownload.xsd @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/xmlbeans/src/toolschema/xsdownload.xsdconfig b/xmlbeans/src/toolschema/xsdownload.xsdconfig new file mode 100644 index 000000000..089d8a372 --- /dev/null +++ b/xmlbeans/src/toolschema/xsdownload.xsdconfig @@ -0,0 +1,17 @@ + + + + + org.apache.xmlbeans.impl.xb.xsdownload + + + diff --git a/xmlbeans/src/typeholder/org/apache/xmlbeans/impl/schema/TypeSystemHolder.java b/xmlbeans/src/typeholder/org/apache/xmlbeans/impl/schema/TypeSystemHolder.java new file mode 100644 index 000000000..2b31e1b6a --- /dev/null +++ b/xmlbeans/src/typeholder/org/apache/xmlbeans/impl/schema/TypeSystemHolder.java @@ -0,0 +1,79 @@ +/* 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.SchemaTypeSystem; + +/** + * This class is the hook which causes the SchemaTypeSystem to be loaded when + * a generated class is used. It isn't used by the runtime directly, instead + * this class is used by the schema compiler as a template class. By using a + * template class, the SchemaTypeSystemImpl can create all the binary files + * required without needing to rely on javac. The generated source still + * requires a java compiler. + * + * @see SchemaTypeSystemImpl.save() + */ +// +// !!! It's important that there never NEVER be any references to this class because +// !!! the static initializer will fail. This class must only be used as a class file. +// !!! If this scares you, turn back now !!! +// +// !!! If you modify this class, you will have to run bootstrap. +// !!! If this scares you, turn back now !!! +// +public class TypeSystemHolder +{ + private TypeSystemHolder() { } + + public static final SchemaTypeSystem typeSystem = loadTypeSystem(); + + // Commenting out this line has the effect of not loading all components in a + // typesystem upfront, but just as they are needed, which may improve + // performance significantly + //static { typeSystem.resolve(); } + + private static final SchemaTypeSystem loadTypeSystem() + { + try + { + // The fact that we are using TypeSystemHolder.class.getClassLoader() + // to load the SchemaTypeSystem class means that the TypeSystemHolder's + // classloader MUST be a descendant of the XmlBeans classloader, even + // though it can be different. + // In other words, each Schema type has only one copy per VM, not one + // copy per copy of XmlBeans in use, therefore this implies that + // there either must be one copy of XmlBeans in the VM or copies in + // different classloaders will each need a different copy of one + // Schema type, which seems a reasonable restriction, but needs to be + // understood nevertheless + return (SchemaTypeSystem) + Class.forName( + "org.apache.xmlbeans.impl.schema.SchemaTypeSystemImpl", + true, TypeSystemHolder.class.getClassLoader()) + .getConstructor(new Class[] { Class.class }) + .newInstance(new java.lang.Object[] { TypeSystemHolder.class }); + } + catch (ClassNotFoundException e) + { + throw new RuntimeException("Cannot load org.apache.xmlbeans.impl.SchemaTypeSystemImpl: make sure xbean.jar is on the classpath.", e); + } + catch (Exception e) + { + throw new RuntimeException("Could not instantiate SchemaTypeSystemImpl (" + e.toString() + "): is the version of xbean.jar correct?", e); + } + } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/regex/BMPattern.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/regex/BMPattern.java new file mode 100644 index 000000000..43e2d178f --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/regex/BMPattern.java @@ -0,0 +1,230 @@ +/* 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.regex; + +import java.text.CharacterIterator; + +/** + * Boyer-Moore searcher. + */ +public class BMPattern { + char[] pattern; + int[] shiftTable; + boolean ignoreCase; + + public BMPattern(String pat, boolean ignoreCase) { + this(pat, 256, ignoreCase); + } + + public BMPattern(String pat, int tableSize, boolean ignoreCase) { + this.pattern = pat.toCharArray(); + this.shiftTable = new int[tableSize]; + this.ignoreCase = ignoreCase; + + int length = pattern.length; + for (int i = 0; i < this.shiftTable.length; i ++) + this.shiftTable[i] = length; + + for (int i = 0; i < length; i ++) { + char ch = this.pattern[i]; + int diff = length-i-1; + int index = ch % this.shiftTable.length; + if (diff < this.shiftTable[index]) + this.shiftTable[index] = diff; + if (this.ignoreCase) { + ch = Character.toUpperCase(ch); + index = ch % this.shiftTable.length; + if (diff < this.shiftTable[index]) + this.shiftTable[index] = diff; + ch = Character.toLowerCase(ch); + index = ch % this.shiftTable.length; + if (diff < this.shiftTable[index]) + this.shiftTable[index] = diff; + } + } + } + + /** + * + * @return -1 if iterator does not contain this pattern. + */ + public int matches(CharacterIterator iterator, int start, int limit) { + if (this.ignoreCase) return this.matchesIgnoreCase(iterator, start, limit); + int plength = this.pattern.length; + if (plength == 0) return start; + int index = start+plength; + while (index <= limit) { + int pindex = plength; + int nindex = index+1; + char ch; + do { + if ((ch = iterator.setIndex(--index)) != this.pattern[--pindex]) + break; + if (pindex == 0) + return index; + } while (pindex > 0); + index += this.shiftTable[ch % this.shiftTable.length]+1; + if (index < nindex) index = nindex; + } + return -1; + } + + /** + * + * @return -1 if str does not contain this pattern. + */ + public int matches(String str, int start, int limit) { + if (this.ignoreCase) return this.matchesIgnoreCase(str, start, limit); + int plength = this.pattern.length; + if (plength == 0) return start; + int index = start+plength; + while (index <= limit) { + //System.err.println("Starts at "+index); + int pindex = plength; + int nindex = index+1; + char ch; + do { + if ((ch = str.charAt(--index)) != this.pattern[--pindex]) + break; + if (pindex == 0) + return index; + } while (pindex > 0); + index += this.shiftTable[ch % this.shiftTable.length]+1; + if (index < nindex) index = nindex; + } + return -1; + } + /** + * + * @return -1 if chars does not contain this pattern. + */ + public int matches(char[] chars, int start, int limit) { + if (this.ignoreCase) return this.matchesIgnoreCase(chars, start, limit); + int plength = this.pattern.length; + if (plength == 0) return start; + int index = start+plength; + while (index <= limit) { + //System.err.println("Starts at "+index); + int pindex = plength; + int nindex = index+1; + char ch; + do { + if ((ch = chars[--index]) != this.pattern[--pindex]) + break; + if (pindex == 0) + return index; + } while (pindex > 0); + index += this.shiftTable[ch % this.shiftTable.length]+1; + if (index < nindex) index = nindex; + } + return -1; + } + + int matchesIgnoreCase(CharacterIterator iterator, int start, int limit) { + int plength = this.pattern.length; + if (plength == 0) return start; + int index = start+plength; + while (index <= limit) { + int pindex = plength; + int nindex = index+1; + char ch; + do { + char ch1 = ch = iterator.setIndex(--index); + char ch2 = this.pattern[--pindex]; + if (ch1 != ch2) { + ch1 = Character.toUpperCase(ch1); + ch2 = Character.toUpperCase(ch2); + if (ch1 != ch2 && Character.toLowerCase(ch1) != Character.toLowerCase(ch2)) + break; + } + if (pindex == 0) + return index; + } while (pindex > 0); + index += this.shiftTable[ch % this.shiftTable.length]+1; + if (index < nindex) index = nindex; + } + return -1; + } + + int matchesIgnoreCase(String text, int start, int limit) { + int plength = this.pattern.length; + if (plength == 0) return start; + int index = start+plength; + while (index <= limit) { + int pindex = plength; + int nindex = index+1; + char ch; + do { + char ch1 = ch = text.charAt(--index); + char ch2 = this.pattern[--pindex]; + if (ch1 != ch2) { + ch1 = Character.toUpperCase(ch1); + ch2 = Character.toUpperCase(ch2); + if (ch1 != ch2 && Character.toLowerCase(ch1) != Character.toLowerCase(ch2)) + break; + } + if (pindex == 0) + return index; + } while (pindex > 0); + index += this.shiftTable[ch % this.shiftTable.length]+1; + if (index < nindex) index = nindex; + } + return -1; + } + int matchesIgnoreCase(char[] chars, int start, int limit) { + int plength = this.pattern.length; + if (plength == 0) return start; + int index = start+plength; + while (index <= limit) { + int pindex = plength; + int nindex = index+1; + char ch; + do { + char ch1 = ch = chars[--index]; + char ch2 = this.pattern[--pindex]; + if (ch1 != ch2) { + ch1 = Character.toUpperCase(ch1); + ch2 = Character.toUpperCase(ch2); + if (ch1 != ch2 && Character.toLowerCase(ch1) != Character.toLowerCase(ch2)) + break; + } + if (pindex == 0) + return index; + } while (pindex > 0); + index += this.shiftTable[ch % this.shiftTable.length]+1; + if (index < nindex) index = nindex; + } + return -1; + } + + /* + public static void main(String[] argv) { + try { + int[] shiftTable = new int[256]; + initializeBoyerMoore(argv[0], shiftTable, true); + int o = -1; + CharacterIterator ite = new java.text.StringCharacterIterator(argv[1]); + long start = System.currentTimeMillis(); + //for (int i = 0; i < 10000; i ++) + o = searchIgnoreCasesWithBoyerMoore(ite, 0, argv[0], shiftTable); + start = System.currentTimeMillis()-start; + System.out.println("Result: "+o+", Elapsed: "+start); + } catch (Exception ex) { + ex.printStackTrace(); + } + }*/ +} + diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/regex/Match.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/regex/Match.java new file mode 100644 index 000000000..08e9c97f9 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/regex/Match.java @@ -0,0 +1,180 @@ +/* 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.regex; + +import java.text.CharacterIterator; + +/** + * + * An instance of this class has ranges captured in matching. + * + * @see RegularExpression#matches(char[], int, int, Match) + * @see RegularExpression#matches(char[], Match) + * @see RegularExpression#matches(java.text.CharacterIterator, Match) + * @see RegularExpression#matches(java.lang.String, int, int, Match) + * @see RegularExpression#matches(java.lang.String, Match) + * @author TAMURA Kent <kent@trl.ibm.co.jp> + */ +public class Match implements Cloneable { + int[] beginpos = null; + int[] endpos = null; + int nofgroups = 0; + + CharacterIterator ciSource = null; + String strSource = null; + char[] charSource = null; + + /** + * Creates an instance. + */ + public Match() { + } + + /** + * + */ + public synchronized Object clone() { + Match ma = new Match(); + if (this.nofgroups > 0) { + ma.setNumberOfGroups(this.nofgroups); + if (this.ciSource != null) ma.setSource(this.ciSource); + if (this.strSource != null) ma.setSource(this.strSource); + for (int i = 0; i < this.nofgroups; i ++) { + ma.setBeginning(i, this.getBeginning(i)); + ma.setEnd(i, this.getEnd(i)); + } + } + return ma; + } + + /** + * + */ + protected void setNumberOfGroups(int n) { + int oldn = this.nofgroups; + this.nofgroups = n; + if (oldn <= 0 + || oldn < n || n*2 < oldn) { + this.beginpos = new int[n]; + this.endpos = new int[n]; + } + for (int i = 0; i < n; i ++) { + this.beginpos[i] = -1; + this.endpos[i] = -1; + } + } + + /** + * + */ + protected void setSource(CharacterIterator ci) { + this.ciSource = ci; + this.strSource = null; + this.charSource = null; + } + /** + * + */ + protected void setSource(String str) { + this.ciSource = null; + this.strSource = str; + this.charSource = null; + } + /** + * + */ + protected void setSource(char[] chars) { + this.ciSource = null; + this.strSource = null; + this.charSource = chars; + } + + /** + * + */ + protected void setBeginning(int index, int v) { + this.beginpos[index] = v; + } + + /** + * + */ + protected void setEnd(int index, int v) { + this.endpos[index] = v; + } + + /** + * Return the number of regular expression groups. + * This method returns 1 when the regular expression has no capturing-parenthesis. + */ + public int getNumberOfGroups() { + if (this.nofgroups <= 0) + throw new IllegalStateException("A result is not set."); + return this.nofgroups; + } + + /** + * Return a start position in the target text matched to specified regular expression group. + * + * @param index Less than getNumberOfGroups(). + */ + public int getBeginning(int index) { + if (this.beginpos == null) + throw new IllegalStateException("A result is not set."); + if (index < 0 || this.nofgroups <= index) + throw new IllegalArgumentException("The parameter must be less than " + +this.nofgroups+": "+index); + return this.beginpos[index]; + } + + /** + * Return an end position in the target text matched to specified regular expression group. + * + * @param index Less than getNumberOfGroups(). + */ + public int getEnd(int index) { + if (this.endpos == null) + throw new IllegalStateException("A result is not set."); + if (index < 0 || this.nofgroups <= index) + throw new IllegalArgumentException("The parameter must be less than " + +this.nofgroups+": "+index); + return this.endpos[index]; + } + + /** + * Return an substring of the target text matched to specified regular expression group. + * + * @param index Less than getNumberOfGroups(). + */ + public String getCapturedText(int index) { + if (this.beginpos == null) + throw new IllegalStateException("match() has never been called."); + if (index < 0 || this.nofgroups <= index) + throw new IllegalArgumentException("The parameter must be less than " + +this.nofgroups+": "+index); + String ret; + int begin = this.beginpos[index], end = this.endpos[index]; + if (begin < 0 || end < 0) return null; + if (this.ciSource != null) { + ret = REUtil.substring(this.ciSource, begin, end); + } else if (this.strSource != null) { + ret = this.strSource.substring(begin, end); + } else { + ret = new String(this.charSource, begin, end-begin); + } + return ret; + } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/regex/Op.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/regex/Op.java new file mode 100644 index 000000000..428ffc96e --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/regex/Op.java @@ -0,0 +1,247 @@ +/* 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.regex; + +import java.util.Vector; + +/** + */ +class Op { + static final int DOT = 0; + static final int CHAR = 1; // Single character + static final int RANGE = 3; // [a-zA-Z] + static final int NRANGE = 4; // [^a-zA-Z] + static final int ANCHOR = 5; // ^ $ ... + static final int STRING = 6; // literal String + static final int CLOSURE = 7; // X* + static final int NONGREEDYCLOSURE = 8; // X*? + static final int QUESTION = 9; // X? + static final int NONGREEDYQUESTION = 10; // X?? + static final int UNION = 11; // X|Y + static final int CAPTURE = 15; // ( and ) + static final int BACKREFERENCE = 16; // \1 \2 ... + static final int LOOKAHEAD = 20; // (?=...) + static final int NEGATIVELOOKAHEAD = 21; // (?!...) + static final int LOOKBEHIND = 22; // (?<=...) + static final int NEGATIVELOOKBEHIND = 23; // (?...) + static final int MODIFIER = 25; // (?ims-ims:...) + static final int CONDITION = 26; // (?(..)yes|no) + + static int nofinstances = 0; + static final boolean COUNT = false; + + static Op createDot() { + if (Op.COUNT) Op.nofinstances ++; + return new Op(Op.DOT); + } + static CharOp createChar(int data) { + if (Op.COUNT) Op.nofinstances ++; + return new CharOp(Op.CHAR, data); + } + static CharOp createAnchor(int data) { + if (Op.COUNT) Op.nofinstances ++; + return new CharOp(Op.ANCHOR, data); + } + static CharOp createCapture(int number, Op next) { + if (Op.COUNT) Op.nofinstances ++; + CharOp op = new CharOp(Op.CAPTURE, number); + op.next = next; + return op; + } + static UnionOp createUnion(int size) { + if (Op.COUNT) Op.nofinstances ++; + //System.err.println("Creates UnionOp"); + return new UnionOp(Op.UNION, size); + } + static ChildOp createClosure(int id) { + if (Op.COUNT) Op.nofinstances ++; + return new ModifierOp(Op.CLOSURE, id, -1); + } + static ChildOp createNonGreedyClosure() { + if (Op.COUNT) Op.nofinstances ++; + return new ChildOp(Op.NONGREEDYCLOSURE); + } + static ChildOp createQuestion(boolean nongreedy) { + if (Op.COUNT) Op.nofinstances ++; + return new ChildOp(nongreedy ? Op.NONGREEDYQUESTION : Op.QUESTION); + } + static RangeOp createRange(Token tok) { + if (Op.COUNT) Op.nofinstances ++; + return new RangeOp(Op.RANGE, tok); + } + static ChildOp createLook(int type, Op next, Op branch) { + if (Op.COUNT) Op.nofinstances ++; + ChildOp op = new ChildOp(type); + op.setChild(branch); + op.next = next; + return op; + } + static CharOp createBackReference(int refno) { + if (Op.COUNT) Op.nofinstances ++; + return new CharOp(Op.BACKREFERENCE, refno); + } + static StringOp createString(String literal) { + if (Op.COUNT) Op.nofinstances ++; + return new StringOp(Op.STRING, literal); + } + static ChildOp createIndependent(Op next, Op branch) { + if (Op.COUNT) Op.nofinstances ++; + ChildOp op = new ChildOp(Op.INDEPENDENT); + op.setChild(branch); + op.next = next; + return op; + } + static ModifierOp createModifier(Op next, Op branch, int add, int mask) { + if (Op.COUNT) Op.nofinstances ++; + ModifierOp op = new ModifierOp(Op.MODIFIER, add, mask); + op.setChild(branch); + op.next = next; + return op; + } + static ConditionOp createCondition(Op next, int ref, Op conditionflow, Op yesflow, Op noflow) { + if (Op.COUNT) Op.nofinstances ++; + ConditionOp op = new ConditionOp(Op.CONDITION, ref, conditionflow, yesflow, noflow); + op.next = next; + return op; + } + + int type; + Op next = null; + + protected Op(int type) { + this.type = type; + } + + int size() { // for UNION + return 0; + } + Op elementAt(int index) { // for UNIoN + throw new RuntimeException("Internal Error: type="+this.type); + } + Op getChild() { // for CLOSURE, QUESTION + throw new RuntimeException("Internal Error: type="+this.type); + } + // ModifierOp + int getData() { // CharOp for CHAR, BACKREFERENCE, CAPTURE, ANCHOR, + throw new RuntimeException("Internal Error: type="+this.type); + } + int getData2() { // ModifierOp + throw new RuntimeException("Internal Error: type="+this.type); + } + RangeToken getToken() { // RANGE, NRANGE + throw new RuntimeException("Internal Error: type="+this.type); + } + String getString() { // STRING + throw new RuntimeException("Internal Error: type="+this.type); + } + + // ================================================================ + static class CharOp extends Op { + int charData; + CharOp(int type, int data) { + super(type); + this.charData = data; + } + int getData() { + return this.charData; + } + } + + // ================================================================ + static class UnionOp extends Op { + Vector branches; + UnionOp(int type, int size) { + super(type); + this.branches = new Vector(size); + } + void addElement(Op op) { + this.branches.addElement(op); + } + int size() { + return this.branches.size(); + } + Op elementAt(int index) { + return (Op)this.branches.elementAt(index); + } + } + + // ================================================================ + static class ChildOp extends Op { + Op child; + ChildOp(int type) { + super(type); + } + void setChild(Op child) { + this.child = child; + } + Op getChild() { + return this.child; + } + } + // ================================================================ + static class ModifierOp extends ChildOp { + int v1; + int v2; + ModifierOp(int type, int v1, int v2) { + super(type); + this.v1 = v1; + this.v2 = v2; + } + int getData() { + return this.v1; + } + int getData2() { + return this.v2; + } + } + // ================================================================ + static class RangeOp extends Op { + Token tok; + RangeOp(int type, Token tok) { + super(type); + this.tok = tok; + } + RangeToken getToken() { + return (RangeToken)this.tok; + } + } + // ================================================================ + static class StringOp extends Op { + String string; + StringOp(int type, String literal) { + super(type); + this.string = literal; + } + String getString() { + return this.string; + } + } + // ================================================================ + static class ConditionOp extends Op { + int refNumber; + Op condition; + Op yes; + Op no; + ConditionOp(int type, int refno, Op conditionflow, Op yesflow, Op noflow) { + super(type); + this.refNumber = refno; + this.condition = conditionflow; + this.yes = yesflow; + this.no = noflow; + } + } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/regex/ParseException.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/regex/ParseException.java new file mode 100644 index 000000000..0d16e0d07 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/regex/ParseException.java @@ -0,0 +1,45 @@ +/* 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.regex; + +/** + * + * @author TAMURA Kent <kent@trl.ibm.co.jp> + */ +public class ParseException extends RuntimeException { + int location; + + /* + public ParseException(String mes) { + this(mes, -1); + } + */ + /** + * + */ + public ParseException(String mes, int location) { + super(mes); + this.location = location; + } + + /** + * + * @return -1 if location information is not available. + */ + public int getLocation() { + return this.location; + } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/regex/ParserForXMLSchema.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/regex/ParserForXMLSchema.java new file mode 100644 index 000000000..ff41545a8 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/regex/ParserForXMLSchema.java @@ -0,0 +1,476 @@ +/* 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.regex; + +import java.util.Hashtable; +import java.util.Locale; + +/** + * A regular expression parser for the XML Schema. + * + * @author TAMURA Kent <kent@trl.ibm.co.jp> + */ +class ParserForXMLSchema extends RegexParser { + + public ParserForXMLSchema() { + //this.setLocale(Locale.getDefault()); + } + public ParserForXMLSchema(Locale locale) { + //this.setLocale(locale); + } + + Token processCaret() throws ParseException { + this.next(); + return Token.createChar('^'); + } + Token processDollar() throws ParseException { + this.next(); + return Token.createChar('$'); + } + Token processLookahead() throws ParseException { + throw ex("parser.process.1", this.offset); + } + Token processNegativelookahead() throws ParseException { + throw ex("parser.process.1", this.offset); + } + Token processLookbehind() throws ParseException { + throw ex("parser.process.1", this.offset); + } + Token processNegativelookbehind() throws ParseException { + throw ex("parser.process.1", this.offset); + } + Token processBacksolidus_A() throws ParseException { + throw ex("parser.process.1", this.offset); + } + Token processBacksolidus_Z() throws ParseException { + throw ex("parser.process.1", this.offset); + } + Token processBacksolidus_z() throws ParseException { + throw ex("parser.process.1", this.offset); + } + Token processBacksolidus_b() throws ParseException { + throw ex("parser.process.1", this.offset); + } + Token processBacksolidus_B() throws ParseException { + throw ex("parser.process.1", this.offset); + } + Token processBacksolidus_lt() throws ParseException { + throw ex("parser.process.1", this.offset); + } + Token processBacksolidus_gt() throws ParseException { + throw ex("parser.process.1", this.offset); + } + Token processStar(Token tok) throws ParseException { + this.next(); + return Token.createClosure(tok); + } + Token processPlus(Token tok) throws ParseException { + // X+ -> XX* + this.next(); + return Token.createConcat(tok, Token.createClosure(tok)); + } + Token processQuestion(Token tok) throws ParseException { + // X? -> X| + this.next(); + Token par = Token.createUnion(); + par.addChild(tok); + par.addChild(Token.createEmpty()); + return par; + } + boolean checkQuestion(int off) { + return false; + } + Token processParen() throws ParseException { + this.next(); + Token tok = Token.createParen(this.parseRegex(), 0); + if (this.read() != super.T_RPAREN) throw ex("parser.factor.1", this.offset-1); + this.next(); // Skips ')' + return tok; + } + Token processParen2() throws ParseException { + throw ex("parser.process.1", this.offset); + } + Token processCondition() throws ParseException { + throw ex("parser.process.1", this.offset); + } + Token processModifiers() throws ParseException { + throw ex("parser.process.1", this.offset); + } + Token processIndependent() throws ParseException { + throw ex("parser.process.1", this.offset); + } + Token processBacksolidus_c() throws ParseException { + this.next(); + return this.getTokenForShorthand('c'); + } + Token processBacksolidus_C() throws ParseException { + this.next(); + return this.getTokenForShorthand('C'); + } + Token processBacksolidus_i() throws ParseException { + this.next(); + return this.getTokenForShorthand('i'); + } + Token processBacksolidus_I() throws ParseException { + this.next(); + return this.getTokenForShorthand('I'); + } + Token processBacksolidus_g() throws ParseException { + throw this.ex("parser.process.1", this.offset-2); + } + Token processBacksolidus_X() throws ParseException { + throw ex("parser.process.1", this.offset-2); + } + Token processBackreference() throws ParseException { + throw ex("parser.process.1", this.offset-4); + } + + int processCIinCharacterClass(RangeToken tok, int c) { + tok.mergeRanges(this.getTokenForShorthand(c)); + return -1; + } + + + /** + * Parses a character-class-expression, not a character-class-escape. + * + * c-c-expression ::= '[' c-group ']' + * c-group ::= positive-c-group | negative-c-group | c-c-subtraction + * positive-c-group ::= (c-range | c-c-escape)+ + * negative-c-group ::= '^' positive-c-group + * c-c-subtraction ::= (positive-c-group | negative-c-group) subtraction + * subtraction ::= '-' c-c-expression + * c-range ::= single-range | from-to-range + * single-range ::= multi-c-escape | category-c-escape | block-c-escape | + * cc-normal-c ::= + * from-to-range ::= cc-normal-c '-' cc-normal-c + * + * @param useNrage Ignored. + * @return This returns no NrangeToken. + */ + protected RangeToken parseCharacterClass(boolean useNrange) throws ParseException { + this.setContext(S_INBRACKETS); + this.next(); // '[' + boolean nrange = false; + RangeToken base = null; + RangeToken tok; + if (this.read() == T_CHAR && this.chardata == '^') { + nrange = true; + this.next(); // '^' + base = Token.createRange(); + base.addRange(0, Token.UTF16_MAX); + tok = Token.createRange(); + } else { + tok = Token.createRange(); + } + int type; + boolean firstloop = true; + while ((type = this.read()) != T_EOF) { // Don't use 'cotinue' for this loop. + // single-range | from-to-range | subtraction + if (type == T_CHAR && this.chardata == ']' && !firstloop) { + if (nrange) { + base.subtractRanges(tok); + tok = base; + } + break; + } + int c = this.chardata; + boolean end = false; + if (type == T_BACKSOLIDUS) { + switch (c) { + case 'd': case 'D': + case 'w': case 'W': + case 's': case 'S': + tok.mergeRanges(this.getTokenForShorthand(c)); + end = true; + break; + + case 'i': case 'I': + case 'c': case 'C': + c = this.processCIinCharacterClass(tok, c); + if (c < 0) end = true; + break; + + case 'p': + case 'P': + int pstart = this.offset; + RangeToken tok2 = this.processBacksolidus_pP(c); + if (tok2 == null) throw this.ex("parser.atom.5", pstart); + tok.mergeRanges(tok2); + end = true; + break; + + default: + c = this.decodeEscaped(); + } // \ + c + } // backsolidus + else if (type == T_XMLSCHEMA_CC_SUBTRACTION && !firstloop) { + // Subraction + if (nrange) { + base.subtractRanges(tok); + tok = base; + } + RangeToken range2 = this.parseCharacterClass(false); + tok.subtractRanges(range2); + if (this.read() != T_CHAR || this.chardata != ']') + throw this.ex("parser.cc.5", this.offset); + break; // Exit this loop + } + this.next(); + if (!end) { // if not shorthands... + if (type == T_CHAR) { + if (c == '[') throw this.ex("parser.cc.6", this.offset-2); + if (c == ']') throw this.ex("parser.cc.7", this.offset-2); + //https://issues.apache.org/jira/browse/XMLBEANS-412 + //unescaped single char '-' is a valid char after '[' and before ']' positive range only + if (c== '-' && !firstloop && this.chardata!=']') throw this.ex("parser.cc.8", this.offset-2); + } + if (this.read() != T_CHAR || this.chardata != '-') { // Here is no '-'. + tok.addRange(c, c); + } else { // Found '-' + // Is this '-' is a from-to token?? + this.next(); // Skips '-' + if ((type = this.read()) == T_EOF) throw this.ex("parser.cc.2", this.offset); + // c '-' ']' -> '-' is a single-range. + if (type == T_XMLSCHEMA_CC_SUBTRACTION) { + throw this.ex("parser.cc.8", this.offset-1); + } else if (type == T_CHAR && this.chardata == ']') { + //'-' occurs after a single-range but before ']' + tok.addRange(c,c); + tok.addRange('-','-'); + } else { + int rangeend = this.chardata; + if (type == T_CHAR) { + if (rangeend == '[') throw this.ex("parser.cc.6", this.offset-1); + if (rangeend == ']') throw this.ex("parser.cc.7", this.offset-1); + if (rangeend == '-') { + this.next(); + if (this.chardata!=']') + throw this.ex("parser.cc.8", this.offset-2); + } + } + else if (type == T_BACKSOLIDUS) + rangeend = this.decodeEscaped(); + if (rangeend!='-' || this.chardata!=']') + this.next(); + + if (c > rangeend) throw this.ex("parser.ope.3", this.offset-1); + tok.addRange(c, rangeend); + } + } + } + firstloop = false; + } + if (this.read() == T_EOF) + throw this.ex("parser.cc.2", this.offset); + tok.sortRanges(); + tok.compactRanges(); + //tok.dumpRanges(); + this.setContext(S_NORMAL); + this.next(); // Skips ']' + + return tok; + } + + protected RangeToken parseSetOperations() throws ParseException { + throw this.ex("parser.process.1", this.offset); + } + + Token getTokenForShorthand(int ch) { + switch (ch) { + case 'd': + return ParserForXMLSchema.getRange("xml:isDigit", true); + case 'D': + return ParserForXMLSchema.getRange("xml:isDigit", false); + case 'w': + return ParserForXMLSchema.getRange("xml:isWord", true); + case 'W': + return ParserForXMLSchema.getRange("xml:isWord", false); + case 's': + return ParserForXMLSchema.getRange("xml:isSpace", true); + case 'S': + return ParserForXMLSchema.getRange("xml:isSpace", false); + case 'c': + return ParserForXMLSchema.getRange("xml:isNameChar", true); + case 'C': + return ParserForXMLSchema.getRange("xml:isNameChar", false); + case 'i': + return ParserForXMLSchema.getRange("xml:isInitialNameChar", true); + case 'I': + return ParserForXMLSchema.getRange("xml:isInitialNameChar", false); + default: + throw new RuntimeException("Internal Error: shorthands: \\u"+Integer.toString(ch, 16)); + } + } + int decodeEscaped() throws ParseException { + if (this.read() != T_BACKSOLIDUS) throw ex("parser.next.1", this.offset-1); + int c = this.chardata; + switch (c) { + case 'n': c = '\n'; break; // LINE FEED U+000A + case 'r': c = '\r'; break; // CRRIAGE RETURN U+000D + case 't': c = '\t'; break; // HORIZONTAL TABULATION U+0009 + case '\\': + case '|': + case '.': + case '^': + case '-': + case '?': + case '*': + case '+': + case '{': + case '}': + case '(': + case ')': + case '[': + case ']': + break; // return actucal char + default: + throw ex("parser.process.1", this.offset-2); + } + return c; + } + + static private Hashtable ranges = null; + static private Hashtable ranges2 = null; + static synchronized protected RangeToken getRange(String name, boolean positive) { + if (ranges == null) { + ranges = new Hashtable(); + ranges2 = new Hashtable(); + + Token tok = Token.createRange(); + setupRange(tok, SPACES); + ranges.put("xml:isSpace", tok); + ranges2.put("xml:isSpace", Token.complementRanges(tok)); + + tok = Token.createRange(); + setupRange(tok, DIGITS); + ranges.put("xml:isDigit", tok); + ranges2.put("xml:isDigit", Token.complementRanges(tok)); + + tok = Token.createRange(); + setupRange(tok, DIGITS); + ranges.put("xml:isDigit", tok); + ranges2.put("xml:isDigit", Token.complementRanges(tok)); + + tok = Token.createRange(); + setupRange(tok, LETTERS); + tok.mergeRanges((Token)ranges.get("xml:isDigit")); + ranges.put("xml:isWord", tok); + ranges2.put("xml:isWord", Token.complementRanges(tok)); + + tok = Token.createRange(); + setupRange(tok, NAMECHARS); + ranges.put("xml:isNameChar", tok); + ranges2.put("xml:isNameChar", Token.complementRanges(tok)); + + tok = Token.createRange(); + setupRange(tok, LETTERS); + tok.addRange('_', '_'); + tok.addRange(':', ':'); + ranges.put("xml:isInitialNameChar", tok); + ranges2.put("xml:isInitialNameChar", Token.complementRanges(tok)); + } + RangeToken tok = positive ? (RangeToken)ranges.get(name) + : (RangeToken)ranges2.get(name); + return tok; + } + + static void setupRange(Token range, String src) { + int len = src.length(); + for (int i = 0; i < len; i += 2) + range.addRange(src.charAt(i), src.charAt(i+1)); + } + + private static final String SPACES = "\t\n\r\r "; + private static final String NAMECHARS = + "\u002d\u002e\u0030\u003a\u0041\u005a\u005f\u005f\u0061\u007a\u00b7\u00b7\u00c0\u00d6" + +"\u00d8\u00f6\u00f8\u0131\u0134\u013e\u0141\u0148\u014a\u017e\u0180\u01c3\u01cd\u01f0" + +"\u01f4\u01f5\u01fa\u0217\u0250\u02a8\u02bb\u02c1\u02d0\u02d1\u0300\u0345\u0360\u0361" + +"\u0386\u038a\u038c\u038c\u038e\u03a1\u03a3\u03ce\u03d0\u03d6\u03da\u03da\u03dc\u03dc" + +"\u03de\u03de\u03e0\u03e0\u03e2\u03f3\u0401\u040c\u040e\u044f\u0451\u045c\u045e\u0481" + +"\u0483\u0486\u0490\u04c4\u04c7\u04c8\u04cb\u04cc\u04d0\u04eb\u04ee\u04f5\u04f8\u04f9" + +"\u0531\u0556\u0559\u0559\u0561\u0586\u0591\u05a1\u05a3\u05b9\u05bb\u05bd\u05bf\u05bf" + +"\u05c1\u05c2\u05c4\u05c4\u05d0\u05ea\u05f0\u05f2\u0621\u063a\u0640\u0652\u0660\u0669" + +"\u0670\u06b7\u06ba\u06be\u06c0\u06ce\u06d0\u06d3\u06d5\u06e8\u06ea\u06ed\u06f0\u06f9" + +"\u0901\u0903\u0905\u0939\u093c\u094d\u0951\u0954\u0958\u0963\u0966\u096f\u0981\u0983" + +"\u0985\u098c\u098f\u0990\u0993\u09a8\u09aa\u09b0\u09b2\u09b2\u09b6\u09b9\u09bc\u09bc" + +"\u09be\u09c4\u09c7\u09c8\u09cb\u09cd\u09d7\u09d7\u09dc\u09dd\u09df\u09e3\u09e6\u09f1" + +"\u0a02\u0a02\u0a05\u0a0a\u0a0f\u0a10\u0a13\u0a28\u0a2a\u0a30\u0a32\u0a33\u0a35\u0a36" + +"\u0a38\u0a39\u0a3c\u0a3c\u0a3e\u0a42\u0a47\u0a48\u0a4b\u0a4d\u0a59\u0a5c\u0a5e\u0a5e" + +"\u0a66\u0a74\u0a81\u0a83\u0a85\u0a8b\u0a8d\u0a8d\u0a8f\u0a91\u0a93\u0aa8\u0aaa\u0ab0" + +"\u0ab2\u0ab3\u0ab5\u0ab9\u0abc\u0ac5\u0ac7\u0ac9\u0acb\u0acd\u0ae0\u0ae0\u0ae6\u0aef" + +"\u0b01\u0b03\u0b05\u0b0c\u0b0f\u0b10\u0b13\u0b28\u0b2a\u0b30\u0b32\u0b33\u0b36\u0b39" + +"\u0b3c\u0b43\u0b47\u0b48\u0b4b\u0b4d\u0b56\u0b57\u0b5c\u0b5d\u0b5f\u0b61\u0b66\u0b6f" + +"\u0b82\u0b83\u0b85\u0b8a\u0b8e\u0b90\u0b92\u0b95\u0b99\u0b9a\u0b9c\u0b9c\u0b9e\u0b9f" + +"\u0ba3\u0ba4\u0ba8\u0baa\u0bae\u0bb5\u0bb7\u0bb9\u0bbe\u0bc2\u0bc6\u0bc8\u0bca\u0bcd" + +"\u0bd7\u0bd7\u0be7\u0bef\u0c01\u0c03\u0c05\u0c0c\u0c0e\u0c10\u0c12\u0c28\u0c2a\u0c33" + +"\u0c35\u0c39\u0c3e\u0c44\u0c46\u0c48\u0c4a\u0c4d\u0c55\u0c56\u0c60\u0c61\u0c66\u0c6f" + +"\u0c82\u0c83\u0c85\u0c8c\u0c8e\u0c90\u0c92\u0ca8\u0caa\u0cb3\u0cb5\u0cb9\u0cbe\u0cc4" + +"\u0cc6\u0cc8\u0cca\u0ccd\u0cd5\u0cd6\u0cde\u0cde\u0ce0\u0ce1\u0ce6\u0cef\u0d02\u0d03" + +"\u0d05\u0d0c\u0d0e\u0d10\u0d12\u0d28\u0d2a\u0d39\u0d3e\u0d43\u0d46\u0d48\u0d4a\u0d4d" + +"\u0d57\u0d57\u0d60\u0d61\u0d66\u0d6f\u0e01\u0e2e\u0e30\u0e3a\u0e40\u0e4e\u0e50\u0e59" + +"\u0e81\u0e82\u0e84\u0e84\u0e87\u0e88\u0e8a\u0e8a\u0e8d\u0e8d\u0e94\u0e97\u0e99\u0e9f" + +"\u0ea1\u0ea3\u0ea5\u0ea5\u0ea7\u0ea7\u0eaa\u0eab\u0ead\u0eae\u0eb0\u0eb9\u0ebb\u0ebd" + +"\u0ec0\u0ec4\u0ec6\u0ec6\u0ec8\u0ecd\u0ed0\u0ed9\u0f18\u0f19\u0f20\u0f29\u0f35\u0f35" + +"\u0f37\u0f37\u0f39\u0f39\u0f3e\u0f47\u0f49\u0f69\u0f71\u0f84\u0f86\u0f8b\u0f90\u0f95" + +"\u0f97\u0f97\u0f99\u0fad\u0fb1\u0fb7\u0fb9\u0fb9\u10a0\u10c5\u10d0\u10f6\u1100\u1100" + +"\u1102\u1103\u1105\u1107\u1109\u1109\u110b\u110c\u110e\u1112\u113c\u113c\u113e\u113e" + +"\u1140\u1140\u114c\u114c\u114e\u114e\u1150\u1150\u1154\u1155\u1159\u1159\u115f\u1161" + +"\u1163\u1163\u1165\u1165\u1167\u1167\u1169\u1169\u116d\u116e\u1172\u1173\u1175\u1175" + +"\u119e\u119e\u11a8\u11a8\u11ab\u11ab\u11ae\u11af\u11b7\u11b8\u11ba\u11ba\u11bc\u11c2" + +"\u11eb\u11eb\u11f0\u11f0\u11f9\u11f9\u1e00\u1e9b\u1ea0\u1ef9\u1f00\u1f15\u1f18\u1f1d" + +"\u1f20\u1f45\u1f48\u1f4d\u1f50\u1f57\u1f59\u1f59\u1f5b\u1f5b\u1f5d\u1f5d\u1f5f\u1f7d" + +"\u1f80\u1fb4\u1fb6\u1fbc\u1fbe\u1fbe\u1fc2\u1fc4\u1fc6\u1fcc\u1fd0\u1fd3\u1fd6\u1fdb" + +"\u1fe0\u1fec\u1ff2\u1ff4\u1ff6\u1ffc\u20d0\u20dc\u20e1\u20e1\u2126\u2126\u212a\u212b" + +"\u212e\u212e\u2180\u2182\u3005\u3005\u3007\u3007\u3021\u302f\u3031\u3035\u3041\u3094" + +"\u3099\u309a\u309d\u309e\u30a1\u30fa\u30fc\u30fe\u3105\u312c\u4e00\u9fa5\uac00\ud7a3" + +""; + private static final String LETTERS = + "\u0041\u005a\u0061\u007a\u00c0\u00d6\u00d8\u00f6\u00f8\u0131\u0134\u013e\u0141\u0148" + +"\u014a\u017e\u0180\u01c3\u01cd\u01f0\u01f4\u01f5\u01fa\u0217\u0250\u02a8\u02bb\u02c1" + +"\u0386\u0386\u0388\u038a\u038c\u038c\u038e\u03a1\u03a3\u03ce\u03d0\u03d6\u03da\u03da" + +"\u03dc\u03dc\u03de\u03de\u03e0\u03e0\u03e2\u03f3\u0401\u040c\u040e\u044f\u0451\u045c" + +"\u045e\u0481\u0490\u04c4\u04c7\u04c8\u04cb\u04cc\u04d0\u04eb\u04ee\u04f5\u04f8\u04f9" + +"\u0531\u0556\u0559\u0559\u0561\u0586\u05d0\u05ea\u05f0\u05f2\u0621\u063a\u0641\u064a" + +"\u0671\u06b7\u06ba\u06be\u06c0\u06ce\u06d0\u06d3\u06d5\u06d5\u06e5\u06e6\u0905\u0939" + +"\u093d\u093d\u0958\u0961\u0985\u098c\u098f\u0990\u0993\u09a8\u09aa\u09b0\u09b2\u09b2" + +"\u09b6\u09b9\u09dc\u09dd\u09df\u09e1\u09f0\u09f1\u0a05\u0a0a\u0a0f\u0a10\u0a13\u0a28" + +"\u0a2a\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59\u0a5c\u0a5e\u0a5e\u0a72\u0a74" + +"\u0a85\u0a8b\u0a8d\u0a8d\u0a8f\u0a91\u0a93\u0aa8\u0aaa\u0ab0\u0ab2\u0ab3\u0ab5\u0ab9" + +"\u0abd\u0abd\u0ae0\u0ae0\u0b05\u0b0c\u0b0f\u0b10\u0b13\u0b28\u0b2a\u0b30\u0b32\u0b33" + +"\u0b36\u0b39\u0b3d\u0b3d\u0b5c\u0b5d\u0b5f\u0b61\u0b85\u0b8a\u0b8e\u0b90\u0b92\u0b95" + +"\u0b99\u0b9a\u0b9c\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8\u0baa\u0bae\u0bb5\u0bb7\u0bb9" + +"\u0c05\u0c0c\u0c0e\u0c10\u0c12\u0c28\u0c2a\u0c33\u0c35\u0c39\u0c60\u0c61\u0c85\u0c8c" + +"\u0c8e\u0c90\u0c92\u0ca8\u0caa\u0cb3\u0cb5\u0cb9\u0cde\u0cde\u0ce0\u0ce1\u0d05\u0d0c" + +"\u0d0e\u0d10\u0d12\u0d28\u0d2a\u0d39\u0d60\u0d61\u0e01\u0e2e\u0e30\u0e30\u0e32\u0e33" + +"\u0e40\u0e45\u0e81\u0e82\u0e84\u0e84\u0e87\u0e88\u0e8a\u0e8a\u0e8d\u0e8d\u0e94\u0e97" + +"\u0e99\u0e9f\u0ea1\u0ea3\u0ea5\u0ea5\u0ea7\u0ea7\u0eaa\u0eab\u0ead\u0eae\u0eb0\u0eb0" + +"\u0eb2\u0eb3\u0ebd\u0ebd\u0ec0\u0ec4\u0f40\u0f47\u0f49\u0f69\u10a0\u10c5\u10d0\u10f6" + +"\u1100\u1100\u1102\u1103\u1105\u1107\u1109\u1109\u110b\u110c\u110e\u1112\u113c\u113c" + +"\u113e\u113e\u1140\u1140\u114c\u114c\u114e\u114e\u1150\u1150\u1154\u1155\u1159\u1159" + +"\u115f\u1161\u1163\u1163\u1165\u1165\u1167\u1167\u1169\u1169\u116d\u116e\u1172\u1173" + +"\u1175\u1175\u119e\u119e\u11a8\u11a8\u11ab\u11ab\u11ae\u11af\u11b7\u11b8\u11ba\u11ba" + +"\u11bc\u11c2\u11eb\u11eb\u11f0\u11f0\u11f9\u11f9\u1e00\u1e9b\u1ea0\u1ef9\u1f00\u1f15" + +"\u1f18\u1f1d\u1f20\u1f45\u1f48\u1f4d\u1f50\u1f57\u1f59\u1f59\u1f5b\u1f5b\u1f5d\u1f5d" + +"\u1f5f\u1f7d\u1f80\u1fb4\u1fb6\u1fbc\u1fbe\u1fbe\u1fc2\u1fc4\u1fc6\u1fcc\u1fd0\u1fd3" + +"\u1fd6\u1fdb\u1fe0\u1fec\u1ff2\u1ff4\u1ff6\u1ffc\u2126\u2126\u212a\u212b\u212e\u212e" + +"\u2180\u2182\u3007\u3007\u3021\u3029\u3041\u3094\u30a1\u30fa\u3105\u312c\u4e00\u9fa5" + +"\uac00\ud7a3"; + private static final String DIGITS = + "\u0030\u0039\u0660\u0669\u06F0\u06F9\u0966\u096F\u09E6\u09EF\u0A66\u0A6F\u0AE6\u0AEF" + +"\u0B66\u0B6F\u0BE7\u0BEF\u0C66\u0C6F\u0CE6\u0CEF\u0D66\u0D6F\u0E50\u0E59\u0ED0\u0ED9" + +"\u0F20\u0F29"; +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/regex/README.txt b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/regex/README.txt new file mode 100644 index 000000000..a98fe4ae7 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/regex/README.txt @@ -0,0 +1,24 @@ +This is an isolated directory that was taken from the +Apache Xerces-J 2.0 project. + +BMPPattern.java,v 1.4 2004/02/24 +Match.java,v 1.5 2004/02/24 +Op.java,v 1.4 2004/02/24 +ParseException.java,v 1.4 2004/02/24 +ParserForXMLSchema.java,v 1.6 2004/02/24 +RangeToken.java,v 1.5 2004/02/24 +RegexParser.java,v 1.9 2004/02/24 +RegularExpression.java,v 1.8 2004/02/24 +REUtil.java,v 1.8 2004/02/24 +Token.java,v 1.8 2004/02/24 +message.properties, 1.6 2003/03/25 + +It contains the following modifications: + +(1) a change in namespace. +(2) the addition of a SchemaRegularExpression class for fast + detection of NCNAME, etc. +(3) Bugfix in file ParserForXMLSchema:237 + +No xbean code outside this directory or other directories with +similar README notices was taken from Apache. diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/regex/REUtil.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/regex/REUtil.java new file mode 100644 index 000000000..089fe8896 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/regex/REUtil.java @@ -0,0 +1,326 @@ +/* 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.regex; + +import java.text.CharacterIterator; + +public final class REUtil { + private REUtil() { + } + + static final int composeFromSurrogates(int high, int low) { + return 0x10000 + ((high-0xd800)<<10) + low-0xdc00; + } + + static final boolean isLowSurrogate(int ch) { + return (ch & 0xfc00) == 0xdc00; + } + + static final boolean isHighSurrogate(int ch) { + return (ch & 0xfc00) == 0xd800; + } + + static final String decomposeToSurrogates(int ch) { + char[] chs = new char[2]; + ch -= 0x10000; + chs[0] = (char)((ch>>10)+0xd800); + chs[1] = (char)((ch&0x3ff)+0xdc00); + return new String(chs); + } + + static final String substring(CharacterIterator iterator, int begin, int end) { + char[] src = new char[end-begin]; + for (int i = 0; i < src.length; i ++) + src[i] = iterator.setIndex(i+begin); + return new String(src); + } + + // ================================================================ + + static final int getOptionValue(int ch) { + int ret = 0; + switch (ch) { + case 'i': + ret = RegularExpression.IGNORE_CASE; + break; + case 'm': + ret = RegularExpression.MULTIPLE_LINES; + break; + case 's': + ret = RegularExpression.SINGLE_LINE; + break; + case 'x': + ret = RegularExpression.EXTENDED_COMMENT; + break; + case 'u': + ret = RegularExpression.USE_UNICODE_CATEGORY; + break; + case 'w': + ret = RegularExpression.UNICODE_WORD_BOUNDARY; + break; + case 'F': + ret = RegularExpression.PROHIBIT_FIXED_STRING_OPTIMIZATION; + break; + case 'H': + ret = RegularExpression.PROHIBIT_HEAD_CHARACTER_OPTIMIZATION; + break; + case 'X': + ret = RegularExpression.XMLSCHEMA_MODE; + break; + case ',': + ret = RegularExpression.SPECIAL_COMMA; + break; + default: + } + return ret; + } + + static final int parseOptions(String opts) throws ParseException { + if (opts == null) return 0; + int options = 0; + for (int i = 0; i < opts.length(); i ++) { + int v = getOptionValue(opts.charAt(i)); + if (v == 0) + throw new ParseException("Unknown Option: "+opts.substring(i), -1); + options |= v; + } + return options; + } + + static final String createOptionString(int options) { + StringBuffer sb = new StringBuffer(9); + if ((options & RegularExpression.PROHIBIT_FIXED_STRING_OPTIMIZATION) != 0) + sb.append((char)'F'); + if ((options & RegularExpression.PROHIBIT_HEAD_CHARACTER_OPTIMIZATION) != 0) + sb.append((char)'H'); + if ((options & RegularExpression.XMLSCHEMA_MODE) != 0) + sb.append((char)'X'); + if ((options & RegularExpression.IGNORE_CASE) != 0) + sb.append((char)'i'); + if ((options & RegularExpression.MULTIPLE_LINES) != 0) + sb.append((char)'m'); + if ((options & RegularExpression.SINGLE_LINE) != 0) + sb.append((char)'s'); + if ((options & RegularExpression.USE_UNICODE_CATEGORY) != 0) + sb.append((char)'u'); + if ((options & RegularExpression.UNICODE_WORD_BOUNDARY) != 0) + sb.append((char)'w'); + if ((options & RegularExpression.EXTENDED_COMMENT) != 0) + sb.append((char)'x'); + if ((options & RegularExpression.SPECIAL_COMMA) != 0) + sb.append((char)','); + return sb.toString().intern(); + } + + // ================================================================ + + static String stripExtendedComment(String regex) { + int len = regex.length(); + StringBuffer buffer = new StringBuffer(len); + int offset = 0; + while (offset < len) { + int ch = regex.charAt(offset++); + // Skips a white space. + if (ch == '\t' || ch == '\n' || ch == '\f' || ch == '\r' || ch == ' ') + continue; + + if (ch == '#') { // Skips chracters between '#' and a line end. + while (offset < len) { + ch = regex.charAt(offset++); + if (ch == '\r' || ch == '\n') + break; + } + continue; + } + + int next; // Strips an escaped white space. + if (ch == '\\' && offset < len) { + if ((next = regex.charAt(offset)) == '#' + || next == '\t' || next == '\n' || next == '\f' + || next == '\r' || next == ' ') { + buffer.append((char)next); + offset ++; + } else { // Other escaped character. + buffer.append((char)'\\'); + buffer.append((char)next); + offset ++; + } + } else // As is. + buffer.append((char)ch); + } + return buffer.toString(); + } + + // ================================================================ + + /** + * Sample entry. + *
    Usage: org.apache.xerces.utils.regex.REUtil <regex> <string>
    + */ + public static void main(String[] argv) { + String pattern = null; + try { + String options = ""; + String target = null; + if( argv.length == 0 ) { + System.out.println( "Error:Usage: java REUtil -i|-m|-s|-u|-w|-X regularExpression String" ); + System.exit( 0 ); + } + for (int i = 0; i < argv.length; i ++) { + if (argv[i].length() == 0 || argv[i].charAt(0) != '-') { + if (pattern == null) + pattern = argv[i]; + else if (target == null) + target = argv[i]; + else + System.err.println("Unnecessary: "+argv[i]); + } else if (argv[i].equals("-i")) { + options += "i"; + } else if (argv[i].equals("-m")) { + options += "m"; + } else if (argv[i].equals("-s")) { + options += "s"; + } else if (argv[i].equals("-u")) { + options += "u"; + } else if (argv[i].equals("-w")) { + options += "w"; + } else if (argv[i].equals("-X")) { + options += "X"; + } else { + System.err.println("Unknown option: "+argv[i]); + } + } + RegularExpression reg = new RegularExpression(pattern, options); + System.out.println("RegularExpression: "+reg); + Match match = new Match(); + reg.matches(target, match); + for (int i = 0; i < match.getNumberOfGroups(); i ++) { + if (i == 0 ) System.out.print("Matched range for the whole pattern: "); + else System.out.print("["+i+"]: "); + if (match.getBeginning(i) < 0) + System.out.println("-1"); + else { + System.out.print(match.getBeginning(i)+", "+match.getEnd(i)+", "); + System.out.println("\""+match.getCapturedText(i)+"\""); + } + } + } catch (ParseException pe) { + if (pattern == null) { + pe.printStackTrace(); + } else { + System.err.println("org.apache.xerces.utils.regex.ParseException: "+pe.getMessage()); + String indent = " "; + System.err.println(indent+pattern); + int loc = pe.getLocation(); + if (loc >= 0) { + System.err.print(indent); + for (int i = 0; i < loc; i ++) System.err.print("-"); + System.err.println("^"); + } + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + static final int CACHESIZE = 20; + static final RegularExpression[] regexCache = new RegularExpression[CACHESIZE]; + /** + * Creates a RegularExpression instance. + * This method caches created instances. + * + * @see RegularExpression#RegularExpression(java.lang.String, java.lang.String) + */ + public static RegularExpression createRegex(String pattern, String options) + throws ParseException { + RegularExpression re = null; + int intOptions = REUtil.parseOptions(options); + synchronized (REUtil.regexCache) { + int i; + for (i = 0; i < REUtil.CACHESIZE; i ++) { + RegularExpression cached = REUtil.regexCache[i]; + if (cached == null) { + i = -1; + break; + } + if (cached.equals(pattern, intOptions)) { + re = cached; + break; + } + } + if (re != null) { + if (i != 0) { + System.arraycopy(REUtil.regexCache, 0, REUtil.regexCache, 1, i); + REUtil.regexCache[0] = re; + } + } else { + re = new RegularExpression(pattern, options); + System.arraycopy(REUtil.regexCache, 0, REUtil.regexCache, 1, REUtil.CACHESIZE-1); + REUtil.regexCache[0] = re; + } + } + return re; + } + + /** + * + * @see RegularExpression#matches(java.lang.String) + */ + public static boolean matches(String regex, String target) throws ParseException { + return REUtil.createRegex(regex, null).matches(target); + } + + /** + * + * @see RegularExpression#matches(java.lang.String) + */ + public static boolean matches(String regex, String options, String target) throws ParseException { + return REUtil.createRegex(regex, options).matches(target); + } + + // ================================================================ + + /** + * + */ + public static String quoteMeta(String literal) { + int len = literal.length(); + StringBuffer buffer = null; + for (int i = 0; i < len; i ++) { + int ch = literal.charAt(i); + if (".*+?{[()|\\^$".indexOf(ch) >= 0) { + if (buffer == null) { + buffer = new StringBuffer(i+(len-i)*2); + if (i > 0) buffer.append(literal.substring(0, i)); + } + buffer.append((char)'\\'); + buffer.append((char)ch); + } else if (buffer != null) + buffer.append((char)ch); + } + return buffer != null ? buffer.toString() : literal; + } + + // ================================================================ + + static void dumpString(String v) { + for (int i = 0; i < v.length(); i ++) { + System.out.print(Integer.toHexString(v.charAt(i))); + System.out.print(" "); + } + System.out.println(); + } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/regex/RangeToken.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/regex/RangeToken.java new file mode 100644 index 000000000..482ff08b5 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/regex/RangeToken.java @@ -0,0 +1,614 @@ +/* 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.regex; + +/** + * This class represents a character class such as [a-z] or a period. + */ +final class RangeToken extends Token implements java.io.Serializable { + + int[] ranges; + boolean sorted; + boolean compacted; + RangeToken icaseCache = null; + int[] map = null; + int nonMapIndex; + + RangeToken(int type) { + super(type); + this.setSorted(false); + } + + // for RANGE or NRANGE + protected void addRange(int start, int end) { + this.icaseCache = null; + //System.err.println("Token#addRange(): "+start+" "+end); + int r1, r2; + if (start <= end) { + r1 = start; + r2 = end; + } else { + r1 = end; + r2 = start; + } + + int pos = 0; + if (this.ranges == null) { + this.ranges = new int[2]; + this.ranges[0] = r1; + this.ranges[1] = r2; + this.setSorted(true); + } else { + pos = this.ranges.length; + if (this.ranges[pos-1]+1 == r1) { + this.ranges[pos-1] = r2; + return; + } + int[] temp = new int[pos+2]; + System.arraycopy(this.ranges, 0, temp, 0, pos); + this.ranges = temp; + if (this.ranges[pos-1] >= r1) + this.setSorted(false); + this.ranges[pos++] = r1; + this.ranges[pos] = r2; + if (!this.sorted) + this.sortRanges(); + } + } + + private final boolean isSorted() { + return this.sorted; + } + private final void setSorted(boolean sort) { + this.sorted = sort; + if (!sort) this.compacted = false; + } + private final boolean isCompacted() { + return this.compacted; + } + private final void setCompacted() { + this.compacted = true; + } + + protected void sortRanges() { + if (this.isSorted()) + return; + if (this.ranges == null) + return; + //System.err.println("Do sorting: "+this.ranges.length); + + // Bubble sort + // Why? -- In many cases, + // this.ranges has few elements. + for (int i = this.ranges.length-4; i >= 0; i -= 2) { + for (int j = 0; j <= i; j += 2) { + if (this.ranges[j] > this.ranges[j+2] + || this.ranges[j] == this.ranges[j+2] && this.ranges[j+1] > this.ranges[j+3]) { + int tmp; + tmp = this.ranges[j+2]; + this.ranges[j+2] = this.ranges[j]; + this.ranges[j] = tmp; + tmp = this.ranges[j+3]; + this.ranges[j+3] = this.ranges[j+1]; + this.ranges[j+1] = tmp; + } + } + } + this.setSorted(true); + } + + /** + * this.ranges is sorted. + */ + protected void compactRanges() { + boolean DEBUG = false; + if (this.ranges == null || this.ranges.length <= 2) + return; + if (this.isCompacted()) + return; + int base = 0; // Index of writing point + int target = 0; // Index of processing point + + while (target < this.ranges.length) { + if (base != target) { + this.ranges[base] = this.ranges[target++]; + this.ranges[base+1] = this.ranges[target++]; + } else + target += 2; + int baseend = this.ranges[base+1]; + while (target < this.ranges.length) { + if (baseend+1 < this.ranges[target]) + break; + if (baseend+1 == this.ranges[target]) { + if (DEBUG) + System.err.println("Token#compactRanges(): Compaction: ["+this.ranges[base] + +", "+this.ranges[base+1] + +"], ["+this.ranges[target] + +", "+this.ranges[target+1] + +"] -> ["+this.ranges[base] + +", "+this.ranges[target+1] + +"]"); + this.ranges[base+1] = this.ranges[target+1]; + baseend = this.ranges[base+1]; + target += 2; + } else if (baseend >= this.ranges[target+1]) { + if (DEBUG) + System.err.println("Token#compactRanges(): Compaction: ["+this.ranges[base] + +", "+this.ranges[base+1] + +"], ["+this.ranges[target] + +", "+this.ranges[target+1] + +"] -> ["+this.ranges[base] + +", "+this.ranges[base+1] + +"]"); + target += 2; + } else if (baseend < this.ranges[target+1]) { + if (DEBUG) + System.err.println("Token#compactRanges(): Compaction: ["+this.ranges[base] + +", "+this.ranges[base+1] + +"], ["+this.ranges[target] + +", "+this.ranges[target+1] + +"] -> ["+this.ranges[base] + +", "+this.ranges[target+1] + +"]"); + this.ranges[base+1] = this.ranges[target+1]; + baseend = this.ranges[base+1]; + target += 2; + } else { + throw new RuntimeException("Token#compactRanges(): Internel Error: [" + +this.ranges[base] + +","+this.ranges[base+1] + +"] ["+this.ranges[target] + +","+this.ranges[target+1]+"]"); + } + } // while + base += 2; + } + + if (base != this.ranges.length) { + int[] result = new int[base]; + System.arraycopy(this.ranges, 0, result, 0, base); + this.ranges = result; + } + this.setCompacted(); + } + + protected void mergeRanges(Token token) { + RangeToken tok = (RangeToken)token; + this.sortRanges(); + tok.sortRanges(); + if (tok.ranges == null) + return; + this.icaseCache = null; + this.setSorted(true); + if (this.ranges == null) { + this.ranges = new int[tok.ranges.length]; + System.arraycopy(tok.ranges, 0, this.ranges, 0, tok.ranges.length); + return; + } + int[] result = new int[this.ranges.length+tok.ranges.length]; + for (int i = 0, j = 0, k = 0; i < this.ranges.length || j < tok.ranges.length;) { + if (i >= this.ranges.length) { + result[k++] = tok.ranges[j++]; + result[k++] = tok.ranges[j++]; + } else if (j >= tok.ranges.length) { + result[k++] = this.ranges[i++]; + result[k++] = this.ranges[i++]; + } else if (tok.ranges[j] < this.ranges[i] + || tok.ranges[j] == this.ranges[i] && tok.ranges[j+1] < this.ranges[i+1]) { + result[k++] = tok.ranges[j++]; + result[k++] = tok.ranges[j++]; + } else { + result[k++] = this.ranges[i++]; + result[k++] = this.ranges[i++]; + } + } + this.ranges = result; + } + + protected void subtractRanges(Token token) { + if (token.type == NRANGE) { + this.intersectRanges(token); + return; + } + RangeToken tok = (RangeToken)token; + if (tok.ranges == null || this.ranges == null) + return; + this.icaseCache = null; + this.sortRanges(); + this.compactRanges(); + tok.sortRanges(); + tok.compactRanges(); + + //System.err.println("Token#substractRanges(): Entry: "+this.ranges.length+", "+tok.ranges.length); + + int[] result = new int[this.ranges.length+tok.ranges.length]; + int wp = 0, src = 0, sub = 0; + while (src < this.ranges.length && sub < tok.ranges.length) { + int srcbegin = this.ranges[src]; + int srcend = this.ranges[src+1]; + int subbegin = tok.ranges[sub]; + int subend = tok.ranges[sub+1]; + if (srcend < subbegin) { // Not overlapped + // src: o-----o + // sub: o-----o + // res: o-----o + // Reuse sub + result[wp++] = this.ranges[src++]; + result[wp++] = this.ranges[src++]; + } else if (srcend >= subbegin + && srcbegin <= subend) { // Overlapped + // src: o--------o + // sub: o----o + // sub: o----o + // sub: o----o + // sub: o------------o + if (subbegin <= srcbegin && srcend <= subend) { + // src: o--------o + // sub: o------------o + // res: empty + // Reuse sub + src += 2; + } else if (subbegin <= srcbegin) { + // src: o--------o + // sub: o----o + // res: o-----o + // Reuse src(=res) + this.ranges[src] = subend+1; + sub += 2; + } else if (srcend <= subend) { + // src: o--------o + // sub: o----o + // res: o-----o + // Reuse sub + result[wp++] = srcbegin; + result[wp++] = subbegin-1; + src += 2; + } else { + // src: o--------o + // sub: o----o + // res: o-o o-o + // Reuse src(=right res) + result[wp++] = srcbegin; + result[wp++] = subbegin-1; + this.ranges[src] = subend+1; + sub += 2; + } + } else if (subend < srcbegin) { + // Not overlapped + // src: o-----o + // sub: o----o + sub += 2; + } else { + throw new RuntimeException("Token#subtractRanges(): Internal Error: ["+this.ranges[src] + +","+this.ranges[src+1] + +"] - ["+tok.ranges[sub] + +","+tok.ranges[sub+1] + +"]"); + } + } + while (src < this.ranges.length) { + result[wp++] = this.ranges[src++]; + result[wp++] = this.ranges[src++]; + } + this.ranges = new int[wp]; + System.arraycopy(result, 0, this.ranges, 0, wp); + // this.ranges is sorted and compacted. + } + + /** + * @param tok Ignore whether it is NRANGE or not. + */ + protected void intersectRanges(Token token) { + RangeToken tok = (RangeToken)token; + if (tok.ranges == null || this.ranges == null) + return; + this.icaseCache = null; + this.sortRanges(); + this.compactRanges(); + tok.sortRanges(); + tok.compactRanges(); + + int[] result = new int[this.ranges.length+tok.ranges.length]; + int wp = 0, src1 = 0, src2 = 0; + while (src1 < this.ranges.length && src2 < tok.ranges.length) { + int src1begin = this.ranges[src1]; + int src1end = this.ranges[src1+1]; + int src2begin = tok.ranges[src2]; + int src2end = tok.ranges[src2+1]; + if (src1end < src2begin) { // Not overlapped + // src1: o-----o + // src2: o-----o + // res: empty + // Reuse src2 + src1 += 2; + } else if (src1end >= src2begin + && src1begin <= src2end) { // Overlapped + // src1: o--------o + // src2: o----o + // src2: o----o + // src2: o----o + // src2: o------------o + if (src2begin <= src2begin && src1end <= src2end) { + // src1: o--------o + // src2: o------------o + // res: o--------o + // Reuse src2 + result[wp++] = src1begin; + result[wp++] = src1end; + src1 += 2; + } else if (src2begin <= src1begin) { + // src1: o--------o + // src2: o----o + // res: o--o + // Reuse the rest of src1 + result[wp++] = src1begin; + result[wp++] = src2end; + this.ranges[src1] = src2end+1; + src2 += 2; + } else if (src1end <= src2end) { + // src1: o--------o + // src2: o----o + // res: o--o + // Reuse src2 + result[wp++] = src2begin; + result[wp++] = src1end; + src1 += 2; + } else { + // src1: o--------o + // src2: o----o + // res: o----o + // Reuse the rest of src1 + result[wp++] = src2begin; + result[wp++] = src2end; + this.ranges[src1] = src2end+1; + } + } else if (src2end < src1begin) { + // Not overlapped + // src1: o-----o + // src2: o----o + src2 += 2; + } else { + throw new RuntimeException("Token#intersectRanges(): Internal Error: [" + +this.ranges[src1] + +","+this.ranges[src1+1] + +"] & ["+tok.ranges[src2] + +","+tok.ranges[src2+1] + +"]"); + } + } + while (src1 < this.ranges.length) { + result[wp++] = this.ranges[src1++]; + result[wp++] = this.ranges[src1++]; + } + this.ranges = new int[wp]; + System.arraycopy(result, 0, this.ranges, 0, wp); + // this.ranges is sorted and compacted. + } + + /** + * for RANGE: Creates complement. + * for NRANGE: Creates the same meaning RANGE. + */ + static Token complementRanges(Token token) { + if (token.type != RANGE && token.type != NRANGE) + throw new IllegalArgumentException("Token#complementRanges(): must be RANGE: "+token.type); + RangeToken tok = (RangeToken)token; + tok.sortRanges(); + tok.compactRanges(); + int len = tok.ranges.length+2; + if (tok.ranges[0] == 0) + len -= 2; + int last = tok.ranges[tok.ranges.length-1]; + if (last == UTF16_MAX) + len -= 2; + RangeToken ret = Token.createRange(); + ret.ranges = new int[len]; + int wp = 0; + if (tok.ranges[0] > 0) { + ret.ranges[wp++] = 0; + ret.ranges[wp++] = tok.ranges[0]-1; + } + for (int i = 1; i < tok.ranges.length-2; i += 2) { + ret.ranges[wp++] = tok.ranges[i]+1; + ret.ranges[wp++] = tok.ranges[i+1]-1; + } + if (last != UTF16_MAX) { + ret.ranges[wp++] = last+1; + ret.ranges[wp] = UTF16_MAX; + } + ret.setCompacted(); + return ret; + } + + synchronized RangeToken getCaseInsensitiveToken() { + if (this.icaseCache != null) + return this.icaseCache; + + RangeToken uppers = this.type == Token.RANGE ? Token.createRange() : Token.createNRange(); + for (int i = 0; i < this.ranges.length; i += 2) { + for (int ch = this.ranges[i]; ch <= this.ranges[i+1]; ch ++) { + if (ch > 0xffff) + uppers.addRange(ch, ch); + else { + char uch = Character.toUpperCase((char)ch); + uppers.addRange(uch, uch); + } + } + } + RangeToken lowers = this.type == Token.RANGE ? Token.createRange() : Token.createNRange(); + for (int i = 0; i < uppers.ranges.length; i += 2) { + for (int ch = uppers.ranges[i]; ch <= uppers.ranges[i+1]; ch ++) { + if (ch > 0xffff) + lowers.addRange(ch, ch); + else { + char uch = Character.toUpperCase((char)ch); + lowers.addRange(uch, uch); + } + } + } + lowers.mergeRanges(uppers); + lowers.mergeRanges(this); + lowers.compactRanges(); + + this.icaseCache = lowers; + return lowers; + } + + void dumpRanges() { + System.err.print("RANGE: "); + if (this.ranges == null) + System.err.println(" NULL"); + for (int i = 0; i < this.ranges.length; i += 2) { + System.err.print("["+this.ranges[i]+","+this.ranges[i+1]+"] "); + } + System.err.println(""); + } + + boolean match(int ch) { + if (this.map == null) this.createMap(); + boolean ret; + if (this.type == RANGE) { + if (ch < MAPSIZE) + return (this.map[ch/32] & (1<<(ch&0x1f))) != 0; + ret = false; + for (int i = this.nonMapIndex; i < this.ranges.length; i += 2) { + if (this.ranges[i] <= ch && ch <= this.ranges[i+1]) + return true; + } + } else { + if (ch < MAPSIZE) + return (this.map[ch/32] & (1<<(ch&0x1f))) == 0; + ret = true; + for (int i = this.nonMapIndex; i < this.ranges.length; i += 2) { + if (this.ranges[i] <= ch && ch <= this.ranges[i+1]) + return false; + } + } + return ret; + } + + private static final int MAPSIZE = 256; + private void createMap() { + int asize = MAPSIZE/32; // 32 is the number of bits in `int'. + // CHANGE(radup) we need a new map, since this is not synchronized + // and if we init the instance map with 0's it's going to be trouble + // -this.map = new int[asize]; + // -this.nonMapIndex = this.ranges.length; + // -for (int i = 0; i < asize; i++) this.map[i] = 0; + int[] localmap = new int[asize]; // + + int localnonMapIndex = this.ranges.length; // + + for (int i = 0; i < asize; i ++) localmap[i] = 0; // + redundant + for (int i = 0; i < this.ranges.length; i += 2) { + int s = this.ranges[i]; + int e = this.ranges[i+1]; + if (s < MAPSIZE) { + for (int j = s; j <= e && j < MAPSIZE; j ++) + localmap[j/32] |= 1<<(j&0x1f); // s&0x1f : 0-31 + } else { + localnonMapIndex = i; + break; + } + if (e >= MAPSIZE) { + localnonMapIndex = i; + break; + } + } + this.nonMapIndex = localnonMapIndex; // + + this.map = localmap; // + + //for (int i = 0; i < asize; i ++) System.err.println("Map: "+Integer.toString(this.map[i], 16)); + } + + public String toString(int options) { + String ret; + if (this.type == RANGE) { + if (this == Token.token_dot) + ret = "."; + else if (this == Token.token_0to9) + ret = "\\d"; + else if (this == Token.token_wordchars) + ret = "\\w"; + else if (this == Token.token_spaces) + ret = "\\s"; + else { + StringBuffer sb = new StringBuffer(); + sb.append("["); + for (int i = 0; i < this.ranges.length; i += 2) { + if ((options & RegularExpression.SPECIAL_COMMA) != 0 && i > 0) sb.append(","); + if (this.ranges[i] == this.ranges[i+1]) { + sb.append(escapeCharInCharClass(this.ranges[i])); + } else { + sb.append(escapeCharInCharClass(this.ranges[i])); + sb.append((char)'-'); + sb.append(escapeCharInCharClass(this.ranges[i+1])); + } + } + sb.append("]"); + ret = sb.toString(); + } + } else { + if (this == Token.token_not_0to9) + ret = "\\D"; + else if (this == Token.token_not_wordchars) + ret = "\\W"; + else if (this == Token.token_not_spaces) + ret = "\\S"; + else { + StringBuffer sb = new StringBuffer(); + sb.append("[^"); + for (int i = 0; i < this.ranges.length; i += 2) { + if ((options & RegularExpression.SPECIAL_COMMA) != 0 && i > 0) sb.append(","); + if (this.ranges[i] == this.ranges[i+1]) { + sb.append(escapeCharInCharClass(this.ranges[i])); + } else { + sb.append(escapeCharInCharClass(this.ranges[i])); + sb.append('-'); + sb.append(escapeCharInCharClass(this.ranges[i+1])); + } + } + sb.append("]"); + ret = sb.toString(); + } + } + return ret; + } + + private static String escapeCharInCharClass(int ch) { + String ret; + switch (ch) { + case '[': case ']': case '-': case '^': + case ',': case '\\': + ret = "\\"+(char)ch; + break; + case '\f': ret = "\\f"; break; + case '\n': ret = "\\n"; break; + case '\r': ret = "\\r"; break; + case '\t': ret = "\\t"; break; + case 0x1b: ret = "\\e"; break; + //case 0x0b: ret = "\\v"; break; + default: + if (ch < 0x20) { + String pre = "0"+Integer.toHexString(ch); + ret = "\\x"+pre.substring(pre.length()-2, pre.length()); + } else if (ch >= 0x10000) { + String pre = "0"+Integer.toHexString(ch); + ret = "\\v"+pre.substring(pre.length()-6, pre.length()); + } else + ret = ""+(char)ch; + } + return ret; + } + +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/regex/RegexParser.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/regex/RegexParser.java new file mode 100644 index 000000000..e2b0ec12d --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/regex/RegexParser.java @@ -0,0 +1,1080 @@ +/* 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.regex; + +import java.util.Locale; +import java.util.MissingResourceException; +import java.util.ResourceBundle; +import java.util.Vector; + +/** + * A Regular Expression Parser. + */ +class RegexParser { + static final int T_CHAR = 0; + static final int T_EOF = 1; + static final int T_OR = 2; // '|' + static final int T_STAR = 3; // '*' + static final int T_PLUS = 4; // '+' + static final int T_QUESTION = 5; // '?' + static final int T_LPAREN = 6; // '(' + static final int T_RPAREN = 7; // ')' + static final int T_DOT = 8; // '.' + static final int T_LBRACKET = 9; // '[' + static final int T_BACKSOLIDUS = 10; // '\' + static final int T_CARET = 11; // '^' + static final int T_DOLLAR = 12; // '$' + static final int T_LPAREN2 = 13; // '(?:' + static final int T_LOOKAHEAD = 14; // '(?=' + static final int T_NEGATIVELOOKAHEAD = 15; // '(?!' + static final int T_LOOKBEHIND = 16; // '(?<=' + static final int T_NEGATIVELOOKBEHIND = 17; // '(?' + static final int T_SET_OPERATIONS = 19; // '(?[' + static final int T_POSIX_CHARCLASS_START = 20; // '[:' in a character class + static final int T_COMMENT = 21; // '(?#' + static final int T_MODIFIERS = 22; // '(?' [\-,a-z,A-Z] + static final int T_CONDITION = 23; // '(?(' + static final int T_XMLSCHEMA_CC_SUBTRACTION = 24; // '-[' in a character class + + static class ReferencePosition { + int refNumber; + int position; + ReferencePosition(int n, int pos) { + this.refNumber = n; + this.position = pos; + } + } + + int offset; + String regex; + int regexlen; + int options; + ResourceBundle resources; + int chardata; + int nexttoken; + static protected final int S_NORMAL = 0; + static protected final int S_INBRACKETS = 1; + static protected final int S_INXBRACKETS = 2; + int context = S_NORMAL; + int parennumber = 1; + boolean hasBackReferences; + Vector references = null; + + public RegexParser() { + this.setLocale(Locale.getDefault()); + } + public RegexParser(Locale locale) { + this.setLocale(locale); + } + + public void setLocale(Locale locale) { + try { + this.resources = ResourceBundle.getBundle("org.apache.xmlbeans.impl.regex.message", locale); + } catch (MissingResourceException mre) { + throw new RuntimeException("Installation Problem??? Couldn't load messages: " + +mre.getMessage()); + } + } + + final ParseException ex(String key, int loc) { + return new ParseException(this.resources.getString(key), loc); + } + + private final boolean isSet(int flag) { + return (this.options & flag) == flag; + } + + synchronized Token parse(String regex, int options) throws ParseException { + this.options = options; + this.offset = 0; + this.setContext(S_NORMAL); + this.parennumber = 1; + this.hasBackReferences = false; + this.regex = regex; + if (this.isSet(RegularExpression.EXTENDED_COMMENT)) + this.regex = REUtil.stripExtendedComment(this.regex); + this.regexlen = this.regex.length(); + + + this.next(); + Token ret = this.parseRegex(); + if (this.offset != this.regexlen) + throw ex("parser.parse.1", this.offset); + if (this.references != null) { + for (int i = 0; i < this.references.size(); i ++) { + ReferencePosition position = (ReferencePosition)this.references.elementAt(i); + if (this.parennumber <= position.refNumber) + throw ex("parser.parse.2", position.position); + } + this.references.removeAllElements(); + } + return ret; + } + + /* + public RegularExpression createRegex(String regex, int options) throws ParseException { + Token tok = this.parse(regex, options); + return new RegularExpression(regex, tok, this.parennumber, this.hasBackReferences, options); + } + */ + + protected final void setContext(int con) { + this.context = con; + } + + final int read() { + return this.nexttoken; + } + + final void next() { + if (this.offset >= this.regexlen) { + this.chardata = -1; + this.nexttoken = T_EOF; + return; + } + + int ret; + int ch = this.regex.charAt(this.offset++); + this.chardata = ch; + + if (this.context == S_INBRACKETS) { + // In a character class, this.chardata has one character, that is to say, + // a pair of surrogates is composed and stored to this.chardata. + switch (ch) { + case '\\': + ret = T_BACKSOLIDUS; + if (this.offset >= this.regexlen) + throw ex("parser.next.1", this.offset-1); + this.chardata = this.regex.charAt(this.offset++); + break; + + case '-': + if (this.isSet(RegularExpression.XMLSCHEMA_MODE) + && this.offset < this.regexlen && this.regex.charAt(this.offset) == '[') { + this.offset++; + ret = T_XMLSCHEMA_CC_SUBTRACTION; + } else + ret = T_CHAR; + break; + + case '[': + if (!this.isSet(RegularExpression.XMLSCHEMA_MODE) + && this.offset < this.regexlen && this.regex.charAt(this.offset) == ':') { + this.offset++; + ret = T_POSIX_CHARCLASS_START; + break; + } // Through down + default: + if (REUtil.isHighSurrogate(ch) && this.offset < this.regexlen) { + int low = this.regex.charAt(this.offset); + if (REUtil.isLowSurrogate(low)) { + this.chardata = REUtil.composeFromSurrogates(ch, low); + this.offset ++; + } + } + ret = T_CHAR; + } + this.nexttoken = ret; + return; + } + + switch (ch) { + case '|': ret = T_OR; break; + case '*': ret = T_STAR; break; + case '+': ret = T_PLUS; break; + case '?': ret = T_QUESTION; break; + case ')': ret = T_RPAREN; break; + case '.': ret = T_DOT; break; + case '[': ret = T_LBRACKET; break; + case '^': ret = T_CARET; break; + case '$': ret = T_DOLLAR; break; + case '(': + ret = T_LPAREN; + if (this.offset >= this.regexlen) + break; + if (this.regex.charAt(this.offset) != '?') + break; + if (++this.offset >= this.regexlen) + throw ex("parser.next.2", this.offset-1); + ch = this.regex.charAt(this.offset++); + switch (ch) { + case ':': ret = T_LPAREN2; break; + case '=': ret = T_LOOKAHEAD; break; + case '!': ret = T_NEGATIVELOOKAHEAD; break; + case '[': ret = T_SET_OPERATIONS; break; + case '>': ret = T_INDEPENDENT; break; + case '<': + if (this.offset >= this.regexlen) + throw ex("parser.next.2", this.offset-3); + ch = this.regex.charAt(this.offset++); + if (ch == '=') { + ret = T_LOOKBEHIND; + } else if (ch == '!') { + ret = T_NEGATIVELOOKBEHIND; + } else + throw ex("parser.next.3", this.offset-3); + break; + case '#': + while (this.offset < this.regexlen) { + ch = this.regex.charAt(this.offset++); + if (ch == ')') break; + } + if (ch != ')') + throw ex("parser.next.4", this.offset-1); + ret = T_COMMENT; + break; + default: + if (ch == '-' || 'a' <= ch && ch <= 'z' || 'A' <= ch && ch <= 'Z') {// Options + this.offset --; + ret = T_MODIFIERS; + break; + } else if (ch == '(') { // conditional + ret = T_CONDITION; // this.offsets points the next of '('. + break; + } + throw ex("parser.next.2", this.offset-2); + } + break; + + case '\\': + ret = T_BACKSOLIDUS; + if (this.offset >= this.regexlen) + throw ex("parser.next.1", this.offset-1); + this.chardata = this.regex.charAt(this.offset++); + break; + + default: + ret = T_CHAR; + } + this.nexttoken = ret; + } + + /** + * regex ::= term (`|` term)* + * term ::= factor+ + * factor ::= ('^' | '$' | '\A' | '\Z' | '\z' | '\b' | '\B' | '\<' | '\>' + * | atom (('*' | '+' | '?' | minmax ) '?'? )?) + * | '(?=' regex ')' | '(?!' regex ')' | '(?<=' regex ')' | '(?<!' regex ')' + * atom ::= char | '.' | range | '(' regex ')' | '(?:' regex ')' | '\' [0-9] + * | '\w' | '\W' | '\d' | '\D' | '\s' | '\S' | category-block + */ + Token parseRegex() throws ParseException { + Token tok = this.parseTerm(); + Token parent = null; + while (this.read() == T_OR) { + this.next(); // '|' + if (parent == null) { + parent = Token.createUnion(); + parent.addChild(tok); + tok = parent; + } + tok.addChild(this.parseTerm()); + } + return tok; + } + + /** + * term ::= factor+ + */ + Token parseTerm() throws ParseException { + int ch = this.read(); + if (ch == T_OR || ch == T_RPAREN || ch == T_EOF) { + return Token.createEmpty(); + } else { + Token tok = this.parseFactor(); + Token concat = null; + while ((ch = this.read()) != T_OR && ch != T_RPAREN && ch != T_EOF) { + if (concat == null) { + concat = Token.createConcat(); + concat.addChild(tok); + tok = concat; + } + concat.addChild(this.parseFactor()); + //tok = Token.createConcat(tok, this.parseFactor()); + } + return tok; + } + } + + // ---------------------------------------------------------------- + + Token processCaret() throws ParseException { + this.next(); + return Token.token_linebeginning; + } + Token processDollar() throws ParseException { + this.next(); + return Token.token_lineend; + } + Token processLookahead() throws ParseException { + this.next(); + Token tok = Token.createLook(Token.LOOKAHEAD, this.parseRegex()); + if (this.read() != T_RPAREN) throw ex("parser.factor.1", this.offset-1); + this.next(); // ')' + return tok; + } + Token processNegativelookahead() throws ParseException { + this.next(); + Token tok = Token.createLook(Token.NEGATIVELOOKAHEAD, this.parseRegex()); + if (this.read() != T_RPAREN) throw ex("parser.factor.1", this.offset-1); + this.next(); // ')' + return tok; + } + Token processLookbehind() throws ParseException { + this.next(); + Token tok = Token.createLook(Token.LOOKBEHIND, this.parseRegex()); + if (this.read() != T_RPAREN) throw ex("parser.factor.1", this.offset-1); + this.next(); // ')' + return tok; + } + Token processNegativelookbehind() throws ParseException { + this.next(); + Token tok = Token.createLook(Token.NEGATIVELOOKBEHIND, this.parseRegex()); + if (this.read() != T_RPAREN) throw ex("parser.factor.1", this.offset-1); + this.next(); // ')' + return tok; + } + Token processBacksolidus_A() throws ParseException { + this.next(); + return Token.token_stringbeginning; + } + Token processBacksolidus_Z() throws ParseException { + this.next(); + return Token.token_stringend2; + } + Token processBacksolidus_z() throws ParseException { + this.next(); + return Token.token_stringend; + } + Token processBacksolidus_b() throws ParseException { + this.next(); + return Token.token_wordedge; + } + Token processBacksolidus_B() throws ParseException { + this.next(); + return Token.token_not_wordedge; + } + Token processBacksolidus_lt() throws ParseException { + this.next(); + return Token.token_wordbeginning; + } + Token processBacksolidus_gt() throws ParseException { + this.next(); + return Token.token_wordend; + } + Token processStar(Token tok) throws ParseException { + this.next(); + if (this.read() == T_QUESTION) { + this.next(); + return Token.createNGClosure(tok); + } else + return Token.createClosure(tok); + } + Token processPlus(Token tok) throws ParseException { + // X+ -> XX* + this.next(); + if (this.read() == T_QUESTION) { + this.next(); + return Token.createConcat(tok, Token.createNGClosure(tok)); + } else + return Token.createConcat(tok, Token.createClosure(tok)); + } + Token processQuestion(Token tok) throws ParseException { + // X? -> X| + this.next(); + Token par = Token.createUnion(); + if (this.read() == T_QUESTION) { + this.next(); + par.addChild(Token.createEmpty()); + par.addChild(tok); + } else { + par.addChild(tok); + par.addChild(Token.createEmpty()); + } + return par; + } + boolean checkQuestion(int off) { + return off < this.regexlen && this.regex.charAt(off) == '?'; + } + Token processParen() throws ParseException { + this.next(); + int p = this.parennumber++; + Token tok = Token.createParen(this.parseRegex(), p); + if (this.read() != T_RPAREN) throw ex("parser.factor.1", this.offset-1); + this.next(); // Skips ')' + return tok; + } + Token processParen2() throws ParseException { + this.next(); + Token tok = Token.createParen(this.parseRegex(), 0); + if (this.read() != T_RPAREN) throw ex("parser.factor.1", this.offset-1); + this.next(); // Skips ')' + return tok; + } + Token processCondition() throws ParseException { + // this.offset points the next of '(' + if (this.offset+1 >= this.regexlen) throw ex("parser.factor.4", this.offset); + // Parses a condition. + int refno = -1; + Token condition = null; + int ch = this.regex.charAt(this.offset); + if ('1' <= ch && ch <= '9') { + refno = ch-'0'; + this.hasBackReferences = true; + if (this.references == null) this.references = new Vector(); + this.references.addElement(new ReferencePosition(refno, this.offset)); + this.offset ++; + if (this.regex.charAt(this.offset) != ')') throw ex("parser.factor.1", this.offset); + this.offset ++; + } else { + if (ch == '?') this.offset --; // Points '('. + this.next(); + condition = this.parseFactor(); + switch (condition.type) { + case Token.LOOKAHEAD: + case Token.NEGATIVELOOKAHEAD: + case Token.LOOKBEHIND: + case Token.NEGATIVELOOKBEHIND: + break; + case Token.ANCHOR: + if (this.read() != T_RPAREN) throw ex("parser.factor.1", this.offset-1); + break; + default: + throw ex("parser.factor.5", this.offset); + } + } + // Parses yes/no-patterns. + this.next(); + Token yesPattern = this.parseRegex(); + Token noPattern = null; + if (yesPattern.type == Token.UNION) { + if (yesPattern.size() != 2) throw ex("parser.factor.6", this.offset); + noPattern = yesPattern.getChild(1); + yesPattern = yesPattern.getChild(0); + } + if (this.read() != T_RPAREN) throw ex("parser.factor.1", this.offset-1); + this.next(); + return Token.createCondition(refno, condition, yesPattern, noPattern); + } + Token processModifiers() throws ParseException { + // this.offset points the next of '?'. + // modifiers ::= [imsw]* ('-' [imsw]*)? ':' + int add = 0, mask = 0, ch = -1; + while (this.offset < this.regexlen) { + ch = this.regex.charAt(this.offset); + int v = REUtil.getOptionValue(ch); + if (v == 0) break; // '-' or ':'? + add |= v; + this.offset ++; + } + if (this.offset >= this.regexlen) throw ex("parser.factor.2", this.offset-1); + if (ch == '-') { + this.offset ++; + while (this.offset < this.regexlen) { + ch = this.regex.charAt(this.offset); + int v = REUtil.getOptionValue(ch); + if (v == 0) break; // ':'? + mask |= v; + this.offset ++; + } + if (this.offset >= this.regexlen) throw ex("parser.factor.2", this.offset-1); + } + Token tok; + if (ch == ':') { + this.offset ++; + this.next(); + tok = Token.createModifierGroup(this.parseRegex(), add, mask); + if (this.read() != T_RPAREN) throw ex("parser.factor.1", this.offset-1); + this.next(); + } else if (ch == ')') { // such as (?-i) + this.offset ++; + this.next(); + tok = Token.createModifierGroup(this.parseRegex(), add, mask); + } else + throw ex("parser.factor.3", this.offset); + + return tok; + } + Token processIndependent() throws ParseException { + this.next(); + Token tok = Token.createLook(Token.INDEPENDENT, this.parseRegex()); + if (this.read() != T_RPAREN) throw ex("parser.factor.1", this.offset-1); + this.next(); // Skips ')' + return tok; + } + Token processBacksolidus_c() throws ParseException { + int ch2; // Must be in 0x0040-0x005f + if (this.offset >= this.regexlen + || ((ch2 = this.regex.charAt(this.offset++)) & 0xffe0) != 0x0040) + throw ex("parser.atom.1", this.offset-1); + this.next(); + return Token.createChar(ch2-0x40); + } + Token processBacksolidus_C() throws ParseException { + throw ex("parser.process.1", this.offset); + } + Token processBacksolidus_i() throws ParseException { + Token tok = Token.createChar('i'); + this.next(); + return tok; + } + Token processBacksolidus_I() throws ParseException { + throw ex("parser.process.1", this.offset); + } + Token processBacksolidus_g() throws ParseException { + this.next(); + return Token.getGraphemePattern(); + } + Token processBacksolidus_X() throws ParseException { + this.next(); + return Token.getCombiningCharacterSequence(); + } + Token processBackreference() throws ParseException { + int refnum = this.chardata-'0'; + Token tok = Token.createBackReference(refnum); + this.hasBackReferences = true; + if (this.references == null) this.references = new Vector(); + this.references.addElement(new ReferencePosition(refnum, this.offset-2)); + this.next(); + return tok; + } + + // ---------------------------------------------------------------- + + /** + * factor ::= ('^' | '$' | '\A' | '\Z' | '\z' | '\b' | '\B' | '\<' | '\>' + * | atom (('*' | '+' | '?' | minmax ) '?'? )?) + * | '(?=' regex ')' | '(?!' regex ')' | '(?<=' regex ')' | '(?<!' regex ')' + * | '(?#' [^)]* ')' + * minmax ::= '{' min (',' max?)? '}' + * min ::= [0-9]+ + * max ::= [0-9]+ + */ + Token parseFactor() throws ParseException { + int ch = this.read(); + Token tok; + switch (ch) { + case T_CARET: return this.processCaret(); + case T_DOLLAR: return this.processDollar(); + case T_LOOKAHEAD: return this.processLookahead(); + case T_NEGATIVELOOKAHEAD: return this.processNegativelookahead(); + case T_LOOKBEHIND: return this.processLookbehind(); + case T_NEGATIVELOOKBEHIND: return this.processNegativelookbehind(); + + case T_COMMENT: + this.next(); + return Token.createEmpty(); + + case T_BACKSOLIDUS: + switch (this.chardata) { + case 'A': return this.processBacksolidus_A(); + case 'Z': return this.processBacksolidus_Z(); + case 'z': return this.processBacksolidus_z(); + case 'b': return this.processBacksolidus_b(); + case 'B': return this.processBacksolidus_B(); + case '<': return this.processBacksolidus_lt(); + case '>': return this.processBacksolidus_gt(); + } + // through down + } + tok = this.parseAtom(); + ch = this.read(); + switch (ch) { + case T_STAR: return this.processStar(tok); + case T_PLUS: return this.processPlus(tok); + case T_QUESTION: return this.processQuestion(tok); + case T_CHAR: + if (this.chardata == '{' && this.offset < this.regexlen) { + + int off = this.offset; // this.offset -> next of '{' + int min = 0, max = -1; + + if ((ch = this.regex.charAt(off++)) >= '0' && ch <= '9') { + + min = ch -'0'; + while (off < this.regexlen + && (ch = this.regex.charAt(off++)) >= '0' && ch <= '9') { + min = min*10 +ch-'0'; + if (min < 0) + throw ex("parser.quantifier.5", this.offset); + } + } + else { + throw ex("parser.quantifier.1", this.offset); + } + + max = min; + if (ch == ',') { + + if (off >= this.regexlen) { + throw ex("parser.quantifier.3", this.offset); + } + else if ((ch = this.regex.charAt(off++)) >= '0' && ch <= '9') { + + max = ch -'0'; // {min,max} + while (off < this.regexlen + && (ch = this.regex.charAt(off++)) >= '0' + && ch <= '9') { + max = max*10 +ch-'0'; + if (max < 0) + throw ex("parser.quantifier.5", this.offset); + } + + if (min > max) + throw ex("parser.quantifier.4", this.offset); + } + else { // assume {min,} + max = -1; + } + } + + if (ch != '}') + throw ex("parser.quantifier.2", this.offset); + + if (this.checkQuestion(off)) { // off -> next of '}' + tok = Token.createNGClosure(tok); + this.offset = off+1; + } else { + tok = Token.createClosure(tok); + this.offset = off; + } + + tok.setMin(min); + tok.setMax(max); + //System.err.println("CLOSURE: "+min+", "+max); + this.next(); + } + } + return tok; + } + + /** + * atom ::= char | '.' | char-class | '(' regex ')' | '(?:' regex ')' | '\' [0-9] + * | '\w' | '\W' | '\d' | '\D' | '\s' | '\S' | category-block + * | '(?>' regex ')' + * char ::= '\\' | '\' [efnrt] | bmp-code | character-1 + */ + Token parseAtom() throws ParseException { + int ch = this.read(); + Token tok = null; + switch (ch) { + case T_LPAREN: return this.processParen(); + case T_LPAREN2: return this.processParen2(); // '(?:' + case T_CONDITION: return this.processCondition(); // '(?(' + case T_MODIFIERS: return this.processModifiers(); // (?modifiers ... ) + case T_INDEPENDENT: return this.processIndependent(); + case T_DOT: + this.next(); // Skips '.' + tok = Token.token_dot; + break; + + /** + * char-class ::= '[' ( '^'? range ','?)+ ']' + * range ::= '\d' | '\w' | '\s' | category-block | range-char + * | range-char '-' range-char + * range-char ::= '\[' | '\]' | '\\' | '\' [,-efnrtv] | bmp-code | character-2 + * bmp-char ::= '\' 'u' [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F] + */ + case T_LBRACKET: return this.parseCharacterClass(true); + case T_SET_OPERATIONS: return this.parseSetOperations(); + + case T_BACKSOLIDUS: + switch (this.chardata) { + case 'd': case 'D': + case 'w': case 'W': + case 's': case 'S': + tok = this.getTokenForShorthand(this.chardata); + this.next(); + return tok; + + case 'e': case 'f': case 'n': case 'r': + case 't': case 'u': case 'v': case 'x': + { + int ch2 = this.decodeEscaped(); + if (ch2 < 0x10000) { + tok = Token.createChar(ch2); + } else { + tok = Token.createString(REUtil.decomposeToSurrogates(ch2)); + } + } + break; + + case 'c': return this.processBacksolidus_c(); + case 'C': return this.processBacksolidus_C(); + case 'i': return this.processBacksolidus_i(); + case 'I': return this.processBacksolidus_I(); + case 'g': return this.processBacksolidus_g(); + case 'X': return this.processBacksolidus_X(); + case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + return this.processBackreference(); + + case 'P': + case 'p': + int pstart = this.offset; + tok = processBacksolidus_pP(this.chardata); + if (tok == null) throw this.ex("parser.atom.5", pstart); + break; + + default: + tok = Token.createChar(this.chardata); + } + this.next(); + break; + + case T_CHAR: + if (this.chardata == ']' || this.chardata == '{' || this.chardata == '}') + throw this.ex("parser.atom.4", this.offset-1); + tok = Token.createChar(this.chardata); + int high = this.chardata; + this.next(); + if (REUtil.isHighSurrogate(high) + && this.read() == T_CHAR && REUtil.isLowSurrogate(this.chardata)) { + char[] sur = new char[2]; + sur[0] = (char)high; + sur[1] = (char)this.chardata; + tok = Token.createParen(Token.createString(new String(sur)), 0); + this.next(); + } + break; + + default: + throw this.ex("parser.atom.4", this.offset-1); + } + return tok; + } + + protected RangeToken processBacksolidus_pP(int c) throws ParseException { + + this.next(); + if (this.read() != T_CHAR || this.chardata != '{') + throw this.ex("parser.atom.2", this.offset-1); + + // handle category escape + boolean positive = c == 'p'; + int namestart = this.offset; + int nameend = this.regex.indexOf('}', namestart); + + if (nameend < 0) + throw this.ex("parser.atom.3", this.offset); + + String pname = this.regex.substring(namestart, nameend); + this.offset = nameend+1; + + return Token.getRange(pname, positive, this.isSet(RegularExpression.XMLSCHEMA_MODE)); + } + + int processCIinCharacterClass(RangeToken tok, int c) { + return this.decodeEscaped(); + } + + /** + * char-class ::= '[' ( '^'? range ','?)+ ']' + * range ::= '\d' | '\w' | '\s' | category-block | range-char + * | range-char '-' range-char + * range-char ::= '\[' | '\]' | '\\' | '\' [,-efnrtv] | bmp-code | character-2 + * bmp-code ::= '\' 'u' [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F] + */ + protected RangeToken parseCharacterClass(boolean useNrange) throws ParseException { + this.setContext(S_INBRACKETS); + this.next(); // '[' + boolean nrange = false; + RangeToken base = null; + RangeToken tok; + if (this.read() == T_CHAR && this.chardata == '^') { + nrange = true; + this.next(); // '^' + if (useNrange) { + tok = Token.createNRange(); + } else { + base = Token.createRange(); + base.addRange(0, Token.UTF16_MAX); + tok = Token.createRange(); + } + } else { + tok = Token.createRange(); + } + int type; + boolean firstloop = true; + while ((type = this.read()) != T_EOF) { + if (type == T_CHAR && this.chardata == ']' && !firstloop) + break; + firstloop = false; + int c = this.chardata; + boolean end = false; + if (type == T_BACKSOLIDUS) { + switch (c) { + case 'd': case 'D': + case 'w': case 'W': + case 's': case 'S': + tok.mergeRanges(this.getTokenForShorthand(c)); + end = true; + break; + + case 'i': case 'I': + case 'c': case 'C': + c = this.processCIinCharacterClass(tok, c); + if (c < 0) end = true; + break; + + case 'p': + case 'P': + int pstart = this.offset; + RangeToken tok2 = this.processBacksolidus_pP(c); + if (tok2 == null) throw this.ex("parser.atom.5", pstart); + tok.mergeRanges(tok2); + end = true; + break; + + default: + c = this.decodeEscaped(); + } // \ + c + } // backsolidus + // POSIX Character class such as [:alnum:] + else if (type == T_POSIX_CHARCLASS_START) { + int nameend = this.regex.indexOf(':', this.offset); + if (nameend < 0) throw this.ex("parser.cc.1", this.offset); + boolean positive = true; + if (this.regex.charAt(this.offset) == '^') { + this.offset ++; + positive = false; + } + String name = this.regex.substring(this.offset, nameend); + RangeToken range = Token.getRange(name, positive, + this.isSet(RegularExpression.XMLSCHEMA_MODE)); + if (range == null) throw this.ex("parser.cc.3", this.offset); + tok.mergeRanges(range); + end = true; + if (nameend+1 >= this.regexlen || this.regex.charAt(nameend+1) != ']') + throw this.ex("parser.cc.1", nameend); + this.offset = nameend+2; + } + this.next(); + if (!end) { // if not shorthands... + if (this.read() != T_CHAR || this.chardata != '-') { // Here is no '-'. + tok.addRange(c, c); + } else { + this.next(); // Skips '-' + if ((type = this.read()) == T_EOF) throw this.ex("parser.cc.2", this.offset); + if (type == T_CHAR && this.chardata == ']') { + tok.addRange(c, c); + tok.addRange('-', '-'); + } else { + int rangeend = this.chardata; + if (type == T_BACKSOLIDUS) + rangeend = this.decodeEscaped(); + this.next(); + tok.addRange(c, rangeend); + } + } + } + if (this.isSet(RegularExpression.SPECIAL_COMMA) + && this.read() == T_CHAR && this.chardata == ',') + this.next(); + } + if (this.read() == T_EOF) + throw this.ex("parser.cc.2", this.offset); + if (!useNrange && nrange) { + base.subtractRanges(tok); + tok = base; + } + tok.sortRanges(); + tok.compactRanges(); + //tok.dumpRanges(); + /* + if (this.isSet(RegularExpression.IGNORE_CASE)) + tok = RangeToken.createCaseInsensitiveToken(tok); + */ + this.setContext(S_NORMAL); + this.next(); // Skips ']' + + return tok; + } + + /** + * '(?[' ... ']' (('-' | '+' | '&') '[' ... ']')? ')' + */ + protected RangeToken parseSetOperations() throws ParseException { + RangeToken tok = this.parseCharacterClass(false); + int type; + while ((type = this.read()) != T_RPAREN) { + int ch = this.chardata; + if (type == T_CHAR && (ch == '-' || ch == '&') + || type == T_PLUS) { + this.next(); + if (this.read() != T_LBRACKET) throw ex("parser.ope.1", this.offset-1); + RangeToken t2 = this.parseCharacterClass(false); + if (type == T_PLUS) + tok.mergeRanges(t2); + else if (ch == '-') + tok.subtractRanges(t2); + else if (ch == '&') + tok.intersectRanges(t2); + else + throw new RuntimeException("ASSERT"); + } else { + throw ex("parser.ope.2", this.offset-1); + } + } + this.next(); + return tok; + } + + Token getTokenForShorthand(int ch) { + Token tok; + switch (ch) { + case 'd': + tok = this.isSet(RegularExpression.USE_UNICODE_CATEGORY) + ? Token.getRange("Nd", true) : Token.token_0to9; + break; + case 'D': + tok = this.isSet(RegularExpression.USE_UNICODE_CATEGORY) + ? Token.getRange("Nd", false) : Token.token_not_0to9; + break; + case 'w': + tok = this.isSet(RegularExpression.USE_UNICODE_CATEGORY) + ? Token.getRange("IsWord", true) : Token.token_wordchars; + break; + case 'W': + tok = this.isSet(RegularExpression.USE_UNICODE_CATEGORY) + ? Token.getRange("IsWord", false) : Token.token_not_wordchars; + break; + case 's': + tok = this.isSet(RegularExpression.USE_UNICODE_CATEGORY) + ? Token.getRange("IsSpace", true) : Token.token_spaces; + break; + case 'S': + tok = this.isSet(RegularExpression.USE_UNICODE_CATEGORY) + ? Token.getRange("IsSpace", false) : Token.token_not_spaces; + break; + + default: + throw new RuntimeException("Internal Error: shorthands: \\u"+Integer.toString(ch, 16)); + } + return tok; + } + + /** + */ + int decodeEscaped() throws ParseException { + if (this.read() != T_BACKSOLIDUS) throw ex("parser.next.1", this.offset-1); + int c = this.chardata; + switch (c) { + case 'e': c = 0x1b; break; // ESCAPE U+001B + case 'f': c = '\f'; break; // FORM FEED U+000C + case 'n': c = '\n'; break; // LINE FEED U+000A + case 'r': c = '\r'; break; // CRRIAGE RETURN U+000D + case 't': c = '\t'; break; // HORIZONTAL TABULATION U+0009 + //case 'v': c = 0x0b; break; // VERTICAL TABULATION U+000B + case 'x': + this.next(); + if (this.read() != T_CHAR) throw ex("parser.descape.1", this.offset-1); + if (this.chardata == '{') { + int v1 = 0; + int uv = 0; + do { + this.next(); + if (this.read() != T_CHAR) throw ex("parser.descape.1", this.offset-1); + if ((v1 = hexChar(this.chardata)) < 0) + break; + if (uv > uv*16) throw ex("parser.descape.2", this.offset-1); + uv = uv*16+v1; + } while (true); + if (this.chardata != '}') throw ex("parser.descape.3", this.offset-1); + if (uv > Token.UTF16_MAX) throw ex("parser.descape.4", this.offset-1); + c = uv; + } else { + int v1 = 0; + if (this.read() != T_CHAR || (v1 = hexChar(this.chardata)) < 0) + throw ex("parser.descape.1", this.offset-1); + int uv = v1; + this.next(); + if (this.read() != T_CHAR || (v1 = hexChar(this.chardata)) < 0) + throw ex("parser.descape.1", this.offset-1); + uv = uv*16+v1; + c = uv; + } + break; + + case 'u': + int v1 = 0; + this.next(); + if (this.read() != T_CHAR || (v1 = hexChar(this.chardata)) < 0) + throw ex("parser.descape.1", this.offset-1); + int uv = v1; + this.next(); + if (this.read() != T_CHAR || (v1 = hexChar(this.chardata)) < 0) + throw ex("parser.descape.1", this.offset-1); + uv = uv*16+v1; + this.next(); + if (this.read() != T_CHAR || (v1 = hexChar(this.chardata)) < 0) + throw ex("parser.descape.1", this.offset-1); + uv = uv*16+v1; + this.next(); + if (this.read() != T_CHAR || (v1 = hexChar(this.chardata)) < 0) + throw ex("parser.descape.1", this.offset-1); + uv = uv*16+v1; + c = uv; + break; + + case 'v': + this.next(); + if (this.read() != T_CHAR || (v1 = hexChar(this.chardata)) < 0) + throw ex("parser.descape.1", this.offset-1); + uv = v1; + this.next(); + if (this.read() != T_CHAR || (v1 = hexChar(this.chardata)) < 0) + throw ex("parser.descape.1", this.offset-1); + uv = uv*16+v1; + this.next(); + if (this.read() != T_CHAR || (v1 = hexChar(this.chardata)) < 0) + throw ex("parser.descape.1", this.offset-1); + uv = uv*16+v1; + this.next(); + if (this.read() != T_CHAR || (v1 = hexChar(this.chardata)) < 0) + throw ex("parser.descape.1", this.offset-1); + uv = uv*16+v1; + this.next(); + if (this.read() != T_CHAR || (v1 = hexChar(this.chardata)) < 0) + throw ex("parser.descape.1", this.offset-1); + uv = uv*16+v1; + this.next(); + if (this.read() != T_CHAR || (v1 = hexChar(this.chardata)) < 0) + throw ex("parser.descape.1", this.offset-1); + uv = uv*16+v1; + if (uv > Token.UTF16_MAX) throw ex("parser.descappe.4", this.offset-1); + c = uv; + break; + case 'A': + case 'Z': + case 'z': + throw ex("parser.descape.5", this.offset-2); + default: + } + return c; + } + + static private final int hexChar(int ch) { + if (ch < '0') return -1; + if (ch > 'f') return -1; + if (ch <= '9') return ch-'0'; + if (ch < 'A') return -1; + if (ch <= 'F') return ch-'A'+10; + if (ch < 'a') return -1; + return ch-'a'+10; + } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/regex/RegularExpression.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/regex/RegularExpression.java new file mode 100644 index 000000000..bf4f45532 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/regex/RegularExpression.java @@ -0,0 +1,3147 @@ +/* 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.regex; + +import java.text.CharacterIterator; + +/** + * A regular expression matching engine using Non-deterministic Finite Automaton (NFA). + * This engine does not conform to the POSIX regular expression. + * + *
    + *

    How to use

    + * + *
    + *
    A. Standard way + *
    + *
    + * RegularExpression re = new RegularExpression(regex);
    + * if (re.matches(text)) { ... }
    + * 
    + * + *
    B. Capturing groups + *
    + *
    + * RegularExpression re = new RegularExpression(regex);
    + * Match match = new Match();
    + * if (re.matches(text, match)) {
    + *     ... // You can refer captured texts with methods of the Match class.
    + * }
    + * 
    + * + *
    + * + *

    Case-insensitive matching

    + *
    + * RegularExpression re = new RegularExpression(regex, "i");
    + * if (re.matches(text) >= 0) { ...}
    + * 
    + * + *

    Options

    + *
    + *
    + *
    "i" + *
    This option indicates case-insensitive matching. + *
    "m" + *
    ^ and $ consider the EOL characters within the text. + *
    "s" + *
    . matches any one character. + *
    "u" + *
    Redefines \d \D \w \W \s \S \b \B \< \> as becoming to Unicode. + *
    "w" + *
    By this option, \b \B \< \> are processed with the method of + * 'Unicode Regular Expression Guidelines' Revision 4. + * When "w" and "u" are specified at the same time, + * \b \B \< \> are processed for the "w" option. + *
    "," + *
    The parser treats a comma in a character class as a range separator. + * [a,b] matches a or , or b without this option. + * [a,b] matches a or b with this option. + * + *
    "X" + *
    + * By this option, the engine confoms to XML Schema: Regular Expression. + * The match() method does not do subsring matching + * but entire string matching. + * + *
    + * + *
    + *

    Syntax

    + * + * + * + * + *
    + *

    Differences from the Perl 5 regular expression

    + *
      + *
    • There is 6-digit hexadecimal character representation (\u005cvHHHHHH.) + *
    • Supports subtraction, union, and intersection operations for character classes. + *
    • Not supported: \ooo (Octal character representations), + * \G, \C, \lc, + * \u005c uc, \L, \U, + * \E, \Q, \N{name}, + * (?{code}), (??{code}) + *
    + *
    + * + *

    Meta characters are `. * + ? { [ ( ) | \ ^ $'.

    + *
      + *
    • Character + *
      + *
      . (A period) + *
      Matches any one character except the following characters. + *
      LINE FEED (U+000A), CARRIAGE RETURN (U+000D), + * PARAGRAPH SEPARATOR (U+2029), LINE SEPARATOR (U+2028) + *
      This expression matches one code point in Unicode. It can match a pair of surrogates. + *
      When the "s" option is specified, + * it matches any character including the above four characters. + * + *
      \e \f \n \r \t + *
      Matches ESCAPE (U+001B), FORM FEED (U+000C), LINE FEED (U+000A), + * CARRIAGE RETURN (U+000D), HORIZONTAL TABULATION (U+0009) + * + *
      \cC + *
      Matches a control character. + * The C must be one of '@', 'A'-'Z', + * '[', '\u005c', ']', '^', '_'. + * It matches a control character of which the character code is less than + * the character code of the C by 0x0040. + *
      For example, a \cJ matches a LINE FEED (U+000A), + * and a \c[ matches an ESCAPE (U+001B). + * + *
      a non-meta character + *
      Matches the character. + * + *
      \ + a meta character + *
      Matches the meta character. + * + *
      \u005cxHH \u005cx{HHHH} + *
      Matches a character of which code point is HH (Hexadecimal) in Unicode. + * You can write just 2 digits for \u005cxHH, and + * variable length digits for \u005cx{HHHH}. + * + * + * + *
      \u005cvHHHHHH + *
      Matches a character of which code point is HHHHHH (Hexadecimal) in Unicode. + * + *
      \g + *
      Matches a grapheme. + *
      It is equivalent to (?[\p{ASSIGNED}]-[\p{M}\p{C}])?(?:\p{M}|[\x{094D}\x{09CD}\x{0A4D}\x{0ACD}\x{0B3D}\x{0BCD}\x{0C4D}\x{0CCD}\x{0D4D}\x{0E3A}\x{0F84}]\p{L}|[\x{1160}-\x{11A7}]|[\x{11A8}-\x{11FF}]|[\x{FF9E}\x{FF9F}])* + * + *
      \X + *
      Matches a combining character sequence. + * It is equivalent to (?:\PM\pM*) + *
      + *
    • + * + *
    • Character class + *
      ++ *
      [R1R2...Rn] (without "," option) ++ *
      [R1,R2,...,Rn] (with "," option) + *
      Positive character class. It matches a character in ranges. + *
      Rn: + *
        + *
      • A character (including \e \f \n \r \t \u005cxHH \u005cx{HHHH} \u005cvHHHHHH) + *

        This range matches the character. + *

      • C1-C2 + *

        This range matches a character which has a code point that is >= C1's code point and <= C2's code point. ++ *

      • A POSIX character class: [:alpha:] [:alnum:] [:ascii:] [:cntrl:] [:digit:] [:graph:] [:lower:] [:print:] [:punct:] [:space:] [:upper:] [:xdigit:], ++ * and negative POSIX character classes in Perl like [:^alpha:] + *

        ... + *

      • \d \D \s \S \w \W \p{name} \P{name} + *

        These expressions specifies the same ranges as the following expressions. + *

      + *

      Enumerated ranges are merged (union operation). + * [a-ec-z] is equivalent to [a-z] + * + *

      [^R1R2...Rn] (without a "," option) + *
      [^R1,R2,...,Rn] (with a "," option) + *
      Negative character class. It matches a character not in ranges. + * + *
      (?[ranges]op[ranges]op[ranges] ... ) + * (op is - or + or &.) + *
      Subtraction or union or intersection for character classes. + *
      For exmaple, (?[A-Z]-[CF]) is equivalent to [A-BD-EG-Z], and (?[0x00-0x7f]-[K]&[\p{Lu}]) is equivalent to [A-JL-Z]. + *
      The result of this operations is a positive character class + * even if an expression includes any negative character classes. + * You have to take care on this in case-insensitive matching. + * For instance, (?[^b]) is equivalent to [\x00-ac-\x{10ffff}], + * which is equivalent to [^b] in case-sensitive matching. + * But, in case-insensitive matching, (?[^b]) matches any character because + * it includes 'B' and 'B' matches 'b' + * though [^b] is processed as [^Bb]. + * + *
      [R1R2...-[RnRn+1...]] (with an "X" option)
      + *
      Character class subtraction for the XML Schema. + * You can use this syntax when you specify an "X" option. + * + *
      \d + *
      Equivalent to [0-9]. + *
      When a "u" option is set, it is equivalent to + * \p{Nd}. + * + *
      \D + *
      Equivalent to [^0-9] + *
      When a "u" option is set, it is equivalent to + * \P{Nd}. + * + *
      \s + *
      Equivalent to [ \f\n\r\t] + *
      When a "u" option is set, it is equivalent to + * [ \f\n\r\t\p{Z}]. + * + *
      \S + *
      Equivalent to [^ \f\n\r\t] + *
      When a "u" option is set, it is equivalent to + * [^ \f\n\r\t\p{Z}]. + * + *
      \w + *
      Equivalent to [a-zA-Z0-9_] + *
      When a "u" option is set, it is equivalent to + * [\p{Lu}\p{Ll}\p{Lo}\p{Nd}_]. + * + *
      \W + *
      Equivalent to [^a-zA-Z0-9_] + *
      When a "u" option is set, it is equivalent to + * [^\p{Lu}\p{Ll}\p{Lo}\p{Nd}_]. + * + *
      \p{name} + *
      Matches one character in the specified General Category (the second field in UnicodeData.txt) or the specified Block. + * The following names are available: + *
      + *
      Unicode General Categories: + *
      + * L, M, N, Z, C, P, S, Lu, Ll, Lt, Lm, Lo, Mn, Me, Mc, Nd, Nl, No, Zs, Zl, Zp, + * Cc, Cf, Cn, Co, Cs, Pd, Ps, Pe, Pc, Po, Sm, Sc, Sk, So, + * + *
      (Currently the Cn category includes U+10000-U+10FFFF characters) + *
      Unicode Blocks: + *
      + * Basic Latin, Latin-1 Supplement, Latin Extended-A, Latin Extended-B, + * IPA Extensions, Spacing Modifier Letters, Combining Diacritical Marks, Greek, + * Cyrillic, Armenian, Hebrew, Arabic, Devanagari, Bengali, Gurmukhi, Gujarati, + * Oriya, Tamil, Telugu, Kannada, Malayalam, Thai, Lao, Tibetan, Georgian, + * Hangul Jamo, Latin Extended Additional, Greek Extended, General Punctuation, + * Superscripts and Subscripts, Currency Symbols, Combining Marks for Symbols, + * Letterlike Symbols, Number Forms, Arrows, Mathematical Operators, + * Miscellaneous Technical, Control Pictures, Optical Character Recognition, + * Enclosed Alphanumerics, Box Drawing, Block Elements, Geometric Shapes, + * Miscellaneous Symbols, Dingbats, CJK Symbols and Punctuation, Hiragana, + * Katakana, Bopomofo, Hangul Compatibility Jamo, Kanbun, + * Enclosed CJK Letters and Months, CJK Compatibility, CJK Unified Ideographs, + * Hangul Syllables, High Surrogates, High Private Use Surrogates, Low Surrogates, + * Private Use, CJK Compatibility Ideographs, Alphabetic Presentation Forms, + * Arabic Presentation Forms-A, Combining Half Marks, CJK Compatibility Forms, + * Small Form Variants, Arabic Presentation Forms-B, Specials, + * Halfwidth and Fullwidth Forms + * + *
      Others: + *
      ALL (Equivalent to [\u005cu0000-\u005cv10FFFF]) + *
      ASSGINED (\p{ASSIGNED} is equivalent to \P{Cn}) + *
      UNASSGINED + * (\p{UNASSIGNED} is equivalent to \p{Cn}) + *
      + * + *
      \P{name} + *
      Matches one character not in the specified General Category or the specified Block. + *
      + *
    • + * + *
    • Selection and Quantifier + *
      + *
      X|Y + *
      ... + * + *
      X* + *
      Matches 0 or more X. + * + *
      X+ + *
      Matches 1 or more X. + * + *
      X? + *
      Matches 0 or 1 X. + * + *
      X{number} + *
      Matches number times. + * + *
      X{min,} + *
      ... + * + *
      X{min,max} + *
      ... + * + *
      X*? + *
      X+? + *
      X?? + *
      X{min,}? + *
      X{min,max}? + *
      Non-greedy matching. + *
      + *
    • + * + *
    • Grouping, Capturing, and Back-reference + *
      + *
      (?:X) + *
      Grouping. "foo+" matches "foo" or "foooo". + * If you want it matches "foofoo" or "foofoofoo", + * you have to write "(?:foo)+". + * + *
      (X) + *
      Grouping with capturing. + * It make a group and applications can know + * where in target text a group matched with methods of a Match instance + * after matches(String,Match). + * The 0th group means whole of this regular expression. + * The Nth gorup is the inside of the Nth left parenthesis. + * + *

      For instance, a regular expression is + * " *([^<:]*) +<([^>]*)> *" + * and target text is + * "From: TAMURA Kent <kent@trl.ibm.co.jp>": + *

        + *
      • Match.getCapturedText(0): + * " TAMURA Kent <kent@trl.ibm.co.jp>" + *
      • Match.getCapturedText(1): "TAMURA Kent" + *
      • Match.getCapturedText(2): "kent@trl.ibm.co.jp" + *
      + * + *
      \1 \2 \3 \4 \5 \6 \7 \8 \9 + *
      + * + *
      (?>X) + *
      Independent expression group. ................ + * + *
      (?options:X) + *
      (?options-options2:X) + *
      ............................ + *
      The options or the options2 consists of 'i' 'm' 's' 'w'. + * Note that it can not contain 'u'. + * + *
      (?options) + *
      (?options-options2) + *
      ...... + *
      These expressions must be at the beginning of a group. + *
      + *
    • + * + *
    • Anchor + *
      + *
      \A + *
      Matches the beginnig of the text. + * + *
      \Z + *
      Matches the end of the text, or before an EOL character at the end of the text, + * or CARRIAGE RETURN + LINE FEED at the end of the text. + * + *
      \z + *
      Matches the end of the text. + * + *
      ^ + *
      Matches the beginning of the text. It is equivalent to \A. + *
      When a "m" option is set, + * it matches the beginning of the text, or after one of EOL characters ( + * LINE FEED (U+000A), CARRIAGE RETURN (U+000D), LINE SEPARATOR (U+2028), + * PARAGRAPH SEPARATOR (U+2029).) + * + *
      $ + *
      Matches the end of the text, or before an EOL character at the end of the text, + * or CARRIAGE RETURN + LINE FEED at the end of the text. + *
      When a "m" option is set, + * it matches the end of the text, or before an EOL character. + * + *
      \b + *
      Matches word boundary. + * (See a "w" option) + * + *
      \B + *
      Matches non word boundary. + * (See a "w" option) + * + *
      \< + *
      Matches the beginning of a word. + * (See a "w" option) + * + *
      \> + *
      Matches the end of a word. + * (See a "w" option) + *
      + *
    • + *
    • Lookahead and lookbehind + *
      + *
      (?=X) + *
      Lookahead. + * + *
      (?!X) + *
      Negative lookahead. + * + *
      (?<=X) + *
      Lookbehind. + *
      (Note for text capturing......) + * + *
      (?<!X) + *
      Negative lookbehind. + *
      + *
    • + * + *
    • Misc. + *
      + *
      (?(condition)yes-pattern|no-pattern), + *
      (?(condition)yes-pattern) + *
      ...... + *
      (?#comment) + *
      Comment. A comment string consists of characters except ')'. + * You can not write comments in character classes and before quantifiers. + *
      + *
    • + *
    + * + * + *
    + *

    BNF for the regular expression

    + *
    + * regex ::= ('(?' options ')')? term ('|' term)*
    + * term ::= factor+
    + * factor ::= anchors | atom (('*' | '+' | '?' | minmax ) '?'? )?
    + *            | '(?#' [^)]* ')'
    + * minmax ::= '{' ([0-9]+ | [0-9]+ ',' | ',' [0-9]+ | [0-9]+ ',' [0-9]+) '}'
    + * atom ::= char | '.' | char-class | '(' regex ')' | '(?:' regex ')' | '\' [0-9]
    + *          | '\w' | '\W' | '\d' | '\D' | '\s' | '\S' | category-block | '\X'
    + *          | '(?>' regex ')' | '(?' options ':' regex ')'
    + *          | '(?' ('(' [0-9] ')' | '(' anchors ')' | looks) term ('|' term)? ')'
    + * options ::= [imsw]* ('-' [imsw]+)?
    + * anchors ::= '^' | '$' | '\A' | '\Z' | '\z' | '\b' | '\B' | '\<' | '\>'
    + * looks ::= '(?=' regex ')'  | '(?!' regex ')'
    + *           | '(?<=' regex ')' | '(?<!' regex ')'
    + * char ::= '\\' | '\' [efnrtv] | '\c' [@-_] | code-point | character-1
    + * category-block ::= '\' [pP] category-symbol-1
    + *                    | ('\p{' | '\P{') (category-symbol | block-name
    + *                                       | other-properties) '}'
    + * category-symbol-1 ::= 'L' | 'M' | 'N' | 'Z' | 'C' | 'P' | 'S'
    + * category-symbol ::= category-symbol-1 | 'Lu' | 'Ll' | 'Lt' | 'Lm' | Lo'
    + *                     | 'Mn' | 'Me' | 'Mc' | 'Nd' | 'Nl' | 'No'
    + *                     | 'Zs' | 'Zl' | 'Zp' | 'Cc' | 'Cf' | 'Cn' | 'Co' | 'Cs'
    + *                     | 'Pd' | 'Ps' | 'Pe' | 'Pc' | 'Po'
    + *                     | 'Sm' | 'Sc' | 'Sk' | 'So'
    + * block-name ::= (See above)
    + * other-properties ::= 'ALL' | 'ASSIGNED' | 'UNASSIGNED'
    + * character-1 ::= (any character except meta-characters)
    + *
    + * char-class ::= '[' ranges ']'
    + *                | '(?[' ranges ']' ([-+&] '[' ranges ']')? ')'
    + * ranges ::= '^'? (range ','?)+
    + * range ::= '\d' | '\w' | '\s' | '\D' | '\W' | '\S' | category-block
    + *           | range-char | range-char '-' range-char
    + * range-char ::= '\[' | '\]' | '\\' | '\' [,-efnrtv] | code-point | character-2
    + * code-point ::= '\x' hex-char hex-char
    + *                | '\x{' hex-char+ '}'
    + *                | '\v' hex-char hex-char hex-char hex-char hex-char hex-char
    + * hex-char ::= [0-9a-fA-F]
    + * character-2 ::= (any character except \[]-,)
    + * 
    + * + *
    + *

    TODO

    + * + * + *
    + * + * @author TAMURA Kent <kent@trl.ibm.co.jp> + * @version $Id$ + */ +public class RegularExpression implements java.io.Serializable { + static final boolean DEBUG = false; + + /** + * Compiles a token tree into an operation flow. + */ + private synchronized void compile(Token tok) { + if (this.operations != null) + return; + this.numberOfClosures = 0; + this.operations = this.compile(tok, null, false); + } + + /** + * Converts a token to an operation. + */ + private Op compile(Token tok, Op next, boolean reverse) { + Op ret; + switch (tok.type) { + case Token.DOT: + ret = Op.createDot(); + ret.next = next; + break; + + case Token.CHAR: + ret = Op.createChar(tok.getChar()); + ret.next = next; + break; + + case Token.ANCHOR: + ret = Op.createAnchor(tok.getChar()); + ret.next = next; + break; + + case Token.RANGE: + case Token.NRANGE: + ret = Op.createRange(tok); + ret.next = next; + break; + + case Token.CONCAT: + ret = next; + if (!reverse) { + for (int i = tok.size()-1; i >= 0; i --) { + ret = compile(tok.getChild(i), ret, false); + } + } else { + for (int i = 0; i < tok.size(); i ++) { + ret = compile(tok.getChild(i), ret, true); + } + } + break; + + case Token.UNION: + Op.UnionOp uni = Op.createUnion(tok.size()); + for (int i = 0; i < tok.size(); i ++) { + uni.addElement(compile(tok.getChild(i), next, reverse)); + } + ret = uni; // ret.next is null. + break; + + case Token.CLOSURE: + case Token.NONGREEDYCLOSURE: + Token child = tok.getChild(0); + int min = tok.getMin(); + int max = tok.getMax(); + if (min >= 0 && min == max) { // {n} + ret = next; + for (int i = 0; i < min; i ++) { + ret = compile(child, ret, reverse); + } + break; + } + if (min > 0 && max > 0) + max -= min; + if (max > 0) { + // X{2,6} -> XX(X(X(XX?)?)?)? + ret = next; + for (int i = 0; i < max; i ++) { + Op.ChildOp q = Op.createQuestion(tok.type == Token.NONGREEDYCLOSURE); + q.next = next; + q.setChild(compile(child, ret, reverse)); + ret = q; + } + } else { + Op.ChildOp op; + if (tok.type == Token.NONGREEDYCLOSURE) { + op = Op.createNonGreedyClosure(); + } else { // Token.CLOSURE + if (child.getMinLength() == 0) + op = Op.createClosure(this.numberOfClosures++); + else + op = Op.createClosure(-1); + } + op.next = next; + op.setChild(compile(child, op, reverse)); + ret = op; + } + if (min > 0) { + for (int i = 0; i < min; i ++) { + ret = compile(child, ret, reverse); + } + } + break; + + case Token.EMPTY: + ret = next; + break; + + case Token.STRING: + ret = Op.createString(tok.getString()); + ret.next = next; + break; + + case Token.BACKREFERENCE: + ret = Op.createBackReference(tok.getReferenceNumber()); + ret.next = next; + break; + + case Token.PAREN: + if (tok.getParenNumber() == 0) { + ret = compile(tok.getChild(0), next, reverse); + } else if (reverse) { + next = Op.createCapture(tok.getParenNumber(), next); + next = compile(tok.getChild(0), next, reverse); + ret = Op.createCapture(-tok.getParenNumber(), next); + } else { + next = Op.createCapture(-tok.getParenNumber(), next); + next = compile(tok.getChild(0), next, reverse); + ret = Op.createCapture(tok.getParenNumber(), next); + } + break; + + case Token.LOOKAHEAD: + ret = Op.createLook(Op.LOOKAHEAD, next, compile(tok.getChild(0), null, false)); + break; + case Token.NEGATIVELOOKAHEAD: + ret = Op.createLook(Op.NEGATIVELOOKAHEAD, next, compile(tok.getChild(0), null, false)); + break; + case Token.LOOKBEHIND: + ret = Op.createLook(Op.LOOKBEHIND, next, compile(tok.getChild(0), null, true)); + break; + case Token.NEGATIVELOOKBEHIND: + ret = Op.createLook(Op.NEGATIVELOOKBEHIND, next, compile(tok.getChild(0), null, true)); + break; + + case Token.INDEPENDENT: + ret = Op.createIndependent(next, compile(tok.getChild(0), null, reverse)); + break; + + case Token.MODIFIERGROUP: + ret = Op.createModifier(next, compile(tok.getChild(0), null, reverse), + ((Token.ModifierToken)tok).getOptions(), + ((Token.ModifierToken)tok).getOptionsMask()); + break; + + case Token.CONDITION: + Token.ConditionToken ctok = (Token.ConditionToken)tok; + int ref = ctok.refNumber; + Op condition = ctok.condition == null ? null : compile(ctok.condition, null, reverse); + Op yes = compile(ctok.yes, next, reverse); + Op no = ctok.no == null ? null : compile(ctok.no, next, reverse); + ret = Op.createCondition(next, ref, condition, yes, no); + break; + + default: + throw new RuntimeException("Unknown token type: "+tok.type); + } // switch (tok.type) + return ret; + } + + +//Public + + /** + * Checks whether the target text contains this pattern or not. + * + * @return true if the target is matched to this regular expression. + */ + public boolean matches(char[] target) { + return this.matches(target, 0, target .length , (Match)null); + } + + /** + * Checks whether the target text contains this pattern + * in specified range or not. + * + * @param start Start offset of the range. + * @param end End offset +1 of the range. + * @return true if the target is matched to this regular expression. + */ + public boolean matches(char[] target, int start, int end) { + return this.matches(target, start, end, (Match)null); + } + + /** + * Checks whether the target text contains this pattern or not. + * + * @param match A Match instance for storing matching result. + * @return Offset of the start position in target; or -1 if not match. + */ + public boolean matches(char[] target, Match match) { + return this.matches(target, 0, target .length , match); + } + + + /** + * Checks whether the target text contains this pattern + * in specified range or not. + * + * @param start Start offset of the range. + * @param end End offset +1 of the range. + * @param match A Match instance for storing matching result. + * @return Offset of the start position in target; or -1 if not match. + */ + public boolean matches(char[] target, int start, int end, Match match) { + + synchronized (this) { + if (this.operations == null) + this.prepare(); + if (this.context == null) + this.context = new Context(); + } + Context con = null; + synchronized (this.context) { + con = this.context.inuse ? new Context() : this.context; + con.reset(target, start, end, this.numberOfClosures); + } + if (match != null) { + match.setNumberOfGroups(this.nofparen); + match.setSource(target); + } else if (this.hasBackReferences) { + match = new Match(); + match.setNumberOfGroups(this.nofparen); + // Need not to call setSource() because + // a caller can not access this match instance. + } + con.match = match; + + if (RegularExpression.isSet(this.options, XMLSCHEMA_MODE)) { + int matchEnd = this. matchCharArray (con, this.operations, con.start, 1, this.options); + //System.err.println("DEBUG: matchEnd="+matchEnd); + if (matchEnd == con.limit) { + if (con.match != null) { + con.match.setBeginning(0, con.start); + con.match.setEnd(0, matchEnd); + } + con.inuse = false; + return true; + } + return false; + } + + /* + * The pattern has only fixed string. + * The engine uses Boyer-Moore. + */ + if (this.fixedStringOnly) { + //System.err.println("DEBUG: fixed-only: "+this.fixedString); + int o = this.fixedStringTable.matches(target, con.start, con.limit); + if (o >= 0) { + if (con.match != null) { + con.match.setBeginning(0, o); + con.match.setEnd(0, o+this.fixedString.length()); + } + con.inuse = false; + return true; + } + con.inuse = false; + return false; + } + + /* + * The pattern contains a fixed string. + * The engine checks with Boyer-Moore whether the text contains the fixed string or not. + * If not, it return with false. + */ + if (this.fixedString != null) { + int o = this.fixedStringTable.matches(target, con.start, con.limit); + if (o < 0) { + //System.err.println("Non-match in fixed-string search."); + con.inuse = false; + return false; + } + } + + int limit = con.limit-this.minlength; + int matchStart; + int matchEnd = -1; + + /* + * Checks whether the expression starts with ".*". + */ + if (this.operations != null + && this.operations.type == Op.CLOSURE && this.operations.getChild().type == Op.DOT) { + if (isSet(this.options, SINGLE_LINE)) { + matchStart = con.start; + matchEnd = this. matchCharArray (con, this.operations, con.start, 1, this.options); + } else { + boolean previousIsEOL = true; + for (matchStart = con.start; matchStart <= limit; matchStart ++) { + int ch = target [ matchStart ] ; + if (isEOLChar(ch)) { + previousIsEOL = true; + } else { + if (previousIsEOL) { + if (0 <= (matchEnd = this. matchCharArray (con, this.operations, + matchStart, 1, this.options))) + break; + } + previousIsEOL = false; + } + } + } + } + + /* + * Optimization against the first character. + */ + else if (this.firstChar != null) { + //System.err.println("DEBUG: with firstchar-matching: "+this.firstChar); + RangeToken range = this.firstChar; + if (RegularExpression.isSet(this.options, IGNORE_CASE)) { + range = this.firstChar.getCaseInsensitiveToken(); + for (matchStart = con.start; matchStart <= limit; matchStart ++) { + int ch = target [ matchStart ] ; + if (REUtil.isHighSurrogate(ch) && matchStart+1 < con.limit) { + ch = REUtil.composeFromSurrogates(ch, target [ matchStart+1 ] ); + if (!range.match(ch)) continue; + } else { + if (!range.match(ch)) { + char ch1 = Character.toUpperCase((char)ch); + if (!range.match(ch1)) + if (!range.match(Character.toLowerCase(ch1))) + continue; + } + } + if (0 <= (matchEnd = this. matchCharArray (con, this.operations, + matchStart, 1, this.options))) + break; + } + } else { + for (matchStart = con.start; matchStart <= limit; matchStart ++) { + int ch = target [ matchStart ] ; + if (REUtil.isHighSurrogate(ch) && matchStart+1 < con.limit) + ch = REUtil.composeFromSurrogates(ch, target [ matchStart+1 ] ); + if (!range.match(ch)) continue; + if (0 <= (matchEnd = this. matchCharArray (con, this.operations, + matchStart, 1, this.options))) + break; + } + } + } + + /* + * Straightforward matching. + */ + else { + for (matchStart = con.start; matchStart <= limit; matchStart ++) { + if (0 <= (matchEnd = this. matchCharArray (con, this.operations, matchStart, 1, this.options))) + break; + } + } + + if (matchEnd >= 0) { + if (con.match != null) { + con.match.setBeginning(0, matchStart); + con.match.setEnd(0, matchEnd); + } + con.inuse = false; + return true; + } else { + con.inuse = false; + return false; + } + } + +/** + * @return -1 when not match; offset of the end of matched string when match. + */ + private int matchCharArray (Context con, Op op, int offset, int dx, int opts) { + + char[] target = con.charTarget; + + + while (true) { + if (op == null) + return isSet(opts, XMLSCHEMA_MODE) && offset != con.limit ? -1 : offset; + if (offset > con.limit || offset < con.start) + return -1; + switch (op.type) { + case Op.CHAR: + if (isSet(opts, IGNORE_CASE)) { + int ch = op.getData(); + if (dx > 0) { + if (offset >= con.limit || !matchIgnoreCase(ch, target [ offset ] )) + return -1; + offset ++; + } else { + int o1 = offset-1; + if (o1 >= con.limit || o1 < 0 || !matchIgnoreCase(ch, target [ o1 ] )) + return -1; + offset = o1; + } + } else { + int ch = op.getData(); + if (dx > 0) { + if (offset >= con.limit || ch != target [ offset ] ) + return -1; + offset ++; + } else { + int o1 = offset-1; + if (o1 >= con.limit || o1 < 0 || ch != target [ o1 ] ) + return -1; + offset = o1; + } + } + op = op.next; + break; + + case Op.DOT: + if (dx > 0) { + if (offset >= con.limit) + return -1; + int ch = target [ offset ] ; + if (isSet(opts, SINGLE_LINE)) { + if (REUtil.isHighSurrogate(ch) && offset+1 < con.limit) + offset ++; + } else { + if (REUtil.isHighSurrogate(ch) && offset+1 < con.limit) + ch = REUtil.composeFromSurrogates(ch, target [ ++offset ] ); + if (isEOLChar(ch)) + return -1; + } + offset ++; + } else { + int o1 = offset-1; + if (o1 >= con.limit || o1 < 0) + return -1; + int ch = target [ o1 ] ; + if (isSet(opts, SINGLE_LINE)) { + if (REUtil.isLowSurrogate(ch) && o1-1 >= 0) + o1 --; + } else { + if (REUtil.isLowSurrogate(ch) && o1-1 >= 0) + ch = REUtil.composeFromSurrogates( target [ --o1 ] , ch); + if (!isEOLChar(ch)) + return -1; + } + offset = o1; + } + op = op.next; + break; + + case Op.RANGE: + case Op.NRANGE: + if (dx > 0) { + if (offset >= con.limit) + return -1; + int ch = target [ offset ] ; + if (REUtil.isHighSurrogate(ch) && offset+1 < con.limit) + ch = REUtil.composeFromSurrogates(ch, target [ ++offset ] ); + RangeToken tok = op.getToken(); + if (isSet(opts, IGNORE_CASE)) { + tok = tok.getCaseInsensitiveToken(); + if (!tok.match(ch)) { + if (ch >= 0x10000) return -1; + char uch; + if (!tok.match(uch = Character.toUpperCase((char)ch)) + && !tok.match(Character.toLowerCase(uch))) + return -1; + } + } else { + if (!tok.match(ch)) return -1; + } + offset ++; + } else { + int o1 = offset-1; + if (o1 >= con.limit || o1 < 0) + return -1; + int ch = target [ o1 ] ; + if (REUtil.isLowSurrogate(ch) && o1-1 >= 0) + ch = REUtil.composeFromSurrogates( target [ --o1 ] , ch); + RangeToken tok = op.getToken(); + if (isSet(opts, IGNORE_CASE)) { + tok = tok.getCaseInsensitiveToken(); + if (!tok.match(ch)) { + if (ch >= 0x10000) return -1; + char uch; + if (!tok.match(uch = Character.toUpperCase((char)ch)) + && !tok.match(Character.toLowerCase(uch))) + return -1; + } + } else { + if (!tok.match(ch)) return -1; + } + offset = o1; + } + op = op.next; + break; + + case Op.ANCHOR: + boolean go = false; + switch (op.getData()) { + case '^': + if (isSet(opts, MULTIPLE_LINES)) { + if (!(offset == con.start + || offset > con.start && isEOLChar( target [ offset-1 ] ))) + return -1; + } else { + if (offset != con.start) + return -1; + } + break; + + case '@': // Internal use only. + // The @ always matches line beginnings. + if (!(offset == con.start + || offset > con.start && isEOLChar( target [ offset-1 ] ))) + return -1; + break; + + case '$': + if (isSet(opts, MULTIPLE_LINES)) { + if (!(offset == con.limit + || offset < con.limit && isEOLChar( target [ offset ] ))) + return -1; + } else { + if (!(offset == con.limit + || offset+1 == con.limit && isEOLChar( target [ offset ] ) + || offset+2 == con.limit && target [ offset ] == CARRIAGE_RETURN + && target [ offset+1 ] == LINE_FEED)) + return -1; + } + break; + + case 'A': + if (offset != con.start) return -1; + break; + + case 'Z': + if (!(offset == con.limit + || offset+1 == con.limit && isEOLChar( target [ offset ] ) + || offset+2 == con.limit && target [ offset ] == CARRIAGE_RETURN + && target [ offset+1 ] == LINE_FEED)) + return -1; + break; + + case 'z': + if (offset != con.limit) return -1; + break; + + case 'b': + if (con.length == 0) return -1; + { + int after = getWordType(target, con.start, con.limit, offset, opts); + if (after == WT_IGNORE) return -1; + int before = getPreviousWordType(target, con.start, con.limit, offset, opts); + if (after == before) return -1; + } + break; + + case 'B': + if (con.length == 0) + go = true; + else { + int after = getWordType(target, con.start, con.limit, offset, opts); + go = after == WT_IGNORE + || after == getPreviousWordType(target, con.start, con.limit, offset, opts); + } + if (!go) return -1; + break; + + case '<': + if (con.length == 0 || offset == con.limit) return -1; + if (getWordType(target, con.start, con.limit, offset, opts) != WT_LETTER + || getPreviousWordType(target, con.start, con.limit, offset, opts) != WT_OTHER) + return -1; + break; + + case '>': + if (con.length == 0 || offset == con.start) return -1; + if (getWordType(target, con.start, con.limit, offset, opts) != WT_OTHER + || getPreviousWordType(target, con.start, con.limit, offset, opts) != WT_LETTER) + return -1; + break; + } // switch anchor type + op = op.next; + break; + + case Op.BACKREFERENCE: + { + int refno = op.getData(); + if (refno <= 0 || refno >= this.nofparen) + throw new RuntimeException("Internal Error: Reference number must be more than zero: "+refno); + if (con.match.getBeginning(refno) < 0 + || con.match.getEnd(refno) < 0) + return -1; // ******** + int o2 = con.match.getBeginning(refno); + int literallen = con.match.getEnd(refno)-o2; + if (!isSet(opts, IGNORE_CASE)) { + if (dx > 0) { + if (!regionMatches(target, offset, con.limit, o2, literallen)) + return -1; + offset += literallen; + } else { + if (!regionMatches(target, offset-literallen, con.limit, o2, literallen)) + return -1; + offset -= literallen; + } + } else { + if (dx > 0) { + if (!regionMatchesIgnoreCase(target, offset, con.limit, o2, literallen)) + return -1; + offset += literallen; + } else { + if (!regionMatchesIgnoreCase(target, offset-literallen, con.limit, + o2, literallen)) + return -1; + offset -= literallen; + } + } + } + op = op.next; + break; + case Op.STRING: + { + String literal = op.getString(); + int literallen = literal.length(); + if (!isSet(opts, IGNORE_CASE)) { + if (dx > 0) { + if (!regionMatches(target, offset, con.limit, literal, literallen)) + return -1; + offset += literallen; + } else { + if (!regionMatches(target, offset-literallen, con.limit, literal, literallen)) + return -1; + offset -= literallen; + } + } else { + if (dx > 0) { + if (!regionMatchesIgnoreCase(target, offset, con.limit, literal, literallen)) + return -1; + offset += literallen; + } else { + if (!regionMatchesIgnoreCase(target, offset-literallen, con.limit, + literal, literallen)) + return -1; + offset -= literallen; + } + } + } + op = op.next; + break; + + case Op.CLOSURE: + { + /* + * Saves current position to avoid + * zero-width repeats. + */ + int id = op.getData(); + if (id >= 0) { + int previousOffset = con.offsets[id]; + if (previousOffset < 0 || previousOffset != offset) { + con.offsets[id] = offset; + } else { + con.offsets[id] = -1; + op = op.next; + break; + } + } + + int ret = this. matchCharArray (con, op.getChild(), offset, dx, opts); + if (id >= 0) con.offsets[id] = -1; + if (ret >= 0) return ret; + op = op.next; + } + break; + + case Op.QUESTION: + { + int ret = this. matchCharArray (con, op.getChild(), offset, dx, opts); + if (ret >= 0) return ret; + op = op.next; + } + break; + + case Op.NONGREEDYCLOSURE: + case Op.NONGREEDYQUESTION: + { + int ret = this. matchCharArray (con, op.next, offset, dx, opts); + if (ret >= 0) return ret; + op = op.getChild(); + } + break; + + case Op.UNION: + for (int i = 0; i < op.size(); i ++) { + int ret = this. matchCharArray (con, op.elementAt(i), offset, dx, opts); + if (DEBUG) { + System.err.println("UNION: "+i+", ret="+ret); + } + if (ret >= 0) return ret; + } + return -1; + + case Op.CAPTURE: + int refno = op.getData(); + if (con.match != null && refno > 0) { + int save = con.match.getBeginning(refno); + con.match.setBeginning(refno, offset); + int ret = this. matchCharArray (con, op.next, offset, dx, opts); + if (ret < 0) con.match.setBeginning(refno, save); + return ret; + } else if (con.match != null && refno < 0) { + int index = -refno; + int save = con.match.getEnd(index); + con.match.setEnd(index, offset); + int ret = this. matchCharArray (con, op.next, offset, dx, opts); + if (ret < 0) con.match.setEnd(index, save); + return ret; + } + op = op.next; + break; + + case Op.LOOKAHEAD: + if (0 > this. matchCharArray (con, op.getChild(), offset, 1, opts)) return -1; + op = op.next; + break; + case Op.NEGATIVELOOKAHEAD: + if (0 <= this. matchCharArray (con, op.getChild(), offset, 1, opts)) return -1; + op = op.next; + break; + case Op.LOOKBEHIND: + if (0 > this. matchCharArray (con, op.getChild(), offset, -1, opts)) return -1; + op = op.next; + break; + case Op.NEGATIVELOOKBEHIND: + if (0 <= this. matchCharArray (con, op.getChild(), offset, -1, opts)) return -1; + op = op.next; + break; + + case Op.INDEPENDENT: + { + int ret = this. matchCharArray (con, op.getChild(), offset, dx, opts); + if (ret < 0) return ret; + offset = ret; + op = op.next; + } + break; + + case Op.MODIFIER: + { + int localopts = opts; + localopts |= op.getData(); + localopts &= ~op.getData2(); + //System.err.println("MODIFIER: "+Integer.toString(opts, 16)+" -> "+Integer.toString(localopts, 16)); + int ret = this. matchCharArray (con, op.getChild(), offset, dx, localopts); + if (ret < 0) return ret; + offset = ret; + op = op.next; + } + break; + + case Op.CONDITION: + { + Op.ConditionOp cop = (Op.ConditionOp)op; + boolean matchp = false; + if (cop.refNumber > 0) { + if (cop.refNumber >= this.nofparen) + throw new RuntimeException("Internal Error: Reference number must be more than zero: "+cop.refNumber); + matchp = con.match.getBeginning(cop.refNumber) >= 0 + && con.match.getEnd(cop.refNumber) >= 0; + } else { + matchp = 0 <= this. matchCharArray (con, cop.condition, offset, dx, opts); + } + + if (matchp) { + op = cop.yes; + } else if (cop.no != null) { + op = cop.no; + } else { + op = cop.next; + } + } + break; + + default: + throw new RuntimeException("Unknown operation type: "+op.type); + } // switch (op.type) + } // while + } + + private static final int getPreviousWordType(char[] target, int begin, int end, + int offset, int opts) { + int ret = getWordType(target, begin, end, --offset, opts); + while (ret == WT_IGNORE) + ret = getWordType(target, begin, end, --offset, opts); + return ret; + } + + private static final int getWordType(char[] target, int begin, int end, + int offset, int opts) { + if (offset < begin || offset >= end) return WT_OTHER; + return getWordType0( target [ offset ] , opts); + } + + + + private static final boolean regionMatches(char[] target, int offset, int limit, + String part, int partlen) { + if (offset < 0) return false; + if (limit-offset < partlen) + return false; + int i = 0; + while (partlen-- > 0) { + if ( target [ offset++ ] != part.charAt(i++)) + return false; + } + return true; + } + + private static final boolean regionMatches(char[] target, int offset, int limit, + int offset2, int partlen) { + if (offset < 0) return false; + if (limit-offset < partlen) + return false; + int i = offset2; + while (partlen-- > 0) { + if ( target [ offset++ ] != target [ i++ ] ) + return false; + } + return true; + } + +/** + * @see java.lang.String#regionMatches + */ + private static final boolean regionMatchesIgnoreCase(char[] target, int offset, int limit, + String part, int partlen) { + if (offset < 0) return false; + if (limit-offset < partlen) + return false; + int i = 0; + while (partlen-- > 0) { + char ch1 = target [ offset++ ] ; + char ch2 = part.charAt(i++); + if (ch1 == ch2) + continue; + char uch1 = Character.toUpperCase(ch1); + char uch2 = Character.toUpperCase(ch2); + if (uch1 == uch2) + continue; + if (Character.toLowerCase(uch1) != Character.toLowerCase(uch2)) + return false; + } + return true; + } + + private static final boolean regionMatchesIgnoreCase(char[] target, int offset, int limit, + int offset2, int partlen) { + if (offset < 0) return false; + if (limit-offset < partlen) + return false; + int i = offset2; + while (partlen-- > 0) { + char ch1 = target [ offset++ ] ; + char ch2 = target [ i++ ] ; + if (ch1 == ch2) + continue; + char uch1 = Character.toUpperCase(ch1); + char uch2 = Character.toUpperCase(ch2); + if (uch1 == uch2) + continue; + if (Character.toLowerCase(uch1) != Character.toLowerCase(uch2)) + return false; + } + return true; + } + + + + + /** + * Checks whether the target text contains this pattern or not. + * + * @return true if the target is matched to this regular expression. + */ + public boolean matches(String target) { + return this.matches(target, 0, target .length() , (Match)null); + } + + /** + * Checks whether the target text contains this pattern + * in specified range or not. + * + * @param start Start offset of the range. + * @param end End offset +1 of the range. + * @return true if the target is matched to this regular expression. + */ + public boolean matches(String target, int start, int end) { + return this.matches(target, start, end, (Match)null); + } + + /** + * Checks whether the target text contains this pattern or not. + * + * @param match A Match instance for storing matching result. + * @return Offset of the start position in target; or -1 if not match. + */ + public boolean matches(String target, Match match) { + return this.matches(target, 0, target .length() , match); + } + + /** + * Checks whether the target text contains this pattern + * in specified range or not. + * + * @param start Start offset of the range. + * @param end End offset +1 of the range. + * @param match A Match instance for storing matching result. + * @return Offset of the start position in target; or -1 if not match. + */ + public boolean matches(String target, int start, int end, Match match) { + + synchronized (this) { + if (this.operations == null) + this.prepare(); + if (this.context == null) + this.context = new Context(); + } + Context con = null; + synchronized (this.context) { + con = this.context.inuse ? new Context() : this.context; + con.reset(target, start, end, this.numberOfClosures); + } + if (match != null) { + match.setNumberOfGroups(this.nofparen); + match.setSource(target); + } else if (this.hasBackReferences) { + match = new Match(); + match.setNumberOfGroups(this.nofparen); + // Need not to call setSource() because + // a caller can not access this match instance. + } + con.match = match; + + if (RegularExpression.isSet(this.options, XMLSCHEMA_MODE)) { + if (DEBUG) { + System.err.println("target string="+target); + } + int matchEnd = this. matchString (con, this.operations, con.start, 1, this.options); + if (DEBUG) { + System.err.println("matchEnd="+matchEnd); + System.err.println("con.limit="+con.limit); + } + if (matchEnd == con.limit) { + if (con.match != null) { + con.match.setBeginning(0, con.start); + con.match.setEnd(0, matchEnd); + } + con.inuse = false; + return true; + } + return false; + } + + /* + * The pattern has only fixed string. + * The engine uses Boyer-Moore. + */ + if (this.fixedStringOnly) { + //System.err.println("DEBUG: fixed-only: "+this.fixedString); + int o = this.fixedStringTable.matches(target, con.start, con.limit); + if (o >= 0) { + if (con.match != null) { + con.match.setBeginning(0, o); + con.match.setEnd(0, o+this.fixedString.length()); + } + con.inuse = false; + return true; + } + con.inuse = false; + return false; + } + + /* + * The pattern contains a fixed string. + * The engine checks with Boyer-Moore whether the text contains the fixed string or not. + * If not, it return with false. + */ + if (this.fixedString != null) { + int o = this.fixedStringTable.matches(target, con.start, con.limit); + if (o < 0) { + //System.err.println("Non-match in fixed-string search."); + con.inuse = false; + return false; + } + } + + int limit = con.limit-this.minlength; + int matchStart; + int matchEnd = -1; + + /* + * Checks whether the expression starts with ".*". + */ + if (this.operations != null + && this.operations.type == Op.CLOSURE && this.operations.getChild().type == Op.DOT) { + if (isSet(this.options, SINGLE_LINE)) { + matchStart = con.start; + matchEnd = this. matchString (con, this.operations, con.start, 1, this.options); + } else { + boolean previousIsEOL = true; + for (matchStart = con.start; matchStart <= limit; matchStart ++) { + int ch = target .charAt( matchStart ) ; + if (isEOLChar(ch)) { + previousIsEOL = true; + } else { + if (previousIsEOL) { + if (0 <= (matchEnd = this. matchString (con, this.operations, + matchStart, 1, this.options))) + break; + } + previousIsEOL = false; + } + } + } + } + + /* + * Optimization against the first character. + */ + else if (this.firstChar != null) { + //System.err.println("DEBUG: with firstchar-matching: "+this.firstChar); + RangeToken range = this.firstChar; + if (RegularExpression.isSet(this.options, IGNORE_CASE)) { + range = this.firstChar.getCaseInsensitiveToken(); + for (matchStart = con.start; matchStart <= limit; matchStart ++) { + int ch = target .charAt( matchStart ) ; + if (REUtil.isHighSurrogate(ch) && matchStart+1 < con.limit) { + ch = REUtil.composeFromSurrogates(ch, target .charAt( matchStart+1 ) ); + if (!range.match(ch)) continue; + } else { + if (!range.match(ch)) { + char ch1 = Character.toUpperCase((char)ch); + if (!range.match(ch1)) + if (!range.match(Character.toLowerCase(ch1))) + continue; + } + } + if (0 <= (matchEnd = this. matchString (con, this.operations, + matchStart, 1, this.options))) + break; + } + } else { + for (matchStart = con.start; matchStart <= limit; matchStart ++) { + int ch = target .charAt( matchStart ) ; + if (REUtil.isHighSurrogate(ch) && matchStart+1 < con.limit) + ch = REUtil.composeFromSurrogates(ch, target .charAt( matchStart+1 ) ); + if (!range.match(ch)) continue; + if (0 <= (matchEnd = this. matchString (con, this.operations, + matchStart, 1, this.options))) + break; + } + } + } + + /* + * Straightforward matching. + */ + else { + for (matchStart = con.start; matchStart <= limit; matchStart ++) { + if (0 <= (matchEnd = this. matchString (con, this.operations, matchStart, 1, this.options))) + break; + } + } + + if (matchEnd >= 0) { + if (con.match != null) { + con.match.setBeginning(0, matchStart); + con.match.setEnd(0, matchEnd); + } + con.inuse = false; + return true; + } else { + con.inuse = false; + return false; + } + } + + /** + * @return -1 when not match; offset of the end of matched string when match. + */ + private int matchString (Context con, Op op, int offset, int dx, int opts) { + + + + + String target = con.strTarget; + + + + + while (true) { + if (op == null) + return isSet(opts, XMLSCHEMA_MODE) && offset != con.limit ? -1 : offset; + if (offset > con.limit || offset < con.start) + return -1; + switch (op.type) { + case Op.CHAR: + if (isSet(opts, IGNORE_CASE)) { + int ch = op.getData(); + if (dx > 0) { + if (offset >= con.limit || !matchIgnoreCase(ch, target .charAt( offset ) )) + return -1; + offset ++; + } else { + int o1 = offset-1; + if (o1 >= con.limit || o1 < 0 || !matchIgnoreCase(ch, target .charAt( o1 ) )) + return -1; + offset = o1; + } + } else { + int ch = op.getData(); + if (dx > 0) { + if (offset >= con.limit || ch != target .charAt( offset ) ) + return -1; + offset ++; + } else { + int o1 = offset-1; + if (o1 >= con.limit || o1 < 0 || ch != target .charAt( o1 ) ) + return -1; + offset = o1; + } + } + op = op.next; + break; + + case Op.DOT: + if (dx > 0) { + if (offset >= con.limit) + return -1; + int ch = target .charAt( offset ) ; + if (isSet(opts, SINGLE_LINE)) { + if (REUtil.isHighSurrogate(ch) && offset+1 < con.limit) + offset ++; + } else { + if (REUtil.isHighSurrogate(ch) && offset+1 < con.limit) + ch = REUtil.composeFromSurrogates(ch, target .charAt( ++offset ) ); + if (isEOLChar(ch)) + return -1; + } + offset ++; + } else { + int o1 = offset-1; + if (o1 >= con.limit || o1 < 0) + return -1; + int ch = target .charAt( o1 ) ; + if (isSet(opts, SINGLE_LINE)) { + if (REUtil.isLowSurrogate(ch) && o1-1 >= 0) + o1 --; + } else { + if (REUtil.isLowSurrogate(ch) && o1-1 >= 0) + ch = REUtil.composeFromSurrogates( target .charAt( --o1 ) , ch); + if (!isEOLChar(ch)) + return -1; + } + offset = o1; + } + op = op.next; + break; + + case Op.RANGE: + case Op.NRANGE: + if (dx > 0) { + if (offset >= con.limit) + return -1; + int ch = target .charAt( offset ) ; + if (REUtil.isHighSurrogate(ch) && offset+1 < con.limit) + ch = REUtil.composeFromSurrogates(ch, target .charAt( ++offset ) ); + RangeToken tok = op.getToken(); + if (isSet(opts, IGNORE_CASE)) { + tok = tok.getCaseInsensitiveToken(); + if (!tok.match(ch)) { + if (ch >= 0x10000) return -1; + char uch; + if (!tok.match(uch = Character.toUpperCase((char)ch)) + && !tok.match(Character.toLowerCase(uch))) + return -1; + } + } else { + if (!tok.match(ch)) return -1; + } + offset ++; + } else { + int o1 = offset-1; + if (o1 >= con.limit || o1 < 0) + return -1; + int ch = target .charAt( o1 ) ; + if (REUtil.isLowSurrogate(ch) && o1-1 >= 0) + ch = REUtil.composeFromSurrogates( target .charAt( --o1 ) , ch); + RangeToken tok = op.getToken(); + if (isSet(opts, IGNORE_CASE)) { + tok = tok.getCaseInsensitiveToken(); + if (!tok.match(ch)) { + if (ch >= 0x10000) return -1; + char uch; + if (!tok.match(uch = Character.toUpperCase((char)ch)) + && !tok.match(Character.toLowerCase(uch))) + return -1; + } + } else { + if (!tok.match(ch)) return -1; + } + offset = o1; + } + op = op.next; + break; + + case Op.ANCHOR: + boolean go = false; + switch (op.getData()) { + case '^': + if (isSet(opts, MULTIPLE_LINES)) { + if (!(offset == con.start + || offset > con.start && isEOLChar( target .charAt( offset-1 ) ))) + return -1; + } else { + if (offset != con.start) + return -1; + } + break; + + case '@': // Internal use only. + // The @ always matches line beginnings. + if (!(offset == con.start + || offset > con.start && isEOLChar( target .charAt( offset-1 ) ))) + return -1; + break; + + case '$': + if (isSet(opts, MULTIPLE_LINES)) { + if (!(offset == con.limit + || offset < con.limit && isEOLChar( target .charAt( offset ) ))) + return -1; + } else { + if (!(offset == con.limit + || offset+1 == con.limit && isEOLChar( target .charAt( offset ) ) + || offset+2 == con.limit && target .charAt( offset ) == CARRIAGE_RETURN + && target .charAt( offset+1 ) == LINE_FEED)) + return -1; + } + break; + + case 'A': + if (offset != con.start) return -1; + break; + + case 'Z': + if (!(offset == con.limit + || offset+1 == con.limit && isEOLChar( target .charAt( offset ) ) + || offset+2 == con.limit && target .charAt( offset ) == CARRIAGE_RETURN + && target .charAt( offset+1 ) == LINE_FEED)) + return -1; + break; + + case 'z': + if (offset != con.limit) return -1; + break; + + case 'b': + if (con.length == 0) return -1; + { + int after = getWordType(target, con.start, con.limit, offset, opts); + if (after == WT_IGNORE) return -1; + int before = getPreviousWordType(target, con.start, con.limit, offset, opts); + if (after == before) return -1; + } + break; + + case 'B': + if (con.length == 0) + go = true; + else { + int after = getWordType(target, con.start, con.limit, offset, opts); + go = after == WT_IGNORE + || after == getPreviousWordType(target, con.start, con.limit, offset, opts); + } + if (!go) return -1; + break; + + case '<': + if (con.length == 0 || offset == con.limit) return -1; + if (getWordType(target, con.start, con.limit, offset, opts) != WT_LETTER + || getPreviousWordType(target, con.start, con.limit, offset, opts) != WT_OTHER) + return -1; + break; + + case '>': + if (con.length == 0 || offset == con.start) return -1; + if (getWordType(target, con.start, con.limit, offset, opts) != WT_OTHER + || getPreviousWordType(target, con.start, con.limit, offset, opts) != WT_LETTER) + return -1; + break; + } // switch anchor type + op = op.next; + break; + + case Op.BACKREFERENCE: + { + int refno = op.getData(); + if (refno <= 0 || refno >= this.nofparen) + throw new RuntimeException("Internal Error: Reference number must be more than zero: "+refno); + if (con.match.getBeginning(refno) < 0 + || con.match.getEnd(refno) < 0) + return -1; // ******** + int o2 = con.match.getBeginning(refno); + int literallen = con.match.getEnd(refno)-o2; + if (!isSet(opts, IGNORE_CASE)) { + if (dx > 0) { + if (!regionMatches(target, offset, con.limit, o2, literallen)) + return -1; + offset += literallen; + } else { + if (!regionMatches(target, offset-literallen, con.limit, o2, literallen)) + return -1; + offset -= literallen; + } + } else { + if (dx > 0) { + if (!regionMatchesIgnoreCase(target, offset, con.limit, o2, literallen)) + return -1; + offset += literallen; + } else { + if (!regionMatchesIgnoreCase(target, offset-literallen, con.limit, + o2, literallen)) + return -1; + offset -= literallen; + } + } + } + op = op.next; + break; + case Op.STRING: + { + String literal = op.getString(); + int literallen = literal.length(); + if (!isSet(opts, IGNORE_CASE)) { + if (dx > 0) { + if (!regionMatches(target, offset, con.limit, literal, literallen)) + return -1; + offset += literallen; + } else { + if (!regionMatches(target, offset-literallen, con.limit, literal, literallen)) + return -1; + offset -= literallen; + } + } else { + if (dx > 0) { + if (!regionMatchesIgnoreCase(target, offset, con.limit, literal, literallen)) + return -1; + offset += literallen; + } else { + if (!regionMatchesIgnoreCase(target, offset-literallen, con.limit, + literal, literallen)) + return -1; + offset -= literallen; + } + } + } + op = op.next; + break; + + case Op.CLOSURE: + { + /* + * Saves current position to avoid + * zero-width repeats. + */ + int id = op.getData(); + if (id >= 0) { + int previousOffset = con.offsets[id]; + if (previousOffset < 0 || previousOffset != offset) { + con.offsets[id] = offset; + } else { + con.offsets[id] = -1; + op = op.next; + break; + } + } + int ret = this. matchString (con, op.getChild(), offset, dx, opts); + if (id >= 0) con.offsets[id] = -1; + if (ret >= 0) return ret; + op = op.next; + } + break; + + case Op.QUESTION: + { + int ret = this. matchString (con, op.getChild(), offset, dx, opts); + if (ret >= 0) return ret; + op = op.next; + } + break; + + case Op.NONGREEDYCLOSURE: + case Op.NONGREEDYQUESTION: + { + int ret = this. matchString (con, op.next, offset, dx, opts); + if (ret >= 0) return ret; + op = op.getChild(); + } + break; + + case Op.UNION: + for (int i = 0; i < op.size(); i ++) { + int ret = this. matchString (con, op.elementAt(i), offset, dx, opts); + if (DEBUG) { + System.err.println("UNION: "+i+", ret="+ret); + } + if (ret >= 0) return ret; + } + return -1; + + case Op.CAPTURE: + int refno = op.getData(); + if (con.match != null && refno > 0) { + int save = con.match.getBeginning(refno); + con.match.setBeginning(refno, offset); + int ret = this. matchString (con, op.next, offset, dx, opts); + if (ret < 0) con.match.setBeginning(refno, save); + return ret; + } else if (con.match != null && refno < 0) { + int index = -refno; + int save = con.match.getEnd(index); + con.match.setEnd(index, offset); + int ret = this. matchString (con, op.next, offset, dx, opts); + if (ret < 0) con.match.setEnd(index, save); + return ret; + } + op = op.next; + break; + + case Op.LOOKAHEAD: + if (0 > this. matchString (con, op.getChild(), offset, 1, opts)) return -1; + op = op.next; + break; + case Op.NEGATIVELOOKAHEAD: + if (0 <= this. matchString (con, op.getChild(), offset, 1, opts)) return -1; + op = op.next; + break; + case Op.LOOKBEHIND: + if (0 > this. matchString (con, op.getChild(), offset, -1, opts)) return -1; + op = op.next; + break; + case Op.NEGATIVELOOKBEHIND: + if (0 <= this. matchString (con, op.getChild(), offset, -1, opts)) return -1; + op = op.next; + break; + + case Op.INDEPENDENT: + { + int ret = this. matchString (con, op.getChild(), offset, dx, opts); + if (ret < 0) return ret; + offset = ret; + op = op.next; + } + break; + + case Op.MODIFIER: + { + int localopts = opts; + localopts |= op.getData(); + localopts &= ~op.getData2(); + //System.err.println("MODIFIER: "+Integer.toString(opts, 16)+" -> "+Integer.toString(localopts, 16)); + int ret = this. matchString (con, op.getChild(), offset, dx, localopts); + if (ret < 0) return ret; + offset = ret; + op = op.next; + } + break; + + case Op.CONDITION: + { + Op.ConditionOp cop = (Op.ConditionOp)op; + boolean matchp = false; + if (cop.refNumber > 0) { + if (cop.refNumber >= this.nofparen) + throw new RuntimeException("Internal Error: Reference number must be more than zero: "+cop.refNumber); + matchp = con.match.getBeginning(cop.refNumber) >= 0 + && con.match.getEnd(cop.refNumber) >= 0; + } else { + matchp = 0 <= this. matchString (con, cop.condition, offset, dx, opts); + } + + if (matchp) { + op = cop.yes; + } else if (cop.no != null) { + op = cop.no; + } else { + op = cop.next; + } + } + break; + + default: + throw new RuntimeException("Unknown operation type: "+op.type); + } // switch (op.type) + } // while + } + + private static final int getPreviousWordType(String target, int begin, int end, + int offset, int opts) { + int ret = getWordType(target, begin, end, --offset, opts); + while (ret == WT_IGNORE) + ret = getWordType(target, begin, end, --offset, opts); + return ret; + } + + private static final int getWordType(String target, int begin, int end, + int offset, int opts) { + if (offset < begin || offset >= end) return WT_OTHER; + return getWordType0( target .charAt( offset ) , opts); + } + + + private static final boolean regionMatches(String text, int offset, int limit, + String part, int partlen) { + if (limit-offset < partlen) return false; + return text.regionMatches(offset, part, 0, partlen); + } + + private static final boolean regionMatches(String text, int offset, int limit, + int offset2, int partlen) { + if (limit-offset < partlen) return false; + return text.regionMatches(offset, text, offset2, partlen); + } + + private static final boolean regionMatchesIgnoreCase(String text, int offset, int limit, + String part, int partlen) { + return text.regionMatches(true, offset, part, 0, partlen); + } + + private static final boolean regionMatchesIgnoreCase(String text, int offset, int limit, + int offset2, int partlen) { + if (limit-offset < partlen) return false; + return text.regionMatches(true, offset, text, offset2, partlen); + } + + + + + + + + /** + * Checks whether the target text contains this pattern or not. + * + * @return true if the target is matched to this regular expression. + */ + public boolean matches(CharacterIterator target) { + return this.matches(target, (Match)null); + } + + + /** + * Checks whether the target text contains this pattern or not. + * + * @param match A Match instance for storing matching result. + * @return Offset of the start position in target; or -1 if not match. + */ + public boolean matches(CharacterIterator target, Match match) { + int start = target.getBeginIndex(); + int end = target.getEndIndex(); + + + + synchronized (this) { + if (this.operations == null) + this.prepare(); + if (this.context == null) + this.context = new Context(); + } + Context con = null; + synchronized (this.context) { + con = this.context.inuse ? new Context() : this.context; + con.reset(target, start, end, this.numberOfClosures); + } + if (match != null) { + match.setNumberOfGroups(this.nofparen); + match.setSource(target); + } else if (this.hasBackReferences) { + match = new Match(); + match.setNumberOfGroups(this.nofparen); + // Need not to call setSource() because + // a caller can not access this match instance. + } + con.match = match; + + if (RegularExpression.isSet(this.options, XMLSCHEMA_MODE)) { + int matchEnd = this. matchCharacterIterator (con, this.operations, con.start, 1, this.options); + //System.err.println("DEBUG: matchEnd="+matchEnd); + if (matchEnd == con.limit) { + if (con.match != null) { + con.match.setBeginning(0, con.start); + con.match.setEnd(0, matchEnd); + } + con.inuse = false; + return true; + } + return false; + } + + /* + * The pattern has only fixed string. + * The engine uses Boyer-Moore. + */ + if (this.fixedStringOnly) { + //System.err.println("DEBUG: fixed-only: "+this.fixedString); + int o = this.fixedStringTable.matches(target, con.start, con.limit); + if (o >= 0) { + if (con.match != null) { + con.match.setBeginning(0, o); + con.match.setEnd(0, o+this.fixedString.length()); + } + con.inuse = false; + return true; + } + con.inuse = false; + return false; + } + + /* + * The pattern contains a fixed string. + * The engine checks with Boyer-Moore whether the text contains the fixed string or not. + * If not, it return with false. + */ + if (this.fixedString != null) { + int o = this.fixedStringTable.matches(target, con.start, con.limit); + if (o < 0) { + //System.err.println("Non-match in fixed-string search."); + con.inuse = false; + return false; + } + } + + int limit = con.limit-this.minlength; + int matchStart; + int matchEnd = -1; + + /* + * Checks whether the expression starts with ".*". + */ + if (this.operations != null + && this.operations.type == Op.CLOSURE && this.operations.getChild().type == Op.DOT) { + if (isSet(this.options, SINGLE_LINE)) { + matchStart = con.start; + matchEnd = this. matchCharacterIterator (con, this.operations, con.start, 1, this.options); + } else { + boolean previousIsEOL = true; + for (matchStart = con.start; matchStart <= limit; matchStart ++) { + int ch = target .setIndex( matchStart ) ; + if (isEOLChar(ch)) { + previousIsEOL = true; + } else { + if (previousIsEOL) { + if (0 <= (matchEnd = this. matchCharacterIterator (con, this.operations, + matchStart, 1, this.options))) + break; + } + previousIsEOL = false; + } + } + } + } + + /* + * Optimization against the first character. + */ + else if (this.firstChar != null) { + //System.err.println("DEBUG: with firstchar-matching: "+this.firstChar); + RangeToken range = this.firstChar; + if (RegularExpression.isSet(this.options, IGNORE_CASE)) { + range = this.firstChar.getCaseInsensitiveToken(); + for (matchStart = con.start; matchStart <= limit; matchStart ++) { + int ch = target .setIndex( matchStart ) ; + if (REUtil.isHighSurrogate(ch) && matchStart+1 < con.limit) { + ch = REUtil.composeFromSurrogates(ch, target .setIndex( matchStart+1 ) ); + if (!range.match(ch)) continue; + } else { + if (!range.match(ch)) { + char ch1 = Character.toUpperCase((char)ch); + if (!range.match(ch1)) + if (!range.match(Character.toLowerCase(ch1))) + continue; + } + } + if (0 <= (matchEnd = this. matchCharacterIterator (con, this.operations, + matchStart, 1, this.options))) + break; + } + } else { + for (matchStart = con.start; matchStart <= limit; matchStart ++) { + int ch = target .setIndex( matchStart ) ; + if (REUtil.isHighSurrogate(ch) && matchStart+1 < con.limit) + ch = REUtil.composeFromSurrogates(ch, target .setIndex( matchStart+1 ) ); + if (!range.match(ch)) continue; + if (0 <= (matchEnd = this. matchCharacterIterator (con, this.operations, + matchStart, 1, this.options))) + break; + } + } + } + + /* + * Straightforward matching. + */ + else { + for (matchStart = con.start; matchStart <= limit; matchStart ++) { + if (0 <= (matchEnd = this. matchCharacterIterator (con, this.operations, matchStart, 1, this.options))) + break; + } + } + + if (matchEnd >= 0) { + if (con.match != null) { + con.match.setBeginning(0, matchStart); + con.match.setEnd(0, matchEnd); + } + con.inuse = false; + return true; + } else { + con.inuse = false; + return false; + } + } + + /** + * @return -1 when not match; offset of the end of matched string when match. + */ + private int matchCharacterIterator (Context con, Op op, int offset, int dx, int opts) { + + + CharacterIterator target = con.ciTarget; + + + + + + + while (true) { + if (op == null) + return isSet(opts, XMLSCHEMA_MODE) && offset != con.limit ? -1 : offset; + if (offset > con.limit || offset < con.start) + return -1; + switch (op.type) { + case Op.CHAR: + if (isSet(opts, IGNORE_CASE)) { + int ch = op.getData(); + if (dx > 0) { + if (offset >= con.limit || !matchIgnoreCase(ch, target .setIndex( offset ) )) + return -1; + offset ++; + } else { + int o1 = offset-1; + if (o1 >= con.limit || o1 < 0 || !matchIgnoreCase(ch, target .setIndex( o1 ) )) + return -1; + offset = o1; + } + } else { + int ch = op.getData(); + if (dx > 0) { + if (offset >= con.limit || ch != target .setIndex( offset ) ) + return -1; + offset ++; + } else { + int o1 = offset-1; + if (o1 >= con.limit || o1 < 0 || ch != target .setIndex( o1 ) ) + return -1; + offset = o1; + } + } + op = op.next; + break; + + case Op.DOT: + if (dx > 0) { + if (offset >= con.limit) + return -1; + int ch = target .setIndex( offset ) ; + if (isSet(opts, SINGLE_LINE)) { + if (REUtil.isHighSurrogate(ch) && offset+1 < con.limit) + offset ++; + } else { + if (REUtil.isHighSurrogate(ch) && offset+1 < con.limit) + ch = REUtil.composeFromSurrogates(ch, target .setIndex( ++offset ) ); + if (isEOLChar(ch)) + return -1; + } + offset ++; + } else { + int o1 = offset-1; + if (o1 >= con.limit || o1 < 0) + return -1; + int ch = target .setIndex( o1 ) ; + if (isSet(opts, SINGLE_LINE)) { + if (REUtil.isLowSurrogate(ch) && o1-1 >= 0) + o1 --; + } else { + if (REUtil.isLowSurrogate(ch) && o1-1 >= 0) + ch = REUtil.composeFromSurrogates( target .setIndex( --o1 ) , ch); + if (!isEOLChar(ch)) + return -1; + } + offset = o1; + } + op = op.next; + break; + + case Op.RANGE: + case Op.NRANGE: + if (dx > 0) { + if (offset >= con.limit) + return -1; + int ch = target .setIndex( offset ) ; + if (REUtil.isHighSurrogate(ch) && offset+1 < con.limit) + ch = REUtil.composeFromSurrogates(ch, target .setIndex( ++offset ) ); + RangeToken tok = op.getToken(); + if (isSet(opts, IGNORE_CASE)) { + tok = tok.getCaseInsensitiveToken(); + if (!tok.match(ch)) { + if (ch >= 0x10000) return -1; + char uch; + if (!tok.match(uch = Character.toUpperCase((char)ch)) + && !tok.match(Character.toLowerCase(uch))) + return -1; + } + } else { + if (!tok.match(ch)) return -1; + } + offset ++; + } else { + int o1 = offset-1; + if (o1 >= con.limit || o1 < 0) + return -1; + int ch = target .setIndex( o1 ) ; + if (REUtil.isLowSurrogate(ch) && o1-1 >= 0) + ch = REUtil.composeFromSurrogates( target .setIndex( --o1 ) , ch); + RangeToken tok = op.getToken(); + if (isSet(opts, IGNORE_CASE)) { + tok = tok.getCaseInsensitiveToken(); + if (!tok.match(ch)) { + if (ch >= 0x10000) return -1; + char uch; + if (!tok.match(uch = Character.toUpperCase((char)ch)) + && !tok.match(Character.toLowerCase(uch))) + return -1; + } + } else { + if (!tok.match(ch)) return -1; + } + offset = o1; + } + op = op.next; + break; + + case Op.ANCHOR: + boolean go = false; + switch (op.getData()) { + case '^': + if (isSet(opts, MULTIPLE_LINES)) { + if (!(offset == con.start + || offset > con.start && isEOLChar( target .setIndex( offset-1 ) ))) + return -1; + } else { + if (offset != con.start) + return -1; + } + break; + + case '@': // Internal use only. + // The @ always matches line beginnings. + if (!(offset == con.start + || offset > con.start && isEOLChar( target .setIndex( offset-1 ) ))) + return -1; + break; + + case '$': + if (isSet(opts, MULTIPLE_LINES)) { + if (!(offset == con.limit + || offset < con.limit && isEOLChar( target .setIndex( offset ) ))) + return -1; + } else { + if (!(offset == con.limit + || offset+1 == con.limit && isEOLChar( target .setIndex( offset ) ) + || offset+2 == con.limit && target .setIndex( offset ) == CARRIAGE_RETURN + && target .setIndex( offset+1 ) == LINE_FEED)) + return -1; + } + break; + + case 'A': + if (offset != con.start) return -1; + break; + + case 'Z': + if (!(offset == con.limit + || offset+1 == con.limit && isEOLChar( target .setIndex( offset ) ) + || offset+2 == con.limit && target .setIndex( offset ) == CARRIAGE_RETURN + && target .setIndex( offset+1 ) == LINE_FEED)) + return -1; + break; + + case 'z': + if (offset != con.limit) return -1; + break; + + case 'b': + if (con.length == 0) return -1; + { + int after = getWordType(target, con.start, con.limit, offset, opts); + if (after == WT_IGNORE) return -1; + int before = getPreviousWordType(target, con.start, con.limit, offset, opts); + if (after == before) return -1; + } + break; + + case 'B': + if (con.length == 0) + go = true; + else { + int after = getWordType(target, con.start, con.limit, offset, opts); + go = after == WT_IGNORE + || after == getPreviousWordType(target, con.start, con.limit, offset, opts); + } + if (!go) return -1; + break; + + case '<': + if (con.length == 0 || offset == con.limit) return -1; + if (getWordType(target, con.start, con.limit, offset, opts) != WT_LETTER + || getPreviousWordType(target, con.start, con.limit, offset, opts) != WT_OTHER) + return -1; + break; + + case '>': + if (con.length == 0 || offset == con.start) return -1; + if (getWordType(target, con.start, con.limit, offset, opts) != WT_OTHER + || getPreviousWordType(target, con.start, con.limit, offset, opts) != WT_LETTER) + return -1; + break; + } // switch anchor type + op = op.next; + break; + + case Op.BACKREFERENCE: + { + int refno = op.getData(); + if (refno <= 0 || refno >= this.nofparen) + throw new RuntimeException("Internal Error: Reference number must be more than zero: "+refno); + if (con.match.getBeginning(refno) < 0 + || con.match.getEnd(refno) < 0) + return -1; // ******** + int o2 = con.match.getBeginning(refno); + int literallen = con.match.getEnd(refno)-o2; + if (!isSet(opts, IGNORE_CASE)) { + if (dx > 0) { + if (!regionMatches(target, offset, con.limit, o2, literallen)) + return -1; + offset += literallen; + } else { + if (!regionMatches(target, offset-literallen, con.limit, o2, literallen)) + return -1; + offset -= literallen; + } + } else { + if (dx > 0) { + if (!regionMatchesIgnoreCase(target, offset, con.limit, o2, literallen)) + return -1; + offset += literallen; + } else { + if (!regionMatchesIgnoreCase(target, offset-literallen, con.limit, + o2, literallen)) + return -1; + offset -= literallen; + } + } + } + op = op.next; + break; + case Op.STRING: + { + String literal = op.getString(); + int literallen = literal.length(); + if (!isSet(opts, IGNORE_CASE)) { + if (dx > 0) { + if (!regionMatches(target, offset, con.limit, literal, literallen)) + return -1; + offset += literallen; + } else { + if (!regionMatches(target, offset-literallen, con.limit, literal, literallen)) + return -1; + offset -= literallen; + } + } else { + if (dx > 0) { + if (!regionMatchesIgnoreCase(target, offset, con.limit, literal, literallen)) + return -1; + offset += literallen; + } else { + if (!regionMatchesIgnoreCase(target, offset-literallen, con.limit, + literal, literallen)) + return -1; + offset -= literallen; + } + } + } + op = op.next; + break; + + case Op.CLOSURE: + { + /* + * Saves current position to avoid + * zero-width repeats. + */ + int id = op.getData(); + if (id >= 0) { + int previousOffset = con.offsets[id]; + if (previousOffset < 0 || previousOffset != offset) { + con.offsets[id] = offset; + } else { + con.offsets[id] = -1; + op = op.next; + break; + } + } + + int ret = this. matchCharacterIterator (con, op.getChild(), offset, dx, opts); + if (id >= 0) con.offsets[id] = -1; + if (ret >= 0) return ret; + op = op.next; + } + break; + + case Op.QUESTION: + { + int ret = this. matchCharacterIterator (con, op.getChild(), offset, dx, opts); + if (ret >= 0) return ret; + op = op.next; + } + break; + + case Op.NONGREEDYCLOSURE: + case Op.NONGREEDYQUESTION: + { + int ret = this. matchCharacterIterator (con, op.next, offset, dx, opts); + if (ret >= 0) return ret; + op = op.getChild(); + } + break; + + case Op.UNION: + for (int i = 0; i < op.size(); i ++) { + int ret = this. matchCharacterIterator (con, op.elementAt(i), offset, dx, opts); + if (DEBUG) { + System.err.println("UNION: "+i+", ret="+ret); + } + if (ret >= 0) return ret; + } + return -1; + + case Op.CAPTURE: + int refno = op.getData(); + if (con.match != null && refno > 0) { + int save = con.match.getBeginning(refno); + con.match.setBeginning(refno, offset); + int ret = this. matchCharacterIterator (con, op.next, offset, dx, opts); + if (ret < 0) con.match.setBeginning(refno, save); + return ret; + } else if (con.match != null && refno < 0) { + int index = -refno; + int save = con.match.getEnd(index); + con.match.setEnd(index, offset); + int ret = this. matchCharacterIterator (con, op.next, offset, dx, opts); + if (ret < 0) con.match.setEnd(index, save); + return ret; + } + op = op.next; + break; + + case Op.LOOKAHEAD: + if (0 > this. matchCharacterIterator (con, op.getChild(), offset, 1, opts)) return -1; + op = op.next; + break; + case Op.NEGATIVELOOKAHEAD: + if (0 <= this. matchCharacterIterator (con, op.getChild(), offset, 1, opts)) return -1; + op = op.next; + break; + case Op.LOOKBEHIND: + if (0 > this. matchCharacterIterator (con, op.getChild(), offset, -1, opts)) return -1; + op = op.next; + break; + case Op.NEGATIVELOOKBEHIND: + if (0 <= this. matchCharacterIterator (con, op.getChild(), offset, -1, opts)) return -1; + op = op.next; + break; + + case Op.INDEPENDENT: + { + int ret = this. matchCharacterIterator (con, op.getChild(), offset, dx, opts); + if (ret < 0) return ret; + offset = ret; + op = op.next; + } + break; + + case Op.MODIFIER: + { + int localopts = opts; + localopts |= op.getData(); + localopts &= ~op.getData2(); + //System.err.println("MODIFIER: "+Integer.toString(opts, 16)+" -> "+Integer.toString(localopts, 16)); + int ret = this. matchCharacterIterator (con, op.getChild(), offset, dx, localopts); + if (ret < 0) return ret; + offset = ret; + op = op.next; + } + break; + + case Op.CONDITION: + { + Op.ConditionOp cop = (Op.ConditionOp)op; + boolean matchp = false; + if (cop.refNumber > 0) { + if (cop.refNumber >= this.nofparen) + throw new RuntimeException("Internal Error: Reference number must be more than zero: "+cop.refNumber); + matchp = con.match.getBeginning(cop.refNumber) >= 0 + && con.match.getEnd(cop.refNumber) >= 0; + } else { + matchp = 0 <= this. matchCharacterIterator (con, cop.condition, offset, dx, opts); + } + + if (matchp) { + op = cop.yes; + } else if (cop.no != null) { + op = cop.no; + } else { + op = cop.next; + } + } + break; + + default: + throw new RuntimeException("Unknown operation type: "+op.type); + } // switch (op.type) + } // while + } + + private static final int getPreviousWordType(CharacterIterator target, int begin, int end, + int offset, int opts) { + int ret = getWordType(target, begin, end, --offset, opts); + while (ret == WT_IGNORE) + ret = getWordType(target, begin, end, --offset, opts); + return ret; + } + + private static final int getWordType(CharacterIterator target, int begin, int end, + int offset, int opts) { + if (offset < begin || offset >= end) return WT_OTHER; + return getWordType0( target .setIndex( offset ) , opts); + } + + + + private static final boolean regionMatches(CharacterIterator target, int offset, int limit, + String part, int partlen) { + if (offset < 0) return false; + if (limit-offset < partlen) + return false; + int i = 0; + while (partlen-- > 0) { + if ( target .setIndex( offset++ ) != part.charAt(i++)) + return false; + } + return true; + } + + private static final boolean regionMatches(CharacterIterator target, int offset, int limit, + int offset2, int partlen) { + if (offset < 0) return false; + if (limit-offset < partlen) + return false; + int i = offset2; + while (partlen-- > 0) { + if ( target .setIndex( offset++ ) != target .setIndex( i++ ) ) + return false; + } + return true; + } + + /** + * @see java.lang.String#regionMatches + */ + private static final boolean regionMatchesIgnoreCase(CharacterIterator target, int offset, int limit, + String part, int partlen) { + if (offset < 0) return false; + if (limit-offset < partlen) + return false; + int i = 0; + while (partlen-- > 0) { + char ch1 = target .setIndex( offset++ ) ; + char ch2 = part.charAt(i++); + if (ch1 == ch2) + continue; + char uch1 = Character.toUpperCase(ch1); + char uch2 = Character.toUpperCase(ch2); + if (uch1 == uch2) + continue; + if (Character.toLowerCase(uch1) != Character.toLowerCase(uch2)) + return false; + } + return true; + } + + private static final boolean regionMatchesIgnoreCase(CharacterIterator target, int offset, int limit, + int offset2, int partlen) { + if (offset < 0) return false; + if (limit-offset < partlen) + return false; + int i = offset2; + while (partlen-- > 0) { + char ch1 = target .setIndex( offset++ ) ; + char ch2 = target .setIndex( i++ ) ; + if (ch1 == ch2) + continue; + char uch1 = Character.toUpperCase(ch1); + char uch2 = Character.toUpperCase(ch2); + if (uch1 == uch2) + continue; + if (Character.toLowerCase(uch1) != Character.toLowerCase(uch2)) + return false; + } + return true; + } + + + + + // ================================================================ + + /** + * A regular expression. + * @serial + */ + String regex; + /** + * @serial + */ + int options; + + /** + * The number of parenthesis in the regular expression. + * @serial + */ + int nofparen; + /** + * Internal representation of the regular expression. + * @serial + */ + Token tokentree; + + boolean hasBackReferences = false; + + transient int minlength; + transient Op operations = null; + transient int numberOfClosures; + transient Context context = null; + transient RangeToken firstChar = null; + + transient String fixedString = null; + transient int fixedStringOptions; + transient BMPattern fixedStringTable = null; + transient boolean fixedStringOnly = false; + + + static final class Context { + CharacterIterator ciTarget; + String strTarget; + char[] charTarget; + int start; + int limit; + int length; + Match match; + boolean inuse = false; + int[] offsets; + + Context() { + } + + private void resetCommon(int nofclosures) { + this.length = this.limit-this.start; + this.inuse = true; + this.match = null; + if (this.offsets == null || this.offsets.length != nofclosures) + this.offsets = new int[nofclosures]; + for (int i = 0; i < nofclosures; i ++) this.offsets[i] = -1; + } + void reset(CharacterIterator target, int start, int limit, int nofclosures) { + this.ciTarget = target; + this.start = start; + this.limit = limit; + this.resetCommon(nofclosures); + } + void reset(String target, int start, int limit, int nofclosures) { + this.strTarget = target; + this.start = start; + this.limit = limit; + this.resetCommon(nofclosures); + } + void reset(char[] target, int start, int limit, int nofclosures) { + this.charTarget = target; + this.start = start; + this.limit = limit; + this.resetCommon(nofclosures); + } + } + + /** + * Prepares for matching. This method is called just before starting matching. + */ + void prepare() { + if (Op.COUNT) Op.nofinstances = 0; + this.compile(this.tokentree); + /* + if (this.operations.type == Op.CLOSURE && this.operations.getChild().type == Op.DOT) { // .* + Op anchor = Op.createAnchor(isSet(this.options, SINGLE_LINE) ? 'A' : '@'); + anchor.next = this.operations; + this.operations = anchor; + } + */ + if (Op.COUNT) System.err.println("DEBUG: The number of operations: "+Op.nofinstances); + + this.minlength = this.tokentree.getMinLength(); + + this.firstChar = null; + if (!isSet(this.options, PROHIBIT_HEAD_CHARACTER_OPTIMIZATION) + && !isSet(this.options, XMLSCHEMA_MODE)) { + RangeToken firstChar = Token.createRange(); + int fresult = this.tokentree.analyzeFirstCharacter(firstChar, this.options); + if (fresult == Token.FC_TERMINAL) { + firstChar.compactRanges(); + this.firstChar = firstChar; + if (DEBUG) + System.err.println("DEBUG: Use the first character optimization: "+firstChar); + } + } + + if (this.operations != null + && (this.operations.type == Op.STRING || this.operations.type == Op.CHAR) + && this.operations.next == null) { + if (DEBUG) + System.err.print(" *** Only fixed string! *** "); + this.fixedStringOnly = true; + if (this.operations.type == Op.STRING) + this.fixedString = this.operations.getString(); + else if (this.operations.getData() >= 0x10000) { // Op.CHAR + this.fixedString = REUtil.decomposeToSurrogates(this.operations.getData()); + } else { + char[] ac = new char[1]; + ac[0] = (char)this.operations.getData(); + this.fixedString = new String(ac); + } + this.fixedStringOptions = this.options; + this.fixedStringTable = new BMPattern(this.fixedString, 256, + isSet(this.fixedStringOptions, IGNORE_CASE)); + } else if (!isSet(this.options, PROHIBIT_FIXED_STRING_OPTIMIZATION) + && !isSet(this.options, XMLSCHEMA_MODE)) { + Token.FixedStringContainer container = new Token.FixedStringContainer(); + this.tokentree.findFixedString(container, this.options); + this.fixedString = container.token == null ? null : container.token.getString(); + this.fixedStringOptions = container.options; + if (this.fixedString != null && this.fixedString.length() < 2) + this.fixedString = null; + // This pattern has a fixed string of which length is more than one. + if (this.fixedString != null) { + this.fixedStringTable = new BMPattern(this.fixedString, 256, + isSet(this.fixedStringOptions, IGNORE_CASE)); + if (DEBUG) { + System.err.println("DEBUG: The longest fixed string: "+this.fixedString.length() + +"/" //+this.fixedString + +"/"+REUtil.createOptionString(this.fixedStringOptions)); + System.err.print("String: "); + REUtil.dumpString(this.fixedString); + } + } + } + } + + /** + * An option. + * If you specify this option, (X) + * captures matched text, and (:?X) + * does not capture. + * + * @see #RegularExpression(java.lang.String,int) + * @see #setPattern(java.lang.String,int) + static final int MARK_PARENS = 1<<0; + */ + + /** + * "i" + */ + static final int IGNORE_CASE = 1<<1; + + /** + * "s" + */ + static final int SINGLE_LINE = 1<<2; + + /** + * "m" + */ + static final int MULTIPLE_LINES = 1<<3; + + /** + * "x" + */ + static final int EXTENDED_COMMENT = 1<<4; + + /** + * This option redefines \d \D \w \W \s \S. + * + * @see #RegularExpression(java.lang.String,int) + * @see #setPattern(java.lang.String,int) + * @see #UNICODE_WORD_BOUNDARY + */ + static final int USE_UNICODE_CATEGORY = 1<<5; // "u" + + /** + * An option. + * This enables to process locale-independent word boundary for \b \B \< \>. + *

    By default, the engine considers a position between a word character + * (\w) and a non word character + * is a word boundary. + *

    By this option, the engine checks word boundaries with the method of + * 'Unicode Regular Expression Guidelines' Revision 4. + * + * @see #RegularExpression(java.lang.String,int) + * @see #setPattern(java.lang.String,int) + */ + static final int UNICODE_WORD_BOUNDARY = 1<<6; // "w" + + /** + * "H" + */ + static final int PROHIBIT_HEAD_CHARACTER_OPTIMIZATION = 1<<7; + /** + * "F" + */ + static final int PROHIBIT_FIXED_STRING_OPTIMIZATION = 1<<8; + /** + * "X". XML Schema mode. + */ + static final int XMLSCHEMA_MODE = 1<<9; + /** + * ",". + */ + static final int SPECIAL_COMMA = 1<<10; + + + private static final boolean isSet(int options, int flag) { + return (options & flag) == flag; + } + + /** + * Creates a new RegularExpression instance. + * + * @param regex A regular expression + * @exception org.apache.xerces.utils.regex.ParseException regex is not conforming to the syntax. + */ + public RegularExpression(String regex) throws ParseException { + this.setPattern(regex, null); + } + + /** + * Creates a new RegularExpression instance with options. + * + * @param regex A regular expression + * @param options A String consisted of "i" "m" "s" "u" "w" "," "X" + * @exception org.apache.xerces.utils.regex.ParseException regex is not conforming to the syntax. + */ + public RegularExpression(String regex, String options) throws ParseException { + this.setPattern(regex, options); + } + + RegularExpression(String regex, Token tok, int parens, boolean hasBackReferences, int options) { + this.regex = regex; + this.tokentree = tok; + this.nofparen = parens; + this.options = options; + this.hasBackReferences = hasBackReferences; + } + + /** + * + */ + public void setPattern(String newPattern) throws ParseException { + this.setPattern(newPattern, this.options); + } + + private void setPattern(String newPattern, int options) throws ParseException { + this.regex = newPattern; + this.options = options; + RegexParser rp = RegularExpression.isSet(this.options, RegularExpression.XMLSCHEMA_MODE) + ? new ParserForXMLSchema() : new RegexParser(); + this.tokentree = rp.parse(this.regex, this.options); + this.nofparen = rp.parennumber; + this.hasBackReferences = rp.hasBackReferences; + + this.operations = null; + this.context = null; + } + /** + * + */ + public void setPattern(String newPattern, String options) throws ParseException { + this.setPattern(newPattern, REUtil.parseOptions(options)); + } + + /** + * + */ + public String getPattern() { + return this.regex; + } + + /** + * Represents this instence in String. + */ + public String toString() { + return this.tokentree.toString(this.options); + } + + /** + * Returns a option string. + * The order of letters in it may be different from a string specified + * in a constructor or setPattern(). + * + * @see #RegularExpression(java.lang.String,java.lang.String) + * @see #setPattern(java.lang.String,java.lang.String) + */ + public String getOptions() { + return REUtil.createOptionString(this.options); + } + + /** + * Return true if patterns are the same and the options are equivalent. + */ + public boolean equals(Object obj) { + if (obj == null) return false; + if (!(obj instanceof RegularExpression)) + return false; + RegularExpression r = (RegularExpression)obj; + return this.regex.equals(r.regex) && this.options == r.options; + } + + boolean equals(String pattern, int options) { + return this.regex.equals(pattern) && this.options == options; + } + + /** + * + */ + public int hashCode() { + return (this.regex+"/"+this.getOptions()).hashCode(); + } + + /** + * Return the number of regular expression groups. + * This method returns 1 when the regular expression has no capturing-parenthesis. + * + */ + public int getNumberOfGroups() { + return this.nofparen; + } + + // ================================================================ + + private static final int WT_IGNORE = 0; + private static final int WT_LETTER = 1; + private static final int WT_OTHER = 2; + private static final int getWordType0(char ch, int opts) { + if (!isSet(opts, UNICODE_WORD_BOUNDARY)) { + if (isSet(opts, USE_UNICODE_CATEGORY)) { + return (Token.getRange("IsWord", true).match(ch)) ? WT_LETTER : WT_OTHER; + } + return isWordChar(ch) ? WT_LETTER : WT_OTHER; + } + + switch (Character.getType(ch)) { + case Character.UPPERCASE_LETTER: // L + case Character.LOWERCASE_LETTER: // L + case Character.TITLECASE_LETTER: // L + case Character.MODIFIER_LETTER: // L + case Character.OTHER_LETTER: // L + case Character.LETTER_NUMBER: // N + case Character.DECIMAL_DIGIT_NUMBER: // N + case Character.OTHER_NUMBER: // N + case Character.COMBINING_SPACING_MARK: // Mc + return WT_LETTER; + + case Character.FORMAT: // Cf + case Character.NON_SPACING_MARK: // Mn + case Character.ENCLOSING_MARK: // Mc + return WT_IGNORE; + + case Character.CONTROL: // Cc + switch (ch) { + case '\t': + case '\n': + case '\u000B': + case '\f': + case '\r': + return WT_OTHER; + default: + return WT_IGNORE; + } + + default: + return WT_OTHER; + } + } + + // ================================================================ + + static final int LINE_FEED = 0x000A; + static final int CARRIAGE_RETURN = 0x000D; + static final int LINE_SEPARATOR = 0x2028; + static final int PARAGRAPH_SEPARATOR = 0x2029; + + private static final boolean isEOLChar(int ch) { + return ch == LINE_FEED || ch == CARRIAGE_RETURN || ch == LINE_SEPARATOR + || ch == PARAGRAPH_SEPARATOR; + } + + private static final boolean isWordChar(int ch) { // Legacy word characters + if (ch == '_') return true; + if (ch < '0') return false; + if (ch > 'z') return false; + if (ch <= '9') return true; + if (ch < 'A') return false; + if (ch <= 'Z') return true; + if (ch < 'a') return false; + return true; + } + + private static final boolean matchIgnoreCase(int chardata, int ch) { + if (chardata == ch) return true; + if (chardata > 0xffff || ch > 0xffff) return false; + char uch1 = Character.toUpperCase((char)chardata); + char uch2 = Character.toUpperCase((char)ch); + if (uch1 == uch2) return true; + return Character.toLowerCase(uch1) == Character.toLowerCase(uch2); + } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/regex/SchemaRegularExpression.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/regex/SchemaRegularExpression.java new file mode 100644 index 000000000..7aa15573e --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/regex/SchemaRegularExpression.java @@ -0,0 +1,51 @@ +/* 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.regex; + +import org.apache.xmlbeans.impl.common.XMLChar; + +import java.util.HashMap; +import java.util.Map; + +public class SchemaRegularExpression extends RegularExpression +{ + private SchemaRegularExpression(String pattern) + { + super(pattern, "X"); + } + + public static RegularExpression forPattern(String s) + { + SchemaRegularExpression tre = (SchemaRegularExpression)knownPatterns.get(s); + if (tre != null) + return tre; + return new RegularExpression(s, "X"); + } + + static final Map knownPatterns = buildKnownPatternMap(); + + private static Map buildKnownPatternMap() + { + Map result = new HashMap(); + result.put("\\c+", new SchemaRegularExpression("\\c+") + { public boolean matches(String s) { return XMLChar.isValidNmtoken(s); } } ); + result.put("\\i\\c*", new SchemaRegularExpression("\\i\\c*") + { public boolean matches(String s) { return XMLChar.isValidName(s); } } ); + result.put("[\\i-[:]][\\c-[:]]*", new SchemaRegularExpression("[\\i-[:]][\\c-[:]]*") + { public boolean matches(String s) { return XMLChar.isValidNCName(s); } } ); + return result; + } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/regex/Token.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/regex/Token.java new file mode 100644 index 000000000..6d85fb2a5 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/regex/Token.java @@ -0,0 +1,1518 @@ +/* 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.regex; + +import java.util.Vector; +import java.util.Hashtable; + +/** + * This class represents a node in parse tree. + */ +class Token implements java.io.Serializable { + static final boolean COUNTTOKENS = true; + static int tokens = 0; + + static final int CHAR = 0; // Literal char + static final int DOT = 11; // . + static final int CONCAT = 1; // XY + static final int UNION = 2; // X|Y|Z + static final int CLOSURE = 3; // X* + static final int RANGE = 4; // [a-zA-Z] etc. + static final int NRANGE = 5; // [^a-zA-Z] etc. + static final int PAREN = 6; // (X) or (?:X) + static final int EMPTY = 7; // + static final int ANCHOR = 8; // ^ $ \b \B \< \> \A \Z \z + static final int NONGREEDYCLOSURE = 9; // *? +? + static final int STRING = 10; // strings + static final int BACKREFERENCE = 12; // back references + static final int LOOKAHEAD = 20; // (?=...) + static final int NEGATIVELOOKAHEAD = 21; // (?!...) + static final int LOOKBEHIND = 22; // (?<=...) + static final int NEGATIVELOOKBEHIND = 23; // (?...) + static final int MODIFIERGROUP = 25; // (?ims-ims:...) + static final int CONDITION = 26; // (?(...)yes|no) + + static final int UTF16_MAX = 0x10ffff; + + int type; + + static Token token_dot; + static Token token_0to9; + static Token token_wordchars; + static Token token_not_0to9; + static Token token_not_wordchars; + static Token token_spaces; + static Token token_not_spaces; + static Token token_empty; + static Token token_linebeginning; + static Token token_linebeginning2; + static Token token_lineend; + static Token token_stringbeginning; + static Token token_stringend; + static Token token_stringend2; + static Token token_wordedge; + static Token token_not_wordedge; + static Token token_wordbeginning; + static Token token_wordend; + static { + Token.token_empty = new Token(Token.EMPTY); + + Token.token_linebeginning = Token.createAnchor('^'); + Token.token_linebeginning2 = Token.createAnchor('@'); + Token.token_lineend = Token.createAnchor('$'); + Token.token_stringbeginning = Token.createAnchor('A'); + Token.token_stringend = Token.createAnchor('z'); + Token.token_stringend2 = Token.createAnchor('Z'); + Token.token_wordedge = Token.createAnchor('b'); + Token.token_not_wordedge = Token.createAnchor('B'); + Token.token_wordbeginning = Token.createAnchor('<'); + Token.token_wordend = Token.createAnchor('>'); + + Token.token_dot = new Token(Token.DOT); + + Token.token_0to9 = Token.createRange(); + Token.token_0to9.addRange('0', '9'); + Token.token_wordchars = Token.createRange(); + Token.token_wordchars.addRange('0', '9'); + Token.token_wordchars.addRange('A', 'Z'); + Token.token_wordchars.addRange('_', '_'); + Token.token_wordchars.addRange('a', 'z'); + Token.token_spaces = Token.createRange(); + Token.token_spaces.addRange('\t', '\t'); + Token.token_spaces.addRange('\n', '\n'); + Token.token_spaces.addRange('\f', '\f'); + Token.token_spaces.addRange('\r', '\r'); + Token.token_spaces.addRange(' ', ' '); + + Token.token_not_0to9 = Token.complementRanges(Token.token_0to9); + Token.token_not_wordchars = Token.complementRanges(Token.token_wordchars); + Token.token_not_spaces = Token.complementRanges(Token.token_spaces); + } + + static Token.ParenToken createLook(int type, Token child) { + if (COUNTTOKENS) Token.tokens ++; + return new Token.ParenToken(type, child, 0); + } + static Token.ParenToken createParen(Token child, int pnumber) { + if (COUNTTOKENS) Token.tokens ++; + return new Token.ParenToken(Token.PAREN, child, pnumber); + } + static Token.ClosureToken createClosure(Token tok) { + if (COUNTTOKENS) Token.tokens ++; + return new Token.ClosureToken(Token.CLOSURE, tok); + } + static Token.ClosureToken createNGClosure(Token tok) { + if (COUNTTOKENS) Token.tokens ++; + return new Token.ClosureToken(Token.NONGREEDYCLOSURE, tok); + } + static Token.ConcatToken createConcat(Token tok1, Token tok2) { + if (COUNTTOKENS) Token.tokens ++; + return new Token.ConcatToken(tok1, tok2); + } + static Token.UnionToken createConcat() { + if (COUNTTOKENS) Token.tokens ++; + return new Token.UnionToken(Token.CONCAT); // *** It is not a bug. + } + static Token.UnionToken createUnion() { + if (COUNTTOKENS) Token.tokens ++; + return new Token.UnionToken(Token.UNION); + } + static Token createEmpty() { + return Token.token_empty; + } + static RangeToken createRange() { + if (COUNTTOKENS) Token.tokens ++; + return new RangeToken(Token.RANGE); + } + static RangeToken createNRange() { + if (COUNTTOKENS) Token.tokens ++; + return new RangeToken(Token.NRANGE); + } + static Token.CharToken createChar(int ch) { + if (COUNTTOKENS) Token.tokens ++; + return new Token.CharToken(Token.CHAR, ch); + } + static private Token.CharToken createAnchor(int ch) { + if (COUNTTOKENS) Token.tokens ++; + return new Token.CharToken(Token.ANCHOR, ch); + } + static Token.StringToken createBackReference(int refno) { + if (COUNTTOKENS) Token.tokens ++; + return new Token.StringToken(Token.BACKREFERENCE, null, refno); + } + static Token.StringToken createString(String str) { + if (COUNTTOKENS) Token.tokens ++; + return new Token.StringToken(Token.STRING, str, 0); + } + static Token.ModifierToken createModifierGroup(Token child, int add, int mask) { + if (COUNTTOKENS) Token.tokens ++; + return new Token.ModifierToken(child, add, mask); + } + static Token.ConditionToken createCondition(int refno, Token condition, + Token yespat, Token nopat) { + if (COUNTTOKENS) Token.tokens ++; + return new Token.ConditionToken(refno, condition, yespat, nopat); + } + + protected Token(int type) { + this.type = type; + } + + /** + * A number of children. + */ + int size() { + return 0; + } + Token getChild(int index) { + return null; + } + void addChild(Token tok) { + throw new RuntimeException("Not supported."); + } + + // for RANGE or NRANGE + protected void addRange(int start, int end) { + throw new RuntimeException("Not supported."); + } + protected void sortRanges() { + throw new RuntimeException("Not supported."); + } + protected void compactRanges() { + throw new RuntimeException("Not supported."); + } + protected void mergeRanges(Token tok) { + throw new RuntimeException("Not supported."); + } + protected void subtractRanges(Token tok) { + throw new RuntimeException("Not supported."); + } + protected void intersectRanges(Token tok) { + throw new RuntimeException("Not supported."); + } + static Token complementRanges(Token tok) { + return RangeToken.complementRanges(tok); + } + + + void setMin(int min) { // for CLOSURE + } + void setMax(int max) { // for CLOSURE + } + int getMin() { // for CLOSURE + return -1; + } + int getMax() { // for CLOSURE + return -1; + } + int getReferenceNumber() { // for STRING + return 0; + } + String getString() { // for STRING + return null; + } + + int getParenNumber() { + return 0; + } + int getChar() { + return -1; + } + + public String toString() { + return this.toString(0); + } + public String toString(int options) { + return this.type == Token.DOT ? "." : ""; + } + + /** + * How many characters are needed? + */ + final int getMinLength() { + switch (this.type) { + case CONCAT: + int sum = 0; + for (int i = 0; i < this.size(); i ++) + sum += this.getChild(i).getMinLength(); + return sum; + + case CONDITION: + case UNION: + if (this.size() == 0) + return 0; + int ret = this.getChild(0).getMinLength(); + for (int i = 1; i < this.size(); i ++) { + int min = this.getChild(i).getMinLength(); + if (min < ret) ret = min; + } + return ret; + + case CLOSURE: + case NONGREEDYCLOSURE: + if (this.getMin() >= 0) + return this.getMin() * this.getChild(0).getMinLength(); + return 0; + + case EMPTY: + case ANCHOR: + return 0; + + case DOT: + case CHAR: + case RANGE: + case NRANGE: + return 1; + + case INDEPENDENT: + case PAREN: + case MODIFIERGROUP: + return this.getChild(0).getMinLength(); + + case BACKREFERENCE: + return 0; // ******* + + case STRING: + return this.getString().length(); + + case LOOKAHEAD: + case NEGATIVELOOKAHEAD: + case LOOKBEHIND: + case NEGATIVELOOKBEHIND: + return 0; // ***** Really? + + default: + throw new RuntimeException("Token#getMinLength(): Invalid Type: "+this.type); + } + } + + final int getMaxLength() { + switch (this.type) { + case CONCAT: + int sum = 0; + for (int i = 0; i < this.size(); i ++) { + int d = this.getChild(i).getMaxLength(); + if (d < 0) return -1; + sum += d; + } + return sum; + + case CONDITION: + case UNION: + if (this.size() == 0) + return 0; + int ret = this.getChild(0).getMaxLength(); + for (int i = 1; ret >= 0 && i < this.size(); i ++) { + int max = this.getChild(i).getMaxLength(); + if (max < 0) { // infinity + ret = -1; + break; + } + if (max > ret) ret = max; + } + return ret; + + case CLOSURE: + case NONGREEDYCLOSURE: + if (this.getMax() >= 0) + // When this.child.getMaxLength() < 0, + // this returns minus value + return this.getMax() * this.getChild(0).getMaxLength(); + return -1; + + case EMPTY: + case ANCHOR: + return 0; + + case CHAR: + return 1; + case DOT: + case RANGE: + case NRANGE: + return 2; + + case INDEPENDENT: + case PAREN: + case MODIFIERGROUP: + return this.getChild(0).getMaxLength(); + + case BACKREFERENCE: + return -1; // ****** + + case STRING: + return this.getString().length(); + + case LOOKAHEAD: + case NEGATIVELOOKAHEAD: + case LOOKBEHIND: + case NEGATIVELOOKBEHIND: + return 0; // ***** Really? + + default: + throw new RuntimeException("Token#getMaxLength(): Invalid Type: "+this.type); + } + } + + static final int FC_CONTINUE = 0; + static final int FC_TERMINAL = 1; + static final int FC_ANY = 2; + private static final boolean isSet(int options, int flag) { + return (options & flag) == flag; + } + final int analyzeFirstCharacter(RangeToken result, int options) { + switch (this.type) { + case CONCAT: + int ret = FC_CONTINUE; + for (int i = 0; i < this.size(); i ++) + if ((ret = this.getChild(i).analyzeFirstCharacter(result, options)) != FC_CONTINUE) + break; + return ret; + + case UNION: + if (this.size() == 0) + return FC_CONTINUE; + /* + * a|b|c -> FC_TERMINAL + * a|.|c -> FC_ANY + * a|b| -> FC_CONTINUE + */ + int ret2 = FC_CONTINUE; + boolean hasEmpty = false; + for (int i = 0; i < this.size(); i ++) { + ret2 = this.getChild(i).analyzeFirstCharacter(result, options); + if (ret2 == FC_ANY) + break; + else if (ret2 == FC_CONTINUE) + hasEmpty = true; + } + return hasEmpty ? FC_CONTINUE : ret2; + + case CONDITION: + int ret3 = this.getChild(0).analyzeFirstCharacter(result, options); + if (this.size() == 1) return FC_CONTINUE; + if (ret3 == FC_ANY) return ret3; + int ret4 = this.getChild(1).analyzeFirstCharacter(result, options); + if (ret4 == FC_ANY) return ret4; + return ret3 == FC_CONTINUE || ret4 == FC_CONTINUE ? FC_CONTINUE : FC_TERMINAL; + + case CLOSURE: + case NONGREEDYCLOSURE: + this.getChild(0).analyzeFirstCharacter(result, options); + return FC_CONTINUE; + + case EMPTY: + case ANCHOR: + return FC_CONTINUE; + + case CHAR: + int ch = this.getChar(); + result.addRange(ch, ch); + if (ch < 0x10000 && isSet(options, RegularExpression.IGNORE_CASE)) { + ch = Character.toUpperCase((char)ch); + result.addRange(ch, ch); + ch = Character.toLowerCase((char)ch); + result.addRange(ch, ch); + } + return FC_TERMINAL; + + case DOT: // **** + if (isSet(options, RegularExpression.SINGLE_LINE)) { + return FC_CONTINUE; // **** We can not optimize. + } else { + return FC_CONTINUE; + /* + result.addRange(0, RegularExpression.LINE_FEED-1); + result.addRange(RegularExpression.LINE_FEED+1, RegularExpression.CARRIAGE_RETURN-1); + result.addRange(RegularExpression.CARRIAGE_RETURN+1, + RegularExpression.LINE_SEPARATOR-1); + result.addRange(RegularExpression.PARAGRAPH_SEPARATOR+1, UTF16_MAX); + return 1; + */ + } + + case RANGE: + if (isSet(options, RegularExpression.IGNORE_CASE)) { + result.mergeRanges(((RangeToken)this).getCaseInsensitiveToken()); + } else { + result.mergeRanges(this); + } + return FC_TERMINAL; + + case NRANGE: // **** + if (isSet(options, RegularExpression.IGNORE_CASE)) { + result.mergeRanges(Token.complementRanges(((RangeToken)this).getCaseInsensitiveToken())); + } else { + result.mergeRanges(Token.complementRanges(this)); + } + return FC_TERMINAL; + + case INDEPENDENT: + case PAREN: + return this.getChild(0).analyzeFirstCharacter(result, options); + + case MODIFIERGROUP: + options |= ((ModifierToken)this).getOptions(); + options &= ~((ModifierToken)this).getOptionsMask(); + return this.getChild(0).analyzeFirstCharacter(result, options); + + case BACKREFERENCE: + result.addRange(0, UTF16_MAX); // **** We can not optimize. + return FC_ANY; + + case STRING: + int cha = this.getString().charAt(0); + int ch2; + if (REUtil.isHighSurrogate(cha) + && this.getString().length() >= 2 + && REUtil.isLowSurrogate((ch2 = this.getString().charAt(1)))) + cha = REUtil.composeFromSurrogates(cha, ch2); + result.addRange(cha, cha); + if (cha < 0x10000 && isSet(options, RegularExpression.IGNORE_CASE)) { + cha = Character.toUpperCase((char)cha); + result.addRange(cha, cha); + cha = Character.toLowerCase((char)cha); + result.addRange(cha, cha); + } + return FC_TERMINAL; + + case LOOKAHEAD: + case NEGATIVELOOKAHEAD: + case LOOKBEHIND: + case NEGATIVELOOKBEHIND: + return FC_CONTINUE; + + default: + throw new RuntimeException("Token#analyzeHeadCharacter(): Invalid Type: "+this.type); + } + } + + private final boolean isShorterThan(Token tok) { + if (tok == null) return false; + /* + int mylength; + if (this.type == STRING) mylength = this.getString().length(); + else if (this.type == CHAR) mylength = this.getChar() >= 0x10000 ? 2 : 1; + else throw new RuntimeException("Internal Error: Illegal type: "+this.type); + int otherlength; + if (tok.type == STRING) otherlength = tok.getString().length(); + else if (tok.type == CHAR) otherlength = tok.getChar() >= 0x10000 ? 2 : 1; + else throw new RuntimeException("Internal Error: Illegal type: "+tok.type); + */ + int mylength; + if (this.type == STRING) mylength = this.getString().length(); + else throw new RuntimeException("Internal Error: Illegal type: "+this.type); + int otherlength; + if (tok.type == STRING) otherlength = tok.getString().length(); + else throw new RuntimeException("Internal Error: Illegal type: "+tok.type); + return mylength < otherlength; + } + + static class FixedStringContainer { + Token token = null; + int options = 0; + FixedStringContainer() { + } + } + + final void findFixedString(FixedStringContainer container, int options) { + switch (this.type) { + case CONCAT: + Token prevToken = null; + int prevOptions = 0; + for (int i = 0; i < this.size(); i ++) { + this.getChild(i).findFixedString(container, options); + if (prevToken == null || prevToken.isShorterThan(container.token)) { + prevToken = container.token; + prevOptions = container.options; + } + } + container.token = prevToken; + container.options = prevOptions; + return; + + case UNION: + case CLOSURE: + case NONGREEDYCLOSURE: + case EMPTY: + case ANCHOR: + case RANGE: + case DOT: + case NRANGE: + case BACKREFERENCE: + case LOOKAHEAD: + case NEGATIVELOOKAHEAD: + case LOOKBEHIND: + case NEGATIVELOOKBEHIND: + case CONDITION: + container.token = null; + return; + + case CHAR: // Ignore CHAR tokens. + container.token = null; // ** + return; // ** + + case STRING: + container.token = this; + container.options = options; + return; + + case INDEPENDENT: + case PAREN: + this.getChild(0).findFixedString(container, options); + return; + + case MODIFIERGROUP: + options |= ((ModifierToken)this).getOptions(); + options &= ~((ModifierToken)this).getOptionsMask(); + this.getChild(0).findFixedString(container, options); + return; + + default: + throw new RuntimeException("Token#findFixedString(): Invalid Type: "+this.type); + } + } + + boolean match(int ch) { + throw new RuntimeException("NFAArrow#match(): Internal error: "+this.type); + } + + // ------------------------------------------------------ + private final static Hashtable categories = new Hashtable(); + private final static Hashtable categories2 = new Hashtable(); + private static final String[] categoryNames = { + "Cn", "Lu", "Ll", "Lt", "Lm", "Lo", "Mn", "Me", "Mc", "Nd", + "Nl", "No", "Zs", "Zl", "Zp", "Cc", "Cf", null, "Co", "Cs", + "Pd", "Ps", "Pe", "Pc", "Po", "Sm", "Sc", "Sk", "So", // 28 + "Pi", "Pf", // 29, 30 + "L", "M", "N", "Z", "C", "P", "S", // 31-37 + }; + + // Schema Rec. {Datatypes} - Punctuation + static final int CHAR_INIT_QUOTE = 29; // Pi - initial quote + static final int CHAR_FINAL_QUOTE = 30; // Pf - final quote + static final int CHAR_LETTER = 31; + static final int CHAR_MARK = 32; + static final int CHAR_NUMBER = 33; + static final int CHAR_SEPARATOR = 34; + static final int CHAR_OTHER = 35; + static final int CHAR_PUNCTUATION = 36; + static final int CHAR_SYMBOL = 37; + + //blockNames in UNICODE 3.1 that supported by XML Schema REC + private static final String[] blockNames = { + /*0000..007F;*/ "Basic Latin", + /*0080..00FF;*/ "Latin-1 Supplement", + /*0100..017F;*/ "Latin Extended-A", + /*0180..024F;*/ "Latin Extended-B", + /*0250..02AF;*/ "IPA Extensions", + /*02B0..02FF;*/ "Spacing Modifier Letters", + /*0300..036F;*/ "Combining Diacritical Marks", + /*0370..03FF;*/ "Greek", + /*0400..04FF;*/ "Cyrillic", + /*0530..058F;*/ "Armenian", + /*0590..05FF;*/ "Hebrew", + /*0600..06FF;*/ "Arabic", + /*0700..074F;*/ "Syriac", + /*0780..07BF;*/ "Thaana", + /*0900..097F;*/ "Devanagari", + /*0980..09FF;*/ "Bengali", + /*0A00..0A7F;*/ "Gurmukhi", + /*0A80..0AFF;*/ "Gujarati", + /*0B00..0B7F;*/ "Oriya", + /*0B80..0BFF;*/ "Tamil", + /*0C00..0C7F;*/ "Telugu", + /*0C80..0CFF;*/ "Kannada", + /*0D00..0D7F;*/ "Malayalam", + /*0D80..0DFF;*/ "Sinhala", + /*0E00..0E7F;*/ "Thai", + /*0E80..0EFF;*/ "Lao", + /*0F00..0FFF;*/ "Tibetan", + /*1000..109F;*/ "Myanmar", + /*10A0..10FF;*/ "Georgian", + /*1100..11FF;*/ "Hangul Jamo", + /*1200..137F;*/ "Ethiopic", + /*13A0..13FF;*/ "Cherokee", + /*1400..167F;*/ "Unified Canadian Aboriginal Syllabics", + /*1680..169F;*/ "Ogham", + /*16A0..16FF;*/ "Runic", + /*1780..17FF;*/ "Khmer", + /*1800..18AF;*/ "Mongolian", + /*1E00..1EFF;*/ "Latin Extended Additional", + /*1F00..1FFF;*/ "Greek Extended", + /*2000..206F;*/ "General Punctuation", + /*2070..209F;*/ "Superscripts and Subscripts", + /*20A0..20CF;*/ "Currency Symbols", + /*20D0..20FF;*/ "Combining Marks for Symbols", + /*2100..214F;*/ "Letterlike Symbols", + /*2150..218F;*/ "Number Forms", + /*2190..21FF;*/ "Arrows", + /*2200..22FF;*/ "Mathematical Operators", + /*2300..23FF;*/ "Miscellaneous Technical", + /*2400..243F;*/ "Control Pictures", + /*2440..245F;*/ "Optical Character Recognition", + /*2460..24FF;*/ "Enclosed Alphanumerics", + /*2500..257F;*/ "Box Drawing", + /*2580..259F;*/ "Block Elements", + /*25A0..25FF;*/ "Geometric Shapes", + /*2600..26FF;*/ "Miscellaneous Symbols", + /*2700..27BF;*/ "Dingbats", + /*2800..28FF;*/ "Braille Patterns", + /*2E80..2EFF;*/ "CJK Radicals Supplement", + /*2F00..2FDF;*/ "Kangxi Radicals", + /*2FF0..2FFF;*/ "Ideographic Description Characters", + /*3000..303F;*/ "CJK Symbols and Punctuation", + /*3040..309F;*/ "Hiragana", + /*30A0..30FF;*/ "Katakana", + /*3100..312F;*/ "Bopomofo", + /*3130..318F;*/ "Hangul Compatibility Jamo", + /*3190..319F;*/ "Kanbun", + /*31A0..31BF;*/ "Bopomofo Extended", + /*3200..32FF;*/ "Enclosed CJK Letters and Months", + /*3300..33FF;*/ "CJK Compatibility", + /*3400..4DB5;*/ "CJK Unified Ideographs Extension A", + /*4E00..9FFF;*/ "CJK Unified Ideographs", + /*A000..A48F;*/ "Yi Syllables", + /*A490..A4CF;*/ "Yi Radicals", + /*AC00..D7A3;*/ "Hangul Syllables", + /*E000..F8FF;*/ "Private Use", + /*F900..FAFF;*/ "CJK Compatibility Ideographs", + /*FB00..FB4F;*/ "Alphabetic Presentation Forms", + /*FB50..FDFF;*/ "Arabic Presentation Forms-A", + /*FE20..FE2F;*/ "Combining Half Marks", + /*FE30..FE4F;*/ "CJK Compatibility Forms", + /*FE50..FE6F;*/ "Small Form Variants", + /*FE70..FEFE;*/ "Arabic Presentation Forms-B", + /*FEFF..FEFF;*/ "Specials", + /*FF00..FFEF;*/ "Halfwidth and Fullwidth Forms", + //missing Specials add manually + /*10300..1032F;*/ "Old Italic", // 84 + /*10330..1034F;*/ "Gothic", + /*10400..1044F;*/ "Deseret", + /*1D000..1D0FF;*/ "Byzantine Musical Symbols", + /*1D100..1D1FF;*/ "Musical Symbols", + /*1D400..1D7FF;*/ "Mathematical Alphanumeric Symbols", + /*20000..2A6D6;*/ "CJK Unified Ideographs Extension B", + /*2F800..2FA1F;*/ "CJK Compatibility Ideographs Supplement", + /*E0000..E007F;*/ "Tags", + //missing 2 private use add manually + + }; + //ADD THOSE MANUALLY + //F0000..FFFFD; "Private Use", + //100000..10FFFD; "Private Use" + //FFF0..FFFD; "Specials", + static final String blockRanges = + "\u0000\u007F\u0080\u00FF\u0100\u017F\u0180\u024F\u0250\u02AF\u02B0\u02FF\u0300\u036F" + +"\u0370\u03FF\u0400\u04FF\u0530\u058F\u0590\u05FF\u0600\u06FF\u0700\u074F\u0780\u07BF" + +"\u0900\u097F\u0980\u09FF\u0A00\u0A7F\u0A80\u0AFF\u0B00\u0B7F\u0B80\u0BFF\u0C00\u0C7F\u0C80\u0CFF" + +"\u0D00\u0D7F\u0D80\u0DFF\u0E00\u0E7F\u0E80\u0EFF\u0F00\u0FFF\u1000\u109F\u10A0\u10FF\u1100\u11FF" + +"\u1200\u137F\u13A0\u13FF\u1400\u167F\u1680\u169F\u16A0\u16FF\u1780\u17FF\u1800\u18AF\u1E00\u1EFF" + +"\u1F00\u1FFF\u2000\u206F\u2070\u209F\u20A0\u20CF\u20D0\u20FF\u2100\u214F\u2150\u218F\u2190\u21FF\u2200\u22FF" + +"\u2300\u23FF\u2400\u243F\u2440\u245F\u2460\u24FF\u2500\u257F\u2580\u259F\u25A0\u25FF\u2600\u26FF\u2700\u27BF" + +"\u2800\u28FF\u2E80\u2EFF\u2F00\u2FDF\u2FF0\u2FFF\u3000\u303F\u3040\u309F\u30A0\u30FF\u3100\u312F\u3130\u318F" + +"\u3190\u319F\u31A0\u31BF\u3200\u32FF\u3300\u33FF\u3400\u4DB5\u4E00\u9FFF\uA000\uA48F\uA490\uA4CF" + +"\uAC00\uD7A3\uE000\uF8FF\uF900\uFAFF\uFB00\uFB4F\uFB50\uFDFF" + +"\uFE20\uFE2F\uFE30\uFE4F\uFE50\uFE6F\uFE70\uFEFE\uFEFF\uFEFF\uFF00\uFFEF"; + static final int[] nonBMPBlockRanges = { + 0x10300, 0x1032F, // 84 + 0x10330, 0x1034F, + 0x10400, 0x1044F, + 0x1D000, 0x1D0FF, + 0x1D100, 0x1D1FF, + 0x1D400, 0x1D7FF, + 0x20000, 0x2A6D6, + 0x2F800, 0x2FA1F, + 0xE0000, 0xE007F + }; + private static final int NONBMP_BLOCK_START = 84; + + static protected RangeToken getRange(String name, boolean positive) { + if (Token.categories.size() == 0) { + synchronized (Token.categories) { + Token[] ranges = new Token[Token.categoryNames.length]; + for (int i = 0; i < ranges.length; i ++) { + ranges[i] = Token.createRange(); + } + int type; + for (int i = 0; i < 0x10000; i ++) { + type = Character.getType((char)i); + if (type == Character.START_PUNCTUATION || + type == Character.END_PUNCTUATION) { + //build table of Pi values + if (i == 0x00AB || i == 0x2018 || i == 0x201B || i == 0x201C || + i == 0x201F || i == 0x2039) { + type = CHAR_INIT_QUOTE; + } + //build table of Pf values + if (i == 0x00BB || i == 0x2019 || i == 0x201D || i == 0x203A ) { + type = CHAR_FINAL_QUOTE; + } + } + ranges[type].addRange(i, i); + switch (type) { + case Character.UPPERCASE_LETTER: + case Character.LOWERCASE_LETTER: + case Character.TITLECASE_LETTER: + case Character.MODIFIER_LETTER: + case Character.OTHER_LETTER: + type = CHAR_LETTER; + break; + case Character.NON_SPACING_MARK: + case Character.COMBINING_SPACING_MARK: + case Character.ENCLOSING_MARK: + type = CHAR_MARK; + break; + case Character.DECIMAL_DIGIT_NUMBER: + case Character.LETTER_NUMBER: + case Character.OTHER_NUMBER: + type = CHAR_NUMBER; + break; + case Character.SPACE_SEPARATOR: + case Character.LINE_SEPARATOR: + case Character.PARAGRAPH_SEPARATOR: + type = CHAR_SEPARATOR; + break; + case Character.CONTROL: + case Character.FORMAT: + case Character.SURROGATE: + case Character.PRIVATE_USE: + case Character.UNASSIGNED: + type = CHAR_OTHER; + break; + case Character.CONNECTOR_PUNCTUATION: + case Character.DASH_PUNCTUATION: + case Character.START_PUNCTUATION: + case Character.END_PUNCTUATION: + case CHAR_INIT_QUOTE: + case CHAR_FINAL_QUOTE: + case Character.OTHER_PUNCTUATION: + type = CHAR_PUNCTUATION; + break; + case Character.MATH_SYMBOL: + case Character.CURRENCY_SYMBOL: + case Character.MODIFIER_SYMBOL: + case Character.OTHER_SYMBOL: + type = CHAR_SYMBOL; + break; + default: + throw new RuntimeException("org.apache.xerces.utils.regex.Token#getRange(): Unknown Unicode category: "+type); + } + ranges[type].addRange(i, i); + } // for all characters + ranges[Character.UNASSIGNED].addRange(0x10000, Token.UTF16_MAX); + + for (int i = 0; i < ranges.length; i ++) { + if (Token.categoryNames[i] != null) { + if (i == Character.UNASSIGNED) { // Unassigned + ranges[i].addRange(0x10000, Token.UTF16_MAX); + } + Token.categories.put(Token.categoryNames[i], ranges[i]); + Token.categories2.put(Token.categoryNames[i], + Token.complementRanges(ranges[i])); + } + } + //REVISIT: do we really need to support block names as in Unicode 3.1 + // or we can just create all the names in IsBLOCKNAME format (XML Schema REC)? + // + StringBuffer buffer = new StringBuffer(50); + for (int i = 0; i < Token.blockNames.length; i ++) { + Token r1 = Token.createRange(); + int location; + if (i < NONBMP_BLOCK_START) { + location = i*2; + int rstart = Token.blockRanges.charAt(location); + int rend = Token.blockRanges.charAt(location+1); + //DEBUGING + //System.out.println(n+" " +Integer.toHexString(rstart) + // +"-"+ Integer.toHexString(rend)); + r1.addRange(rstart, rend); + } else { + location = (i - NONBMP_BLOCK_START) * 2; + r1.addRange(Token.nonBMPBlockRanges[location], + Token.nonBMPBlockRanges[location + 1]); + } + String n = Token.blockNames[i]; + if (n.equals("Specials")) + r1.addRange(0xfff0, 0xfffd); + if (n.equals("Private Use")) { + r1.addRange(0xF0000,0xFFFFD); + r1.addRange(0x100000,0x10FFFD); + } + Token.categories.put(n, r1); + Token.categories2.put(n, Token.complementRanges(r1)); + buffer.setLength(0); + buffer.append("Is"); + if (n.indexOf(' ') >= 0) { + for (int ci = 0; ci < n.length(); ci ++) + if (n.charAt(ci) != ' ') buffer.append((char)n.charAt(ci)); + } + else { + buffer.append(n); + } + Token.setAlias(buffer.toString(), n, true); + } + + // TR#18 1.2 + Token.setAlias("ASSIGNED", "Cn", false); + Token.setAlias("UNASSIGNED", "Cn", true); + Token all = Token.createRange(); + all.addRange(0, Token.UTF16_MAX); + Token.categories.put("ALL", all); + Token.categories2.put("ALL", Token.complementRanges(all)); + Token.registerNonXS("ASSIGNED"); + Token.registerNonXS("UNASSIGNED"); + Token.registerNonXS("ALL"); + + Token isalpha = Token.createRange(); + isalpha.mergeRanges(ranges[Character.UPPERCASE_LETTER]); // Lu + isalpha.mergeRanges(ranges[Character.LOWERCASE_LETTER]); // Ll + isalpha.mergeRanges(ranges[Character.OTHER_LETTER]); // Lo + Token.categories.put("IsAlpha", isalpha); + Token.categories2.put("IsAlpha", Token.complementRanges(isalpha)); + Token.registerNonXS("IsAlpha"); + + Token isalnum = Token.createRange(); + isalnum.mergeRanges(isalpha); // Lu Ll Lo + isalnum.mergeRanges(ranges[Character.DECIMAL_DIGIT_NUMBER]); // Nd + Token.categories.put("IsAlnum", isalnum); + Token.categories2.put("IsAlnum", Token.complementRanges(isalnum)); + Token.registerNonXS("IsAlnum"); + + Token isspace = Token.createRange(); + isspace.mergeRanges(Token.token_spaces); + isspace.mergeRanges(ranges[CHAR_SEPARATOR]); // Z + Token.categories.put("IsSpace", isspace); + Token.categories2.put("IsSpace", Token.complementRanges(isspace)); + Token.registerNonXS("IsSpace"); + + Token isword = Token.createRange(); + isword.mergeRanges(isalnum); // Lu Ll Lo Nd + isword.addRange('_', '_'); + Token.categories.put("IsWord", isword); + Token.categories2.put("IsWord", Token.complementRanges(isword)); + Token.registerNonXS("IsWord"); + + Token isascii = Token.createRange(); + isascii.addRange(0, 127); + Token.categories.put("IsASCII", isascii); + Token.categories2.put("IsASCII", Token.complementRanges(isascii)); + Token.registerNonXS("IsASCII"); + + Token isnotgraph = Token.createRange(); + isnotgraph.mergeRanges(ranges[CHAR_OTHER]); + isnotgraph.addRange(' ', ' '); + Token.categories.put("IsGraph", Token.complementRanges(isnotgraph)); + Token.categories2.put("IsGraph", isnotgraph); + Token.registerNonXS("IsGraph"); + + Token isxdigit = Token.createRange(); + isxdigit.addRange('0', '9'); + isxdigit.addRange('A', 'F'); + isxdigit.addRange('a', 'f'); + Token.categories.put("IsXDigit", Token.complementRanges(isxdigit)); + Token.categories2.put("IsXDigit", isxdigit); + Token.registerNonXS("IsXDigit"); + + Token.setAlias("IsDigit", "Nd", true); + Token.setAlias("IsUpper", "Lu", true); + Token.setAlias("IsLower", "Ll", true); + Token.setAlias("IsCntrl", "C", true); + Token.setAlias("IsPrint", "C", false); + Token.setAlias("IsPunct", "P", true); + Token.registerNonXS("IsDigit"); + Token.registerNonXS("IsUpper"); + Token.registerNonXS("IsLower"); + Token.registerNonXS("IsCntrl"); + Token.registerNonXS("IsPrint"); + Token.registerNonXS("IsPunct"); + + Token.setAlias("alpha", "IsAlpha", true); + Token.setAlias("alnum", "IsAlnum", true); + Token.setAlias("ascii", "IsASCII", true); + Token.setAlias("cntrl", "IsCntrl", true); + Token.setAlias("digit", "IsDigit", true); + Token.setAlias("graph", "IsGraph", true); + Token.setAlias("lower", "IsLower", true); + Token.setAlias("print", "IsPrint", true); + Token.setAlias("punct", "IsPunct", true); + Token.setAlias("space", "IsSpace", true); + Token.setAlias("upper", "IsUpper", true); + Token.setAlias("word", "IsWord", true); // Perl extension + Token.setAlias("xdigit", "IsXDigit", true); + Token.registerNonXS("alpha"); + Token.registerNonXS("alnum"); + Token.registerNonXS("ascii"); + Token.registerNonXS("cntrl"); + Token.registerNonXS("digit"); + Token.registerNonXS("graph"); + Token.registerNonXS("lower"); + Token.registerNonXS("print"); + Token.registerNonXS("punct"); + Token.registerNonXS("space"); + Token.registerNonXS("upper"); + Token.registerNonXS("word"); + Token.registerNonXS("xdigit"); + } // synchronized + } // if null + RangeToken tok = positive ? (RangeToken)Token.categories.get(name) + : (RangeToken)Token.categories2.get(name); + //if (tok == null) System.out.println(name); + return tok; + } + static protected RangeToken getRange(String name, boolean positive, boolean xs) { + RangeToken range = Token.getRange(name, positive); + if (xs && range != null && Token.isRegisterNonXS(name)) + range = null; + return range; + } + + static Hashtable nonxs = null; + /** + * This method is called by only getRange(). + * So this method need not MT-safe. + */ + static protected void registerNonXS(String name) { + if (Token.nonxs == null) + Token.nonxs = new Hashtable(); + Token.nonxs.put(name, name); + } + static protected boolean isRegisterNonXS(String name) { + if (Token.nonxs == null) + return false; + //DEBUG + //System.err.println("isRegisterNonXS: "+name); + return Token.nonxs.containsKey(name); + } + + private static void setAlias(String newName, String name, boolean positive) { + Token t1 = (Token)Token.categories.get(name); + Token t2 = (Token)Token.categories2.get(name); + if (positive) { + Token.categories.put(newName, t1); + Token.categories2.put(newName, t2); + } else { + Token.categories2.put(newName, t1); + Token.categories.put(newName, t2); + } + } + + // ------------------------------------------------------ + + static final String viramaString = + "\u094D"// ;DEVANAGARI SIGN VIRAMA;Mn;9;ON;;;;;N;;;;; + +"\u09CD"//;BENGALI SIGN VIRAMA;Mn;9;ON;;;;;N;;;;; + +"\u0A4D"//;GURMUKHI SIGN VIRAMA;Mn;9;ON;;;;;N;;;;; + +"\u0ACD"//;GUJARATI SIGN VIRAMA;Mn;9;ON;;;;;N;;;;; + +"\u0B4D"//;ORIYA SIGN VIRAMA;Mn;9;ON;;;;;N;;;;; + +"\u0BCD"//;TAMIL SIGN VIRAMA;Mn;9;ON;;;;;N;;;;; + +"\u0C4D"//;TELUGU SIGN VIRAMA;Mn;9;ON;;;;;N;;;;; + +"\u0CCD"//;KANNADA SIGN VIRAMA;Mn;9;ON;;;;;N;;;;; + +"\u0D4D"//;MALAYALAM SIGN VIRAMA;Mn;9;ON;;;;;N;;;;; + +"\u0E3A"//;THAI CHARACTER PHINTHU;Mn;9;ON;;;;;N;THAI VOWEL SIGN PHINTHU;;;; + +"\u0F84";//;TIBETAN MARK HALANTA;Mn;9;ON;;;;;N;TIBETAN VIRAMA;;;; + + static private Token token_grapheme = null; + static synchronized Token getGraphemePattern() { + if (Token.token_grapheme != null) + return Token.token_grapheme; + + Token base_char = Token.createRange(); // [{ASSIGNED}]-[{M},{C}] + base_char.mergeRanges(Token.getRange("ASSIGNED", true)); + base_char.subtractRanges(Token.getRange("M", true)); + base_char.subtractRanges(Token.getRange("C", true)); + + Token virama = Token.createRange(); + for (int i = 0; i < Token.viramaString.length(); i ++) { + int ch = viramaString.charAt(i); + virama.addRange(i, i); + } + + Token combiner_wo_virama = Token.createRange(); + combiner_wo_virama.mergeRanges(Token.getRange("M", true)); + combiner_wo_virama.addRange(0x1160, 0x11ff); // hangul_medial and hangul_final + combiner_wo_virama.addRange(0xff9e, 0xff9f); // extras + + Token left = Token.createUnion(); // base_char? + left.addChild(base_char); + left.addChild(Token.token_empty); + + Token foo = Token.createUnion(); + foo.addChild(Token.createConcat(virama, Token.getRange("L", true))); + foo.addChild(combiner_wo_virama); + + foo = Token.createClosure(foo); + + foo = Token.createConcat(left, foo); + + Token.token_grapheme = foo; + return Token.token_grapheme; + } + + /** + * Combing Character Sequence in Perl 5.6. + */ + static private Token token_ccs = null; + static synchronized Token getCombiningCharacterSequence() { + if (Token.token_ccs != null) + return Token.token_ccs; + + Token foo = Token.createClosure(Token.getRange("M", true)); // \pM* + foo = Token.createConcat(Token.getRange("M", false), foo); // \PM + \pM* + Token.token_ccs = foo; + return Token.token_ccs; + } + + // ------------------------------------------------------ + + // ------------------------------------------------------ + /** + * This class represents a node in parse tree. + */ + static class StringToken extends Token implements java.io.Serializable { + String string; + int refNumber; + + StringToken(int type, String str, int n) { + super(type); + this.string = str; + this.refNumber = n; + } + + int getReferenceNumber() { // for STRING + return this.refNumber; + } + String getString() { // for STRING + return this.string; + } + + public String toString(int options) { + if (this.type == BACKREFERENCE) + return "\\"+this.refNumber; + else + return REUtil.quoteMeta(this.string); + } + } + + /** + * This class represents a node in parse tree. + */ + static class ConcatToken extends Token implements java.io.Serializable { + Token child; + Token child2; + + ConcatToken(Token t1, Token t2) { + super(Token.CONCAT); + this.child = t1; + this.child2 = t2; + } + + int size() { + return 2; + } + Token getChild(int index) { + return index == 0 ? this.child : this.child2; + } + + public String toString(int options) { + String ret; + if (this.child2.type == CLOSURE && this.child2.getChild(0) == this.child) { + ret = this.child.toString(options)+"+"; + } else if (this.child2.type == NONGREEDYCLOSURE && this.child2.getChild(0) == this.child) { + ret = this.child.toString(options)+"+?"; + } else + ret = this.child.toString(options)+this.child2.toString(options); + return ret; + } + } + + /** + * This class represents a node in parse tree. + */ + static class CharToken extends Token implements java.io.Serializable { + int chardata; + + CharToken(int type, int ch) { + super(type); + this.chardata = ch; + } + + int getChar() { + return this.chardata; + } + + public String toString(int options) { + String ret; + switch (this.type) { + case CHAR: + switch (this.chardata) { + case '|': case '*': case '+': case '?': + case '(': case ')': case '.': case '[': + case '{': case '\\': + ret = "\\"+(char)this.chardata; + break; + case '\f': ret = "\\f"; break; + case '\n': ret = "\\n"; break; + case '\r': ret = "\\r"; break; + case '\t': ret = "\\t"; break; + case 0x1b: ret = "\\e"; break; + //case 0x0b: ret = "\\v"; break; + default: + if (this.chardata >= 0x10000) { + String pre = "0"+Integer.toHexString(this.chardata); + ret = "\\v"+pre.substring(pre.length()-6, pre.length()); + } else + ret = ""+(char)this.chardata; + } + break; + + case ANCHOR: + if (this == Token.token_linebeginning || this == Token.token_lineend) + ret = ""+(char)this.chardata; + else + ret = "\\"+(char)this.chardata; + break; + + default: + ret = null; + } + return ret; + } + + boolean match(int ch) { + if (this.type == CHAR) { + return ch == this.chardata; + } else + throw new RuntimeException("NFAArrow#match(): Internal error: "+this.type); + } + } + + /** + * This class represents a node in parse tree. + */ + static class ClosureToken extends Token implements java.io.Serializable { + int min; + int max; + Token child; + + ClosureToken(int type, Token tok) { + super(type); + this.child = tok; + this.setMin(-1); + this.setMax(-1); + } + + int size() { + return 1; + } + Token getChild(int index) { + return this.child; + } + + final void setMin(int min) { + this.min = min; + } + final void setMax(int max) { + this.max = max; + } + final int getMin() { + return this.min; + } + final int getMax() { + return this.max; + } + + public String toString(int options) { + String ret; + if (this.type == CLOSURE) { + if (this.getMin() < 0 && this.getMax() < 0) { + ret = this.child.toString(options)+"*"; + } else if (this.getMin() == this.getMax()) { + ret = this.child.toString(options)+"{"+this.getMin()+"}"; + } else if (this.getMin() >= 0 && this.getMax() >= 0) { + ret = this.child.toString(options)+"{"+this.getMin()+","+this.getMax()+"}"; + } else if (this.getMin() >= 0 && this.getMax() < 0) { + ret = this.child.toString(options)+"{"+this.getMin()+",}"; + } else + throw new RuntimeException("Token#toString(): CLOSURE " + +this.getMin()+", "+this.getMax()); + } else { + if (this.getMin() < 0 && this.getMax() < 0) { + ret = this.child.toString(options)+"*?"; + } else if (this.getMin() == this.getMax()) { + ret = this.child.toString(options)+"{"+this.getMin()+"}?"; + } else if (this.getMin() >= 0 && this.getMax() >= 0) { + ret = this.child.toString(options)+"{"+this.getMin()+","+this.getMax()+"}?"; + } else if (this.getMin() >= 0 && this.getMax() < 0) { + ret = this.child.toString(options)+"{"+this.getMin()+",}?"; + } else + throw new RuntimeException("Token#toString(): NONGREEDYCLOSURE " + +this.getMin()+", "+this.getMax()); + } + return ret; + } + } + + /** + * This class represents a node in parse tree. + */ + static class ParenToken extends Token implements java.io.Serializable { + Token child; + int parennumber; + + ParenToken(int type, Token tok, int paren) { + super(type); + this.child = tok; + this.parennumber = paren; + } + + int size() { + return 1; + } + Token getChild(int index) { + return this.child; + } + + int getParenNumber() { + return this.parennumber; + } + + public String toString(int options) { + String ret = null; + switch (this.type) { + case PAREN: + if (this.parennumber == 0) { + ret = "(?:"+this.child.toString(options)+")"; + } else { + ret = "("+this.child.toString(options)+")"; + } + break; + + case LOOKAHEAD: + ret = "(?="+this.child.toString(options)+")"; + break; + case NEGATIVELOOKAHEAD: + ret = "(?!"+this.child.toString(options)+")"; + break; + case LOOKBEHIND: + ret = "(?<="+this.child.toString(options)+")"; + break; + case NEGATIVELOOKBEHIND: + ret = "(?"+this.child.toString(options)+")"; + break; + } + return ret; + } + } + + /** + * (?(condition)yes-pattern|no-pattern) + */ + static class ConditionToken extends Token implements java.io.Serializable { + int refNumber; + Token condition; + Token yes; + Token no; + ConditionToken(int refno, Token cond, Token yespat, Token nopat) { + super(Token.CONDITION); + this.refNumber = refno; + this.condition = cond; + this.yes = yespat; + this.no = nopat; + } + int size() { + return this.no == null ? 1 : 2; + } + Token getChild(int index) { + if (index == 0) return this.yes; + if (index == 1) return this.no; + throw new RuntimeException("Internal Error: "+index); + } + + public String toString(int options) { + String ret; + if (refNumber > 0) { + ret = "(?("+refNumber+")"; + } else if (this.condition.type == Token.ANCHOR) { + ret = "(?("+this.condition+")"; + } else { + ret = "(?"+this.condition; + } + + if (this.no == null) { + ret += this.yes+")"; + } else { + ret += this.yes+"|"+this.no+")"; + } + return ret; + } + } + + /** + * (ims-ims: .... ) + */ + static class ModifierToken extends Token implements java.io.Serializable { + Token child; + int add; + int mask; + + ModifierToken(Token tok, int add, int mask) { + super(Token.MODIFIERGROUP); + this.child = tok; + this.add = add; + this.mask = mask; + } + + int size() { + return 1; + } + Token getChild(int index) { + return this.child; + } + + int getOptions() { + return this.add; + } + int getOptionsMask() { + return this.mask; + } + + public String toString(int options) { + return "(?" + +(this.add == 0 ? "" : REUtil.createOptionString(this.add)) + +(this.mask == 0 ? "" : REUtil.createOptionString(this.mask)) + +":" + +this.child.toString(options) + +")"; + } + } + + /** + * This class represents a node in parse tree. + * for UNION or CONCAT. + */ + static class UnionToken extends Token implements java.io.Serializable { + Vector children; + + UnionToken(int type) { + super(type); + } + + void addChild(Token tok) { + if (tok == null) return; + if (this.children == null) this.children = new Vector(); + if (this.type == UNION) { + this.children.addElement(tok); + return; + } + // This is CONCAT, and new child is CONCAT. + if (tok.type == CONCAT) { + for (int i = 0; i < tok.size(); i ++) + this.addChild(tok.getChild(i)); // Recursion + return; + } + int size = this.children.size(); + if (size == 0) { + this.children.addElement(tok); + return; + } + Token previous = (Token)this.children.elementAt(size-1); + if (!((previous.type == CHAR || previous.type == STRING) + && (tok.type == CHAR || tok.type == STRING))) { + this.children.addElement(tok); + return; + } + + //System.err.println("Merge '"+previous+"' and '"+tok+"'."); + + StringBuffer buffer; + int nextMaxLength = (tok.type == CHAR ? 2 : tok.getString().length()); + if (previous.type == CHAR) { // Replace previous token by STRING + buffer = new StringBuffer(2 + nextMaxLength); + int ch = previous.getChar(); + if (ch >= 0x10000) + buffer.append(REUtil.decomposeToSurrogates(ch)); + else + buffer.append((char)ch); + previous = Token.createString(null); + this.children.setElementAt(previous, size-1); + } else { // STRING + buffer = new StringBuffer(previous.getString().length() + nextMaxLength); + buffer.append(previous.getString()); + } + + if (tok.type == CHAR) { + int ch = tok.getChar(); + if (ch >= 0x10000) + buffer.append(REUtil.decomposeToSurrogates(ch)); + else + buffer.append((char)ch); + } else { + buffer.append(tok.getString()); + } + + ((StringToken)previous).string = new String(buffer); + } + + int size() { + return this.children == null ? 0 : this.children.size(); + } + Token getChild(int index) { + return (Token)this.children.elementAt(index); + } + + public String toString(int options) { + String ret; + if (this.type == CONCAT) { + if (this.children.size() == 2) { + Token ch = this.getChild(0); + Token ch2 = this.getChild(1); + if (ch2.type == CLOSURE && ch2.getChild(0) == ch) { + ret = ch.toString(options)+"+"; + } else if (ch2.type == NONGREEDYCLOSURE && ch2.getChild(0) == ch) { + ret = ch.toString(options)+"+?"; + } else + ret = ch.toString(options)+ch2.toString(options); + } else { + StringBuffer sb = new StringBuffer(); + for (int i = 0; i < this.children.size(); i ++) { + sb.append(((Token)this.children.elementAt(i)).toString(options)); + } + ret = new String(sb); + } + return ret; + } + if (this.children.size() == 2 && this.getChild(1).type == EMPTY) { + ret = this.getChild(0).toString(options)+"?"; + } else if (this.children.size() == 2 + && this.getChild(0).type == EMPTY) { + ret = this.getChild(1).toString(options)+"??"; + } else { + StringBuffer sb = new StringBuffer(); + sb.append(((Token)this.children.elementAt(0)).toString(options)); + for (int i = 1; i < this.children.size(); i ++) { + sb.append((char)'|'); + sb.append(((Token)this.children.elementAt(i)).toString(options)); + } + ret = new String(sb); + } + return ret; + } + } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/regex/message.properties b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/regex/message.properties new file mode 100644 index 000000000..48e15b054 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/regex/message.properties @@ -0,0 +1,39 @@ +parser.parse.1=Wrong character. +parser.parse.2=Invalid reference number. +parser.next.1=A character is required after \\. +parser.next.2='?' is not expected. '(?:' or '(?=' or '(?!' or '(?<' or '(?#' or '(?>'? +parser.next.3='(?<=' or '(?'? +parser.next.3='(?<=' ou '(?' \u3067\u3059\u304b? +parser.next.3='(?<=' \u304b '(?= SchemaType.BTC_FIRST_PRIMITIVE && btc <= SchemaType.BTC_LAST_PRIMITIVE) + result.setPrimitiveTypeRef(result.getRef()); + else if (variety == SchemaType.ATOMIC) + { + if (base == null) + throw new IllegalStateException("Base was null for " + btc); + if (base.getPrimitiveType() == null) + throw new IllegalStateException("Base.gpt was null for " + btc); + result.setPrimitiveTypeRef(base.getPrimitiveType().getRef()); + } + + XmlValueRef[] facets; + boolean[] fixedf; + int wsr = SchemaType.WS_COLLAPSE; + int decimalSize = SchemaType.NOT_DECIMAL; + + // now set up facets + switch (btc) + { + default: + assert(false); + + case SchemaType.BTC_ANY_TYPE: + case SchemaType.BTC_ANY_SIMPLE: + case SchemaType.BTC_NOT_BUILTIN: + facets = FACETS_NONE; + fixedf = FIXED_FACETS_NONE; + wsr = SchemaType.WS_UNSPECIFIED; + break; + + case SchemaType.BTC_STRING: + facets = FACETS_WS_PRESERVE; + fixedf = FIXED_FACETS_NONE; + wsr = SchemaType.WS_PRESERVE; + break; + + case SchemaType.BTC_BOOLEAN: + case SchemaType.BTC_BASE_64_BINARY: + case SchemaType.BTC_HEX_BINARY: + case SchemaType.BTC_ANY_URI: + case SchemaType.BTC_QNAME: + case SchemaType.BTC_FLOAT: + case SchemaType.BTC_DOUBLE: + case SchemaType.BTC_NOTATION: + 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: + facets = FACETS_WS_COLLAPSE; + fixedf = FIXED_FACETS_WS; + break; + + case SchemaType.BTC_DECIMAL: + facets = FACETS_WS_COLLAPSE; + fixedf = FIXED_FACETS_WS; + decimalSize = SchemaType.SIZE_BIG_DECIMAL; + break; + + // derived numerics + case SchemaType.BTC_INTEGER: + facets = FACETS_INTEGER; + fixedf = FIXED_FACETS_INTEGER; + decimalSize = SchemaType.SIZE_BIG_INTEGER; + break; + + case SchemaType.BTC_LONG: + facets = FACETS_LONG; + fixedf = FIXED_FACETS_INTEGER; + decimalSize = SchemaType.SIZE_LONG; + break; + + case SchemaType.BTC_INT: + facets = FACETS_INT; + fixedf = FIXED_FACETS_INTEGER; + decimalSize = SchemaType.SIZE_INT; + break; + + case SchemaType.BTC_SHORT: + facets = FACETS_SHORT; + fixedf = FIXED_FACETS_INTEGER; + decimalSize = SchemaType.SIZE_SHORT; + break; + + case SchemaType.BTC_BYTE: + facets = FACETS_BYTE; + fixedf = FIXED_FACETS_INTEGER; + decimalSize = SchemaType.SIZE_BYTE; + break; + + case SchemaType.BTC_NON_POSITIVE_INTEGER: + facets = FACETS_NONPOSITIVE; + fixedf = FIXED_FACETS_INTEGER; + decimalSize = SchemaType.SIZE_BIG_INTEGER; + break; + + case SchemaType.BTC_NEGATIVE_INTEGER: + facets = FACETS_NEGATIVE; + fixedf = FIXED_FACETS_INTEGER; + decimalSize = SchemaType.SIZE_BIG_INTEGER; + break; + + case SchemaType.BTC_NON_NEGATIVE_INTEGER: + facets = FACETS_NONNEGATIVE; + fixedf = FIXED_FACETS_INTEGER; + decimalSize = SchemaType.SIZE_BIG_INTEGER; + break; + + case SchemaType.BTC_POSITIVE_INTEGER: + facets = FACETS_POSITIVE; + fixedf = FIXED_FACETS_INTEGER; + decimalSize = SchemaType.SIZE_BIG_INTEGER; + break; + + case SchemaType.BTC_UNSIGNED_LONG: + facets = FACETS_UNSIGNED_LONG; + fixedf = FIXED_FACETS_INTEGER; + decimalSize = SchemaType.SIZE_BIG_INTEGER; + break; + + case SchemaType.BTC_UNSIGNED_INT: + facets = FACETS_UNSIGNED_INT; + fixedf = FIXED_FACETS_INTEGER; + decimalSize = SchemaType.SIZE_LONG; + break; + + case SchemaType.BTC_UNSIGNED_SHORT: + facets = FACETS_UNSIGNED_SHORT; + fixedf = FIXED_FACETS_INTEGER; + decimalSize = SchemaType.SIZE_INT; + break; + + case SchemaType.BTC_UNSIGNED_BYTE: + facets = FACETS_UNSIGNED_BYTE; + fixedf = FIXED_FACETS_INTEGER; + decimalSize = SchemaType.SIZE_SHORT; + break; + + + // derived strings + case SchemaType.BTC_NORMALIZED_STRING: + facets = FACETS_WS_REPLACE; + fixedf = FIXED_FACETS_NONE; + wsr = SchemaType.WS_REPLACE; + break; + + case SchemaType.BTC_TOKEN: + case SchemaType.BTC_NAME: + case SchemaType.BTC_NCNAME: + case SchemaType.BTC_LANGUAGE: + case SchemaType.BTC_ID: + case SchemaType.BTC_IDREF: + case SchemaType.BTC_IDREFS: + case SchemaType.BTC_ENTITY: + case SchemaType.BTC_NMTOKEN: + facets = FACETS_WS_COLLAPSE; + fixedf = FIXED_FACETS_NONE; + wsr = SchemaType.WS_COLLAPSE; + break; + + case SchemaType.BTC_ENTITIES: + case SchemaType.BTC_NMTOKENS: + facets = FACETS_BUILTIN_LIST; + fixedf = FIXED_FACETS_NONE; + wsr = SchemaType.WS_UNSPECIFIED; + break; + } + + // fundamental facets + int ordered = SchemaType.UNORDERED; + boolean isNumeric = false; + boolean isFinite = false; + boolean isBounded = false; + + switch (btc) + { + default: + assert(false); + + case SchemaType.BTC_ANY_TYPE: + case SchemaType.BTC_NOT_BUILTIN: + case SchemaType.BTC_ANY_SIMPLE: + case SchemaType.BTC_STRING: + case SchemaType.BTC_BASE_64_BINARY: + case SchemaType.BTC_HEX_BINARY: + case SchemaType.BTC_ANY_URI: + case SchemaType.BTC_QNAME: + case SchemaType.BTC_NOTATION: + case SchemaType.BTC_NORMALIZED_STRING: + case SchemaType.BTC_TOKEN: + case SchemaType.BTC_NAME: + case SchemaType.BTC_NCNAME: + case SchemaType.BTC_LANGUAGE: + case SchemaType.BTC_ID: + case SchemaType.BTC_IDREF: + case SchemaType.BTC_IDREFS: + case SchemaType.BTC_ENTITY: + case SchemaType.BTC_NMTOKEN: + case SchemaType.BTC_ENTITIES: + case SchemaType.BTC_NMTOKENS: + break; + + case SchemaType.BTC_BOOLEAN: + isFinite = true; + break; + + + case SchemaType.BTC_FLOAT: + case SchemaType.BTC_DOUBLE: + case SchemaType.BTC_DECIMAL: + case SchemaType.BTC_INTEGER: + isNumeric = true; + ordered = SchemaType.TOTAL_ORDER; + break; + + 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: + ordered = SchemaType.PARTIAL_ORDER; + break; + + case SchemaType.BTC_LONG: + case SchemaType.BTC_INT: + case SchemaType.BTC_SHORT: + case SchemaType.BTC_BYTE: + case SchemaType.BTC_NON_POSITIVE_INTEGER: + case SchemaType.BTC_NEGATIVE_INTEGER: + case SchemaType.BTC_NON_NEGATIVE_INTEGER: + case SchemaType.BTC_POSITIVE_INTEGER: + case SchemaType.BTC_UNSIGNED_LONG: + case SchemaType.BTC_UNSIGNED_INT: + case SchemaType.BTC_UNSIGNED_SHORT: + case SchemaType.BTC_UNSIGNED_BYTE: + isNumeric = true; + ordered = SchemaType.TOTAL_ORDER; + isFinite = true; + isBounded = true; + break; + } + + result.setBasicFacets(facets, fixedf); + result.setWhiteSpaceRule(wsr); + result.setOrdered(ordered); + result.setBounded(isBounded); + result.setNumeric(isNumeric); + result.setFinite(isFinite); + result.setDecimalSize(decimalSize); + result.setAnonymousTypeRefs(EMPTY_SCHEMATYPEREF_ARRAY); + + String pattern = null; + boolean hasPattern = false; + + switch (btc) + { + case SchemaType.BTC_LANGUAGE: + pattern = "[a-zA-Z]{1,8}(-[a-zA-Z0-9]{1,8})*"; // we used to have ([a-zA-Z]{2}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*", but s4s uses the more lenient pattern to the left. + hasPattern = true; + break; + case SchemaType.BTC_NMTOKEN: + pattern = "\\c+"; + hasPattern = true; + break; + case SchemaType.BTC_NAME: + pattern = "\\i\\c*"; + hasPattern = true; + break; + case SchemaType.BTC_NCNAME: + pattern = "[\\i-[:]][\\c-[:]]*"; + hasPattern = true; + break; + + // These types inherit their patterns + case SchemaType.BTC_ID: + case SchemaType.BTC_IDREF: + case SchemaType.BTC_ENTITY: + hasPattern = true; + break; + } + + if (pattern != null) + { + org.apache.xmlbeans.impl.regex.RegularExpression p = null; + try { p = org.apache.xmlbeans.impl.regex.SchemaRegularExpression.forPattern(pattern); } + catch (org.apache.xmlbeans.impl.regex.ParseException e) { assert false; } + result.setPatterns(new org.apache.xmlbeans.impl.regex.RegularExpression[] {p}); + } + result.setPatternFacet(hasPattern); + + + + // ANY_TYPE has to be able to act like a complex type + if (btc == SchemaType.BTC_ANY_TYPE) + { + SchemaParticleImpl contentModel = new SchemaParticleImpl(); + contentModel.setParticleType(SchemaParticle.WILDCARD); + contentModel.setWildcardSet(QNameSet.ALL); + contentModel.setWildcardProcess(SchemaParticle.LAX); + contentModel.setMinOccurs(BigInteger.ZERO); + contentModel.setMaxOccurs(null); + contentModel.setTransitionRules(QNameSet.ALL, true); + contentModel.setTransitionNotes(QNameSet.ALL, true); + + SchemaAttributeModelImpl attrModel = new SchemaAttributeModelImpl(); + attrModel.setWildcardProcess(SchemaAttributeModel.LAX); + attrModel.setWildcardSet(QNameSet.ALL); + + result.setComplexTypeVariety(SchemaType.MIXED_CONTENT); + result.setContentModel(contentModel, attrModel, Collections.EMPTY_MAP, Collections.EMPTY_MAP, false); + result.setAnonymousTypeRefs(EMPTY_SCHEMATYPEREF_ARRAY); + result.setWildcardSummary(QNameSet.ALL, true, QNameSet.ALL, true); + } + else if (btc == SchemaType.BTC_NOT_BUILTIN) + { + // so does the no_type : it permits no contents (and even empty contents is invalid, but that's special-cased) + SchemaParticleImpl contentModel = null; // empty + SchemaAttributeModelImpl attrModel = new SchemaAttributeModelImpl(); // empty + result.setComplexTypeVariety(SchemaType.EMPTY_CONTENT); + result.setContentModel(contentModel, attrModel, Collections.EMPTY_MAP, Collections.EMPTY_MAP, false); + result.setAnonymousTypeRefs(EMPTY_SCHEMATYPEREF_ARRAY); + result.setWildcardSummary(QNameSet.EMPTY, false, QNameSet.EMPTY, false); + } + + result.setOrderSensitive(false); + } + + public static SchemaType getNoType() + { + return ST_NO_TYPE; + } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/ClassLoaderResourceLoader.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/ClassLoaderResourceLoader.java new file mode 100644 index 000000000..14697c6cb --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/ClassLoaderResourceLoader.java @@ -0,0 +1,37 @@ +/* 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.ResourceLoader; + +import java.io.InputStream; + +public class ClassLoaderResourceLoader implements ResourceLoader +{ + ClassLoader _classLoader; + + public ClassLoaderResourceLoader(ClassLoader classLoader) + { + _classLoader = classLoader; + } + + public InputStream getResourceAsStream(String resourceName) + { + return _classLoader.getResourceAsStream(resourceName); + } + + public void close() {} +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/FileResourceLoader.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/FileResourceLoader.java new file mode 100644 index 000000000..70ac7c601 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/FileResourceLoader.java @@ -0,0 +1,80 @@ +/* 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.ResourceLoader; + +import java.io.InputStream; +import java.io.FileInputStream; +import java.io.File; +import java.io.IOException; +import java.util.zip.ZipFile; +import java.util.zip.ZipEntry; + +public class FileResourceLoader implements ResourceLoader +{ + private File _directory; + private ZipFile _zipfile; + + public FileResourceLoader(File file) throws IOException + { + if (file.isDirectory()) + _directory = file; + else + { + _zipfile = new ZipFile(file); + } + } + + public InputStream getResourceAsStream(String resourceName) + { + try + { + if (_zipfile != null) + { + ZipEntry entry = _zipfile.getEntry(resourceName); + if (entry == null) + return null; + return _zipfile.getInputStream(entry); + } + else + { + return new FileInputStream(new File(_directory, resourceName)); + } + } + catch (IOException e) + { + return null; + } + } + + public void close() + { + if (_zipfile != null) + { + try + { + _zipfile.close(); + } + catch (IOException e) + { + // oh well. + } + _zipfile = null; + } + } +} + diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/PathResourceLoader.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/PathResourceLoader.java new file mode 100644 index 000000000..4e21415e3 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/PathResourceLoader.java @@ -0,0 +1,79 @@ +/* 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.ResourceLoader; + +import java.io.InputStream; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +public class PathResourceLoader implements ResourceLoader +{ + private ResourceLoader[] _path; + + public PathResourceLoader(ResourceLoader[] loaderpath) throws IOException + { + _path = new ResourceLoader[loaderpath.length]; + System.arraycopy(loaderpath, 0, _path, 0, _path.length); + } + + public PathResourceLoader(File[] filepath) + { + List pathlist = new ArrayList(); + for (int i = 0; i < filepath.length; i++) + { + try + { + ResourceLoader path = new FileResourceLoader(filepath[i]); + pathlist.add(path); + } + catch (IOException e) + { + continue; // can't read a file on classpath? skip it. + } + } + _path = (ResourceLoader[])pathlist.toArray(new ResourceLoader[pathlist.size()]); + } + + public InputStream getResourceAsStream(String resourceName) + { + for (int i = 0; i < _path.length; i++) + { + InputStream result = _path[i].getResourceAsStream(resourceName); + if (result != null) + return result; + } + return null; + } + + public void close() + { + for (int i = 0; i < _path.length; i++) + { + try + { + _path[i].close(); + } + catch (Exception e) + { + // oh well. + } + } + } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaAnnotationImpl.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaAnnotationImpl.java new file mode 100755 index 000000000..da3558855 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaAnnotationImpl.java @@ -0,0 +1,231 @@ +/* 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 java.util.ArrayList; +import java.util.List; + +import javax.xml.namespace.QName; + +import org.apache.xmlbeans.SchemaAnnotation; +import org.apache.xmlbeans.SchemaTypeSystem; +import org.apache.xmlbeans.XmlCursor; +import org.apache.xmlbeans.XmlException; +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.impl.xb.xsdschema.AppinfoDocument; +import org.apache.xmlbeans.impl.xb.xsdschema.Annotated; +import org.apache.xmlbeans.impl.xb.xsdschema.AnnotationDocument; +import org.apache.xmlbeans.impl.xb.xsdschema.DocumentationDocument; +import org.apache.xmlbeans.SchemaComponent; + +public class SchemaAnnotationImpl implements SchemaAnnotation +{ + private SchemaContainer _container; + private String[] _appInfoAsXml; + private AppinfoDocument.Appinfo[] _appInfo; + private String[] _documentationAsXml; + private DocumentationDocument.Documentation[] _documentation; + private Attribute[] _attributes; + private String _filename; + + public void setFilename(String filename) + { + _filename = filename; + } + + public String getSourceName() + { + return _filename; + } + + public XmlObject[] getApplicationInformation() + { + if (_appInfo == null) + { + int n = _appInfoAsXml.length; + _appInfo = new AppinfoDocument.Appinfo[n]; + for (int i = 0; i < n; i++) + { + String appInfo = _appInfoAsXml[i]; + try + { + _appInfo[i] = AppinfoDocument.Factory. + parse(appInfo).getAppinfo(); + } + catch(XmlException e) + { + // problem in the classfile + _appInfo[i] = AppinfoDocument.Factory. + newInstance().getAppinfo(); + } + } + } + return _appInfo; + } + + public XmlObject[] getUserInformation() + { + if (_documentation == null) + { + int n = _documentationAsXml.length; + _documentation = new DocumentationDocument.Documentation[n]; + for (int i = 0; i < n; i++) + { + String doc = _documentationAsXml[i]; + try + { + _documentation[i] = DocumentationDocument.Factory. + parse(doc).getDocumentation(); + } + catch (XmlException e) + { + // problem in the classfile + _documentation[i] = DocumentationDocument.Factory. + newInstance().getDocumentation(); + } + } + } + return _documentation; + } + + public Attribute[] getAttributes() + { return _attributes; } + + public int getComponentType() + { return ANNOTATION; } + + public SchemaTypeSystem getTypeSystem() + { return _container != null ? _container.getTypeSystem() : null; } + + SchemaContainer getContainer() + { return _container; } + + public QName getName() + { return null; } + + public SchemaComponent.Ref getComponentRef() + { return null; } + + public static SchemaAnnotationImpl getAnnotation(SchemaContainer c, + Annotated elem) + { + AnnotationDocument.Annotation ann = elem.getAnnotation(); + + return getAnnotation(c, elem, ann); + } + + public static SchemaAnnotationImpl getAnnotation(SchemaContainer c, + XmlObject elem, AnnotationDocument.Annotation ann) + { + // Check option + if (StscState.get().noAnn()) + return null; + + SchemaAnnotationImpl result = new SchemaAnnotationImpl(c); + // Retrieving attributes, first attributes on the enclosing element + ArrayList attrArray = new ArrayList(2); + addNoSchemaAttributes(elem, attrArray); + if (ann == null) + { + if (attrArray.size() == 0) + return null; // no annotation present + // no annotation element present, but attributes on the enclosing + // element present, so we have an annotation component + result._appInfo = new AppinfoDocument.Appinfo[0]; + result._documentation = new DocumentationDocument.Documentation[0]; + } + else + { + result._appInfo = ann.getAppinfoArray(); + result._documentation = ann.getDocumentationArray(); + // Now the attributes on the annotation element + addNoSchemaAttributes(ann, attrArray); + } + + result._attributes = + (AttributeImpl[]) attrArray.toArray(new AttributeImpl[attrArray.size()]); + return result; + } + + private static void addNoSchemaAttributes(XmlObject elem, List attrList) + { + XmlCursor cursor = elem.newCursor(); + boolean hasAttributes = cursor.toFirstAttribute(); + while (hasAttributes) + { + QName name = cursor.getName(); + String namespaceURI = name.getNamespaceURI(); + if ("".equals(namespaceURI) || + "http://www.w3.org/2001/XMLSchema".equals(namespaceURI)) + ; // no nothing + else + { + String attValue = cursor.getTextValue(); + String valUri; + String prefix; + if (attValue.indexOf(':') > 0) + prefix = attValue.substring(0, attValue.indexOf(':')); + else + prefix = ""; + cursor.push(); + cursor.toParent(); + valUri = cursor.namespaceForPrefix(prefix); + cursor.pop(); + attrList.add(new AttributeImpl(name, attValue, valUri)); //add the attribute + } + hasAttributes = cursor.toNextAttribute(); + } + cursor.dispose(); + } + + private SchemaAnnotationImpl(SchemaContainer c) + { + _container = c; + } + + /*package*/ SchemaAnnotationImpl(SchemaContainer c, + String[] aapStrings, String[] adocStrings, + Attribute[] aat) + { + _container = c; + _appInfoAsXml = aapStrings; + _documentationAsXml = adocStrings; + _attributes = aat; + } + + /*package*/ static class AttributeImpl implements Attribute + { + private QName _name; + private String _value; + private String _valueUri; + + /*package*/ AttributeImpl(QName name, String value, String valueUri) + { + _name = name; + _value = value; + _valueUri = valueUri; + } + + public QName getName() + { return _name; } + + public String getValue() + { return _value; } + + public String getValueUri() + { return _valueUri; } + } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaAttributeGroupImpl.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaAttributeGroupImpl.java new file mode 100644 index 000000000..a2949dfd6 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaAttributeGroupImpl.java @@ -0,0 +1,113 @@ +/* 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 javax.xml.namespace.QName; +import org.apache.xmlbeans.SchemaAnnotation; +import org.apache.xmlbeans.SchemaComponent; +import org.apache.xmlbeans.SchemaAttributeGroup; +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.SchemaTypeSystem; + +public class SchemaAttributeGroupImpl implements SchemaAttributeGroup +{ + private SchemaContainer _container; + private QName _name; + private XmlObject _parseObject; + private Object _userData; + private String _parseTNS; + private String _formDefault; + private boolean _chameleon; + private boolean _redefinition; + private SchemaAnnotation _annotation; + private String _filename; + + public SchemaAttributeGroupImpl(SchemaContainer container) + { + _container = container; + } + + public SchemaAttributeGroupImpl(SchemaContainer container, QName name) + { + _container = container; + _name = name; + } + + public void init(QName name, String targetNamespace, boolean chameleon, String formDefault, boolean redefinition, XmlObject x, SchemaAnnotation a, Object userData) + { + assert _name == null || name.equals( _name ); + + _name = name; + _parseTNS = targetNamespace; + _chameleon = chameleon; + _formDefault = formDefault; + _redefinition = redefinition; + _parseObject = x; + _annotation = a; + _userData = userData; + } + + public SchemaTypeSystem getTypeSystem() + { + return _container.getTypeSystem(); + } + + SchemaContainer getContainer() + { + return _container; + } + + public int getComponentType() + { return SchemaComponent.ATTRIBUTE_GROUP; } + + public void setFilename(String filename) + { _filename = filename; } + + public String getSourceName() + { return _filename; } + + public QName getName() + { return _name; } + + public XmlObject getParseObject() + { return _parseObject; } + + public String getTargetNamespace() + { return _parseTNS; } + + public String getChameleonNamespace() + { return _chameleon ? _parseTNS : null; } + + public String getFormDefault() + { return _formDefault; } + + public SchemaAnnotation getAnnotation() + { return _annotation; } + + private SchemaAttributeGroup.Ref _selfref = new SchemaAttributeGroup.Ref(this); + + public SchemaAttributeGroup.Ref getRef() + { return _selfref; } + + public SchemaComponent.Ref getComponentRef() + { return getRef(); } + + public boolean isRedefinition() + { return _redefinition; } + + public Object getUserData() + { return _userData; } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaAttributeModelImpl.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaAttributeModelImpl.java new file mode 100644 index 000000000..cca4eda74 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaAttributeModelImpl.java @@ -0,0 +1,106 @@ +/* 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.SchemaAttributeModel; +import org.apache.xmlbeans.SchemaGlobalAttribute; +import org.apache.xmlbeans.QNameSet; +import org.apache.xmlbeans.QNameSetBuilder; +import org.apache.xmlbeans.SchemaLocalAttribute; +import javax.xml.namespace.QName; + +import java.util.Map; +import java.util.LinkedHashMap; + +public class SchemaAttributeModelImpl implements SchemaAttributeModel +{ + private Map attrMap; + private QNameSet wcSet; + private int wcProcess; + + public SchemaAttributeModelImpl() + { + attrMap = new LinkedHashMap(); + wcSet = null; + wcProcess = NONE; + } + + public SchemaAttributeModelImpl(SchemaAttributeModel sam) + { + attrMap = new LinkedHashMap(); + if (sam == null) + { + wcSet = null; + wcProcess = NONE; + } + else + { + SchemaLocalAttribute[] attrs = sam.getAttributes(); + for (int i = 0; i < attrs.length; i++) + { + attrMap.put(attrs[i].getName(), attrs[i]); + } + + if (sam.getWildcardProcess() != SchemaAttributeModel.NONE) + { + wcSet = sam.getWildcardSet(); + wcProcess = sam.getWildcardProcess(); + } + } + } + + private static final SchemaLocalAttribute[] EMPTY_SLA_ARRAY = new SchemaLocalAttribute[0]; + + public SchemaLocalAttribute[] getAttributes() + { + return (SchemaLocalAttribute[])attrMap.values().toArray(EMPTY_SLA_ARRAY); + } + + public SchemaLocalAttribute getAttribute(QName name) + { + return (SchemaLocalAttribute)attrMap.get(name); + } + + public void addAttribute(SchemaLocalAttribute attruse) + { + attrMap.put(attruse.getName(), attruse); + } + + public void removeProhibitedAttribute(QName name) + { + attrMap.remove(name); + } + + public QNameSet getWildcardSet() + { + return wcSet == null ? QNameSet.EMPTY : wcSet; + } + + public void setWildcardSet(QNameSet set) + { + wcSet = set; + } + + public int getWildcardProcess() + { + return wcProcess; + } + + public void setWildcardProcess(int proc) + { + wcProcess = proc; + } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaContainer.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaContainer.java new file mode 100644 index 000000000..e3fe3f562 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaContainer.java @@ -0,0 +1,210 @@ +/* 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 java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.apache.xmlbeans.SchemaAnnotation; +import org.apache.xmlbeans.SchemaAttributeGroup; +import org.apache.xmlbeans.SchemaComponent; +import org.apache.xmlbeans.SchemaGlobalAttribute; +import org.apache.xmlbeans.SchemaGlobalElement; +import org.apache.xmlbeans.SchemaIdentityConstraint; +import org.apache.xmlbeans.SchemaModelGroup; +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.SchemaTypeSystem; + +/*package*/ class SchemaContainer +{ + // The namespace that this is the container for + // TODO(radup) In the future, I think the right approach is one container + // per file instead of per namespace, but per namespace is easier for now + private String _namespace; + + SchemaContainer(String namespace) + { + _namespace = namespace; + } + + String getNamespace() + { + return _namespace; + } + + // The SchemaTypeSystem on behalf of which this acts + private SchemaTypeSystem _typeSystem; + + // This is the whole idea of the containers + // By synchronizing getter/setters on this field, we allow + // both SchemaTypeSystems and SchemaTypes to be immutable + // at the same time providing the mechanism through which + // we can "move" SchemaTypes from one SchemaTypeSystem to another + // via incremental compilation + synchronized SchemaTypeSystem getTypeSystem() + { + return _typeSystem; + } + + synchronized void setTypeSystem(SchemaTypeSystem typeSystem) + { + _typeSystem = typeSystem; + } + + // Immutability refers to the content of the container + // Once the container has been initialized, one cannot add/remove + // SchemaComponents from it. Instead, one has to blow it away + // and build a new one. + // Immutability does not mean that one cannot move this container + // between typesystems. + boolean _immutable; + + synchronized void setImmutable() + { + _immutable = true; + } + + synchronized void unsetImmutable() + { + _immutable = false; + } + + private void check_immutable() + { + if (_immutable) + throw new IllegalStateException("Cannot add components to immutable SchemaContainer"); + } + + // Data + // TODO(radup) unmodifiableList() is not really necessary, since this + // is package-level access and code in this package should do the "right thing" + // Global Elements + private List/**/ _globalElements = new ArrayList(); + + void addGlobalElement(SchemaGlobalElement.Ref e) + { check_immutable(); _globalElements.add(e); } + + List globalElements() + { return getComponentList(_globalElements); } + + // Global Attributes + private List/**/ _globalAttributes = new ArrayList(); + + void addGlobalAttribute(SchemaGlobalAttribute.Ref a) + { check_immutable(); _globalAttributes.add(a); } + + List globalAttributes() + { return getComponentList(_globalAttributes); } + + // Model Groups + private List/**/ _modelGroups = new ArrayList(); + + void addModelGroup(SchemaModelGroup.Ref g) + { check_immutable(); _modelGroups.add(g); } + + List modelGroups() + { return getComponentList(_modelGroups); } + + // Redefined Model Groups + private List/**/ _redefinedModelGroups = new ArrayList(); + + void addRedefinedModelGroup(SchemaModelGroup.Ref g) + { check_immutable(); _redefinedModelGroups.add(g); } + + List redefinedModelGroups() + { return getComponentList(_redefinedModelGroups); } + + // Attribute Groups + private List/**/ _attributeGroups = new ArrayList(); + + void addAttributeGroup(SchemaAttributeGroup.Ref g) + { check_immutable(); _attributeGroups.add(g); } + + List attributeGroups() + { return getComponentList(_attributeGroups); } + + // Redefined Attribute Groups + private List/**/ _redefinedAttributeGroups = new ArrayList(); + + void addRedefinedAttributeGroup(SchemaAttributeGroup.Ref g) + { check_immutable(); _redefinedAttributeGroups.add(g); } + + List redefinedAttributeGroups() + { return getComponentList(_redefinedAttributeGroups); } + + // Global Types + private List/**/ _globalTypes = new ArrayList(); + + void addGlobalType(SchemaType.Ref t) + { check_immutable(); _globalTypes.add(t); } + + List globalTypes() + { return getComponentList(_globalTypes); } + + // Redefined Global Types + private List/**/ _redefinedGlobalTypes = new ArrayList(); + + void addRedefinedType(SchemaType.Ref t) + { check_immutable(); _redefinedGlobalTypes.add(t); } + + List redefinedGlobalTypes() + { return getComponentList(_redefinedGlobalTypes); } + + // Document Types + private List/**/ _documentTypes = new ArrayList(); + + void addDocumentType(SchemaType.Ref t) + { check_immutable(); _documentTypes.add(t); } + + List documentTypes() + { return getComponentList(_documentTypes); } + + // Attribute Types + private List/**/ _attributeTypes = new ArrayList(); + + void addAttributeType(SchemaType.Ref t) + { check_immutable(); _attributeTypes.add(t); } + + List attributeTypes() + { return getComponentList(_attributeTypes); } + + // Identity Constraints + private List/**/ _identityConstraints = new ArrayList(); + + void addIdentityConstraint(SchemaIdentityConstraint.Ref c) + { check_immutable(); _identityConstraints.add(c); } + + List identityConstraints() + { return getComponentList(_identityConstraints); } + + // Annotations + private List/**/ _annotations = new ArrayList(); + + void addAnnotation(SchemaAnnotation a) + { check_immutable(); _annotations.add(a); } + + List annotations() + { return Collections.unmodifiableList(_annotations); } + + private List getComponentList(List referenceList) + { + List result = new ArrayList(); + for (int i = 0; i < referenceList.size(); i ++) + result.add(((SchemaComponent.Ref) referenceList.get(i)).getComponent()); + return Collections.unmodifiableList(result); + } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaDependencies.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaDependencies.java new file mode 100644 index 000000000..3f4b6c7a3 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaDependencies.java @@ -0,0 +1,162 @@ +/* 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 java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +public class SchemaDependencies +{ + // This class is NOT synchronized + + void registerDependency(String source, String target) + { + Set depSet = (Set) _dependencies.get(target); + if (depSet == null) + { + depSet = new HashSet(); + _dependencies.put(target, depSet); + } + depSet.add(source); + } + + + + /** + * Records anti-dependencies. Keys are namespaces and values are + * the lists of namespaces that depend on each key + */ + private Map/*>*/ _dependencies; + + Set computeTransitiveClosure(List modifiedNamespaces) + { + List nsList = new ArrayList(modifiedNamespaces); + Set result = new HashSet(modifiedNamespaces); + for (int i = 0; i < nsList.size(); i++) + { + Set deps = (Set) _dependencies.get(nsList.get(i)); + if (deps == null) + continue; + for (Iterator it = deps.iterator(); it.hasNext(); ) + { + String ns = (String) it.next(); + if (!result.contains(ns)) + { + nsList.add(ns); + result.add(ns); + } + } + } + return result; + } + + SchemaDependencies() + { + _dependencies = new HashMap(); + _contributions = new HashMap(); + } + + SchemaDependencies(SchemaDependencies base, Set updatedNs) + { + _dependencies = new HashMap(); + _contributions = new HashMap(); + for (Iterator it = base._dependencies.keySet().iterator(); it.hasNext(); ) + { + String target = (String) it.next(); + if (updatedNs.contains(target)) + continue; + Set depSet = new HashSet(); + _dependencies.put(target, depSet); + Set baseDepSet = (Set) base._dependencies.get(target); + for (Iterator it2 = baseDepSet.iterator(); it2.hasNext(); ) + { + String source = (String) it2.next(); + if (updatedNs.contains(source)) + continue; + depSet.add(source); + } + } + for (Iterator it = base._contributions.keySet().iterator(); it.hasNext(); ) + { + String ns = (String) it.next(); + if (updatedNs.contains(ns)) + continue; + List fileList = new ArrayList(); + _contributions.put(ns, fileList); + List baseFileList = (List) base._contributions.get(ns); + for (Iterator it2 = baseFileList.iterator(); it2.hasNext(); ) + fileList.add(it2.next()); + } + } + + /** + * Records the list of files associated to each namespace. + * This is needed so that we can return a list of files that + * need to be compiled once we get a set of altered namespaces + */ + private Map/*>*/ _contributions; + + void registerContribution(String ns, String fileURL) + { + List fileList = (List) _contributions.get(ns); + if (fileList == null) + { + fileList = new ArrayList(); + _contributions.put(ns, fileList); + } + fileList.add(fileURL); + } + + boolean isFileRepresented(String fileURL) + { + for (Iterator it = _contributions.values().iterator(); it.hasNext(); ) + { + List fileList = (List) it.next(); + if (fileList.contains(fileURL)) + return true; + } + return false; + } + + List getFilesTouched(Set updatedNs) + { + List result = new ArrayList(); + for (Iterator it = updatedNs.iterator(); it.hasNext(); ) + { + result.addAll((List) _contributions.get(it.next())); + } + return result; + } + + List getNamespacesTouched(Set modifiedFiles) + { + List result = new ArrayList(); + for (Iterator it = _contributions.keySet().iterator(); it.hasNext(); ) + { + String ns = (String) it.next(); + List files = (List) _contributions.get(ns); + for (int i = 0; i < files.size(); i++) + if (modifiedFiles.contains(files.get(i))) + result.add(ns); + } + return result; + } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaGlobalAttributeImpl.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaGlobalAttributeImpl.java new file mode 100644 index 000000000..7366a6eab --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaGlobalAttributeImpl.java @@ -0,0 +1,85 @@ +/* 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.SchemaGlobalAttribute; +import org.apache.xmlbeans.SchemaComponent; +import org.apache.xmlbeans.SchemaTypeSystem; +import org.apache.xmlbeans.XmlObject; + +public class SchemaGlobalAttributeImpl extends SchemaLocalAttributeImpl + implements SchemaGlobalAttribute +{ + SchemaContainer _container; + String _filename; + private String _parseTNS; + private boolean _chameleon; + + public SchemaGlobalAttributeImpl(SchemaContainer container) + { + _container = container; + } + + public SchemaTypeSystem getTypeSystem() + { + return _container.getTypeSystem(); + } + + SchemaContainer getContainer() + { + return _container; + } + + + public int getComponentType() + { + return SchemaComponent.ATTRIBUTE; + } + + public String getSourceName() + { + return _filename; + } + + public void setFilename(String filename) + { + _filename = filename; + } + + public void setParseContext(XmlObject parseObject, String targetNamespace, boolean chameleon) + { + _parseObject = parseObject; + _parseTNS = targetNamespace; + _chameleon = chameleon; + } + + public XmlObject getParseObject() + { return _parseObject; } + + public String getTargetNamespace() + { return _parseTNS; } + + public String getChameleonNamespace() + { return _chameleon ? _parseTNS : null; } + + private SchemaGlobalAttribute.Ref _selfref = new SchemaGlobalAttribute.Ref(this); + + public SchemaGlobalAttribute.Ref getRef() + { return _selfref; } + + public SchemaComponent.Ref getComponentRef() + { return getRef(); } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaGlobalElementImpl.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaGlobalElementImpl.java new file mode 100644 index 000000000..a8f1a4cfd --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaGlobalElementImpl.java @@ -0,0 +1,130 @@ +/* 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.SchemaGlobalElement; +import org.apache.xmlbeans.SchemaComponent; +import org.apache.xmlbeans.SchemaTypeSystem; +import org.apache.xmlbeans.XmlObject; +import javax.xml.namespace.QName; + +import java.util.LinkedHashSet; +import java.util.Set; + +public class SchemaGlobalElementImpl extends SchemaLocalElementImpl + implements SchemaGlobalElement +{ + private Set _sgMembers = new LinkedHashSet(); + private static final QName[] _namearray = new QName[0]; + private boolean _finalExt; + private boolean _finalRest; + private SchemaContainer _container; + private String _filename; + // private XmlObject _parseObject; now inherited from base + private String _parseTNS; + private boolean _chameleon; + private SchemaGlobalElement.Ref _sg; + + public SchemaGlobalElementImpl(SchemaContainer container) + { + _container = container; + } + + public SchemaTypeSystem getTypeSystem() + { + return _container.getTypeSystem(); + } + + SchemaContainer getContainer() + { + return _container; + } + + public String getSourceName() + { + return _filename; + } + + public void setFilename(String filename) + { + _filename = filename; + } + + void setFinal(boolean finalExt, boolean finalRest) + { + mutate(); _finalExt = finalExt; _finalRest = finalRest; + } + + public int getComponentType() + { + return SchemaComponent.ELEMENT; + } + + public SchemaGlobalElement substitutionGroup() + { + return _sg == null ? null : _sg.get(); + } + + public void setSubstitutionGroup(SchemaGlobalElement.Ref sg) + { + _sg = sg; + } + + public QName[] substitutionGroupMembers() + { + return (QName[])_sgMembers.toArray(_namearray); + } + + public void addSubstitutionGroupMember(QName name) + { + mutate(); _sgMembers.add(name); + } + + + public boolean finalExtension() + { + return _finalExt; + } + + public boolean finalRestriction() + { + return _finalRest; + } + + public void setParseContext(XmlObject parseObject, String targetNamespace, boolean chameleon) + { + _parseObject = parseObject; + _parseTNS = targetNamespace; + _chameleon = chameleon; + } + + public XmlObject getParseObject() + { return _parseObject; } + + public String getTargetNamespace() + { return _parseTNS; } + + public String getChameleonNamespace() + { return _chameleon ? _parseTNS : null; } + + private SchemaGlobalElement.Ref _selfref = new SchemaGlobalElement.Ref(this); + + public SchemaGlobalElement.Ref getRef() + { return _selfref; } + + public SchemaComponent.Ref getComponentRef() + { return getRef(); } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaIdentityConstraintImpl.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaIdentityConstraintImpl.java new file mode 100644 index 000000000..196d24a83 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaIdentityConstraintImpl.java @@ -0,0 +1,213 @@ +/* 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.SchemaIdentityConstraint; +import org.apache.xmlbeans.SchemaTypeSystem; +import org.apache.xmlbeans.SchemaAnnotation; +import org.apache.xmlbeans.SchemaComponent; +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.impl.common.XPath; +import javax.xml.namespace.QName; +import java.util.Map; +import java.util.Collections; + +public class SchemaIdentityConstraintImpl implements SchemaIdentityConstraint +{ + private SchemaContainer _container; + private String _selector; + private String[] _fields; + private SchemaIdentityConstraint.Ref _key; + private QName _name; + private int _type; + private XmlObject _parse; + private Object _userData; + private SchemaAnnotation _annotation; + private Map _nsMap = Collections.EMPTY_MAP; + private String _parseTNS; + private boolean _chameleon; + private String _filename; + + // Lazily computed paths + private volatile XPath _selectorPath; + private volatile XPath[] _fieldPaths; + + public SchemaIdentityConstraintImpl(SchemaContainer c) { + _container = c; + } + + public void setFilename(String filename) + { _filename = filename; } + + public String getSourceName() + { return _filename; } + + + public String getSelector() { + return _selector; + } + + public Object getSelectorPath() { + XPath p = _selectorPath; + if (p == null) { + try { + buildPaths(); + p = _selectorPath; + } + catch (XPath.XPathCompileException e) { + assert false: "Failed to compile xpath. Should be caught by compiler " + e; + return null; + } + } + return p; + } + + public void setAnnotation(SchemaAnnotation ann) + { + _annotation = ann; + } + + public SchemaAnnotation getAnnotation() + { + return _annotation; + } + + public void setNSMap(Map nsMap) { + _nsMap = nsMap; + } + + public Map getNSMap() { + return Collections.unmodifiableMap(_nsMap); + } + + public void setSelector(String selector) { + assert selector != null; + _selector = selector; + } + + public void setFields(String[] fields) { + assert fields != null && fields.length > 0; + _fields = fields; + } + + public String[] getFields() { + String[] fields = new String[_fields.length]; + System.arraycopy(_fields, 0, fields, 0, fields.length); + return fields; + } + + public Object getFieldPath(int index) { + XPath[] p = _fieldPaths; + if (p == null) { + try { + buildPaths(); + p = _fieldPaths; + } + catch (XPath.XPathCompileException e) { + assert false: "Failed to compile xpath. Should be caught by compiler " + e; + return null; + } + } + return p[index]; + } + + public void buildPaths() throws XPath.XPathCompileException { + // TODO: Need the namespace map - requires store support + _selectorPath = XPath.compileXPath(_selector, _nsMap); + + _fieldPaths = new XPath[_fields.length]; + for (int i = 0 ; i < _fieldPaths.length ; i++) + _fieldPaths[i] = XPath.compileXPath(_fields[i], _nsMap); + } + + public void setReferencedKey(SchemaIdentityConstraint.Ref key) { + _key = key; + } + + public SchemaIdentityConstraint getReferencedKey() { + return _key.get(); + } + + public void setConstraintCategory(int type) { + assert type >= CC_KEY && type <= CC_UNIQUE; + _type = type; + } + + public int getConstraintCategory() { + return _type; + } + + public void setName(QName name) { + assert name != null; + _name = name; + } + + public QName getName() { + return _name; + } + + public int getComponentType() { + return IDENTITY_CONSTRAINT; + } + + public SchemaTypeSystem getTypeSystem() { + return _container.getTypeSystem(); + } + + SchemaContainer getContainer() { + return _container; + } + + public void setParseContext(XmlObject o, String targetNamespace, boolean chameleon) { + _parse = o; + _parseTNS = targetNamespace; + _chameleon = chameleon; + } + + public XmlObject getParseObject() { + return _parse; + } + + public String getTargetNamespace() { + return _parseTNS; + } + + public String getChameleonNamespace() { + return _chameleon ? _parseTNS : null; + } + + + /** + * Only applicable to keyrefs. Other types are implicitly resolved. + */ + public boolean isResolved() { + return getConstraintCategory() != CC_KEYREF || _key != null; + } + + private SchemaIdentityConstraint.Ref _selfref = new SchemaIdentityConstraint.Ref(this); + + public SchemaIdentityConstraint.Ref getRef() + { return _selfref; } + + public SchemaComponent.Ref getComponentRef() + { return getRef(); } + + public Object getUserData() + { return _userData; } + + public void setUserData(Object data) + { _userData = data; } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaLocalAttributeImpl.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaLocalAttributeImpl.java new file mode 100644 index 000000000..c46b6577c --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaLocalAttributeImpl.java @@ -0,0 +1,147 @@ +/* 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 javax.xml.namespace.QName; +import org.apache.xmlbeans.SchemaAnnotation; +import org.apache.xmlbeans.SchemaBookmark; +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.SchemaLocalAttribute; +import org.apache.xmlbeans.XmlCursor; +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.XmlAnySimpleType; +import org.apache.xmlbeans.XmlQName; +import org.apache.xmlbeans.soap.SOAPArrayType; +import org.apache.xmlbeans.soap.SchemaWSDLArrayType; +import org.apache.xmlbeans.impl.values.NamespaceContext; + +import java.math.BigInteger; + +public class SchemaLocalAttributeImpl implements SchemaLocalAttribute, SchemaWSDLArrayType +{ + public SchemaLocalAttributeImpl() + { + } + + public void init(QName name, SchemaType.Ref typeref, int use, String deftext, XmlObject parseObject, XmlValueRef defvalue, boolean isFixed, SOAPArrayType wsdlArray, SchemaAnnotation ann, Object userData) + { + if (_xmlName != null || _typeref != null) + throw new IllegalStateException("Already initialized"); + _use = use; + _typeref = typeref; + _defaultText = deftext; + _parseObject = parseObject; + _defaultValue = defvalue; + _isDefault = (deftext != null); + _isFixed = isFixed; + _xmlName = name; + _wsdlArrayType = wsdlArray; + _annotation = ann; + _userData = userData; + } + + private String _defaultText; + /* package */ XmlValueRef _defaultValue; + private boolean _isFixed; + private boolean _isDefault; + private QName _xmlName; + private SchemaType.Ref _typeref; + private SOAPArrayType _wsdlArrayType; + private int _use; + private SchemaAnnotation _annotation; + protected XmlObject _parseObject; // for QName resolution + private Object _userData; + + public boolean isTypeResolved() + { + return (_typeref != null); + } + + public void resolveTypeRef(SchemaType.Ref typeref) + { + if (_typeref != null) + throw new IllegalStateException(); + _typeref = typeref; + } + + public int getUse() + { return _use; } + + public QName getName() + { return _xmlName; } + + public String getDefaultText() + { return _defaultText; } + + public boolean isDefault() + { return _isDefault; } + + public boolean isFixed() + { return _isFixed; } + + public boolean isAttribute() + { return true; } + + public SchemaAnnotation getAnnotation() + { return _annotation; } + + public SchemaType getType() + { return _typeref.get(); } + + public SchemaType.Ref getTypeRef() + { return _typeref; } + + public BigInteger getMinOccurs() + { return _use == REQUIRED ? BigInteger.ONE : BigInteger.ZERO; } + + public BigInteger getMaxOccurs() + { return _use == PROHIBITED ? BigInteger.ZERO : BigInteger.ONE; } + + public boolean isNillable() + { return false; } + + public SOAPArrayType getWSDLArrayType() + { return _wsdlArrayType; } + + public XmlAnySimpleType getDefaultValue() + { + if (_defaultValue != null) + return _defaultValue.get(); + if (_defaultText != null && XmlAnySimpleType.type.isAssignableFrom(getType())) + { + if (_parseObject != null) + { + try + { + NamespaceContext.push(new NamespaceContext(_parseObject)); + return getType().newValue(_defaultText); + } + finally + { + NamespaceContext.pop(); + } + } + return getType().newValue(_defaultText); + } + return null; + } + + public void setDefaultValue(XmlValueRef defaultRef) + { _defaultValue = defaultRef; } + + public Object getUserData() + { return _userData; } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaLocalElementImpl.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaLocalElementImpl.java new file mode 100644 index 000000000..4aa51f5ce --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaLocalElementImpl.java @@ -0,0 +1,113 @@ +/* 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.SchemaAnnotation; +import org.apache.xmlbeans.SchemaLocalElement; +import org.apache.xmlbeans.SchemaParticle; +import org.apache.xmlbeans.SchemaIdentityConstraint; +import org.apache.xmlbeans.soap.SOAPArrayType; +import org.apache.xmlbeans.soap.SchemaWSDLArrayType; + +public class SchemaLocalElementImpl extends SchemaParticleImpl + implements SchemaLocalElement, SchemaWSDLArrayType +{ + private boolean _blockExt; + private boolean _blockRest; + private boolean _blockSubst; + protected boolean _abs; + private SchemaAnnotation _annotation; + private SOAPArrayType _wsdlArrayType; + private SchemaIdentityConstraint.Ref[] _constraints = new SchemaIdentityConstraint.Ref[0]; + + + public SchemaLocalElementImpl() + { + setParticleType(SchemaParticle.ELEMENT); + } + + public boolean blockExtension() + { + return _blockExt; + } + + public boolean blockRestriction() + { + return _blockRest; + } + + public boolean blockSubstitution() + { + return _blockSubst; + } + + public boolean isAbstract() + { + return _abs; + } + + public void setAbstract(boolean abs) + { + _abs = abs; + } + + public void setBlock(boolean extension, boolean restriction, boolean substitution) + { + mutate(); + _blockExt = extension; + _blockRest = restriction; + _blockSubst = substitution; + } + + public void setAnnotation(SchemaAnnotation ann) + { + _annotation = ann; + } + + public void setWsdlArrayType(SOAPArrayType arrayType) + { + _wsdlArrayType = arrayType; + } + + public SchemaAnnotation getAnnotation() + { + return _annotation; + } + + public SOAPArrayType getWSDLArrayType() + { + return _wsdlArrayType; + } + + public void setIdentityConstraints(SchemaIdentityConstraint.Ref[] constraints) { + mutate(); + _constraints = constraints; + } + + public SchemaIdentityConstraint[] getIdentityConstraints() { + SchemaIdentityConstraint[] result = new SchemaIdentityConstraint[_constraints.length]; + for (int i = 0 ; i < result.length ; i++) + result[i] = _constraints[i].get(); + return result; + } + + public SchemaIdentityConstraint.Ref[] getIdentityConstraintRefs() { + SchemaIdentityConstraint.Ref[] result = new SchemaIdentityConstraint.Ref[_constraints.length]; + System.arraycopy(_constraints, 0, result, 0, result.length); + return result; + } + +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaModelGroupImpl.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaModelGroupImpl.java new file mode 100644 index 000000000..f0f8de1b2 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaModelGroupImpl.java @@ -0,0 +1,119 @@ +/* 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.SchemaAnnotation; +import org.apache.xmlbeans.SchemaComponent; +import org.apache.xmlbeans.SchemaModelGroup; +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.SchemaTypeSystem; +import javax.xml.namespace.QName; + +public class SchemaModelGroupImpl implements SchemaModelGroup +{ + private SchemaContainer _container; + private QName _name; + private XmlObject _parseObject; + private Object _userData; + private String _parseTNS; + private boolean _chameleon; + private String _elemFormDefault; + private String _attFormDefault; + private boolean _redefinition; + private SchemaAnnotation _annotation; + private String _filename; + + + public SchemaModelGroupImpl(SchemaContainer container) + { + _container = container; + } + + public SchemaModelGroupImpl(SchemaContainer container, QName name) + { + _container = container; + _name = name; + } + + public void init(QName name, String targetNamespace, boolean chameleon, String elemFormDefault, String attFormDefault, boolean redefinition, XmlObject x, SchemaAnnotation a, Object userData) + { + assert _name == null || name.equals( _name ); + + _name = name; + _parseTNS = targetNamespace; + _chameleon = chameleon; + _elemFormDefault = elemFormDefault; + _attFormDefault = attFormDefault; + _redefinition = redefinition; + _parseObject = x; + _annotation = a; + _userData = userData; + } + + public SchemaTypeSystem getTypeSystem() + { + return _container.getTypeSystem(); + } + + SchemaContainer getContainer() + { + return _container; + } + + public int getComponentType() + { return SchemaComponent.MODEL_GROUP; } + + public void setFilename(String filename) + { _filename = filename; } + + public String getSourceName() + { return _filename; } + + public QName getName() + { return _name; } + + public XmlObject getParseObject() + { return _parseObject; } + + public String getTargetNamespace() + { return _parseTNS; } + + public String getChameleonNamespace() + { return _chameleon ? _parseTNS : null; } + + public String getElemFormDefault() + { return _elemFormDefault; } + + public String getAttFormDefault() + { return _attFormDefault; } + + public boolean isRedefinition() + { return _redefinition; } + + public SchemaAnnotation getAnnotation() + { return _annotation; } + + private SchemaModelGroup.Ref _selfref = new SchemaModelGroup.Ref(this); + + public SchemaModelGroup.Ref getRef() + { return _selfref; } + + public SchemaComponent.Ref getComponentRef() + { return getRef(); } + + public Object getUserData() + { return _userData; } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaParticleImpl.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaParticleImpl.java new file mode 100644 index 000000000..047d95fc2 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaParticleImpl.java @@ -0,0 +1,258 @@ +/* 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.SchemaParticle; +import org.apache.xmlbeans.QNameSet; +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.XmlAnySimpleType; +import org.apache.xmlbeans.XmlQName; +import org.apache.xmlbeans.impl.values.NamespaceContext; + +import java.math.BigInteger; + +import javax.xml.namespace.QName; + +public class SchemaParticleImpl implements SchemaParticle +{ + private int _particleType; + private BigInteger _minOccurs; + private BigInteger _maxOccurs; + private SchemaParticle[] _particleChildren; + private boolean _isImmutable; + private QNameSet _startSet; + private QNameSet _excludeNextSet; + private boolean _isSkippable; + private boolean _isDeterministic; + private int _intMinOccurs; + private int _intMaxOccurs; + private QNameSet _wildcardSet; + private int _wildcardProcess; + private String _defaultText; + private boolean _isDefault; + private boolean _isFixed; + private QName _qName; + private boolean _isNillable; + private SchemaType.Ref _typeref; + protected XmlObject _parseObject; + private Object _userData; + private XmlValueRef _defaultValue; + + protected void mutate() + { if (_isImmutable) throw new IllegalStateException(); } + + public void setImmutable() + { mutate(); _isImmutable = true; } + + public boolean hasTransitionRules() + { return (_startSet != null); } + + public boolean hasTransitionNotes() + { return (_excludeNextSet != null); } + + public void setTransitionRules(QNameSet start, + boolean isSkippable) + { + _startSet = start; + _isSkippable = isSkippable; + } + + public void setTransitionNotes(QNameSet excludeNext, boolean isDeterministic) + { + _excludeNextSet = excludeNext; + _isDeterministic = isDeterministic; + } + + public boolean canStartWithElement(QName name) + { return name != null && _startSet.contains(name); } + + public QNameSet acceptedStartNames() + { return _startSet; } + + public QNameSet getExcludeNextSet() + { return _excludeNextSet; } + + public boolean isSkippable() + { return _isSkippable; } + + public boolean isDeterministic() + { return _isDeterministic; } + + public int getParticleType() + { return _particleType; } + + public void setParticleType(int pType) + { mutate(); _particleType = pType; } + + public boolean isSingleton() + { return _maxOccurs != null && + _maxOccurs.compareTo(BigInteger.ONE) == 0 && + _minOccurs.compareTo(BigInteger.ONE) == 0; } + + public BigInteger getMinOccurs() + { return _minOccurs; } + + public void setMinOccurs(BigInteger min) + { mutate(); _minOccurs = min; _intMinOccurs = pegBigInteger(min); } + + public int getIntMinOccurs() + { return _intMinOccurs; } + + public BigInteger getMaxOccurs() + { return _maxOccurs; } + + public int getIntMaxOccurs() + { return _intMaxOccurs; } + + public void setMaxOccurs(BigInteger max) + { mutate(); _maxOccurs = max; _intMaxOccurs = pegBigInteger(max); } + + public SchemaParticle[] getParticleChildren() + { + if (_particleChildren == null) + { + assert _particleType != SchemaParticle.ALL && + _particleType != SchemaParticle.SEQUENCE && + _particleType != SchemaParticle.CHOICE; + return null; + } + SchemaParticle[] result = new SchemaParticle[_particleChildren.length]; + System.arraycopy(_particleChildren, 0, result, 0, _particleChildren.length); + return result; + } + + public void setParticleChildren(SchemaParticle[] children) + { mutate(); _particleChildren = children; } + + public SchemaParticle getParticleChild(int i) + { return _particleChildren[i]; } + + public int countOfParticleChild() + { return _particleChildren == null ? 0 : _particleChildren.length; } + + public void setWildcardSet(QNameSet set) + { mutate(); _wildcardSet = set; } + + public QNameSet getWildcardSet() + { return _wildcardSet; } + + public void setWildcardProcess(int process) + { mutate(); _wildcardProcess = process; } + + public int getWildcardProcess() + { return _wildcardProcess; } + + private static final BigInteger _maxint = BigInteger.valueOf(Integer.MAX_VALUE); + + private static final int pegBigInteger(BigInteger bi) + { + if (bi == null) + return Integer.MAX_VALUE; + if (bi.signum() <= 0) + return 0; + if (bi.compareTo(_maxint) >= 0) + return Integer.MAX_VALUE; + return bi.intValue(); + } + + public QName getName() + { return _qName; } + + public void setNameAndTypeRef(QName formname, SchemaType.Ref typeref) + { mutate(); _qName = formname; _typeref = typeref; } + + public boolean isTypeResolved() + { + return (_typeref != null); + } + + public void resolveTypeRef(SchemaType.Ref typeref) + { + if (_typeref != null) + throw new IllegalStateException(); + _typeref = typeref; + } + + public boolean isAttribute() + { return false; } + + public SchemaType getType() + { if (_typeref == null) return null; return _typeref.get(); } + + public String getDefaultText() + { return _defaultText; } + + public boolean isDefault() + { return _isDefault; } + + public boolean isFixed() + { return _isFixed; } + + public void setDefault(String deftext, boolean isFixed, XmlObject parseObject) + { + mutate(); + _defaultText = deftext; + _isDefault = (deftext != null); + _isFixed = isFixed; + _parseObject = parseObject; + } + + public boolean isNillable() + { return _isNillable; } + + public void setNillable(boolean nillable) + { mutate(); _isNillable = nillable; } + + public XmlAnySimpleType getDefaultValue() + { + if (_defaultValue != null) + return _defaultValue.get(); + if (_defaultText != null && XmlAnySimpleType.type.isAssignableFrom(getType())) + { + if (_parseObject != null && XmlQName.type.isAssignableFrom(getType())) + { + try + { + NamespaceContext.push(new NamespaceContext(_parseObject)); + return getType().newValue(_defaultText); + } + finally + { + NamespaceContext.pop(); + } + } + return getType().newValue(_defaultText); + } + return null; + } + + public void setDefaultValue(XmlValueRef defaultRef) + { + mutate(); + _defaultValue = defaultRef; + } + + public Object getUserData() + { + return _userData; + } + + public void setUserData(Object data) + { + _userData = data; + } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaPropertyImpl.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaPropertyImpl.java new file mode 100644 index 000000000..fb5cce37a --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaPropertyImpl.java @@ -0,0 +1,204 @@ +/* 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.SchemaComponent; +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.SchemaGlobalElement; +import org.apache.xmlbeans.SchemaGlobalAttribute; +import org.apache.xmlbeans.SchemaProperty; +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.SchemaField; +import org.apache.xmlbeans.QNameSet; +import org.apache.xmlbeans.XmlAnySimpleType; +import org.apache.xmlbeans.XmlQName; +import org.apache.xmlbeans.impl.values.NamespaceContext; + +import java.math.BigInteger; +import java.util.Set; + +import javax.xml.namespace.QName; + +public class SchemaPropertyImpl implements SchemaProperty +{ + private QName _name; + private SchemaType.Ref _typeref; + private boolean _isAttribute; + private SchemaType.Ref _containerTypeRef; + private String _javaPropertyName; + private BigInteger _minOccurs; + private BigInteger _maxOccurs; + private int _hasNillable; + private int _hasDefault; + private int _hasFixed; + private String _defaultText; + private boolean _isImmutable; + private SchemaType.Ref _javaBasedOnTypeRef; + private boolean _extendsSingleton; + private boolean _extendsArray; + private boolean _extendsOption; + private int _javaTypeCode; + private QNameSet _javaSetterDelimiter; + private XmlValueRef _defaultValue; + private Set _acceptedNames; + + private void mutate() + { if (_isImmutable) throw new IllegalStateException(); } + + public void setImmutable() + { mutate(); _isImmutable = true; } + + public SchemaType getContainerType() + { return _containerTypeRef.get(); } + + public void setContainerTypeRef(SchemaType.Ref typeref) + { mutate(); _containerTypeRef = typeref; } + + public QName getName() + { return _name; } + + public void setName(QName name) + { mutate(); _name = name; } + + public String getJavaPropertyName() + { return _javaPropertyName; } + + public void setJavaPropertyName(String name) + { mutate(); _javaPropertyName = name; } + + public boolean isAttribute() + { return _isAttribute; } + + public void setAttribute(boolean isAttribute) + { mutate(); _isAttribute = isAttribute; } + + public boolean isReadOnly() + { return false; } + + public SchemaType getType() + { return _typeref.get(); } + + public void setTypeRef(SchemaType.Ref typeref) + { mutate(); _typeref = typeref; } + + public SchemaType javaBasedOnType() + { return _javaBasedOnTypeRef == null ? null : _javaBasedOnTypeRef.get(); } + + public boolean extendsJavaSingleton() + { return _extendsSingleton; } + + public boolean extendsJavaArray() + { return _extendsArray; } + + public boolean extendsJavaOption() + { return _extendsOption; } + + public void setExtendsJava(SchemaType.Ref javaBasedOnTypeRef, boolean singleton, boolean option, boolean array) + { + mutate(); + _javaBasedOnTypeRef = javaBasedOnTypeRef; + _extendsSingleton = singleton; + _extendsOption = option; + _extendsArray = array; + } + + public QNameSet getJavaSetterDelimiter() + { + if (_isAttribute) + return QNameSet.EMPTY; + if (_javaSetterDelimiter == null) + ((SchemaTypeImpl) getContainerType()).assignJavaElementSetterModel(); + assert _javaSetterDelimiter != null; + return _javaSetterDelimiter; + } + + void setJavaSetterDelimiter(QNameSet set) + { _javaSetterDelimiter = set; } + + public QName[] acceptedNames() + { + if (_acceptedNames == null) + return new QName[] { _name }; + + return (QName[])_acceptedNames.toArray(new QName[_acceptedNames.size()]); + } + + public void setAcceptedNames(Set set) + { + mutate(); + _acceptedNames = set; + } + public void setAcceptedNames(QNameSet set) + { + mutate(); + _acceptedNames = set.includedQNamesInExcludedURIs(); + } + + public BigInteger getMinOccurs() + { return _minOccurs; } + + public void setMinOccurs(BigInteger min) + { mutate(); _minOccurs = min; } + + public BigInteger getMaxOccurs() + { return _maxOccurs; } + + public void setMaxOccurs(BigInteger max) + { mutate(); _maxOccurs = max; } + + public int hasNillable() + { return _hasNillable; } + + public void setNillable(int when) + { mutate(); _hasNillable = when; } + + public int hasDefault() + { return _hasDefault; } + + public void setDefault(int when) + { mutate(); _hasDefault = when; } + + public int hasFixed() + { return _hasFixed; } + + public void setFixed(int when) + { mutate(); _hasFixed = when; } + + public String getDefaultText() + { return _defaultText; } + + public void setDefaultText(String val) + { mutate(); _defaultText = val; } + + public XmlAnySimpleType getDefaultValue() + { + if (_defaultValue != null) + return _defaultValue.get(); + return null; + } + + public void setDefaultValue(XmlValueRef defaultRef) + { + mutate(); + _defaultValue = defaultRef; + } + + public int getJavaTypeCode() + { return _javaTypeCode; } + + public void setJavaTypeCode(int code) + { mutate(); _javaTypeCode = code; } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaStringEnumEntryImpl.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaStringEnumEntryImpl.java new file mode 100644 index 000000000..6ac2c70ef --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaStringEnumEntryImpl.java @@ -0,0 +1,47 @@ +/* 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.SchemaStringEnumEntry; + +public class SchemaStringEnumEntryImpl implements SchemaStringEnumEntry +{ + private String _string; + private int _int; + private String _enumName; + + public SchemaStringEnumEntryImpl(String str, int i, String enumName) + { + _string = str; + _int = i; + _enumName = enumName; + } + + public String getString() + { + return _string; + } + + public int getIntValue() + { + return _int; + } + + public String getEnumName() + { + return _enumName; + } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaTypeCodePrinter.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaTypeCodePrinter.java new file mode 100644 index 000000000..0e6e20cf5 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaTypeCodePrinter.java @@ -0,0 +1,2859 @@ +/* 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 java.io.Writer; +import java.io.IOException; +import java.nio.charset.CharacterCodingException; +import java.nio.charset.Charset; +import java.nio.charset.CharsetEncoder; +import java.util.ArrayList; +import java.util.Map; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.List; + +import javax.xml.namespace.QName; +import org.apache.xmlbeans.impl.common.NameUtil; +import org.apache.xmlbeans.PrePostExtension; +import org.apache.xmlbeans.InterfaceExtension; +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.SchemaTypeSystem; +import org.apache.xmlbeans.SchemaProperty; +import org.apache.xmlbeans.SchemaStringEnumEntry; +import org.apache.xmlbeans.SystemProperties; +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.XmlOptions; +import org.apache.xmlbeans.SchemaCodePrinter; + +/** + * Prints the java code for a single schema type + */ +public final class SchemaTypeCodePrinter implements SchemaCodePrinter +{ + Writer _writer; + int _indent; + boolean _useJava15; + + + static final String LINE_SEPARATOR = + SystemProperties.getProperty("line.separator") == null + ? "\n" + : SystemProperties.getProperty("line.separator"); + + static final String MAX_SPACES = " "; + static final int INDENT_INCREMENT = 4; + + public static final String INDEX_CLASSNAME = "TypeSystemHolder"; + + public static void printTypeImpl ( Writer writer, SchemaType sType, + XmlOptions opt ) + throws IOException + { + getPrinter(opt).printTypeImpl( writer, sType ); + } + + public static void printType ( Writer writer, SchemaType sType, + XmlOptions opt ) + throws IOException + { + getPrinter(opt).printType( writer, sType ); + } + + /** @deprecated */ + public static void printLoader ( Writer writer, SchemaTypeSystem system, + XmlOptions opt ) + throws IOException + { + getPrinter(opt).printLoader( writer, system ); + } + + private static SchemaCodePrinter getPrinter(XmlOptions opt) + { + Object printer = XmlOptions.safeGet + (opt, XmlOptions.SCHEMA_CODE_PRINTER); + if (printer == null || !(printer instanceof SchemaCodePrinter)) + { + printer = new SchemaTypeCodePrinter(opt); + } + return (SchemaCodePrinter) printer; + } + + public SchemaTypeCodePrinter (XmlOptions opt) + { + _indent = 0; + + String genversion = null; + + if (opt != null && XmlOptions.hasOption(opt, XmlOptions.GENERATE_JAVA_VERSION)) + genversion = (String)opt.get(XmlOptions.GENERATE_JAVA_VERSION); + + if (genversion == null) + genversion = XmlOptions.GENERATE_JAVA_14; + + _useJava15 = XmlOptions.GENERATE_JAVA_15.equals(genversion); + } + + void indent() + { + _indent += INDENT_INCREMENT; + } + + void outdent() + { + _indent -= INDENT_INCREMENT; + } + + String encodeString ( String s ) + { + StringBuffer sb = new StringBuffer(); + + sb.append( '"' ); + + for ( int i = 0 ; i < s.length() ; i++ ) + { + char ch = s.charAt( i ); + + if (ch == '"') + { + sb.append( '\\' ); + sb.append( '\"' ); + } + else if (ch == '\\') + { + sb.append( '\\' ); + sb.append( '\\' ); + } + else if (ch == '\r') + { + sb.append( '\\' ); + sb.append( 'r' ); + } + else if (ch == '\n') + { + sb.append( '\\' ); + sb.append( 'n' ); + } + else if (ch == '\t') + { + sb.append( '\\' ); + sb.append( 't' ); + } + else + sb.append( ch ); + } + + sb.append( '"' ); + + return sb.toString(); + } + + void emit(String s) throws IOException + { + int indent = _indent; + + if (indent > MAX_SPACES.length() / 2) + indent = MAX_SPACES.length() / 4 + indent / 2; + + if (indent > MAX_SPACES.length()) + indent = MAX_SPACES.length(); + + _writer.write(MAX_SPACES.substring(0, indent)); + try + { + _writer.write(s); + } + catch (CharacterCodingException cce) + { + _writer.write(makeSafe(s)); + } + _writer.write(LINE_SEPARATOR); + + // System.out.print(MAX_SPACES.substring(0, indent)); + // System.out.println(s); + } + + private static String makeSafe(String s) + { + Charset charset = Charset.forName(System.getProperty("file.encoding")); + if (charset == null) + throw new IllegalStateException("Default character set is null!"); + CharsetEncoder cEncoder = charset.newEncoder(); + StringBuffer result = new StringBuffer(); + int i; + for (i = 0; i < s.length(); i++) + { + char c = s.charAt(i); + if (!cEncoder.canEncode(c)) + break; + } + for (; i < s.length(); i++) + { + char c = s.charAt(i); + if (cEncoder.canEncode(c)) + result.append(c); + else + { + String hexValue = Integer.toHexString((int) c); + switch (hexValue.length()) + { + case 1: + result.append("\\u000").append(hexValue); break; + case 2: + result.append("\\u00").append(hexValue); break; + case 3: + result.append("\\u0").append(hexValue); break; + case 4: + result.append("\\u").append(hexValue); break; + default: + throw new IllegalStateException(); + } + } + } + return result.toString(); + } + + public void printType(Writer writer, SchemaType sType) throws IOException + { + _writer = writer; + printTopComment(sType); + printPackage(sType, true); + emit(""); + printInnerType(sType, sType.getTypeSystem()); + _writer.flush(); + } + + public void printTypeImpl(Writer writer, SchemaType sType) + throws IOException + { + _writer = writer; + printTopComment(sType); + printPackage(sType, false); + printInnerTypeImpl(sType, sType.getTypeSystem(), false); + } + + /** + * Since not all schema types have java types, this skips + * over any that don't and gives you the nearest java base type. + */ + String findJavaType ( SchemaType sType ) + { + while ( sType.getFullJavaName() == null ) + sType = sType.getBaseType(); + + return sType.getFullJavaName(); + } + + static String prettyQName(QName qname) + { + String result = qname.getLocalPart(); + if (qname.getNamespaceURI() != null) + result += "(@" + qname.getNamespaceURI() + ")"; + return result; + } + + void printInnerTypeJavaDoc(SchemaType sType) throws IOException + { + QName name = sType.getName(); + if (name == null) + { + if (sType.isDocumentType()) + name = sType.getDocumentElementName(); + else if (sType.isAttributeType()) + name = sType.getAttributeTypeAttributeName(); + else if (sType.getContainerField() != null) + name = sType.getContainerField().getName(); + } + + emit("/**"); + if (sType.isDocumentType()) + emit(" * A document containing one " + prettyQName(name) + " element."); + else if (sType.isAttributeType()) + emit(" * A document containing one " + prettyQName(name) + " attribute."); + else if (name != null) + emit(" * An XML " + prettyQName(name) + "."); + else + emit(" * An anonymous inner XML type."); + emit(" *"); + switch (sType.getSimpleVariety()) + { + case SchemaType.NOT_SIMPLE: + emit(" * This is a complex type."); + break; + case SchemaType.ATOMIC: + emit(" * This is an atomic type that is a restriction of " + getFullJavaName(sType) + "."); + break; + case SchemaType.LIST: + emit(" * This is a list type whose items are " + sType.getListItemType().getFullJavaName() + "."); + break; + case SchemaType.UNION: + emit(" * This is a union type. Instances are of one of the following types:"); + SchemaType[] members = sType.getUnionConstituentTypes(); + for (int i = 0; i < members.length; i++) + emit(" * " + members[i].getFullJavaName()); + break; + } + emit(" */"); + } + + private String getFullJavaName(SchemaType sType) + { + + SchemaTypeImpl sTypeI = (SchemaTypeImpl) sType; + String ret = sTypeI.getFullJavaName(); + + while (sTypeI.isRedefinition()) + { + ret = sTypeI.getFullJavaName(); + sTypeI = (SchemaTypeImpl) sTypeI.getBaseType(); + } + return ret; + } + + private String getUserTypeStaticHandlerMethod(boolean encode, SchemaTypeImpl stype) + { + String unqualifiedName = stype.getName().getLocalPart(); + if (unqualifiedName.length() < 2) + unqualifiedName = unqualifiedName.toUpperCase(); + else + unqualifiedName = unqualifiedName.substring(0, 1).toUpperCase() + unqualifiedName.substring(1); + + if (encode) + return stype.getUserTypeHandlerName() + ".encode" + unqualifiedName; + else + return stype.getUserTypeHandlerName() + ".decode" + unqualifiedName; + } + + + public static String indexClassForSystem(SchemaTypeSystem system) + { + String name = system.getName(); + return name + "." + INDEX_CLASSNAME; + } + + static String shortIndexClassForSystem(SchemaTypeSystem system) + { + return INDEX_CLASSNAME; + } + + void printStaticTypeDeclaration(SchemaType sType, SchemaTypeSystem system) throws IOException + { + String interfaceShortName = sType.getShortJavaName(); + emit("public static final org.apache.xmlbeans.SchemaType type = (org.apache.xmlbeans.SchemaType)"); + indent(); + emit("org.apache.xmlbeans.XmlBeans.typeSystemForClassLoader(" + + interfaceShortName + ".class.getClassLoader(), \"" + system.getName() + "\")" + + ".resolveHandle(\"" + + ((SchemaTypeSystemImpl)system).handleForType(sType) + "\");"); + outdent(); + } + + /** @deprecated */ + public void printLoader(Writer writer, SchemaTypeSystem system) + throws IOException + { + // deprecated + } + + void printInnerType(SchemaType sType, SchemaTypeSystem system) throws IOException + { + emit(""); + + printInnerTypeJavaDoc(sType); + + startInterface(sType); + + printStaticTypeDeclaration(sType, system); + + if (sType.isSimpleType()) + { + if (sType.hasStringEnumValues()) + printStringEnumeration(sType); + } + else + { + if (sType.getContentType() == SchemaType.SIMPLE_CONTENT && sType.hasStringEnumValues()) + printStringEnumeration(sType); + + SchemaProperty[] props = getDerivedProperties(sType); + + for (int i = 0; i < props.length; i++) + { + SchemaProperty prop = props[i]; + + printPropertyGetters( + prop.getName(), + prop.isAttribute(), + prop.getJavaPropertyName(), + prop.getJavaTypeCode(), + javaTypeForProperty(prop), + xmlTypeForProperty(prop), + prop.hasNillable() != SchemaProperty.NEVER, + prop.extendsJavaOption(), + prop.extendsJavaArray(), + prop.extendsJavaSingleton() + ); + + if (!prop.isReadOnly()) + { + printPropertySetters( + prop.getName(), + prop.isAttribute(), + prop.getJavaPropertyName(), + prop.getJavaTypeCode(), + javaTypeForProperty(prop), + xmlTypeForProperty(prop), + prop.hasNillable() != SchemaProperty.NEVER, + prop.extendsJavaOption(), + prop.extendsJavaArray(), + prop.extendsJavaSingleton() + ); + } + } + + } + + printNestedInnerTypes(sType, system); + + printFactory(sType); + + endBlock(); + } + + void printFactory(SchemaType sType) throws IOException + { + // Only need full factories for top-level types + boolean fullFactory = true; + if (sType.isAnonymousType() && ! sType.isDocumentType() && !sType.isAttributeType()) + fullFactory = false; + + String fullName = sType.getFullJavaName().replace('$', '.'); + + emit(""); + emit("/**"); + emit(" * A factory class with static methods for creating instances"); + emit(" * of this type."); + emit(" */"); + emit(""); + // BUGBUG - Can I use the name loader here? could it be a + // nested type name? It is lower case! + emit("public static final class Factory"); + emit("{"); + indent(); + + if (sType.isSimpleType()) + { + emit("public static " + fullName + " newValue(java.lang.Object obj) {"); + emit(" return (" + fullName + ") type.newValue( obj ); }"); + emit(""); + } + + // Only need newInstance() for non-abstract types + if (sType.isAbstract()) { + emit("/** @deprecated No need to be able to create instances of abstract types */"); + if (_useJava15) + emit("@Deprecated"); + } + emit("public static " + fullName + " newInstance() {"); + emit(" return (" + fullName + ") org.apache.xmlbeans.XmlBeans.getContextTypeLoader().newInstance( type, null ); }"); + emit(""); + + // Only need newInstance() for non-abstract types + if (sType.isAbstract()) { + emit("/** @deprecated No need to be able to create instances of abstract types */"); + if (_useJava15) + emit("@Deprecated"); + } + emit("public static " + fullName + " newInstance(org.apache.xmlbeans.XmlOptions options) {"); + emit(" return (" + fullName + ") org.apache.xmlbeans.XmlBeans.getContextTypeLoader().newInstance( type, options ); }"); + emit(""); + + if (fullFactory) + { + emit("/** @param xmlAsString the string value to parse */"); + emit("public static " + fullName + " parse(java.lang.String xmlAsString) throws org.apache.xmlbeans.XmlException {"); + emit(" return (" + fullName + ") org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( xmlAsString, type, null ); }"); + emit(""); + + emit("public static " + fullName + " parse(java.lang.String xmlAsString, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException {"); + emit(" return (" + fullName + ") org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( xmlAsString, type, options ); }"); + emit(""); + + emit("/** @param file the file from which to load an xml document */"); + emit("public static " + fullName + " parse(java.io.File file) throws org.apache.xmlbeans.XmlException, java.io.IOException {"); + emit(" return (" + fullName + ") org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( file, type, null ); }"); + emit(""); + + emit("public static " + fullName + " parse(java.io.File file, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException {"); + emit(" return (" + fullName + ") org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( file, type, options ); }"); + emit(""); + + emit("public static " + fullName + " parse(java.net.URL u) throws org.apache.xmlbeans.XmlException, java.io.IOException {"); + emit(" return (" + fullName + ") org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( u, type, null ); }"); + emit(""); + + emit("public static " + fullName + " parse(java.net.URL u, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException {"); + emit(" return (" + fullName + ") org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( u, type, options ); }"); + emit(""); + + emit("public static " + fullName + " parse(java.io.InputStream is) throws org.apache.xmlbeans.XmlException, java.io.IOException {"); + emit(" return (" + fullName + ") org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( is, type, null ); }"); + emit(""); + + emit("public static " + fullName + " parse(java.io.InputStream is, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException {"); + emit(" return (" + fullName + ") org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( is, type, options ); }"); + emit(""); + + emit("public static " + fullName + " parse(java.io.Reader r) throws org.apache.xmlbeans.XmlException, java.io.IOException {"); + emit(" return (" + fullName + ") org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( r, type, null ); }"); + emit(""); + + emit("public static " + fullName + " parse(java.io.Reader r, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException {"); + emit(" return (" + fullName + ") org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( r, type, options ); }"); + emit(""); + + emit("public static " + fullName + " parse(javax.xml.stream.XMLStreamReader sr) throws org.apache.xmlbeans.XmlException {"); + emit(" return (" + fullName + ") org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( sr, type, null ); }"); + emit(""); + + emit("public static " + fullName + " parse(javax.xml.stream.XMLStreamReader sr, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException {"); + emit(" return (" + fullName + ") org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( sr, type, options ); }"); + emit(""); + + emit("public static " + fullName + " parse(org.w3c.dom.Node node) throws org.apache.xmlbeans.XmlException {"); + emit(" return (" + fullName + ") org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( node, type, null ); }"); + emit(""); + + emit("public static " + fullName + " parse(org.w3c.dom.Node node, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException {"); + emit(" return (" + fullName + ") org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( node, type, options ); }"); + emit(""); + + emit("/** @deprecated {@link org.apache.xmlbeans.xml.stream.XMLInputStream} */"); + if (_useJava15) + emit("@Deprecated"); + emit("public static " + fullName + " parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException {"); + emit(" return (" + fullName + ") org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( xis, type, null ); }"); + emit(""); + + emit("/** @deprecated {@link org.apache.xmlbeans.xml.stream.XMLInputStream} */"); + if (_useJava15) + emit("@Deprecated"); + emit("public static " + fullName + " parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException {"); + emit(" return (" + fullName + ") org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( xis, type, options ); }"); + emit(""); + + // Don't have XMLInputStream anymore + emit("/** @deprecated {@link org.apache.xmlbeans.xml.stream.XMLInputStream} */"); + if (_useJava15) + emit("@Deprecated"); + emit("public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException {"); + emit(" return org.apache.xmlbeans.XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, null ); }"); + emit(""); + + // Don't have XMLInputStream anymore + emit("/** @deprecated {@link org.apache.xmlbeans.xml.stream.XMLInputStream} */"); + if (_useJava15) + emit("@Deprecated"); + emit("public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException {"); + emit(" return org.apache.xmlbeans.XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, options ); }"); + emit(""); + } + + emit("private Factory() { } // No instance of this class allowed"); + outdent(); + emit("}"); + } + + void printNestedInnerTypes(SchemaType sType, SchemaTypeSystem system) throws IOException + { + boolean redefinition = sType.getName() != null && + sType.getName().equals(sType.getBaseType().getName()); + while (sType != null) + { + SchemaType[] anonTypes = sType.getAnonymousTypes(); + for (int i = 0; i < anonTypes.length; i++) + { + if (anonTypes[i].isSkippedAnonymousType()) + printNestedInnerTypes(anonTypes[i], system); + else + printInnerType(anonTypes[i], system); + } + // For redefinition other than by extension for complex types, go ahead and print + // the anonymous types in the base + if (!redefinition || + (sType.getDerivationType() != SchemaType.DT_EXTENSION && !sType.isSimpleType())) + break; + sType = sType.getBaseType(); + } + } + + void printTopComment(SchemaType sType) throws IOException + { + emit("/*"); + if (sType.getName() != null) + { + emit(" * XML Type: " + sType.getName().getLocalPart()); + emit(" * Namespace: " + sType.getName().getNamespaceURI()); + } + else + { + QName thename = null; + + if (sType.isDocumentType()) + { + thename = sType.getDocumentElementName(); + emit(" * An XML document type."); + } + else if (sType.isAttributeType()) + { + thename = sType.getAttributeTypeAttributeName(); + emit(" * An XML attribute type."); + } + else + assert false; + + assert( thename != null ); + + emit(" * Localname: " + thename.getLocalPart()); + emit(" * Namespace: " + thename.getNamespaceURI()); + } + emit(" * Java type: " + sType.getFullJavaName()); + emit(" *"); + emit(" * Automatically generated - do not modify."); + emit(" */"); + } + + void printPackage(SchemaType sType, boolean intf) throws IOException + { + String fqjn; + if (intf) + fqjn = sType.getFullJavaName(); + else + fqjn = sType.getFullJavaImplName(); + + int lastdot = fqjn.lastIndexOf('.'); + if (lastdot < 0) + return; + String pkg = fqjn.substring(0, lastdot); + emit("package " + pkg + ";"); + } + + void startInterface(SchemaType sType) throws IOException + { + String shortName = sType.getShortJavaName(); + + String baseInterface = findJavaType(sType.getBaseType()); + + /* + StringBuffer specializedInterfaces = new StringBuffer(); + + if (sType.getSimpleVariety() == SchemaType.ATOMIC && + sType.getPrimitiveType().getBuiltinTypeCode() == SchemaType.BTC_DECIMAL) + { + int bits = sType.getDecimalSize(); + if (bits == SchemaType.SIZE_BIG_INTEGER) + specializedInterfaces.append(", org.apache.xmlbeans.BigIntegerValue"); + if (bits == SchemaType.SIZE_LONG) + specializedInterfaces.append(", org.apache.xmlbeans.LongValue"); + if (bits <= SchemaType.SIZE_INT) + specializedInterfaces.append(", org.apache.xmlbeans.IntValue"); + } + if (sType.getSimpleVariety() == SchemaType.LIST) + specializedInterfaces.append(", org.apache.xmlbeans.ListValue"); + + if (sType.getSimpleVariety() == SchemaType.UNION) + { + SchemaType ctype = sType.getUnionCommonBaseType(); + String javaTypeHolder = javaTypeHolderForType(ctype); + if (javaTypeHolder != null) + specializedInterfaces.append(", " + javaTypeHolder); + } + */ + + emit("public interface " + shortName + " extends " + baseInterface + getExtensionInterfaces(sType)); + emit("{"); + indent(); + emitSpecializedAccessors(sType); + } + + private static String getExtensionInterfaces(SchemaType sType) + { + SchemaTypeImpl sImpl = getImpl(sType); + if (sImpl == null) + return ""; + + StringBuffer sb = new StringBuffer(); + + InterfaceExtension[] exts = sImpl.getInterfaceExtensions(); + if (exts != null) for (int i = 0; i < exts.length; i++) + sb.append(", " + exts[i].getInterface()); + + return sb.toString(); + } + + private static SchemaTypeImpl getImpl(SchemaType sType) + { + if (sType instanceof SchemaTypeImpl) + return (SchemaTypeImpl) sType; + else + return null; + } + + private void emitSpecializedAccessors(SchemaType sType) throws IOException + { + if (sType.getSimpleVariety() == SchemaType.ATOMIC && + sType.getPrimitiveType().getBuiltinTypeCode() == SchemaType.BTC_DECIMAL) + { + int bits = sType.getDecimalSize(); + int parentBits = sType.getBaseType().getDecimalSize(); + if (bits != parentBits || sType.getBaseType().getFullJavaName() == null) + { + if (bits == SchemaType.SIZE_BIG_INTEGER) + { + emit("java.math.BigInteger getBigIntegerValue();"); + emit("void setBigIntegerValue(java.math.BigInteger bi);"); + emit("/** @deprecated */"); + if (_useJava15) + emit("@Deprecated"); + emit("java.math.BigInteger bigIntegerValue();"); + emit("/** @deprecated */"); + if (_useJava15) + emit("@Deprecated"); + emit("void set(java.math.BigInteger bi);"); + } + else if (bits == SchemaType.SIZE_LONG) + { + emit("long getLongValue();"); + emit("void setLongValue(long l);"); + emit("/** @deprecated */"); + if (_useJava15) + emit("@Deprecated"); + emit("long longValue();"); + emit("/** @deprecated */"); + if (_useJava15) + emit("@Deprecated"); + emit("void set(long l);"); + } + else if (bits == SchemaType.SIZE_INT) + { + emit("int getIntValue();"); + emit("void setIntValue(int i);"); + emit("/** @deprecated */"); + if (_useJava15) + emit("@Deprecated"); + emit("int intValue();"); + emit("/** @deprecated */"); + if (_useJava15) + emit("@Deprecated"); + emit("void set(int i);"); + } + else if (bits == SchemaType.SIZE_SHORT) + { + emit("short getShortValue();"); + emit("void setShortValue(short s);"); + emit("/** @deprecated */"); + if (_useJava15) + emit("@Deprecated"); + emit("short shortValue();"); + emit("/** @deprecated */"); + if (_useJava15) + emit("@Deprecated"); + emit("void set(short s);"); + } + else if (bits == SchemaType.SIZE_BYTE) + { + emit("byte getByteValue();"); + emit("void setByteValue(byte b);"); + emit("/** @deprecated */"); + if (_useJava15) + emit("@Deprecated"); + emit("byte byteValue();"); + emit("/** @deprecated */"); + if (_useJava15) + emit("@Deprecated"); + emit("void set(byte b);"); + } + } + } + + if (sType.getSimpleVariety() == SchemaType.UNION) + { + emit("java.lang.Object getObjectValue();"); + emit("void setObjectValue(java.lang.Object val);"); + emit("/** @deprecated */"); + if (_useJava15) + emit("@Deprecated"); + emit("java.lang.Object objectValue();"); + emit("/** @deprecated */"); + if (_useJava15) + emit("@Deprecated"); + emit("void objectSet(java.lang.Object val);"); + emit("org.apache.xmlbeans.SchemaType instanceType();"); + SchemaType ctype = sType.getUnionCommonBaseType(); + if (ctype != null && ctype.getSimpleVariety() != SchemaType.UNION); + emitSpecializedAccessors(ctype); + } + + if (sType.getSimpleVariety() == SchemaType.LIST) + { + emit("java.util.List getListValue();"); + emit("java.util.List xgetListValue();"); + emit("void setListValue(java.util.List list);"); + emit("/** @deprecated */"); + if (_useJava15) + emit("@Deprecated"); + emit("java.util.List listValue();"); + emit("/** @deprecated */"); + if (_useJava15) + emit("@Deprecated"); + emit("java.util.List xlistValue();"); + emit("/** @deprecated */"); + if (_useJava15) + emit("@Deprecated"); + emit("void set(java.util.List list);"); + } + } + + void startBlock() throws IOException + { + emit("{"); + indent(); + } + void endBlock() throws IOException + { + outdent(); + emit("}"); + } + + void printJavaDoc(String sentence) throws IOException + { + emit(""); + emit("/**"); + emit(" * " + sentence); + emit(" */"); + } + + void printShortJavaDoc(String sentence) throws IOException + { + emit("/** " + sentence + " */"); + } + + public static String javaStringEscape(String str) + { + // forbidden: \n, \r, \", \\. + test: { + for (int i = 0; i < str.length(); i++) + { + switch (str.charAt(i)) + { + case '\n': + case '\r': + case '\"': + case '\\': + break test; + } + } + return str; + } + StringBuffer sb = new StringBuffer(); + for (int i = 0; i < str.length(); i++) + { + char ch = str.charAt(i); + switch (ch) + { + default: + sb.append(ch); + break; + case '\n': + sb.append("\\n"); + break; + case '\r': + sb.append("\\r"); + break; + case '\"': + sb.append("\\\""); + break; + case '\\': + sb.append("\\\\"); + break; + } + } + return sb.toString(); + } + + void printStringEnumeration(SchemaType sType) throws IOException + { + SchemaType baseEnumType = sType.getBaseEnumType(); + String baseEnumClass = baseEnumType.getFullJavaName(); + boolean hasBase = hasBase(sType); + + if (!hasBase) + { + emit(""); + emit("org.apache.xmlbeans.StringEnumAbstractBase enumValue();"); + emit("void set(org.apache.xmlbeans.StringEnumAbstractBase e);"); + } + + emit(""); + SchemaStringEnumEntry[] entries = sType.getStringEnumEntries(); + HashSet seenValues = new HashSet(); + HashSet repeatValues = new HashSet(); + for (int i = 0; i < entries.length; i++) + { + String enumValue = entries[i].getString(); + if (seenValues.contains(enumValue)) + { + repeatValues.add(enumValue); + continue; + } + else + seenValues.add(enumValue); + String constName = entries[i].getEnumName(); + if (hasBase) + emit("static final " + baseEnumClass + ".Enum " + constName + " = " + baseEnumClass + "." + constName + ";"); + else + emit("static final Enum " + constName + " = Enum.forString(\"" + javaStringEscape(enumValue) + "\");"); + } + emit(""); + for (int i = 0; i < entries.length; i++) + { + if (repeatValues.contains(entries[i].getString())) + continue; + String constName = "INT_" + entries[i].getEnumName(); + if (hasBase) + emit("static final int " + constName + " = " + baseEnumClass + "." + constName + ";"); + else + emit("static final int " + constName + " = Enum." + constName + ";"); + } + if (!hasBase) + { + emit(""); + emit("/**"); + emit(" * Enumeration value class for " + baseEnumClass + "."); + emit(" * These enum values can be used as follows:"); + emit(" *

    ");
    +            emit(" * enum.toString(); // returns the string value of the enum");
    +            emit(" * enum.intValue(); // returns an int value, useful for switches");
    +            if (entries.length > 0)
    +            emit(" * // e.g., case Enum.INT_" + entries[0].getEnumName());
    +            emit(" * Enum.forString(s); // returns the enum value for a string");
    +            emit(" * Enum.forInt(i); // returns the enum value for an int");
    +            emit(" * 
    "); + emit(" * Enumeration objects are immutable singleton objects that"); + emit(" * can be compared using == object equality. They have no"); + emit(" * public constructor. See the constants defined within this"); + emit(" * class for all the valid values."); + emit(" */"); + emit("static final class Enum extends org.apache.xmlbeans.StringEnumAbstractBase"); + emit("{"); + indent(); + emit("/**"); + emit(" * Returns the enum value for a string, or null if none."); + emit(" */"); + emit("public static Enum forString(java.lang.String s)"); + emit(" { return (Enum)table.forString(s); }"); + emit("/**"); + emit(" * Returns the enum value corresponding to an int, or null if none."); + emit(" */"); + emit("public static Enum forInt(int i)"); + emit(" { return (Enum)table.forInt(i); }"); + emit(""); + emit("private Enum(java.lang.String s, int i)"); + emit(" { super(s, i); }"); + emit(""); + for (int i = 0; i < entries.length; i++) + { + String constName = "INT_" + entries[i].getEnumName(); + int intValue = entries[i].getIntValue(); + emit("static final int " + constName + " = " + intValue + ";"); + } + emit(""); + emit("public static final org.apache.xmlbeans.StringEnumAbstractBase.Table table ="); + emit(" new org.apache.xmlbeans.StringEnumAbstractBase.Table"); + emit("("); + indent(); + emit("new Enum[]"); + emit("{"); + indent(); + for (int i = 0; i < entries.length; i++) + { + String enumValue = entries[i].getString(); + String constName = "INT_" + entries[i].getEnumName(); + emit("new Enum(\"" + javaStringEscape(enumValue) + "\", " + constName + "),"); + } + outdent(); + emit("}"); + outdent(); + emit(");"); + emit("private static final long serialVersionUID = 1L;"); + emit("private java.lang.Object readResolve() { return forInt(intValue()); } "); + outdent(); + emit("}"); + } + } + + private boolean hasBase(SchemaType sType) + { + boolean hasBase; + SchemaType baseEnumType = sType.getBaseEnumType(); + if (baseEnumType.isAnonymousType() && baseEnumType.isSkippedAnonymousType()) + { + if (sType.getContentBasedOnType() != null) + hasBase = sType.getContentBasedOnType().getBaseType() != baseEnumType; + else + hasBase = sType.getBaseType() != baseEnumType; + } + else + hasBase = baseEnumType != sType; + return hasBase; + } + + String xmlTypeForProperty(SchemaProperty sProp) + { + SchemaType sType = sProp.javaBasedOnType(); + return findJavaType(sType).replace('$', '.'); + } + + static boolean xmlTypeForPropertyIsUnion(SchemaProperty sProp) + { + SchemaType sType = sProp.javaBasedOnType(); + return (sType.isSimpleType() && sType.getSimpleVariety() == SchemaType.UNION); + } + + static boolean isJavaPrimitive(int javaType) + { + return (javaType < SchemaProperty.JAVA_FIRST_PRIMITIVE ? false : + (javaType > SchemaProperty.JAVA_LAST_PRIMITIVE ? false : true)); + } + + /** Returns the wrapped type for a java primitive. */ + static String javaWrappedType(int javaType) + { + switch (javaType) + { + case SchemaProperty.JAVA_BOOLEAN: + return "java.lang.Boolean"; + case SchemaProperty.JAVA_FLOAT: + return "java.lang.Float"; + case SchemaProperty.JAVA_DOUBLE: + return "java.lang.Double"; + case SchemaProperty.JAVA_BYTE: + return "java.lang.Byte"; + case SchemaProperty.JAVA_SHORT: + return "java.lang.Short"; + case SchemaProperty.JAVA_INT: + return "java.lang.Integer"; + case SchemaProperty.JAVA_LONG: + return "java.lang.Long"; + + // anything else is not a java primitive + default: + assert false; + throw new IllegalStateException(); + } + } + + String javaTypeForProperty(SchemaProperty sProp) + { + // The type to use is the XML object.... + if (sProp.getJavaTypeCode() == SchemaProperty.XML_OBJECT) + { + SchemaType sType = sProp.javaBasedOnType(); + return findJavaType(sType).replace('$', '.'); + } + + if (sProp.getJavaTypeCode() == SchemaProperty.JAVA_USER) + { + return ((SchemaTypeImpl)sProp.getType()).getUserTypeName(); + } + + switch (sProp.getJavaTypeCode()) + { + case SchemaProperty.JAVA_BOOLEAN: + return "boolean"; + case SchemaProperty.JAVA_FLOAT: + return "float"; + case SchemaProperty.JAVA_DOUBLE: + return "double"; + case SchemaProperty.JAVA_BYTE: + return "byte"; + case SchemaProperty.JAVA_SHORT: + return "short"; + case SchemaProperty.JAVA_INT: + return "int"; + case SchemaProperty.JAVA_LONG: + return "long"; + + case SchemaProperty.JAVA_BIG_DECIMAL: + return "java.math.BigDecimal"; + case SchemaProperty.JAVA_BIG_INTEGER: + return "java.math.BigInteger"; + case SchemaProperty.JAVA_STRING: + return "java.lang.String"; + case SchemaProperty.JAVA_BYTE_ARRAY: + return "byte[]"; + case SchemaProperty.JAVA_GDATE: + return "org.apache.xmlbeans.GDate"; + case SchemaProperty.JAVA_GDURATION: + return "org.apache.xmlbeans.GDuration"; + case SchemaProperty.JAVA_DATE: + return "java.util.Date"; + case SchemaProperty.JAVA_QNAME: + return "javax.xml.namespace.QName"; + case SchemaProperty.JAVA_LIST: + return "java.util.List"; + case SchemaProperty.JAVA_CALENDAR: + return "java.util.Calendar"; + + case SchemaProperty.JAVA_ENUM: + SchemaType sType = sProp.javaBasedOnType(); + if (sType.getSimpleVariety() == SchemaType.UNION) + sType = sType.getUnionCommonBaseType(); + assert sType.getBaseEnumType() != null; + if (hasBase(sType)) + return findJavaType(sType.getBaseEnumType()).replace('$', '.') + ".Enum"; + else + return findJavaType(sType).replace('$', '.') + ".Enum"; + + case SchemaProperty.JAVA_OBJECT: + return "java.lang.Object"; + + default: + assert(false); + throw new IllegalStateException(); + } + } + + void printPropertyGetters(QName qName, boolean isAttr, + String propertyName, int javaType, + String type, String xtype, + boolean nillable, boolean optional, + boolean several, boolean singleton) + throws IOException + { + String propdesc = "\"" + qName.getLocalPart() + "\"" + (isAttr ? " attribute" : " element"); + boolean xmltype = (javaType == SchemaProperty.XML_OBJECT); + + if (singleton) + { + printJavaDoc((several ? "Gets first " : "Gets the ") + propdesc); + emit(type + " get" + propertyName + "();"); + + if (!xmltype) + { + printJavaDoc((several ? "Gets (as xml) first " : "Gets (as xml) the ") + propdesc); + emit(xtype + " xget" + propertyName + "();"); + } + + if (nillable) + { + printJavaDoc((several ? "Tests for nil first " : "Tests for nil ") + propdesc); + emit("boolean isNil" + propertyName + "();"); + } + } + + if (optional) + { + printJavaDoc((several ? "True if has at least one " : "True if has ") + propdesc); + emit("boolean isSet" + propertyName + "();"); + } + + if (several) + { + String arrayName = propertyName + "Array"; + + if (_useJava15) + { + String wrappedType = type; + if (isJavaPrimitive(javaType)) + wrappedType = javaWrappedType(javaType); + + printJavaDoc("Gets a List of " + propdesc + "s"); + emit("java.util.List<" + wrappedType + "> get" + propertyName + "List();"); + } + + if (_useJava15) + { + emit(""); + emit("/**"); + emit(" * Gets array of all " + propdesc + "s"); + emit(" * @deprecated"); + emit(" */"); + emit("@Deprecated"); + } + else + printJavaDoc("Gets array of all " + propdesc + "s"); + emit(type + "[] get" + arrayName + "();"); + + printJavaDoc("Gets ith " + propdesc); + emit(type + " get" + arrayName + "(int i);"); + + if (!xmltype) + { + if (_useJava15) + { + printJavaDoc("Gets (as xml) a List of " + propdesc + "s"); + emit("java.util.List<" + xtype + "> xget" + propertyName + "List();"); + } + + if (_useJava15) + { + emit(""); + emit("/**"); + emit(" * Gets (as xml) array of all " + propdesc + "s"); + emit(" * @deprecated"); + emit(" */"); + emit("@Deprecated"); + } + else + printJavaDoc("Gets (as xml) array of all " + propdesc + "s"); + emit(xtype + "[] xget" + arrayName + "();"); + + printJavaDoc("Gets (as xml) ith " + propdesc); + emit(xtype + " xget" + arrayName + "(int i);"); + } + + if (nillable) + { + printJavaDoc("Tests for nil ith " + propdesc); + emit("boolean isNil" + arrayName + "(int i);"); + } + + printJavaDoc("Returns number of " + propdesc); + emit("int sizeOf" + arrayName + "();"); + } + } + + void printPropertySetters(QName qName, boolean isAttr, + String propertyName, int javaType, String type, String xtype, + boolean nillable, boolean optional, + boolean several, boolean singleton) + throws IOException + { + String safeVarName = NameUtil.nonJavaKeyword(NameUtil.lowerCamelCase(propertyName)); + if (safeVarName.equals("i")) + safeVarName = "iValue"; + boolean xmltype = (javaType == SchemaProperty.XML_OBJECT); + + String propdesc = "\"" + qName.getLocalPart() + "\"" + (isAttr ? " attribute" : " element"); + + if (singleton) + { + printJavaDoc((several ? "Sets first " : "Sets the ") + propdesc); + emit("void set" + propertyName + "(" + type + " " + safeVarName + ");"); + + if (!xmltype) + { + printJavaDoc((several ? "Sets (as xml) first " : "Sets (as xml) the ") + propdesc); + emit("void xset" + propertyName + "(" + xtype + " " + safeVarName + ");"); + } + + if (xmltype && !several) + { + printJavaDoc("Appends and returns a new empty " + propdesc); + emit(xtype + " addNew" + propertyName + "();"); + } + + if (nillable) + { + printJavaDoc((several ? "Nils the first " : "Nils the ") + propdesc); + emit("void setNil" + propertyName + "();"); + } + } + + if (optional) + { + printJavaDoc((several ? "Removes first " : "Unsets the ") + propdesc); + emit("void unset" + propertyName + "();"); + } + + if (several) + { + String arrayName = propertyName + "Array"; + + printJavaDoc("Sets array of all " + propdesc); + emit("void set" + arrayName + "(" + type + "[] " + safeVarName + "Array);"); + + printJavaDoc("Sets ith " + propdesc); + emit("void set" + arrayName + "(int i, " + type + " " + safeVarName + ");"); + + if (!xmltype) + { + printJavaDoc("Sets (as xml) array of all " + propdesc); + emit("void xset" + arrayName + "(" + xtype + "[] " + safeVarName + "Array);"); + + printJavaDoc("Sets (as xml) ith " + propdesc); + emit("void xset" + arrayName + "(int i, " + xtype + " " + safeVarName + ");"); + } + + if (nillable) + { + printJavaDoc("Nils the ith " + propdesc); + emit("void setNil" + arrayName + "(int i);"); + } + + if (!xmltype) + { + printJavaDoc("Inserts the value as the ith " + propdesc); + emit("void insert" + propertyName + "(int i, " + type + " " + safeVarName + ");"); + + printJavaDoc("Appends the value as the last " + propdesc); + emit("void add" + propertyName + "(" + type + " " + safeVarName + ");"); + } + + printJavaDoc("Inserts and returns a new empty value (as xml) as the ith " + propdesc); + emit(xtype + " insertNew" + propertyName + "(int i);"); + + printJavaDoc("Appends and returns a new empty value (as xml) as the last " + propdesc); + emit(xtype + " addNew" + propertyName + "();"); + + printJavaDoc("Removes the ith " + propdesc); + emit("void remove" + propertyName + "(int i);"); + } + } + + String getAtomicRestrictionType(SchemaType sType) { + SchemaType pType = sType.getPrimitiveType(); + switch (pType.getBuiltinTypeCode()) + { + case SchemaType.BTC_ANY_SIMPLE: + return "org.apache.xmlbeans.impl.values.XmlAnySimpleTypeImpl"; + case SchemaType.BTC_BOOLEAN: + return "org.apache.xmlbeans.impl.values.JavaBooleanHolderEx"; + case SchemaType.BTC_BASE_64_BINARY: + return "org.apache.xmlbeans.impl.values.JavaBase64HolderEx"; + case SchemaType.BTC_HEX_BINARY: + return "org.apache.xmlbeans.impl.values.JavaHexBinaryHolderEx"; + case SchemaType.BTC_ANY_URI: + return "org.apache.xmlbeans.impl.values.JavaUriHolderEx"; + case SchemaType.BTC_QNAME: + return "org.apache.xmlbeans.impl.values.JavaQNameHolderEx"; + case SchemaType.BTC_NOTATION: + return "org.apache.xmlbeans.impl.values.JavaNotationHolderEx"; + case SchemaType.BTC_FLOAT: + return "org.apache.xmlbeans.impl.values.JavaFloatHolderEx"; + case SchemaType.BTC_DOUBLE: + return "org.apache.xmlbeans.impl.values.JavaDoubleHolderEx"; + case SchemaType.BTC_DECIMAL: + switch (sType.getDecimalSize()) + { + default: + assert(false); + case SchemaType.SIZE_BIG_DECIMAL: + return "org.apache.xmlbeans.impl.values.JavaDecimalHolderEx"; + case SchemaType.SIZE_BIG_INTEGER: + return "org.apache.xmlbeans.impl.values.JavaIntegerHolderEx"; + case SchemaType.SIZE_LONG: + return "org.apache.xmlbeans.impl.values.JavaLongHolderEx"; + case SchemaType.SIZE_INT: + case SchemaType.SIZE_SHORT: + case SchemaType.SIZE_BYTE: + return "org.apache.xmlbeans.impl.values.JavaIntHolderEx"; + } + case SchemaType.BTC_STRING: + if (sType.hasStringEnumValues()) + return "org.apache.xmlbeans.impl.values.JavaStringEnumerationHolderEx"; + else + return "org.apache.xmlbeans.impl.values.JavaStringHolderEx"; + + 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: + return "org.apache.xmlbeans.impl.values.JavaGDateHolderEx"; + + case SchemaType.BTC_DURATION: + return "org.apache.xmlbeans.impl.values.JavaGDurationHolderEx"; + default: + assert(false) : "unrecognized primitive type"; + return null; + } + } + + static SchemaType findBaseType(SchemaType sType) + { + while (sType.getFullJavaName() == null) + sType = sType.getBaseType(); + return sType; + } + + String getBaseClass(SchemaType sType) { + SchemaType baseType = findBaseType(sType.getBaseType()); + + switch (sType.getSimpleVariety()) + { + case SchemaType.NOT_SIMPLE: + // non-simple-content: inherit from base type impl + if (!XmlObject.type.equals(baseType)) + return baseType.getFullJavaImplName(); + return "org.apache.xmlbeans.impl.values.XmlComplexContentImpl"; + + case SchemaType.ATOMIC: + // We should only get called for restrictions + assert(! sType.isBuiltinType()); + return getAtomicRestrictionType(sType); + + case SchemaType.LIST: + return "org.apache.xmlbeans.impl.values.XmlListImpl"; + + case SchemaType.UNION: + return "org.apache.xmlbeans.impl.values.XmlUnionImpl"; + + default: + throw new IllegalStateException(); + } + } + + void printConstructor(SchemaType sType, String shortName) throws IOException { + emit(""); + emit("public " + shortName + "(org.apache.xmlbeans.SchemaType sType)"); + startBlock(); + emit("super(sType" + (sType.getSimpleVariety() == SchemaType.NOT_SIMPLE ? + "": + ", " + !sType.isSimpleType()) + + ");"); + endBlock(); + + if (sType.getSimpleVariety() != SchemaType.NOT_SIMPLE) + { + emit(""); + emit("protected " + shortName + "(org.apache.xmlbeans.SchemaType sType, boolean b)"); + startBlock(); + emit("super(sType, b);"); + endBlock(); + } + } + + void startClass(SchemaType sType, boolean isInner) throws IOException + { + String shortName = sType.getShortJavaImplName(); + String baseClass = getBaseClass(sType); + StringBuffer interfaces = new StringBuffer(); + interfaces.append(sType.getFullJavaName().replace('$', '.')); + + if (sType.getSimpleVariety() == SchemaType.UNION) { + SchemaType[] memberTypes = sType.getUnionMemberTypes(); + for (int i = 0 ; i < memberTypes.length ; i++) + interfaces.append(", " + memberTypes[i].getFullJavaName().replace('$', '.')); + } + + emit("public " + ( isInner ? "static ": "" ) + "class " + shortName + + " extends " + baseClass + " implements " + interfaces.toString()); + + startBlock(); + + emit("private static final long serialVersionUID = 1L;"); + } + + void makeAttributeDefaultValue(String jtargetType, SchemaProperty prop, String identifier) throws IOException + { + String fullName = jtargetType; + if (fullName == null) + fullName = prop.javaBasedOnType().getFullJavaName().replace('$', '.'); + + emit("target = (" + fullName + ")get_default_attribute_value(" + identifier + ");"); + } + + void makeMissingValue(int javaType) throws IOException + { + switch (javaType) + { + case SchemaProperty.JAVA_BOOLEAN: + emit("return false;"); break; + + case SchemaProperty.JAVA_FLOAT: + emit("return 0.0f;"); break; + + case SchemaProperty.JAVA_DOUBLE: + emit("return 0.0;"); break; + + case SchemaProperty.JAVA_BYTE: + case SchemaProperty.JAVA_SHORT: + case SchemaProperty.JAVA_INT: + emit("return 0;"); break; + + case SchemaProperty.JAVA_LONG: + emit("return 0L;"); break; + + default: + case SchemaProperty.XML_OBJECT: + case SchemaProperty.JAVA_BIG_DECIMAL: + case SchemaProperty.JAVA_BIG_INTEGER: + case SchemaProperty.JAVA_STRING: + case SchemaProperty.JAVA_BYTE_ARRAY: + case SchemaProperty.JAVA_GDATE: + case SchemaProperty.JAVA_GDURATION: + case SchemaProperty.JAVA_DATE: + case SchemaProperty.JAVA_QNAME: + case SchemaProperty.JAVA_LIST: + case SchemaProperty.JAVA_CALENDAR: + case SchemaProperty.JAVA_ENUM: + case SchemaProperty.JAVA_OBJECT: + emit("return null;"); break; + } + } + + void printJGetArrayValue(int javaType, String type, SchemaTypeImpl stype) throws IOException { + switch (javaType) + { + case SchemaProperty.XML_OBJECT: + emit(type + "[] result = new " + type + "[targetList.size()];"); + emit("targetList.toArray(result);"); + break; + + case SchemaProperty.JAVA_ENUM: + emit(type + "[] result = new " + type + "[targetList.size()];"); + emit("for (int i = 0, len = targetList.size() ; i < len ; i++)"); + emit(" result[i] = (" + type + ")((org.apache.xmlbeans.SimpleValue)targetList.get(i)).getEnumValue();"); + break; + + case SchemaProperty.JAVA_BOOLEAN: + emit("boolean[] result = new boolean[targetList.size()];"); + emit("for (int i = 0, len = targetList.size() ; i < len ; i++)"); + emit(" result[i] = ((org.apache.xmlbeans.SimpleValue)targetList.get(i)).getBooleanValue();"); + break; + + case SchemaProperty.JAVA_FLOAT: + emit("float[] result = new float[targetList.size()];"); + emit("for (int i = 0, len = targetList.size() ; i < len ; i++)"); + emit(" result[i] = ((org.apache.xmlbeans.SimpleValue)targetList.get(i)).getFloatValue();"); + break; + + case SchemaProperty.JAVA_DOUBLE: + emit("double[] result = new double[targetList.size()];"); + emit("for (int i = 0, len = targetList.size() ; i < len ; i++)"); + emit(" result[i] = ((org.apache.xmlbeans.SimpleValue)targetList.get(i)).getDoubleValue();"); + break; + + case SchemaProperty.JAVA_BYTE: + emit("byte[] result = new byte[targetList.size()];"); + emit("for (int i = 0, len = targetList.size() ; i < len ; i++)"); + emit(" result[i] = ((org.apache.xmlbeans.SimpleValue)targetList.get(i)).getByteValue();"); + break; + + case SchemaProperty.JAVA_SHORT: + emit("short[] result = new short[targetList.size()];"); + emit("for (int i = 0, len = targetList.size() ; i < len ; i++)"); + emit(" result[i] = ((org.apache.xmlbeans.SimpleValue)targetList.get(i)).getShortValue();"); + break; + + case SchemaProperty.JAVA_INT: + emit("int[] result = new int[targetList.size()];"); + emit("for (int i = 0, len = targetList.size() ; i < len ; i++)"); + emit(" result[i] = ((org.apache.xmlbeans.SimpleValue)targetList.get(i)).getIntValue();"); + break; + + case SchemaProperty.JAVA_LONG: + emit("long[] result = new long[targetList.size()];"); + emit("for (int i = 0, len = targetList.size() ; i < len ; i++)"); + emit(" result[i] = ((org.apache.xmlbeans.SimpleValue)targetList.get(i)).getLongValue();"); + break; + + case SchemaProperty.JAVA_BIG_DECIMAL: + emit("java.math.BigDecimal[] result = new java.math.BigDecimal[targetList.size()];"); + emit("for (int i = 0, len = targetList.size() ; i < len ; i++)"); + emit(" result[i] = ((org.apache.xmlbeans.SimpleValue)targetList.get(i)).getBigDecimalValue();"); + break; + + case SchemaProperty.JAVA_BIG_INTEGER: + emit("java.math.BigInteger[] result = new java.math.BigInteger[targetList.size()];"); + emit("for (int i = 0, len = targetList.size() ; i < len ; i++)"); + emit(" result[i] = ((org.apache.xmlbeans.SimpleValue)targetList.get(i)).getBigIntegerValue();"); + break; + + case SchemaProperty.JAVA_STRING: + emit("java.lang.String[] result = new java.lang.String[targetList.size()];"); + emit("for (int i = 0, len = targetList.size() ; i < len ; i++)"); + emit(" result[i] = ((org.apache.xmlbeans.SimpleValue)targetList.get(i)).getStringValue();"); + break; + + case SchemaProperty.JAVA_BYTE_ARRAY: + emit("byte[][] result = new byte[targetList.size()][];"); + emit("for (int i = 0, len = targetList.size() ; i < len ; i++)"); + emit(" result[i] = ((org.apache.xmlbeans.SimpleValue)targetList.get(i)).getByteArrayValue();"); + break; + + case SchemaProperty.JAVA_CALENDAR: + emit("java.util.Calendar[] result = new java.util.Calendar[targetList.size()];"); + emit("for (int i = 0, len = targetList.size() ; i < len ; i++)"); + emit(" result[i] = ((org.apache.xmlbeans.SimpleValue)targetList.get(i)).getCalendarValue();"); + break; + + case SchemaProperty.JAVA_DATE: + emit("java.util.Date[] result = new java.util.Date[targetList.size()];"); + emit("for (int i = 0, len = targetList.size() ; i < len ; i++)"); + emit(" result[i] = ((org.apache.xmlbeans.SimpleValue)targetList.get(i)).getDateValue();"); + break; + + case SchemaProperty.JAVA_GDATE: + emit("org.apache.xmlbeans.GDate[] result = new org.apache.xmlbeans.GDate[targetList.size()];"); + emit("for (int i = 0, len = targetList.size() ; i < len ; i++)"); + emit(" result[i] = ((org.apache.xmlbeans.SimpleValue)targetList.get(i)).getGDateValue();"); + break; + + case SchemaProperty.JAVA_GDURATION: + emit("org.apache.xmlbeans.GDuration[] result = new org.apache.xmlbeans.GDuration[targetList.size()];"); + emit("for (int i = 0, len = targetList.size() ; i < len ; i++)"); + emit(" result[i] = ((org.apache.xmlbeans.SimpleValue)targetList.get(i)).getGDurationValue();"); + break; + + case SchemaProperty.JAVA_QNAME: + emit("javax.xml.namespace.QName[] result = new javax.xml.namespace.QName[targetList.size()];"); + emit("for (int i = 0, len = targetList.size() ; i < len ; i++)"); + emit(" result[i] = ((org.apache.xmlbeans.SimpleValue)targetList.get(i)).getQNameValue();"); + break; + + case SchemaProperty.JAVA_LIST: + emit("java.util.List[] result = new java.util.List[targetList.size()];"); + emit("for (int i = 0, len = targetList.size() ; i < len ; i++)"); + emit(" result[i] = ((org.apache.xmlbeans.SimpleValue)targetList.get(i)).getListValue();"); + break; + + case SchemaProperty.JAVA_OBJECT: + emit("java.lang.Object[] result = new java.lang.Object[targetList.size()];"); + emit("for (int i = 0, len = targetList.size() ; i < len ; i++)"); + emit(" result[i] = ((org.apache.xmlbeans.SimpleValue)targetList.get(i)).getObjectValue();"); + break; + + case SchemaProperty.JAVA_USER: + emit(stype.getUserTypeName() + "[] result = new " + stype.getUserTypeName() + "[targetList.size()];"); + emit("for (int i = 0, len = targetList.size() ; i < len ; i++)"); + emit(" result[i] = " + getUserTypeStaticHandlerMethod(false, stype) + + "((org.apache.xmlbeans.SimpleValue)targetList.get(i));"); + break; + + default: + throw new IllegalStateException(); + } + emit("return result;"); + } + void printJGetValue(int javaType, String type, SchemaTypeImpl stype) throws IOException { + switch (javaType) + { + case SchemaProperty.XML_OBJECT: + emit("return target;"); break; + + case SchemaProperty.JAVA_BOOLEAN: + emit("return target.getBooleanValue();"); break; + + case SchemaProperty.JAVA_FLOAT: + emit("return target.getFloatValue();"); break; + + case SchemaProperty.JAVA_DOUBLE: + emit("return target.getDoubleValue();"); break; + + case SchemaProperty.JAVA_BYTE: + emit("return target.getByteValue();"); break; + + case SchemaProperty.JAVA_SHORT: + emit("return target.getShortValue();"); break; + + case SchemaProperty.JAVA_INT: + emit("return target.getIntValue();"); break; + + case SchemaProperty.JAVA_LONG: + emit("return target.getLongValue();"); break; + + case SchemaProperty.JAVA_BIG_DECIMAL: + emit("return target.getBigDecimalValue();"); break; + + case SchemaProperty.JAVA_BIG_INTEGER: + emit("return target.getBigIntegerValue();"); break; + + case SchemaProperty.JAVA_STRING: + emit("return target.getStringValue();"); break; + + case SchemaProperty.JAVA_BYTE_ARRAY: + emit("return target.getByteArrayValue();"); break; + + case SchemaProperty.JAVA_GDATE: + emit("return target.getGDateValue();"); break; + + case SchemaProperty.JAVA_GDURATION: + emit("return target.getGDurationValue();"); break; + + case SchemaProperty.JAVA_CALENDAR: + emit("return target.getCalendarValue();"); break; + + case SchemaProperty.JAVA_DATE: + emit("return target.getDateValue();"); break; + + case SchemaProperty.JAVA_QNAME: + emit("return target.getQNameValue();"); break; + + case SchemaProperty.JAVA_LIST: + emit("return target.getListValue();"); break; + + case SchemaProperty.JAVA_ENUM: + emit("return (" + type + ")target.getEnumValue();"); break; + + case SchemaProperty.JAVA_OBJECT: + emit("return target.getObjectValue();"); break; + + case SchemaProperty.JAVA_USER: + emit("return " + getUserTypeStaticHandlerMethod(false, stype) + + "(target);"); + break; + + default: + throw new IllegalStateException(); + } + } + void printJSetValue(int javaType, String safeVarName, SchemaTypeImpl stype) throws IOException { + switch (javaType) + { + case SchemaProperty.XML_OBJECT: + emit("target.set(" + safeVarName + ");"); break; + + case SchemaProperty.JAVA_BOOLEAN: + emit("target.setBooleanValue(" + safeVarName + ");"); break; + + case SchemaProperty.JAVA_FLOAT: + emit("target.setFloatValue(" + safeVarName + ");"); break; + + case SchemaProperty.JAVA_DOUBLE: + emit("target.setDoubleValue(" + safeVarName + ");"); break; + + case SchemaProperty.JAVA_BYTE: + emit("target.setByteValue(" + safeVarName + ");"); break; + + case SchemaProperty.JAVA_SHORT: + emit("target.setShortValue(" + safeVarName + ");"); break; + + case SchemaProperty.JAVA_INT: + emit("target.setIntValue(" + safeVarName + ");"); break; + + case SchemaProperty.JAVA_LONG: + emit("target.setLongValue(" + safeVarName + ");"); break; + + case SchemaProperty.JAVA_BIG_DECIMAL: + emit("target.setBigDecimalValue(" + safeVarName + ");"); break; + + case SchemaProperty.JAVA_BIG_INTEGER: + emit("target.setBigIntegerValue(" + safeVarName + ");"); break; + + case SchemaProperty.JAVA_STRING: + emit("target.setStringValue(" + safeVarName + ");"); break; + + case SchemaProperty.JAVA_BYTE_ARRAY: + emit("target.setByteArrayValue(" + safeVarName + ");"); break; + + case SchemaProperty.JAVA_GDATE: + emit("target.setGDateValue(" + safeVarName + ");"); break; + + case SchemaProperty.JAVA_GDURATION: + emit("target.setGDurationValue(" + safeVarName + ");"); break; + + case SchemaProperty.JAVA_CALENDAR: + emit("target.setCalendarValue(" + safeVarName + ");"); break; + + case SchemaProperty.JAVA_DATE: + emit("target.setDateValue(" + safeVarName + ");"); break; + + case SchemaProperty.JAVA_QNAME: + emit("target.setQNameValue(" + safeVarName + ");"); break; + + case SchemaProperty.JAVA_LIST: + emit("target.setListValue(" + safeVarName + ");"); break; + + case SchemaProperty.JAVA_ENUM: + emit("target.setEnumValue(" + safeVarName + ");"); break; + + case SchemaProperty.JAVA_OBJECT: + emit("target.setObjectValue(" + safeVarName + ");"); break; + + case SchemaProperty.JAVA_USER: + emit(getUserTypeStaticHandlerMethod(true, stype) + + "(" + safeVarName + ", target);"); + break; + + default: + throw new IllegalStateException(); + } + } + + String getIdentifier(Map qNameMap, QName qName) { + return ((String[])qNameMap.get(qName))[0]; + } + + String getSetIdentifier(Map qNameMap, QName qName) { + String[] identifiers = (String[])qNameMap.get(qName); + return identifiers[1] == null ? identifiers[0] : identifiers[1]; + } + + Map printStaticFields(SchemaProperty[] properties) throws IOException { + final Map results = new HashMap(); + + emit(""); + for (int i = 0; i < properties.length; i++) + { + final String[] identifiers = new String[2]; + final SchemaProperty prop = properties[i]; + final QName name = prop.getName(); + results.put(name, identifiers); + final String javaName = prop.getJavaPropertyName(); + identifiers[0] = (javaName + "$" + (i * 2)).toUpperCase(); + final String uriString = "\"" + name.getNamespaceURI() + "\""; + + emit("private static final javax.xml.namespace.QName " + identifiers[0] + + " = " ); + indent(); + emit("new javax.xml.namespace.QName(" + + uriString + ", \"" + name.getLocalPart() + "\");"); + outdent(); + + if (properties[i].acceptedNames() != null) + { + final QName[] qnames = properties[i].acceptedNames(); + + if (qnames.length > 1) + { + identifiers[1] = (javaName + "$" + (i*2+1)).toUpperCase(); + + emit("private static final org.apache.xmlbeans.QNameSet " + identifiers[1] + + " = org.apache.xmlbeans.QNameSet.forArray( new javax.xml.namespace.QName[] { " ); + indent(); + for (int j = 0 ; j < qnames.length ; j++) + { + emit("new javax.xml.namespace.QName(\"" + qnames[j].getNamespaceURI() + + "\", \"" + qnames[j].getLocalPart() + "\"),"); + } + + outdent(); + + emit("});"); + } + } + } + emit(""); + return results; + } + + void emitImplementationPreamble() throws IOException + { + emit("synchronized (monitor())"); + emit("{"); + indent(); + emit("check_orphaned();"); + } + + void emitImplementationPostamble() throws IOException + { + outdent(); + emit("}"); + } + + void emitDeclareTarget(boolean declareTarget, String xtype) + throws IOException + { + if (declareTarget) + emit(xtype + " target = null;"); + } + + void emitAddTarget(String identifier, boolean isAttr, boolean declareTarget, String xtype) + throws IOException + { + if (isAttr) + emit("target = (" + xtype + ")get_store().add_attribute_user(" + identifier + ");"); + else + emit("target = (" + xtype + ")get_store().add_element_user(" + identifier + ");"); + } + + void emitPre(SchemaType sType, int opType, String identifier, boolean isAttr) throws IOException + { + emitPre(sType, opType, identifier, isAttr, "-1"); + } + + void emitPre(SchemaType sType, int opType, String identifier, boolean isAttr, String index) throws IOException + { + SchemaTypeImpl sImpl = getImpl(sType); + if (sImpl == null) + return; + + PrePostExtension ext = sImpl.getPrePostExtension(); + if (ext != null) + { + if (ext.hasPreCall()) + { + emit("if ( " + ext.getStaticHandler() + ".preSet(" + prePostOpString(opType) + ", this, " + identifier + ", " + isAttr + ", " + index + "))"); + startBlock(); + } + } + } + + void emitPost(SchemaType sType, int opType, String identifier, boolean isAttr) throws IOException + { + emitPost(sType, opType, identifier, isAttr, "-1"); + } + + void emitPost(SchemaType sType, int opType, String identifier, boolean isAttr, String index) throws IOException + { + SchemaTypeImpl sImpl = getImpl(sType); + if (sImpl == null) + return; + + PrePostExtension ext = sImpl.getPrePostExtension(); + if (ext != null) + { + if (ext.hasPreCall()) + { + endBlock(); + } + + if (ext.hasPostCall()) + emit(ext.getStaticHandler() + ".postSet(" + prePostOpString(opType) + ", this, " + identifier + ", " + isAttr + ", " + index + ");"); + } + } + + String prePostOpString(int opType) + { + switch (opType) + { + default: + assert false; + + case PrePostExtension.OPERATION_SET: + return "org.apache.xmlbeans.PrePostExtension.OPERATION_SET"; + + case PrePostExtension.OPERATION_INSERT: + return "org.apache.xmlbeans.PrePostExtension.OPERATION_INSERT"; + + case PrePostExtension.OPERATION_REMOVE: + return "org.apache.xmlbeans.PrePostExtension.OPERATION_REMOVE"; + } + } + + private static final int NOTHING = 1; + private static final int ADD_NEW_VALUE = 3; + private static final int THROW_EXCEPTION = 4; + + void emitGetTarget(String setIdentifier, + String identifier, + boolean isAttr, + String index, + int nullBehaviour, + String xtype) + throws IOException + { + assert setIdentifier != null && identifier != null; + + emit(xtype + " target = null;"); + + if (isAttr) + emit("target = (" + xtype + ")get_store().find_attribute_user(" + identifier + ");"); + else + emit("target = (" + xtype + ")get_store().find_element_user(" + setIdentifier + ", " + index + ");"); + + if (nullBehaviour == NOTHING) + return; + + emit("if (target == null)"); + + startBlock(); + + switch (nullBehaviour) + { + case ADD_NEW_VALUE: + // target already emited, no need for emitDeclareTarget(false, xtype); + emitAddTarget(identifier, isAttr, false, xtype); + break; + + case THROW_EXCEPTION: + emit("throw new IndexOutOfBoundsException();"); + break; + + case NOTHING: + break; + + default: + assert false : "Bad behaviour type: " + nullBehaviour; + } + + endBlock(); + } + + void printListGetter15Impl(String parentJavaName, + String propdesc, String propertyName, + String wrappedType, String xtype, + boolean xmltype, boolean xget) + throws IOException + { + String arrayName = propertyName + "Array"; + String listName = propertyName + "List"; + String parentThis = parentJavaName + ".this."; + + String xgetMethod = (xget ? "x" : "") + "get"; + String xsetMethod = (xget ? "x" : "") + "set"; + + printJavaDoc("Gets " + (xget ? "(as xml) " : "") + "a List of " + propdesc + "s"); + + emit("public java.util.List<" + wrappedType + "> " + xgetMethod + listName + "()"); + startBlock(); + + emit("final class " + listName + " extends java.util.AbstractList<" + wrappedType + ">"); + startBlock(); + + // Object get(i) + if (_useJava15) + emit("@Override"); + emit("public " + wrappedType + " get(int i)"); + emit(" { return " + parentThis + xgetMethod + arrayName + "(i); }"); + emit(""); + + // Object set(i, o) + if (_useJava15) + emit("@Override"); + emit("public " + wrappedType + " set(int i, " + wrappedType + " o)"); + startBlock(); + emit(wrappedType + " old = " + parentThis + xgetMethod + arrayName + "(i);"); + emit(parentThis + xsetMethod + arrayName + "(i, o);"); + emit("return old;"); + endBlock(); + emit(""); + + // void add(i, o) + if (_useJava15) + emit("@Override"); + emit("public void add(int i, " + wrappedType +" o)"); + if (xmltype || xget) + emit(" { " + parentThis + "insertNew" + propertyName + "(i).set(o); }"); + else + emit(" { " + parentThis + "insert" + propertyName + "(i, o); }"); + emit(""); + + // Object remove(i) + if (_useJava15) + emit("@Override"); + emit("public " + wrappedType +" remove(int i)"); + startBlock(); + emit(wrappedType + " old = " + parentThis + xgetMethod + arrayName + "(i);"); + emit(parentThis + "remove" + propertyName + "(i);"); + emit("return old;"); + endBlock(); + emit(""); + + // int size() + if (_useJava15) + emit("@Override"); + emit("public int size()"); + emit(" { return " + parentThis + "sizeOf" + arrayName + "(); }"); + emit(""); + + endBlock(); + + emit(""); + + emitImplementationPreamble(); + + emit("return new " + listName + "();"); + + emitImplementationPostamble(); + endBlock(); + } + + void printGetterImpls(String parentJavaName, + SchemaProperty prop, QName qName, boolean isAttr, String propertyName, + int javaType, String type, String xtype, boolean nillable, + boolean optional, boolean several, boolean singleton, + boolean isunion, + String identifier, String setIdentifier ) + throws IOException + { + String propdesc = "\"" + qName.getLocalPart() + "\"" + (isAttr ? " attribute" : " element"); + boolean xmltype = (javaType == SchemaProperty.XML_OBJECT); + String jtargetType = (isunion || !xmltype) ? "org.apache.xmlbeans.SimpleValue" : xtype; + + if (singleton) + { + // Value getProp() + printJavaDoc((several ? "Gets first " : "Gets the ") + propdesc); + emit("public " + type + " get" + propertyName + "()"); + startBlock(); + emitImplementationPreamble(); + + emitGetTarget(setIdentifier, identifier, isAttr, "0", NOTHING, jtargetType); + + if (isAttr && (prop.hasDefault() == SchemaProperty.CONSISTENTLY || + prop.hasFixed() == SchemaProperty.CONSISTENTLY)) + { + emit("if (target == null)"); + startBlock(); + makeAttributeDefaultValue(jtargetType, prop, identifier); + endBlock(); + } + emit("if (target == null)"); + startBlock(); + makeMissingValue(javaType); + endBlock(); + + + printJGetValue(javaType, type, (SchemaTypeImpl)prop.getType()); + + + emitImplementationPostamble(); + + endBlock(); + + if (!xmltype) + { + // Value xgetProp() + printJavaDoc((several ? "Gets (as xml) first " : "Gets (as xml) the ") + propdesc); + emit("public " + xtype + " xget" + propertyName + "()"); + startBlock(); + emitImplementationPreamble(); + emitGetTarget(setIdentifier, identifier, isAttr, "0", NOTHING, xtype); + + if (isAttr && (prop.hasDefault() == SchemaProperty.CONSISTENTLY || + prop.hasFixed() == SchemaProperty.CONSISTENTLY)) + { + emit("if (target == null)"); + startBlock(); + makeAttributeDefaultValue(xtype, prop, identifier); + endBlock(); + } + + emit("return target;"); + emitImplementationPostamble(); + endBlock(); + } + + if (nillable) + { + // boolean isNilProp() + printJavaDoc((several ? "Tests for nil first " : "Tests for nil ") + propdesc); + emit("public boolean isNil" + propertyName + "()"); + startBlock(); + emitImplementationPreamble(); + emitGetTarget(setIdentifier, identifier, isAttr, "0", NOTHING, xtype); + + emit("if (target == null) return false;"); + emit("return target.isNil();"); + emitImplementationPostamble(); + endBlock(); + } + } + + if (optional) + { + // boolean isSetProp() + printJavaDoc((several ? "True if has at least one " : "True if has ") + propdesc); + emit("public boolean isSet" + propertyName + "()"); + + startBlock(); + emitImplementationPreamble(); + + if (isAttr) + emit("return get_store().find_attribute_user(" + identifier +") != null;"); + else + emit("return get_store().count_elements(" + setIdentifier + ") != 0;"); + + emitImplementationPostamble(); + endBlock(); + } + + if (several) + { + String arrayName = propertyName + "Array"; + + if (_useJava15) + { + // use boxed type if the java type is a primitive and jdk1.5 + // jdk1.5 will box/unbox for us + String wrappedType = type; + if (isJavaPrimitive(javaType)) + wrappedType = javaWrappedType(javaType); + + printListGetter15Impl(parentJavaName, propdesc, propertyName, wrappedType, xtype, xmltype, false); + } + + // Value[] getProp() + if (_useJava15) + { + emit(""); + emit("/**"); + emit(" * Gets array of all " + propdesc + "s"); + emit(" * @deprecated"); + emit(" */"); + emit("@Deprecated"); + } + else + printJavaDoc("Gets array of all " + propdesc + "s"); + emit("public " + type + "[] get" + arrayName + "()"); + startBlock(); + emitImplementationPreamble(); + + if (_useJava15) + emit("java.util.List<" + xtype + "> targetList = new java.util.ArrayList<" + xtype + ">();"); + else + emit("java.util.List targetList = new java.util.ArrayList();"); + emit("get_store().find_all_element_users(" + setIdentifier + ", targetList);"); + + printJGetArrayValue(javaType, type, (SchemaTypeImpl)prop.getType()); + + emitImplementationPostamble(); + endBlock(); + + // Value getProp(int i) + printJavaDoc("Gets ith " + propdesc); + emit("public " + type + " get" + arrayName + "(int i)"); + startBlock(); + emitImplementationPreamble(); + + emitGetTarget(setIdentifier, identifier, isAttr, "i", THROW_EXCEPTION, jtargetType); + printJGetValue(javaType, type, (SchemaTypeImpl)prop.getType()); + + emitImplementationPostamble(); + endBlock(); + + if (!xmltype) + { + if (_useJava15) + { + printListGetter15Impl(parentJavaName, propdesc, propertyName, xtype, xtype, xmltype, true); + } + + // Value[] xgetProp() + if (_useJava15) + { + emit(""); + emit("/**"); + emit(" * Gets array of all " + propdesc + "s"); + emit(" * @deprecated"); + emit(" */"); + emit("@Deprecated"); + } + else + printJavaDoc("Gets (as xml) array of all " + propdesc + "s"); + emit("public " + xtype + "[] xget" + arrayName + "()"); + startBlock(); + emitImplementationPreamble(); + if (_useJava15) + emit("java.util.List<" + xtype + "> targetList = new java.util.ArrayList<" + xtype + ">();"); + else + emit("java.util.List targetList = new java.util.ArrayList();"); + emit("get_store().find_all_element_users(" + setIdentifier + ", targetList);"); + emit(xtype + "[] result = new " + xtype + "[targetList.size()];"); + emit("targetList.toArray(result);"); + emit("return result;"); + emitImplementationPostamble(); + endBlock(); + + // Value xgetProp(int i) + printJavaDoc("Gets (as xml) ith " + propdesc); + emit("public " + xtype + " xget" + arrayName + "(int i)"); + startBlock(); + emitImplementationPreamble(); + emitGetTarget(setIdentifier, identifier, isAttr, "i", THROW_EXCEPTION, xtype); + emit("return target;"); + emitImplementationPostamble(); + endBlock(); + + } + + if (nillable) + { + // boolean isNil(int i); + printJavaDoc("Tests for nil ith " + propdesc); + emit("public boolean isNil" + arrayName + "(int i)"); + startBlock(); + emitImplementationPreamble(); + emitGetTarget(setIdentifier, identifier, isAttr, "i", THROW_EXCEPTION, xtype); + emit("return target.isNil();"); + emitImplementationPostamble(); + endBlock(); + } + + // int countProp(); + printJavaDoc("Returns number of " + propdesc); + emit("public int sizeOf" + arrayName + "()"); + startBlock(); + emitImplementationPreamble(); + emit("return get_store().count_elements(" + setIdentifier +");"); + emitImplementationPostamble(); + endBlock(); + } + } + + void printSetterImpls(QName qName, SchemaProperty prop, boolean isAttr, + String propertyName, int javaType, String type, String xtype, + boolean nillable, boolean optional, boolean several, boolean singleton, + boolean isunion, String identifier, String setIdentifier, SchemaType sType) + throws IOException + { + String safeVarName = NameUtil.nonJavaKeyword(NameUtil.lowerCamelCase(propertyName)); + safeVarName = NameUtil.nonExtraKeyword(safeVarName); + + boolean xmltype = (javaType == SchemaProperty.XML_OBJECT); + boolean isobj = (javaType == SchemaProperty.JAVA_OBJECT); + boolean isSubstGroup = identifier != setIdentifier; + String jtargetType = (isunion || !xmltype) ? "org.apache.xmlbeans.SimpleValue" : xtype; + + String propdesc = "\"" + qName.getLocalPart() + "\"" + (isAttr ? " attribute" : " element"); + + if (singleton) + { + // void setProp(Value v); + printJavaDoc((several ? "Sets first " : "Sets the ") + propdesc); + emit("public void set" + propertyName + "(" + type + " " + safeVarName + ")"); + startBlock(); + if ( xmltype && !isSubstGroup ) + { + emitPre(sType, PrePostExtension.OPERATION_SET, identifier, isAttr, several ? "0" : "-1"); + emit("generatedSetterHelperImpl(" + safeVarName + ", " + setIdentifier + ", 0, " + + "org.apache.xmlbeans.impl.values.XmlObjectBase.KIND_SETTERHELPER_SINGLETON);"); + emitPost(sType, PrePostExtension.OPERATION_SET, identifier, isAttr, several ? "0" : "-1"); + } + else + { + emitImplementationPreamble(); + emitPre(sType, PrePostExtension.OPERATION_SET, identifier, isAttr, several ? "0" : "-1"); + emitGetTarget(setIdentifier, identifier, isAttr, "0", ADD_NEW_VALUE, jtargetType); + printJSetValue(javaType, safeVarName, (SchemaTypeImpl)prop.getType()); + emitPost(sType, PrePostExtension.OPERATION_SET, identifier, isAttr, several ? "0" : "-1"); + emitImplementationPostamble(); + } + endBlock(); + + if (!xmltype) + { + // void xsetProp(Value v) + printJavaDoc((several ? "Sets (as xml) first " : "Sets (as xml) the ") + propdesc); + emit("public void xset" + propertyName + "(" + xtype + " " + safeVarName + ")"); + startBlock(); + emitImplementationPreamble(); + emitPre(sType, PrePostExtension.OPERATION_SET, identifier, isAttr, several ? "0" : "-1"); + emitGetTarget(setIdentifier, identifier, isAttr, "0", ADD_NEW_VALUE, xtype); + emit("target.set(" + safeVarName + ");"); + emitPost(sType, PrePostExtension.OPERATION_SET, identifier, isAttr, several ? "0" : "-1"); + emitImplementationPostamble(); + endBlock(); + + } + + if (xmltype && !several) + { + // Value addNewProp() + printJavaDoc("Appends and returns a new empty " + propdesc); + emit("public " + xtype + " addNew" + propertyName + "()"); + startBlock(); + emitImplementationPreamble(); + emitDeclareTarget(true, xtype); + emitPre(sType, PrePostExtension.OPERATION_INSERT, identifier, isAttr); + emitAddTarget(identifier, isAttr, true, xtype); + emitPost(sType, PrePostExtension.OPERATION_INSERT, identifier, isAttr); + emit("return target;"); + emitImplementationPostamble(); + endBlock(); + } + + if (nillable) + { + printJavaDoc((several ? "Nils the first " : "Nils the ") + propdesc); + emit("public void setNil" + propertyName + "()"); + startBlock(); + emitImplementationPreamble(); + emitPre(sType, PrePostExtension.OPERATION_SET, identifier, isAttr, several ? "0" : "-1"); + emitGetTarget(setIdentifier, identifier, isAttr, "0", ADD_NEW_VALUE, xtype); + emit("target.setNil();"); + emitPost(sType, PrePostExtension.OPERATION_SET, identifier, isAttr, several ? "0" : "-1"); + emitImplementationPostamble(); + endBlock(); + } + } + + if (optional) + { + printJavaDoc((several ? "Removes first " : "Unsets the ") + propdesc); + emit("public void unset" + propertyName + "()"); + startBlock(); + emitImplementationPreamble(); + emitPre(sType, PrePostExtension.OPERATION_REMOVE, identifier, isAttr, several ? "0" : "-1"); + if (isAttr) + emit("get_store().remove_attribute(" + identifier + ");"); + else + emit("get_store().remove_element(" + setIdentifier + ", 0);"); + emitPost(sType, PrePostExtension.OPERATION_REMOVE, identifier, isAttr, several ? "0" : "-1"); + emitImplementationPostamble(); + endBlock(); + } + + if (several) + { + String arrayName = propertyName + "Array"; + + if ( xmltype ) + { + printJavaDoc("Sets array of all " + propdesc + " WARNING: This method is not atomicaly synchronized."); + emit("public void set" + arrayName + "(" + type + "[] " + safeVarName + "Array)"); + startBlock(); + // do not use synchronize (monitor()) { and GlobalLock inside } !!! deadlock + //emitImplementationPreamble(); + emit("check_orphaned();"); + emitPre(sType, PrePostExtension.OPERATION_SET, identifier, isAttr); + + if (isobj) + { + if (!isSubstGroup) + emit("unionArraySetterHelper(" + safeVarName + "Array" + ", " + identifier + ");" ); + else + emit("unionArraySetterHelper(" + safeVarName + "Array" + ", " + identifier + ", " + setIdentifier + ");" ); + } + else + { + if (!isSubstGroup) + emit("arraySetterHelper(" + safeVarName + "Array" + ", " + identifier + ");" ); + else + emit("arraySetterHelper(" + safeVarName + "Array" + ", " + identifier + ", " + setIdentifier + ");" ); + } + + emitPost(sType, PrePostExtension.OPERATION_SET, identifier, isAttr); + //emitImplementationPostamble(); to avoid deadlock + endBlock(); + } + else + { + printJavaDoc("Sets array of all " + propdesc ); + emit("public void set" + arrayName + "(" + type + "[] " + safeVarName + "Array)"); + startBlock(); + emitImplementationPreamble(); + emitPre(sType, PrePostExtension.OPERATION_SET, identifier, isAttr); + + if (isobj) + { + if (!isSubstGroup) + emit("unionArraySetterHelper(" + safeVarName + "Array" + ", " + identifier + ");" ); + else + emit("unionArraySetterHelper(" + safeVarName + "Array" + ", " + identifier + ", " + setIdentifier + ");" ); + } + else if (prop.getJavaTypeCode() == SchemaProperty.JAVA_USER) + { + if (!isSubstGroup) + { + emit("org.apache.xmlbeans.SimpleValue[] dests = arraySetterHelper(" + safeVarName + "Array.length" + ", " + identifier + ");" ); + emit("for ( int i = 0 ; i < dests.length ; i++ ) {"); + emit(" " + getUserTypeStaticHandlerMethod(true, (SchemaTypeImpl)prop.getType()) + + "(" + safeVarName + "Array[i], dests[i]);"); + emit("}"); + } + else + { + emit("org.apache.xmlbeans.SimpleValue[] dests = arraySetterHelper(" + safeVarName + "Array.length" + ", " + identifier + ", " + setIdentifier + ");" ); + emit("for ( int i = 0 ; i < dests.length ; i++ ) {"); + emit(" " + getUserTypeStaticHandlerMethod(true, (SchemaTypeImpl)prop.getType()) + + "(" + safeVarName + "Array[i], dests[i]);"); + emit("}"); + } + } + else + { + if (!isSubstGroup) + emit("arraySetterHelper(" + safeVarName + "Array" + ", " + identifier + ");" ); + else + emit("arraySetterHelper(" + safeVarName + "Array" + ", " + identifier + ", " + setIdentifier + ");" ); + } + + emitPost(sType, PrePostExtension.OPERATION_SET, identifier, isAttr); + emitImplementationPostamble(); + endBlock(); + } + + printJavaDoc("Sets ith " + propdesc); + emit("public void set" + arrayName + "(int i, " + type + " " + safeVarName + ")"); + startBlock(); + if ( xmltype && !isSubstGroup ) + { + emitPre(sType, PrePostExtension.OPERATION_SET, identifier, isAttr, "i"); + emit("generatedSetterHelperImpl(" + safeVarName + ", " + setIdentifier + ", i, " + + "org.apache.xmlbeans.impl.values.XmlObjectBase.KIND_SETTERHELPER_ARRAYITEM);"); + emitPost(sType, PrePostExtension.OPERATION_SET, identifier, isAttr, "i"); + } + else + { + emitImplementationPreamble(); + emitPre(sType, PrePostExtension.OPERATION_SET, identifier, isAttr, "i"); + emitGetTarget(setIdentifier, identifier, isAttr, "i", THROW_EXCEPTION, jtargetType); + printJSetValue(javaType, safeVarName, (SchemaTypeImpl)prop.getType()); + emitPost(sType, PrePostExtension.OPERATION_SET, identifier, isAttr, "i"); + emitImplementationPostamble(); + } + endBlock(); + + if (!xmltype) + { + printJavaDoc("Sets (as xml) array of all " + propdesc); + emit("public void xset" + arrayName + "(" + xtype + "[]" + safeVarName + "Array)"); + startBlock(); + emitImplementationPreamble(); + emitPre(sType, PrePostExtension.OPERATION_SET, identifier, isAttr); + emit("arraySetterHelper(" + safeVarName + "Array" + ", " + identifier + ");" ); + emitPost(sType, PrePostExtension.OPERATION_SET, identifier, isAttr); + emitImplementationPostamble(); + endBlock(); + + printJavaDoc("Sets (as xml) ith " + propdesc); + emit("public void xset" + arrayName + "(int i, " + xtype + " " + safeVarName + ")"); + startBlock(); + emitImplementationPreamble(); + emitPre(sType, PrePostExtension.OPERATION_SET, identifier, isAttr, "i"); + emitGetTarget(setIdentifier, identifier, isAttr, "i", THROW_EXCEPTION, xtype); + emit("target.set(" + safeVarName + ");"); + emitPost(sType, PrePostExtension.OPERATION_SET, identifier, isAttr, "i"); + emitImplementationPostamble(); + endBlock(); + } + + if (nillable) + { + printJavaDoc("Nils the ith " + propdesc); + emit("public void setNil" + arrayName + "(int i)"); + startBlock(); + emitImplementationPreamble(); + emitPre(sType, PrePostExtension.OPERATION_SET, identifier, isAttr, "i"); + emitGetTarget(setIdentifier, identifier, isAttr, "i", THROW_EXCEPTION, xtype); + emit("target.setNil();"); + emitPost(sType, PrePostExtension.OPERATION_SET, identifier, isAttr, "i"); + emitImplementationPostamble(); + endBlock(); + } + + if (!xmltype) + { + printJavaDoc("Inserts the value as the ith " + propdesc); + emit("public void insert" + propertyName + "(int i, " + type + " " + safeVarName + ")"); + startBlock(); + emitImplementationPreamble(); + emitPre(sType, PrePostExtension.OPERATION_INSERT, identifier, isAttr, "i"); + emit(jtargetType + " target = "); + indent(); + if (!isSubstGroup) + emit("(" + jtargetType + ")get_store().insert_element_user(" + identifier + ", i);"); + else // This is a subst group case + emit ("(" + jtargetType +")get_store().insert_element_user(" + setIdentifier + ", " + + identifier + ", i);"); + outdent(); + printJSetValue(javaType, safeVarName, (SchemaTypeImpl)prop.getType()); + emitPost(sType, PrePostExtension.OPERATION_INSERT, identifier, isAttr, "i"); + emitImplementationPostamble(); + endBlock(); + + printJavaDoc("Appends the value as the last " + propdesc); + emit("public void add" + propertyName + "(" + type + " " + safeVarName + ")"); + startBlock(); + emitImplementationPreamble(); + emitDeclareTarget(true, jtargetType); + emitPre(sType, PrePostExtension.OPERATION_INSERT, identifier, isAttr); + emitAddTarget(identifier, isAttr, true, jtargetType); + printJSetValue(javaType, safeVarName, (SchemaTypeImpl)prop.getType()); + emitPost(sType, PrePostExtension.OPERATION_INSERT, identifier, isAttr); + emitImplementationPostamble(); + endBlock(); + } + + printJavaDoc("Inserts and returns a new empty value (as xml) as the ith " + propdesc); + emit("public " + xtype + " insertNew" + propertyName + "(int i)"); + startBlock(); + emitImplementationPreamble(); + emitDeclareTarget(true, xtype); + emitPre(sType, PrePostExtension.OPERATION_INSERT, identifier, isAttr, "i"); + if (!isSubstGroup) + { + emit("target = (" + xtype + ")get_store().insert_element_user(" + identifier + ", i);"); + } + else // This is a subst group case + { + emit("target = (" + xtype + ")get_store().insert_element_user(" + + setIdentifier + ", " + identifier + ", i);"); + } + emitPost(sType, PrePostExtension.OPERATION_INSERT, identifier, isAttr, "i"); + emit("return target;"); + emitImplementationPostamble(); + endBlock(); + + printJavaDoc("Appends and returns a new empty value (as xml) as the last " + propdesc); + emit("public " + xtype + " addNew" + propertyName + "()"); + startBlock(); + emitImplementationPreamble(); + emitDeclareTarget(true, xtype); + emitPre(sType, PrePostExtension.OPERATION_INSERT, identifier, isAttr); + emitAddTarget(identifier, isAttr, true, xtype); + emitPost(sType, PrePostExtension.OPERATION_INSERT, identifier, isAttr); + emit("return target;"); + emitImplementationPostamble(); + endBlock(); + + printJavaDoc("Removes the ith " + propdesc); + emit("public void remove" + propertyName + "(int i)"); + startBlock(); + emitImplementationPreamble(); + emitPre(sType, PrePostExtension.OPERATION_REMOVE, identifier, isAttr, "i"); + emit("get_store().remove_element(" + setIdentifier + ", i);"); + emitPost(sType, PrePostExtension.OPERATION_REMOVE, identifier, isAttr, "i"); + emitImplementationPostamble(); + endBlock(); + } + } + + static void getTypeName(Class c, StringBuffer sb) { + int arrayCount = 0; + while (c.isArray()) { + c = c.getComponentType(); + arrayCount++; + } + + sb.append(c.getName()); + + for (int i = 0 ; i < arrayCount; i++) + sb.append("[]"); + + } + + void printInnerTypeImpl( + SchemaType sType, SchemaTypeSystem system, boolean isInner ) throws IOException + { + String shortName = sType.getShortJavaImplName(); + + printInnerTypeJavaDoc(sType); + + startClass(sType, isInner); + + printConstructor(sType, shortName); + + printExtensionImplMethods(sType); + + if (!sType.isSimpleType()) + { + SchemaProperty[] properties; + + if (sType.getContentType() == SchemaType.SIMPLE_CONTENT) + { + // simple content types impls derive directly from "holder" impls + // in order to handle the case (for ints or string enums e.g.) where + // there is a simple type restriction. So property getters need to + // be implemented "from scratch" for each derived complex type + // Moreover, attribute or element properties can be removed via restriction, + // but we still need to implement them because this class is supposed to + // also implement all the interfaces + SchemaType baseType = sType.getBaseType(); + List extraProperties = null; + while (!baseType.isSimpleType() && !baseType.isBuiltinType()) + { + SchemaProperty[] baseProperties = baseType.getDerivedProperties(); + for (int i = 0; i < baseProperties.length; i++) + if (!(baseProperties[i].isAttribute() && + sType.getAttributeProperty(baseProperties[i].getName()) != null)) + { + if (extraProperties == null) + extraProperties = new ArrayList(); + extraProperties.add(baseProperties[i]); + } + baseType = baseType.getBaseType(); + } + + properties = sType.getProperties(); + if (extraProperties != null) + { + for (int i = 0; i < properties.length; i++) + extraProperties.add(properties[i]); + properties = (SchemaProperty[]) extraProperties. + toArray(new SchemaProperty[extraProperties.size()]); + } + } + else + { + // complex content type implementations derive from base type impls + // so derived property impls can be reused + + properties = getDerivedProperties(sType); + } + + Map qNameMap = printStaticFields(properties); + + for (int i = 0; i < properties.length; i++) + { + SchemaProperty prop = properties[i]; + + QName name = prop.getName(); + String xmlType = xmlTypeForProperty( prop ); + + printGetterImpls( + shortName, + prop, + name, + prop.isAttribute(), + prop.getJavaPropertyName(), + prop.getJavaTypeCode(), + javaTypeForProperty(prop), + xmlType, + prop.hasNillable() != SchemaProperty.NEVER, + prop.extendsJavaOption(), + prop.extendsJavaArray(), + prop.extendsJavaSingleton(), + xmlTypeForPropertyIsUnion(prop), + getIdentifier(qNameMap, name), + getSetIdentifier(qNameMap, name) + ); + + if (!prop.isReadOnly()) + { + printSetterImpls( + name, + prop, + prop.isAttribute(), + prop.getJavaPropertyName(), + prop.getJavaTypeCode(), + javaTypeForProperty(prop), + xmlType, + prop.hasNillable() != SchemaProperty.NEVER, + prop.extendsJavaOption(), + prop.extendsJavaArray(), + prop.extendsJavaSingleton(), + xmlTypeForPropertyIsUnion(prop), + getIdentifier(qNameMap, name), + getSetIdentifier(qNameMap, name), + sType + ); + } + } + } + + printNestedTypeImpls(sType, system); + + endBlock(); + } + + private SchemaProperty[] getDerivedProperties(SchemaType sType) + { + // We have to see if this is redefined, because if it is we have + // to include all properties associated to its supertypes + QName name = sType.getName(); + if (name != null && name.equals(sType.getBaseType().getName())) + { + SchemaType sType2 = sType.getBaseType(); + // Walk all the redefined types and record any properties + // not present in sType, because the redefined types do not + // have a generated class to represent them + SchemaProperty[] props = sType.getDerivedProperties(); + Map propsByName = new LinkedHashMap(); + for (int i = 0; i < props.length; i++) + propsByName.put(props[i].getName(), props[i]); + while (sType2 != null && name.equals(sType2.getName())) + { + props = sType2.getDerivedProperties(); + for (int i = 0; i < props.length; i++) + if (!propsByName.containsKey(props[i].getName())) + propsByName.put(props[i].getName(), props[i]); + sType2 = sType2.getBaseType(); + } + return (SchemaProperty[]) propsByName.values().toArray(new SchemaProperty[0]); + } + else + return sType.getDerivedProperties(); + } + + private void printExtensionImplMethods(SchemaType sType) throws IOException + { + SchemaTypeImpl sImpl = getImpl(sType); + if (sImpl == null) + return; + + InterfaceExtension[] exts = sImpl.getInterfaceExtensions(); + if (exts != null) for (int i = 0; i < exts.length; i++) + { + InterfaceExtension.MethodSignature[] methods = exts[i].getMethods(); + if (methods != null) + { + for (int j = 0; j < methods.length; j++) + { + printJavaDoc("Implementation method for interface " + exts[i].getStaticHandler()); + printInterfaceMethodDecl(methods[j]); + startBlock(); + printInterfaceMethodImpl(exts[i].getStaticHandler(), methods[j]); + endBlock(); + } + } + } + } + + void printInterfaceMethodDecl(InterfaceExtension.MethodSignature method) throws IOException + { + StringBuffer decl = new StringBuffer(60); + + decl.append("public ").append(method.getReturnType()); + decl.append(" ").append(method.getName()).append("("); + + String[] paramTypes = method.getParameterTypes(); + for (int i = 0; i < paramTypes.length; i++) + { + if (i != 0) + decl.append(", "); + decl.append(paramTypes[i]).append(" p").append(i); + } + + decl.append(")"); + + String[] exceptions = method.getExceptionTypes(); + for (int i = 0; i < exceptions.length; i++) + decl.append((i == 0 ? " throws " : ", ") + exceptions[i]); + + emit(decl.toString()); + } + + void printInterfaceMethodImpl(String handler, InterfaceExtension.MethodSignature method) throws IOException + { + StringBuffer impl = new StringBuffer(60); + + if (!method.getReturnType().equals("void")) + impl.append("return "); + + impl.append(handler).append(".").append(method.getName()).append("(this"); + + String[] params = method.getParameterTypes(); + for (int i = 0; i < params.length; i++) + impl.append(", p" + i); + + impl.append(");"); + + emit(impl.toString()); + } + + void printNestedTypeImpls(SchemaType sType, SchemaTypeSystem system) throws IOException + { + boolean redefinition = sType.getName() != null && + sType.getName().equals(sType.getBaseType().getName()); + while (sType != null) + { + SchemaType[] anonTypes = sType.getAnonymousTypes(); + for (int i = 0; i < anonTypes.length; i++) + { + if (anonTypes[i].isSkippedAnonymousType()) + printNestedTypeImpls(anonTypes[i], system); + else + printInnerTypeImpl(anonTypes[i], system, true); + } + // For redefinition by extension, go ahead and print the anonymous + // types in the base + if (!redefinition || + (sType.getDerivationType() != SchemaType.DT_EXTENSION && !sType.isSimpleType())) + break; + sType = sType.getBaseType(); + } + } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaTypeImpl.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaTypeImpl.java new file mode 100644 index 000000000..ec4a90d70 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaTypeImpl.java @@ -0,0 +1,2471 @@ +/* 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.QNameSet; +import org.apache.xmlbeans.QNameSetBuilder; +import org.apache.xmlbeans.SchemaAnnotation; +import org.apache.xmlbeans.SchemaAttributeModel; +import org.apache.xmlbeans.SchemaComponent; +import org.apache.xmlbeans.SchemaField; +import org.apache.xmlbeans.SchemaGlobalAttribute; +import org.apache.xmlbeans.SchemaGlobalElement; +import org.apache.xmlbeans.SchemaLocalAttribute; +import org.apache.xmlbeans.SchemaLocalElement; +import org.apache.xmlbeans.SchemaParticle; +import org.apache.xmlbeans.SchemaProperty; +import org.apache.xmlbeans.SchemaStringEnumEntry; +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.SchemaTypeElementSequencer; +import org.apache.xmlbeans.SchemaTypeLoader; +import org.apache.xmlbeans.SchemaTypeSystem; +import org.apache.xmlbeans.StringEnumAbstractBase; +import org.apache.xmlbeans.XmlAnySimpleType; +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.InterfaceExtension; +import org.apache.xmlbeans.PrePostExtension; +import org.apache.xmlbeans.impl.common.QNameHelper; +import org.apache.xmlbeans.impl.values.*; + +import javax.xml.namespace.QName; +import java.lang.reflect.Constructor; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +public final class SchemaTypeImpl implements SchemaType, TypeStoreUserFactory +{ + // global types have names + private QName _name; + + // annotation on the type + private SchemaAnnotation _annotation; + + // compilation support + private int _resolvePhase; + private static final int UNRESOLVED = 0; + private static final int RESOLVING_SGS = 1; // For document types only + private static final int RESOLVED_SGS = 2; // For document types only + private static final int RESOLVING = 3; + private static final int RESOLVED = 4; + private static final int JAVAIZING = 5; + private static final int JAVAIZED = 6; + + // anonymous type support + private SchemaType.Ref _outerSchemaTypeRef; + private volatile SchemaComponent.Ref _containerFieldRef; + private volatile SchemaField _containerField; + private volatile int _containerFieldCode; + private volatile int _containerFieldIndex; + private volatile QName[] _groupReferenceContext; + private SchemaType.Ref[] _anonymousTyperefs; + private boolean _isDocumentType; + private boolean _isAttributeType; + // private boolean _skippedAnonymousType; + + // compiletime java type support + private boolean _isCompiled; + private String _shortJavaName; + private String _fullJavaName; + private String _shortJavaImplName; + private String _fullJavaImplName; + private InterfaceExtension[] _interfaces; + private PrePostExtension _prepost; + + // runtime java type support: volatile because they're cached + private volatile Class _javaClass; + private volatile Class _javaEnumClass; + private volatile Class _javaImplClass; + private volatile Constructor _javaImplConstructor; + private volatile Constructor _javaImplConstructor2; + private volatile boolean _implNotAvailable; + private volatile Class _userTypeClass; + private volatile Class _userTypeHandlerClass; + + // user data objects not persisted + private volatile Object _userData; + + private final Object[] _ctrArgs = new Object[] { this }; + + // reflective support + private SchemaContainer _container; + private String _filename; + + // complex content support + private SchemaParticle _contentModel; + private volatile SchemaLocalElement[] _localElts; // lazily computed + private volatile Map _eltToIndexMap; // lazily computed + private volatile Map _attrToIndexMap; // lazily computed + private Map _propertyModelByElementName; + private Map _propertyModelByAttributeName; + private boolean _hasAllContent; + private boolean _orderSensitive; + private QNameSet _typedWildcardElements; + private QNameSet _typedWildcardAttributes; + private boolean _hasWildcardElements; + private boolean _hasWildcardAttributes; + // set of valid QNames that can be substituted for a property + private Set _validSubstitutions = Collections.EMPTY_SET; + + // simple content support + private int _complexTypeVariety; + private SchemaAttributeModel _attributeModel; + + // simple type support + private int _builtinTypeCode; + + private int _simpleTypeVariety; + private boolean _isSimpleType; + + private SchemaType.Ref _baseTyperef; // via restriction or extension + private int _baseDepth; // how many inheritance steps to AnyType + private int _derivationType; + + // user type support + private String _userTypeName; + private String _userTypeHandler; + + // for complex types with simple content + private SchemaType.Ref _contentBasedOnTyperef; + + // facets + private XmlValueRef[] _facetArray; + private boolean[] _fixedFacetArray; + + // fundamental facets + private int _ordered; + private boolean _isFinite; + private boolean _isBounded; + private boolean _isNumeric; + + private boolean _abs; + private boolean _finalExt; + private boolean _finalRest; + private boolean _finalList; + private boolean _finalUnion; + private boolean _blockExt; + private boolean _blockRest; + + // whitespace facet + private int _whiteSpaceRule; + + // regex patterns + private boolean _hasPatterns; // also takes into account base classes + private org.apache.xmlbeans.impl.regex.RegularExpression[] _patterns; + + // enumerated values + private XmlValueRef[] _enumerationValues; + private SchemaType.Ref _baseEnumTyperef; + private boolean _stringEnumEnsured; + private volatile Map _lookupStringEnum; + private volatile List _listOfStringEnum; + private volatile Map _lookupStringEnumEntry; + private SchemaStringEnumEntry[] _stringEnumEntries; + + // for lists only + private SchemaType.Ref _listItemTyperef; + + // for unions only + private boolean _isUnionOfLists; + private SchemaType.Ref[] _unionMemberTyperefs; + private int _anonymousUnionMemberOrdinal; + private volatile SchemaType[] _unionConstituentTypes; + private volatile SchemaType[] _unionSubTypes; + private volatile SchemaType _unionCommonBaseType; + + // for atomic types only + private SchemaType.Ref _primitiveTypeRef; + + // for decimal restrictions only + private int _decimalSize; + + // lazy loading support + private volatile boolean _unloaded; + + // for document types only - only valid during compilation + private QName _sg; + private List _sgMembers = new ArrayList(); + + public boolean isUnloaded() + { + return _unloaded; + } + + public void finishLoading() + { + _unloaded = false; + } + + + + SchemaTypeImpl(SchemaContainer container) + { + _container = container; + } + + SchemaTypeImpl(SchemaContainer container, boolean unloaded) + { + _container = container; + _unloaded = unloaded; + if (unloaded) + finishQuick(); + } + + public boolean isSGResolved() + { return _resolvePhase >= RESOLVED_SGS; } + + public boolean isSGResolving() + { return _resolvePhase >= RESOLVING_SGS; } + + public boolean isResolved() + { return _resolvePhase >= RESOLVED; } + + public boolean isResolving() + { return _resolvePhase == RESOLVING; } + + public boolean isUnjavaized() + { return _resolvePhase < JAVAIZED; } + + public boolean isJavaized() + { return _resolvePhase == JAVAIZED; } + + public void startResolvingSGs() + { + if (_resolvePhase != UNRESOLVED) + throw new IllegalStateException(); + _resolvePhase = RESOLVING_SGS; + } + + public void finishResolvingSGs() + { + if (_resolvePhase != RESOLVING_SGS) + throw new IllegalStateException(); + _resolvePhase = RESOLVED_SGS; + } + + public void startResolving() + { + if ( (_isDocumentType && _resolvePhase != RESOLVED_SGS) || + (!_isDocumentType && _resolvePhase != UNRESOLVED)) + throw new IllegalStateException(); + _resolvePhase = RESOLVING; + } + + public void finishResolving() + { + if (_resolvePhase != RESOLVING) + throw new IllegalStateException(); + _resolvePhase = RESOLVED; + } + + public void startJavaizing() + { + if (_resolvePhase != RESOLVED) + throw new IllegalStateException(); + _resolvePhase = JAVAIZING; + } + + public void finishJavaizing() + { + if (_resolvePhase != JAVAIZING) + throw new IllegalStateException(); + _resolvePhase = JAVAIZED; + } + + private void finishQuick() + { + _resolvePhase = JAVAIZED; + } + + private void assertUnresolved() + { + if (_resolvePhase != UNRESOLVED && !_unloaded) + throw new IllegalStateException(); + } + + private void assertSGResolving() + { + if (_resolvePhase != RESOLVING_SGS && !_unloaded) + throw new IllegalStateException(); + } + + private void assertSGResolved() + { + if (_resolvePhase != RESOLVED_SGS && !_unloaded) + throw new IllegalStateException(); + } + + private void assertResolving() + { + if (_resolvePhase != RESOLVING && !_unloaded) + throw new IllegalStateException(); + } + + private void assertResolved() + { + if (_resolvePhase != RESOLVED && !_unloaded) + throw new IllegalStateException(); + } + + private void assertJavaizing() + { + if (_resolvePhase != JAVAIZING && !_unloaded) + throw new IllegalStateException(); + } + + public QName getName() + { return _name; } + + public void setName(QName name) + { assertUnresolved(); _name = name; } + + public String getSourceName() + { + if (_filename != null) + return _filename; + if (getOuterType() != null) + return getOuterType().getSourceName(); + + SchemaField field = getContainerField(); + if (field != null) + { + if (field instanceof SchemaGlobalElement) + return ((SchemaGlobalElement)field).getSourceName(); + if (field instanceof SchemaGlobalAttribute) + return ((SchemaGlobalAttribute)field).getSourceName(); + } + return null; + } + + public void setFilename(String filename) + { assertUnresolved(); _filename = filename; } + + public int getComponentType() + { return SchemaComponent.TYPE; } + + public boolean isAnonymousType() + { return _name == null; } + + public boolean isDocumentType() + { return _isDocumentType; } + + public boolean isAttributeType() + { return _isAttributeType; } + + public QName getDocumentElementName() + { + if (_isDocumentType) + { + SchemaParticle sp = getContentModel(); + if (sp != null) + return sp.getName(); + } + + return null; + } + + public QName getAttributeTypeAttributeName() + { + if (_isAttributeType) + { + SchemaAttributeModel sam = getAttributeModel(); + if (sam != null) + { + SchemaLocalAttribute[] slaArray = sam.getAttributes(); + if (slaArray != null && slaArray.length > 0) + { + SchemaLocalAttribute sla = slaArray[0]; + return sla.getName(); + } + } + } + + return null; + } + + public void setAnnotation(SchemaAnnotation ann) + { assertUnresolved(); _annotation = ann; } + + public SchemaAnnotation getAnnotation() + { return _annotation; } + + public void setDocumentType(boolean isDocument) + { assertUnresolved(); _isDocumentType = isDocument; } + + public void setAttributeType(boolean isAttribute) + { assertUnresolved(); _isAttributeType = isAttribute; } + + public int getContentType() + { return _complexTypeVariety; } + + public void setComplexTypeVariety(int complexTypeVariety) + { assertResolving(); _complexTypeVariety = complexTypeVariety; } + + public SchemaTypeElementSequencer getElementSequencer() + { + if (_complexTypeVariety == NOT_COMPLEX_TYPE) + return new SequencerImpl(null); + + return new SequencerImpl(new SchemaTypeVisitorImpl(_contentModel)); + } + + /** Set the abstract and final flags for a complex type */ + void setAbstractFinal( + boolean abs, boolean finalExt, boolean finalRest, boolean finalList, boolean finalUnion) + { + assertResolving(); + _abs = abs; + _finalExt = finalExt; _finalRest = finalRest; + _finalList = finalList; _finalUnion = finalUnion; + } + + /** Set the final flags for a simple type */ + void setSimpleFinal(boolean finalRest, boolean finalList, boolean finalUnion) + { + assertResolving(); _finalRest = finalRest; _finalList = finalList ; _finalUnion = finalUnion; + } + + void setBlock(boolean blockExt, boolean blockRest) + { + assertResolving(); _blockExt = blockExt ; _blockRest = blockRest; + } + + public boolean blockRestriction() + { return _blockRest; } + + public boolean blockExtension() + { return _blockExt; } + + public boolean isAbstract() + { return _abs; } + + public boolean finalExtension() + { return _finalExt; } + + public boolean finalRestriction() + { return _finalRest; } + + public boolean finalList() + { return _finalList; } + + public boolean finalUnion() + { return _finalUnion; } + + public synchronized SchemaField getContainerField() + { + if (_containerFieldCode != -1) + { + SchemaType outer = getOuterType(); + if (_containerFieldCode == 0) + _containerField = _containerFieldRef == null ? null : (SchemaField)_containerFieldRef.getComponent(); + else if (_containerFieldCode == 1) + _containerField = outer.getAttributeModel().getAttributes()[_containerFieldIndex]; + else + _containerField = ((SchemaTypeImpl)outer).getLocalElementByIndex(_containerFieldIndex); + _containerFieldCode = -1; + } + return _containerField; + } + + public void setContainerField(SchemaField field) + { + assertUnresolved(); + _containerField = field; + _containerFieldCode = -1; + } + + public void setContainerFieldRef(SchemaComponent.Ref ref) + { + assertUnresolved(); + _containerFieldRef = ref; + _containerFieldCode = 0; + } + + public void setContainerFieldIndex(short code, int index) + { + assertUnresolved(); + _containerFieldCode = code; + _containerFieldIndex = index; + } + + /* package */ void setGroupReferenceContext(QName[] groupNames) + { + assertUnresolved(); + _groupReferenceContext = groupNames; + } + + /* package */ QName[] getGroupReferenceContext() + { return _groupReferenceContext; } + + public SchemaType getOuterType() + { return _outerSchemaTypeRef == null ? null : _outerSchemaTypeRef.get(); } + + public void setOuterSchemaTypeRef(SchemaType.Ref typeref) + { assertUnresolved(); _outerSchemaTypeRef = typeref; } + + public boolean isCompiled() + { return _isCompiled; } + + public void setCompiled(boolean f) + { assertJavaizing(); _isCompiled = f; } + + public boolean isSkippedAnonymousType() + { + SchemaType outerType = getOuterType(); + return ((outerType == null) ? false : + (outerType.getBaseType() == this || + outerType.getContentBasedOnType() == this)); + } + + public String getShortJavaName() + { return _shortJavaName; } + + public void setShortJavaName(String name) + { + assertResolved(); + _shortJavaName = name; + SchemaType outer = _outerSchemaTypeRef.get(); + while (outer.getFullJavaName() == null) + outer = outer.getOuterType(); + + _fullJavaName = outer.getFullJavaName() + "$" + _shortJavaName; + } + + public String getFullJavaName() + { return _fullJavaName; } + + public void setFullJavaName(String name) + { + assertResolved(); + _fullJavaName = name; + int index = Math.max(_fullJavaName.lastIndexOf('$'), + _fullJavaName.lastIndexOf('.')) + 1; + _shortJavaName = _fullJavaName.substring(index); + } + + public void setShortJavaImplName(String name) + { + assertResolved(); + _shortJavaImplName = name; + SchemaType outer = _outerSchemaTypeRef.get(); + while (outer.getFullJavaImplName() == null) + outer = outer.getOuterType(); + + _fullJavaImplName = outer.getFullJavaImplName() + "$" + _shortJavaImplName; + } + + public void setFullJavaImplName(String name) + { + assertResolved(); + _fullJavaImplName = name; + int index = Math.max(_fullJavaImplName.lastIndexOf('$'), + _fullJavaImplName.lastIndexOf('.')) + 1; + _shortJavaImplName = _fullJavaImplName.substring(index); + } + + public String getFullJavaImplName() { return _fullJavaImplName;} + public String getShortJavaImplName() { return _shortJavaImplName;} + + public String getUserTypeName() + { + return _userTypeName; + } + + public void setUserTypeName(String userTypeName) + { + _userTypeName = userTypeName; + } + + public String getUserTypeHandlerName() + { + return _userTypeHandler; + } + + public void setUserTypeHandlerName(String typeHandler) + { + _userTypeHandler = typeHandler; + } + + public void setInterfaceExtensions(InterfaceExtension[] interfaces) + { + assertResolved(); + _interfaces = interfaces; + } + + public InterfaceExtension[] getInterfaceExtensions() + { + return _interfaces; + } + + public void setPrePostExtension(PrePostExtension prepost) + { + assertResolved(); + _prepost = prepost; + } + + public PrePostExtension getPrePostExtension() + { + return _prepost; + } + + public Object getUserData() + { return _userData; } + + public void setUserData(Object data) + { _userData = data; } + + /* Only used for asserts */ + SchemaContainer getContainer() + { return _container; } + + void setContainer(SchemaContainer container) + { _container = container; } + + public SchemaTypeSystem getTypeSystem() + { return _container.getTypeSystem(); } + + public SchemaParticle getContentModel() + { return _contentModel; } + + private static void buildEltList(List eltList, SchemaParticle contentModel) + { + if (contentModel == null) + return; + + switch (contentModel.getParticleType()) + { + case SchemaParticle.ELEMENT: + eltList.add(contentModel); + return; + case SchemaParticle.ALL: + case SchemaParticle.CHOICE: + case SchemaParticle.SEQUENCE: + for (int i = 0; i < contentModel.countOfParticleChild(); i++) + buildEltList(eltList, contentModel.getParticleChild(i)); + return; + default: + return; + } + } + + private void buildLocalElts() + { + List eltList = new ArrayList(); + buildEltList(eltList, _contentModel); + _localElts = (SchemaLocalElement[])eltList.toArray(new SchemaLocalElement[eltList.size()]); + } + + public SchemaLocalElement getLocalElementByIndex(int i) + { + SchemaLocalElement[] elts = _localElts; + if (elts == null) + { + buildLocalElts(); + elts = _localElts; + } + return elts[i]; + } + + public int getIndexForLocalElement(SchemaLocalElement elt) + { + Map localEltMap = _eltToIndexMap; + if (localEltMap == null) + { + if (_localElts == null) + buildLocalElts(); + localEltMap = new HashMap(); + for (int i = 0; i < _localElts.length; i++) + { + localEltMap.put(_localElts[i], new Integer(i)); + } + _eltToIndexMap = localEltMap; + } + return ((Integer)localEltMap.get(elt)).intValue(); + } + + public int getIndexForLocalAttribute(SchemaLocalAttribute attr) + { + Map localAttrMap = _attrToIndexMap; + if (localAttrMap == null) + { + localAttrMap = new HashMap(); + SchemaLocalAttribute[] attrs = this._attributeModel.getAttributes(); + for (int i = 0; i < attrs.length; i++) + { + localAttrMap.put(attrs[i], new Integer(i)); + } + _attrToIndexMap = localAttrMap; + } + return ((Integer)localAttrMap.get(attr)).intValue(); + } + + public SchemaAttributeModel getAttributeModel() + { return _attributeModel; } + + public SchemaProperty[] getProperties() + { + if (_propertyModelByElementName == null) + return getAttributeProperties(); + + if (_propertyModelByAttributeName == null) + return getElementProperties(); + + List list = new ArrayList(); + list.addAll(_propertyModelByElementName.values()); + list.addAll(_propertyModelByAttributeName.values()); + return (SchemaProperty[])list.toArray(new SchemaProperty[list.size()]); + } + + private static final SchemaProperty[] NO_PROPERTIES = new SchemaProperty[0]; + + public SchemaProperty[] getDerivedProperties() + { + SchemaType baseType = getBaseType(); + if (baseType == null) + return getProperties(); + + List results = new ArrayList(); + + if (_propertyModelByElementName != null) + results.addAll(_propertyModelByElementName.values()); + + if (_propertyModelByAttributeName != null) + results.addAll(_propertyModelByAttributeName.values()); + + for (Iterator it = results.iterator() ; it.hasNext() ; ) + { + SchemaProperty prop = (SchemaProperty)it.next(); + SchemaProperty baseProp = prop.isAttribute() ? + baseType.getAttributeProperty(prop.getName()) : + baseType.getElementProperty(prop.getName()); + + + // Remove the derived property from the results if it is + // A) present in the base type and + // B) all the details are the same (cardinality, nillability, default) + + if (baseProp != null) + { + if ( eq(prop.getMinOccurs(), baseProp.getMinOccurs()) && + eq(prop.getMaxOccurs(), baseProp.getMaxOccurs()) && + prop.hasNillable() == baseProp.hasNillable() && + eq(prop.getDefaultText(), baseProp.getDefaultText())) + { + it.remove(); + } + + } + + } + + return (SchemaProperty[])results.toArray(new SchemaProperty[results.size()]); + } + + private static boolean eq(BigInteger a, BigInteger b) + { + if (a == null && b == null) + return true; + if (a== null || b == null) + return false; + return a.equals(b); + } + + private static boolean eq(String a, String b) + { + if (a == null && b == null) + return true; + if (a== null || b == null) + return false; + return a.equals(b); + } + + public SchemaProperty[] getElementProperties() + { + if (_propertyModelByElementName == null) + return NO_PROPERTIES; + + return (SchemaProperty[]) + _propertyModelByElementName.values().toArray(new SchemaProperty[_propertyModelByElementName.size()]); + } + + public SchemaProperty[] getAttributeProperties() + { + if (_propertyModelByAttributeName == null) + return NO_PROPERTIES; + + return (SchemaProperty[]) + _propertyModelByAttributeName.values().toArray(new SchemaProperty[_propertyModelByAttributeName.size()]); + } + + public SchemaProperty getElementProperty(QName eltName) + { return _propertyModelByElementName == null ? null : (SchemaProperty)_propertyModelByElementName.get(eltName); } + + public SchemaProperty getAttributeProperty(QName attrName) + { return _propertyModelByAttributeName == null ? null : (SchemaProperty)_propertyModelByAttributeName.get(attrName); } + + public boolean hasAllContent() + { return _hasAllContent; } + + public boolean isOrderSensitive() + { return _orderSensitive; } + + public void setOrderSensitive(boolean sensitive) + { assertJavaizing(); _orderSensitive = sensitive; } + + public void setContentModel( + SchemaParticle contentModel, + SchemaAttributeModel attrModel, + Map propertyModelByElementName, + Map propertyModelByAttributeName, + boolean isAll) + { + assertResolving(); + _contentModel = contentModel; + _attributeModel = attrModel; + _propertyModelByElementName = propertyModelByElementName; + _propertyModelByAttributeName = propertyModelByAttributeName; + _hasAllContent = isAll; + + + // Add entries for each element property for substitution group members + if (_propertyModelByElementName != null) + { + _validSubstitutions = new LinkedHashSet(); + Collection eltProps = _propertyModelByElementName.values(); + for (Iterator it = eltProps.iterator() ; it.hasNext() ; ) + { + SchemaProperty prop = (SchemaProperty)it.next(); + QName[] names = prop.acceptedNames(); + for (int i = 0 ; i < names.length ; i++) + { + if (! _propertyModelByElementName.containsKey(names[i])) + _validSubstitutions.add(names[i]); + } + } + } + } + + private boolean containsElements() + { + return getContentType() == ELEMENT_CONTENT || + getContentType() == MIXED_CONTENT; + } + + public boolean hasAttributeWildcards() + { + return _hasWildcardAttributes; + } + + public boolean hasElementWildcards() + { + return _hasWildcardElements; + } + + public boolean isValidSubstitution(QName name) + { + return _validSubstitutions.contains(name); + } + + public SchemaType getElementType(QName eltName, QName xsiType, SchemaTypeLoader wildcardTypeLoader) + { + if (isSimpleType() || !containsElements() || isNoType()) + return BuiltinSchemaTypeSystem.ST_NO_TYPE; + + SchemaType type = null; + SchemaProperty prop = (SchemaProperty)_propertyModelByElementName.get(eltName); + if (prop != null) + { + type = prop.getType(); + } + else + { + if (wildcardTypeLoader == null) + return BuiltinSchemaTypeSystem.ST_NO_TYPE; + + if (_typedWildcardElements.contains(eltName) || + _validSubstitutions.contains(eltName)) + { + SchemaGlobalElement elt = wildcardTypeLoader.findElement(eltName); + if (elt == null) + return BuiltinSchemaTypeSystem.ST_NO_TYPE; + // According to http://www.w3.org/TR/xmlschema-1/#key-lva, + // the line above should return ST_ANY_TYPE. + type = elt.getType(); + } + else + { + // Substitution groups + // Actually, better not enable this yet + /*SchemaGlobalElement elt = wildcardTypeLoader.findElement(eltName); + SchemaGlobalElement sghead = elt == null ? null : elt.substitutionGroup(); + while (sghead != null) + { + prop = (SchemaProperty)_propertyModelByElementName.get(sghead.getName()); + if (prop != null) + { + type = elt.getType(); + break; + } + sghead = sghead.substitutionGroup(); + } + */ + if (type == null) + return BuiltinSchemaTypeSystem.ST_NO_TYPE; + } + } + + if (xsiType != null && wildcardTypeLoader != null) + { + SchemaType itype = wildcardTypeLoader.findType(xsiType); + + // NOTE: a previous version of XMLBeans used ST_NO_TYPE if the + // xsiType was not derived from 'type', but this results in a + // ClassCastException. Instead we ignore xsi:type if it's not + // found or a derived type. + if (itype != null && type.isAssignableFrom(itype)) { + return itype; + } + } + + return type; + } + + public SchemaType getAttributeType(QName attrName, SchemaTypeLoader wildcardTypeLoader) + { + if (isSimpleType() || isNoType()) + return BuiltinSchemaTypeSystem.ST_NO_TYPE; + + if (isURType()) + return BuiltinSchemaTypeSystem.ST_ANY_SIMPLE; + + SchemaProperty prop = (SchemaProperty)_propertyModelByAttributeName.get(attrName); + if (prop != null) + return prop.getType(); + + if (!_typedWildcardAttributes.contains(attrName) || wildcardTypeLoader == null) + return BuiltinSchemaTypeSystem.ST_NO_TYPE; + // For symmetry with the element case (as well as with URType), perhaps + // the above line should be returning ST_ANY_SIMPLE + + SchemaGlobalAttribute attr = wildcardTypeLoader.findAttribute(attrName); + if (attr == null) + return BuiltinSchemaTypeSystem.ST_NO_TYPE; + return attr.getType(); + } + + /* These two methods, createElementType and getElementType have to stay + * synchronized, because they create an XmlObject and return the type + * for that object, respectively. But since they do slightly different + * things, they can't be refactored to share code, so exercise caution + */ + public XmlObject createElementType(QName eltName, QName xsiType, SchemaTypeLoader wildcardTypeLoader) + { + SchemaType type = null; + SchemaProperty prop = null; + if (isSimpleType() || !containsElements() || isNoType()) + { + type = BuiltinSchemaTypeSystem.ST_NO_TYPE; + } + else + { + prop = (SchemaProperty)_propertyModelByElementName.get(eltName); + if (prop != null) + { + type = prop.getType(); + } + else if (_typedWildcardElements.contains(eltName) || + _validSubstitutions.contains(eltName)) + { + SchemaGlobalElement elt = wildcardTypeLoader.findElement(eltName); + if (elt != null) + { + type = elt.getType(); + SchemaType docType = wildcardTypeLoader.findDocumentType(eltName); + if (docType != null) + prop = docType.getElementProperty(eltName); + } + else + type = BuiltinSchemaTypeSystem.ST_NO_TYPE; + } + else + { + // Check if the requested element isn't by any chance part of a + // substitution group headed by one of the declared elements + // Better not enable this yet + /* + SchemaGlobalElement elt = wildcardTypeLoader.findElement(eltName); + SchemaGlobalElement sghead = elt == null ? null : elt.substitutionGroup(); + while (sghead != null) + { + if (_propertyModelByElementName.containsKey(sghead.getName())) + { + type = elt.getType(); + SchemaType docType = wildcardTypeLoader.findDocumentType(elt.getName()); + if (docType != null) + prop = docType.getElementProperty(elt.getName()); + break; + } + sghead = sghead.substitutionGroup(); + } + */ + if (type == null) + type = BuiltinSchemaTypeSystem.ST_NO_TYPE; + } + + if (xsiType != null) + { + SchemaType itype = wildcardTypeLoader.findType(xsiType); + + // NOTE: a previous version of XMLBeans used ST_NO_TYPE if the + // xsiType was not derived from 'type', but this results in a + // ClassCastException. Instead we ignore xsi:type if it's not + // found or a derived type. + if (itype != null && type.isAssignableFrom(itype)) { + type = itype; + } + } + } + + if (type != null) + return ((SchemaTypeImpl)type).createUnattachedNode(prop); + return null; + } + + public XmlObject createAttributeType(QName attrName, SchemaTypeLoader wildcardTypeLoader) + { + SchemaTypeImpl type = null; + SchemaProperty prop = null; + if (isSimpleType() || isNoType()) + { + type = BuiltinSchemaTypeSystem.ST_NO_TYPE; + } + else if (isURType()) + { + type = BuiltinSchemaTypeSystem.ST_ANY_SIMPLE; + } + else + { + prop = (SchemaProperty)_propertyModelByAttributeName.get(attrName); + if (prop != null) + { + type = (SchemaTypeImpl)prop.getType(); + } + else if (!_typedWildcardAttributes.contains(attrName)) + { + type = BuiltinSchemaTypeSystem.ST_NO_TYPE; + } + else + { + SchemaGlobalAttribute attr = wildcardTypeLoader.findAttribute(attrName); + if (attr != null) + type = (SchemaTypeImpl)attr.getType(); + else + type = BuiltinSchemaTypeSystem.ST_NO_TYPE; + } + } + + if (type != null) + return type.createUnattachedNode(prop); + + return null; + } + + public void setWildcardSummary(QNameSet elementSet, boolean haswcElt, QNameSet attributeSet, boolean haswcAtt) + { + assertResolving(); _typedWildcardElements = elementSet; _hasWildcardElements = haswcElt; _typedWildcardAttributes = attributeSet; _hasWildcardAttributes = haswcAtt; + } + + public SchemaType[] getAnonymousTypes() + { + SchemaType[] result = new SchemaType[_anonymousTyperefs.length]; + for (int i = 0; i < result.length; i++) + result[i] = _anonymousTyperefs[i].get(); + return result; + } + + public void setAnonymousTypeRefs(SchemaType.Ref[] anonymousTyperefs) + { + _anonymousTyperefs = anonymousTyperefs; + } + + + private static SchemaType[] staCopy(SchemaType[] a) + { + if (a == null) + return null; + + SchemaType[] result = new SchemaType[a.length]; + System.arraycopy(a, 0, result, 0, a.length); + return result; + } + + private static boolean[] boaCopy(boolean[] a) + { + if (a == null) + return null; + + boolean[] result = new boolean[a.length]; + System.arraycopy(a, 0, result, 0, a.length); + return result; + } + + + + public void setSimpleTypeVariety(int variety) + { assertResolving(); _simpleTypeVariety = variety; } + + public int getSimpleVariety() + { return _simpleTypeVariety; } + + public boolean isURType() + { return _builtinTypeCode == BTC_ANY_TYPE || _builtinTypeCode == BTC_ANY_SIMPLE; } + + public boolean isNoType() + { return this == BuiltinSchemaTypeSystem.ST_NO_TYPE; } + + public boolean isSimpleType() + { return _isSimpleType; } + + public void setSimpleType(boolean f) + { assertUnresolved(); _isSimpleType = f; } + + public boolean isUnionOfLists() + { return _isUnionOfLists; } + + public void setUnionOfLists(boolean f) + { assertResolving(); _isUnionOfLists = f; } + + public SchemaType getPrimitiveType() + { return _primitiveTypeRef == null ? null : _primitiveTypeRef.get(); } + + public void setPrimitiveTypeRef(SchemaType.Ref typeref) + { assertResolving(); _primitiveTypeRef = typeref; } + + public int getDecimalSize() + { return _decimalSize; } + + public void setDecimalSize(int bits) + { assertResolving(); _decimalSize = bits; } + + public SchemaType getBaseType() + { return _baseTyperef == null ? null : _baseTyperef.get(); } + + public void setBaseTypeRef(SchemaType.Ref typeref) + { assertResolving(); _baseTyperef = typeref; } + + public int getBaseDepth() + { return _baseDepth; } + + public void setBaseDepth(int depth) + { assertResolving(); _baseDepth = depth; } + + public SchemaType getContentBasedOnType() + { return _contentBasedOnTyperef == null ? null : _contentBasedOnTyperef.get(); } + + public void setContentBasedOnTypeRef(SchemaType.Ref typeref) + { assertResolving(); _contentBasedOnTyperef = typeref; } + + public int getDerivationType() + { return _derivationType; } + + public void setDerivationType(int type) + { assertResolving(); _derivationType = type; } + + public SchemaType getListItemType() + { return _listItemTyperef == null ? null : _listItemTyperef.get(); } + + public void setListItemTypeRef(SchemaType.Ref typeref) + { assertResolving(); _listItemTyperef = typeref; } + + public SchemaType[] getUnionMemberTypes() + { + SchemaType[] result = new SchemaType[_unionMemberTyperefs ==null ? 0 : _unionMemberTyperefs.length]; + for (int i = 0; i < result.length; i++) + result[i] = _unionMemberTyperefs[i].get(); + return result; + } + + public void setUnionMemberTypeRefs(SchemaType.Ref[] typerefs) + { assertResolving(); _unionMemberTyperefs = typerefs; } + + public int getAnonymousUnionMemberOrdinal() + { return _anonymousUnionMemberOrdinal; } + + public void setAnonymousUnionMemberOrdinal(int i) + { assertUnresolved(); _anonymousUnionMemberOrdinal = i; } + + public synchronized SchemaType[] getUnionConstituentTypes() + { + if (_unionCommonBaseType == null) + computeFlatUnionModel(); + return staCopy(_unionConstituentTypes); + } + + private void setUnionConstituentTypes(SchemaType[] types) + { _unionConstituentTypes = types; } + + public synchronized SchemaType[] getUnionSubTypes() + { + if (_unionCommonBaseType == null) + computeFlatUnionModel(); + return staCopy(_unionSubTypes); + } + + private void setUnionSubTypes(SchemaType[] types) + { _unionSubTypes = types; } + + public synchronized SchemaType getUnionCommonBaseType() + { + if (_unionCommonBaseType == null) + computeFlatUnionModel(); + return _unionCommonBaseType; + } + + private void setUnionCommonBaseType(SchemaType type) + { _unionCommonBaseType = type; } + + private void computeFlatUnionModel() + { + if (getSimpleVariety() != SchemaType.UNION) + throw new IllegalStateException("Operation is only supported on union types"); + Set constituentMemberTypes = new LinkedHashSet(); + Set allSubTypes = new LinkedHashSet(); + SchemaType commonBaseType = null; + + allSubTypes.add(this); + + for (int i = 0; i < _unionMemberTyperefs.length; i++) + { + SchemaTypeImpl mImpl = (SchemaTypeImpl)_unionMemberTyperefs[i].get(); + + switch (mImpl.getSimpleVariety()) + { + case SchemaType.LIST: + constituentMemberTypes.add(mImpl); + allSubTypes.add(mImpl); + commonBaseType = mImpl.getCommonBaseType(commonBaseType); + break; + case SchemaType.UNION: + constituentMemberTypes.addAll(Arrays.asList(mImpl.getUnionConstituentTypes())); + allSubTypes.addAll(Arrays.asList(mImpl.getUnionSubTypes())); + SchemaType otherCommonBaseType = mImpl.getUnionCommonBaseType(); + if (otherCommonBaseType != null) + commonBaseType = otherCommonBaseType.getCommonBaseType(commonBaseType); + break; + case SchemaType.ATOMIC: + constituentMemberTypes.add(mImpl); + allSubTypes.add(mImpl); + commonBaseType = mImpl.getCommonBaseType(commonBaseType); + break; + default: + assert(false); + } + } + + setUnionConstituentTypes((SchemaType[]) + constituentMemberTypes.toArray(StscState.EMPTY_ST_ARRAY)); + setUnionSubTypes((SchemaType[]) + allSubTypes.toArray(StscState.EMPTY_ST_ARRAY)); + setUnionCommonBaseType(commonBaseType); + } + + public QName getSubstitutionGroup() + { return _sg; } + + public void setSubstitutionGroup(QName sg) + { assertSGResolving(); _sg = sg; } + + public void addSubstitutionGroupMember(QName member) + { assertSGResolved(); _sgMembers.add(member); } + + public QName[] getSubstitutionGroupMembers() + { + QName[] result = new QName[_sgMembers.size()]; + return (QName[])_sgMembers.toArray(result); + } + + public int getWhiteSpaceRule() + { return _whiteSpaceRule; } + + public void setWhiteSpaceRule(int ws) + { assertResolving(); _whiteSpaceRule = ws; } + + public XmlAnySimpleType getFacet(int facetCode) + { + if (_facetArray == null) + return null; + XmlValueRef ref = _facetArray[facetCode]; + if (ref == null) + return null; + return ref.get(); + } + + public boolean isFacetFixed(int facetCode) + { + return _fixedFacetArray[facetCode]; + } + + public XmlAnySimpleType[] getBasicFacets() + { + XmlAnySimpleType[] result = new XmlAnySimpleType[SchemaType.LAST_FACET + 1]; + for (int i = 0; i <= SchemaType.LAST_FACET; i++) + { + result[i] = getFacet(i); + } + return result; + } + + public boolean[] getFixedFacets() + { + return boaCopy(_fixedFacetArray); + } + + public void setBasicFacets(XmlValueRef[] values, boolean[] fixed) + { + assertResolving(); + _facetArray = values; + _fixedFacetArray = fixed; + } + + public int ordered() + { return _ordered; } + + public void setOrdered(int ordering) + { assertResolving(); _ordered = ordering; } + + public boolean isBounded() + { return _isBounded; } + + public void setBounded(boolean f) + { assertResolving(); _isBounded = f; } + + public boolean isFinite() + { return _isFinite; } + + public void setFinite(boolean f) + { assertResolving(); _isFinite = f; } + + public boolean isNumeric() + { return _isNumeric; } + + public void setNumeric(boolean f) + { assertResolving(); _isNumeric = f; } + + + public boolean hasPatternFacet() + { return _hasPatterns; } + + public void setPatternFacet(boolean hasPatterns) + { assertResolving(); _hasPatterns = hasPatterns; } + + public boolean matchPatternFacet(String s) + { + if (!_hasPatterns) + return true; + + if (_patterns != null && _patterns.length > 0) + { + int i; + for (i = 0; i < _patterns.length; i++) + { + if (_patterns[i].matches(s)) + break; + } + if (i >= _patterns.length) + return false; + } + + return getBaseType().matchPatternFacet(s); + } + + public String[] getPatterns() + { + if (_patterns == null) + return new String[0]; + String[] patterns = new String[_patterns.length]; + for (int i=0; i< _patterns.length; i++) + patterns[i] = _patterns[i].getPattern(); + return patterns; + } + + public org.apache.xmlbeans.impl.regex.RegularExpression[] getPatternExpressions() + { + if (_patterns == null) + return new org.apache.xmlbeans.impl.regex.RegularExpression[0]; + org.apache.xmlbeans.impl.regex.RegularExpression[] result = new org.apache.xmlbeans.impl.regex.RegularExpression[_patterns.length]; + System.arraycopy(_patterns, 0, result, 0, _patterns.length); + return result; + } + + public void setPatterns(org.apache.xmlbeans.impl.regex.RegularExpression[] list) + { assertResolving(); _patterns = list; } + + public XmlAnySimpleType[] getEnumerationValues() + { + if (_enumerationValues == null) + return null; + XmlAnySimpleType[] result = new XmlAnySimpleType[_enumerationValues.length]; + for (int i = 0; i < result.length; i++) + { + XmlValueRef ref = _enumerationValues[i]; + result[i] = (ref == null ? null : ref.get()); + + } + return result; + } + + public void setEnumerationValues(XmlValueRef[] a) + { assertResolving(); _enumerationValues = a; } + + public StringEnumAbstractBase enumForString(String s) + { + ensureStringEnumInfo(); + if (_lookupStringEnum == null) + return null; + return (StringEnumAbstractBase)_lookupStringEnum.get(s); + } + + public StringEnumAbstractBase enumForInt(int i) + { + ensureStringEnumInfo(); + if (_listOfStringEnum == null || i < 0 || i >= _listOfStringEnum.size()) + return null; + return (StringEnumAbstractBase)_listOfStringEnum.get(i); + } + + public SchemaStringEnumEntry enumEntryForString(String s) + { + ensureStringEnumInfo(); + if (_lookupStringEnumEntry == null) + return null; + return (SchemaStringEnumEntry)_lookupStringEnumEntry.get(s); + } + + public SchemaType getBaseEnumType() + { + return _baseEnumTyperef == null ? null : _baseEnumTyperef.get(); + } + + public void setBaseEnumTypeRef(SchemaType.Ref baseEnumTyperef) + { + _baseEnumTyperef = baseEnumTyperef; + } + + public SchemaStringEnumEntry[] getStringEnumEntries() + { + if (_stringEnumEntries == null) + return null; + SchemaStringEnumEntry[] result = new SchemaStringEnumEntry[_stringEnumEntries.length]; + System.arraycopy(_stringEnumEntries, 0, result, 0, result.length); + return result; + } + + public void setStringEnumEntries(SchemaStringEnumEntry sEnums[]) + { + assertJavaizing(); + _stringEnumEntries = sEnums; + } + + private void ensureStringEnumInfo() + { + if (_stringEnumEnsured) + return; + + SchemaStringEnumEntry[] sEnums = _stringEnumEntries; + if (sEnums == null) + { + _stringEnumEnsured = true; + return; + } + + Map lookupStringEnum = new HashMap(sEnums.length); + List listOfStringEnum = new ArrayList(sEnums.length + 1); + Map lookupStringEnumEntry = new HashMap(sEnums.length); + + for (int i = 0; i < sEnums.length; i++) + { + lookupStringEnumEntry.put(sEnums[i].getString(), sEnums[i]); + } + + Class jc = _baseEnumTyperef.get().getEnumJavaClass(); + if (jc != null) + { + try + { + StringEnumAbstractBase.Table table = (StringEnumAbstractBase.Table)jc.getField("table").get(null); + for (int i = 0; i < sEnums.length; i++) + { + int j = sEnums[i].getIntValue(); + StringEnumAbstractBase enumVal = table.forInt(j); + lookupStringEnum.put(sEnums[i].getString(), enumVal); + while (listOfStringEnum.size() <= j) + listOfStringEnum.add(null); + listOfStringEnum.set(j, enumVal); + } + } + catch (Exception e) + { + System.err.println("Something wrong: could not locate enum table for " + jc); + jc = null; + lookupStringEnum.clear(); + listOfStringEnum.clear(); + } + } + + if (jc == null) + { + for (int i = 0; i < sEnums.length; i++) + { + int j = sEnums[i].getIntValue(); + String s = sEnums[i].getString(); + StringEnumAbstractBase enumVal = new StringEnumValue(s, j); + lookupStringEnum.put(s, enumVal); + while (listOfStringEnum.size() <= j) + listOfStringEnum.add(null); + listOfStringEnum.set(j, enumVal); + } + } + + synchronized (this) + { + if (!_stringEnumEnsured) + { + _lookupStringEnum = lookupStringEnum; + _listOfStringEnum = listOfStringEnum; + _lookupStringEnumEntry = lookupStringEnumEntry; + } + } + // HACKHACK: two syncrhonized blocks force a memory barrier: + // BUGBUG: this behavior is likely to change in future VMs + synchronized (this) + { + _stringEnumEnsured = true; + } + } + + public boolean hasStringEnumValues() + { + return _stringEnumEntries != null; + } + + public void copyEnumerationValues(SchemaTypeImpl baseImpl) + { + assertResolving(); + _enumerationValues = baseImpl._enumerationValues; + _baseEnumTyperef = baseImpl._baseEnumTyperef; + } + + public int getBuiltinTypeCode() + { return _builtinTypeCode; } // special: set up pre-init + + public void setBuiltinTypeCode(int builtinTypeCode) + { assertResolving(); _builtinTypeCode = builtinTypeCode; } + + synchronized void assignJavaElementSetterModel() + { + // To compute the element setter model, we need to compute the + // delimiting elements for each element. + + SchemaProperty[] eltProps = getElementProperties(); + SchemaParticle contentModel = getContentModel(); + Map state = new HashMap(); + QNameSet allContents = computeAllContainedElements(contentModel, state); + + for (int i = 0; i < eltProps.length; i++) + { + SchemaPropertyImpl sImpl = (SchemaPropertyImpl)eltProps[i]; + QNameSet nde = computeNondelimitingElements(sImpl.getName(), contentModel, state); + QNameSetBuilder builder = new QNameSetBuilder(allContents); + builder.removeAll(nde); + sImpl.setJavaSetterDelimiter(builder.toQNameSet()); + } + } + + /** + * Used to compute setter model. + * + * Returns the QNameSet of all elements that can possibly come before an + * element whose name is given by the target in a valid instance of the + * contentModel. When appending an element, it comes before the first + * one that is not in this set. + */ + private static QNameSet computeNondelimitingElements(QName target, SchemaParticle contentModel, Map state) + { + QNameSet allContents = computeAllContainedElements(contentModel, state); + if (!allContents.contains(target)) + return QNameSet.EMPTY; + + // If iterated, then all contents are delimiting. + if (contentModel.getMaxOccurs() == null || + contentModel.getMaxOccurs().compareTo(BigInteger.ONE) > 0) + return allContents; + + QNameSetBuilder builder; + + switch (contentModel.getParticleType()) + { + case SchemaParticle.ALL: + case SchemaParticle.ELEMENT: + default: + return allContents; + + case SchemaParticle.WILDCARD: + return QNameSet.singleton(target); + + case SchemaParticle.CHOICE: + builder = new QNameSetBuilder(); + for (int i = 0; i < contentModel.countOfParticleChild(); i++) + { + QNameSet childContents = computeAllContainedElements(contentModel.getParticleChild(i), state); + if (childContents.contains(target)) + builder.addAll(computeNondelimitingElements(target, contentModel.getParticleChild(i), state)); + } + return builder.toQNameSet(); + + case SchemaParticle.SEQUENCE: + builder = new QNameSetBuilder(); + boolean seenTarget = false; + for (int i = contentModel.countOfParticleChild(); i > 0; ) + { + i--; + QNameSet childContents = computeAllContainedElements(contentModel.getParticleChild(i), state); + if (seenTarget) + { + builder.addAll(childContents); + } + else if (childContents.contains(target)) + { + builder.addAll(computeNondelimitingElements(target, contentModel.getParticleChild(i), state)); + seenTarget = true; + } + } + return builder.toQNameSet(); + } + } + + /** + * Used to compute the setter model. + * + * Returns the set of all QNames of elements that could possibly be + * contained in the given contentModel. The state variable is used + * to record the results, so that if they are needed again later, + * they do not need to be recomputed. + */ + private static QNameSet computeAllContainedElements(SchemaParticle contentModel, Map state) + { + // Remember previously computed results to avoid complexity explosion + QNameSet result = (QNameSet)state.get(contentModel); + if (result != null) + return result; + + QNameSetBuilder builder; + + switch (contentModel.getParticleType()) + { + case SchemaParticle.ALL: + case SchemaParticle.CHOICE: + case SchemaParticle.SEQUENCE: + default: + builder = new QNameSetBuilder(); + for (int i = 0; i < contentModel.countOfParticleChild(); i++) + { + builder.addAll(computeAllContainedElements(contentModel.getParticleChild(i), state)); + } + result = builder.toQNameSet(); + break; + + case SchemaParticle.WILDCARD: + result = contentModel.getWildcardSet(); + break; + + case SchemaParticle.ELEMENT: + // Fix for XMLBEANS-228 + result = ((SchemaLocalElementImpl) contentModel).acceptedStartNames(); + break; + } + state.put(contentModel, result); + return result; + } + + public Class getJavaClass() + { + // This field is declared volatile and Class is immutable so this is allowed. + if (_javaClass == null && getFullJavaName() != null) + { + try + { _javaClass = Class.forName(getFullJavaName(), false, getTypeSystem().getClassLoader()); } + catch (ClassNotFoundException e) + { +// This is a legitimate use, when users get a SchemaTypeSystem without compiling classes +// System.err.println("Could not find class name " + getFullJavaName()); +// System.err.println("Searched in classloader " + getTypeSystem().getClassLoader()); +// e.printStackTrace(System.err); + _javaClass = null; + } + } + + return _javaClass; + } + + public Class getJavaImplClass() { + if (_implNotAvailable) + return null; + + if (_javaImplClass == null) + { + try { + if (getFullJavaImplName() != null) + _javaImplClass = Class.forName(getFullJavaImplName(), false, getTypeSystem().getClassLoader()); + else + _implNotAvailable = true; + } + catch (ClassNotFoundException e) { + _implNotAvailable = true; + } + } + + return _javaImplClass; + } + + public Class getUserTypeClass() + { + // This field is declared volatile and Class is immutable so this is allowed. + if (_userTypeClass == null && getUserTypeName() != null) + { + try + { + _userTypeClass = Class.forName(_userTypeName, false, + getTypeSystem().getClassLoader()); + } + catch (ClassNotFoundException e) + { + _userTypeClass = null; + } + } + + return _userTypeClass; + } + + public Class getUserTypeHandlerClass() + { + // This field is declared volatile and Class is immutable so this is allowed. + if (_userTypeHandlerClass == null && getUserTypeHandlerName() != null) + { + try + { + _userTypeHandlerClass = Class.forName(_userTypeHandler, false, + getTypeSystem().getClassLoader()); + } + catch (ClassNotFoundException e) + { + _userTypeHandlerClass = null; + } + } + + return _userTypeHandlerClass; + } + + public Constructor getJavaImplConstructor() + { + if (_javaImplConstructor == null && !_implNotAvailable) + { + final Class impl = getJavaImplClass(); + if (impl == null) return null; + try + { + _javaImplConstructor = impl.getConstructor(new Class[] { SchemaType.class }); + } + catch (NoSuchMethodException e) + { + e.printStackTrace(); + } + } + + return _javaImplConstructor; + + } + + public Constructor getJavaImplConstructor2() + { + if (_javaImplConstructor2 == null && !_implNotAvailable) + { + final Class impl = getJavaImplClass(); + if (impl == null) return null; + try + { + _javaImplConstructor2 = impl.getDeclaredConstructor(new Class[] { SchemaType.class, boolean.class }); + } + catch (NoSuchMethodException e) + { + e.printStackTrace(); + } + } + + return _javaImplConstructor2; + + } + + public Class getEnumJavaClass() + { + // This field is declared volatile and Class is immutable so this is allowed. + if (_javaEnumClass == null) + { + if ( getBaseEnumType() != null ) + { + try + { + _javaEnumClass = Class.forName(getBaseEnumType().getFullJavaName() + "$Enum", false, getTypeSystem().getClassLoader()); + } + catch (ClassNotFoundException e) + { + _javaEnumClass = null; + } + } + } + + return _javaEnumClass; + } + + public void setJavaClass(Class javaClass) + { + assertResolved(); + _javaClass = javaClass; + setFullJavaName(javaClass.getName()); + } + + public boolean isPrimitiveType() + { + return (getBuiltinTypeCode() >= BTC_FIRST_PRIMITIVE && + getBuiltinTypeCode() <= BTC_LAST_PRIMITIVE); + } + + public boolean isBuiltinType() + { + return getBuiltinTypeCode() != 0; + } + + public XmlObject createUnwrappedNode() + { + // Todo: attach a new xml store! + XmlObject result = createUnattachedNode(null); + return result; + } + + /** + * TypeStoreUserFactory implementation + */ + public TypeStoreUser createTypeStoreUser() + { + return (TypeStoreUser)createUnattachedNode(null); + } + + + public XmlAnySimpleType newValidatingValue(Object obj) + { + return newValue(obj, true); + } + /** + * Creates an immutable simple value. + */ + public XmlAnySimpleType newValue(Object obj) + { + return newValue(obj, false); + } + + public XmlAnySimpleType newValue(Object obj, boolean validateOnSet) + { + if (!isSimpleType() && getContentType() != SchemaType.SIMPLE_CONTENT) + throw new XmlValueOutOfRangeException(); // values must be simple + + XmlObjectBase result = (XmlObjectBase)createUnattachedNode(null); + if (validateOnSet) + result.setValidateOnSet(); + + // In the case of tree copy, need to call a specla setter to avoid + // set(XmlObject) + if (obj instanceof XmlObject) + result.set_newValue((XmlObject)obj); + else + result.objectSet(obj); + + result.check_dated(); + result.setImmutable(); + + return (XmlAnySimpleType) result; + } + + /** + * Creates an instance of this type. + */ + private XmlObject createUnattachedNode(SchemaProperty prop) + { + XmlObject result = null; + + if (!isBuiltinType() && !isNoType()) + { + // System.out.println("Attempting to load impl class: " + getFullJavaImplName()); + Constructor ctr = getJavaImplConstructor(); + if (ctr != null) + { + try + { + // System.out.println("Succeeded!"); + return (XmlObject)ctr.newInstance(_ctrArgs); + } + catch (Exception e) + { + System.out.println("Exception trying to instantiate impl class."); + e.printStackTrace(); + } + } + } + else + { + result = createBuiltinInstance(); + } + + // if no result, we must be a restriction of some compiled type + for (SchemaType sType = this; result == null; sType = sType.getBaseType()) + result = ((SchemaTypeImpl)sType).createUnattachedSubclass(this); + + ((XmlObjectBase)result).init_flags(prop); + return result; + } + + private XmlObject createUnattachedSubclass(SchemaType sType) + { + if (!isBuiltinType() && !isNoType()) + { + // System.out.println("Attempting to load impl class: " + getFullJavaImplName()); + Constructor ctr = getJavaImplConstructor2(); + if (ctr != null) + { + boolean accessible = ctr.isAccessible(); + try + { + ctr.setAccessible(true); + // System.out.println("Succeeded!"); + try + { + return (XmlObject)ctr.newInstance(new Object[] { sType, sType.isSimpleType() ? Boolean.FALSE : Boolean.TRUE }); + } + catch (Exception e) + { + System.out.println("Exception trying to instantiate impl class."); + e.printStackTrace(); + } + finally + { + // Make a best-effort try to set the accessibility back to what it was + try + { ctr.setAccessible(accessible); } + catch (SecurityException se) + { } + } + } + catch (Exception e) + { + System.out.println("Exception trying to instantiate impl class."); + e.printStackTrace(); + } + } + return null; + } + else + { + return createBuiltinSubclass(sType); + } + } + + private XmlObject createBuiltinInstance() + { + switch (getBuiltinTypeCode()) + { + case BTC_NOT_BUILTIN: + return new XmlAnyTypeImpl(BuiltinSchemaTypeSystem.ST_NO_TYPE); + case BTC_ANY_TYPE: + return new XmlAnyTypeImpl(); + case BTC_ANY_SIMPLE: + return new XmlAnySimpleTypeImpl(); + case BTC_BOOLEAN: + return new XmlBooleanImpl(); + case BTC_BASE_64_BINARY: + return new XmlBase64BinaryImpl(); + case BTC_HEX_BINARY: + return new XmlHexBinaryImpl(); + case BTC_ANY_URI: + return new XmlAnyUriImpl(); + case BTC_QNAME: + return new XmlQNameImpl(); + case BTC_NOTATION: + return new XmlNotationImpl(); + case BTC_FLOAT: + return new XmlFloatImpl(); + case BTC_DOUBLE: + return new XmlDoubleImpl(); + case BTC_DECIMAL: + return new XmlDecimalImpl(); + case BTC_STRING: + return new XmlStringImpl(); + case BTC_DURATION: + return new XmlDurationImpl(); + case BTC_DATE_TIME: + return new XmlDateTimeImpl(); + case BTC_TIME: + return new XmlTimeImpl(); + case BTC_DATE: + return new XmlDateImpl(); + case BTC_G_YEAR_MONTH: + return new XmlGYearMonthImpl(); + case BTC_G_YEAR: + return new XmlGYearImpl(); + case BTC_G_MONTH_DAY: + return new XmlGMonthDayImpl(); + case BTC_G_DAY: + return new XmlGDayImpl(); + case BTC_G_MONTH: + return new XmlGMonthImpl(); + case BTC_INTEGER: + return new XmlIntegerImpl(); + case BTC_LONG: + return new XmlLongImpl(); + case BTC_INT: + return new XmlIntImpl(); + case BTC_SHORT: + return new XmlShortImpl(); + case BTC_BYTE: + return new XmlByteImpl(); + case BTC_NON_POSITIVE_INTEGER: + return new XmlNonPositiveIntegerImpl(); + case BTC_NEGATIVE_INTEGER: + return new XmlNegativeIntegerImpl(); + case BTC_NON_NEGATIVE_INTEGER: + return new XmlNonNegativeIntegerImpl(); + case BTC_POSITIVE_INTEGER: + return new XmlPositiveIntegerImpl(); + case BTC_UNSIGNED_LONG: + return new XmlUnsignedLongImpl(); + case BTC_UNSIGNED_INT: + return new XmlUnsignedIntImpl(); + case BTC_UNSIGNED_SHORT: + return new XmlUnsignedShortImpl(); + case BTC_UNSIGNED_BYTE: + return new XmlUnsignedByteImpl(); + case BTC_NORMALIZED_STRING: + return new XmlNormalizedStringImpl(); + case BTC_TOKEN: + return new XmlTokenImpl(); + case BTC_NAME: + return new XmlNameImpl(); + case BTC_NCNAME: + return new XmlNCNameImpl(); + case BTC_LANGUAGE: + return new XmlLanguageImpl(); + case BTC_ID: + return new XmlIdImpl(); + case BTC_IDREF: + return new XmlIdRefImpl(); + case BTC_IDREFS: + return new XmlIdRefsImpl(); + case BTC_ENTITY: + return new XmlEntityImpl(); + case BTC_ENTITIES: + return new XmlEntitiesImpl(); + case BTC_NMTOKEN: + return new XmlNmTokenImpl(); + case BTC_NMTOKENS: + return new XmlNmTokensImpl(); + default: + throw new IllegalStateException("Unrecognized builtin type: " + getBuiltinTypeCode()); + } + } + + private XmlObject createBuiltinSubclass(SchemaType sType) + { + boolean complex = !sType.isSimpleType(); + switch (getBuiltinTypeCode()) + { + case BTC_NOT_BUILTIN: + return new XmlAnyTypeImpl(BuiltinSchemaTypeSystem.ST_NO_TYPE); + case BTC_ANY_TYPE: + case BTC_ANY_SIMPLE: + switch (sType.getSimpleVariety()) + { + case NOT_SIMPLE: + return new XmlComplexContentImpl(sType); + case ATOMIC: + return new XmlAnySimpleTypeRestriction(sType, complex); + case LIST: + return new XmlListImpl(sType, complex); + case UNION: + return new XmlUnionImpl(sType, complex); + default: + throw new IllegalStateException(); + } + case BTC_BOOLEAN: + return new XmlBooleanRestriction(sType, complex); + case BTC_BASE_64_BINARY: + return new XmlBase64BinaryRestriction(sType, complex); + case BTC_HEX_BINARY: + return new XmlHexBinaryRestriction(sType, complex); + case BTC_ANY_URI: + return new XmlAnyUriRestriction(sType, complex); + case BTC_QNAME: + return new XmlQNameRestriction(sType, complex); + case BTC_NOTATION: + return new XmlNotationRestriction(sType, complex); + case BTC_FLOAT: + return new XmlFloatRestriction(sType, complex); + case BTC_DOUBLE: + return new XmlDoubleRestriction(sType, complex); + case BTC_DECIMAL: + return new XmlDecimalRestriction(sType, complex); + case BTC_STRING: + if (sType.hasStringEnumValues()) + return new XmlStringEnumeration(sType, complex); + else + return new XmlStringRestriction(sType, complex); + case BTC_DURATION: + return new XmlDurationImpl(sType, complex); + case BTC_DATE_TIME: + return new XmlDateTimeImpl(sType, complex); + case BTC_TIME: + return new XmlTimeImpl(sType, complex); + case BTC_DATE: + return new XmlDateImpl(sType, complex); + case BTC_G_YEAR_MONTH: + return new XmlGYearMonthImpl(sType, complex); + case BTC_G_YEAR: + return new XmlGYearImpl(sType, complex); + case BTC_G_MONTH_DAY: + return new XmlGMonthDayImpl(sType, complex); + case BTC_G_DAY: + return new XmlGDayImpl(sType, complex); + case BTC_G_MONTH: + return new XmlGMonthImpl(sType, complex); + case BTC_INTEGER: + return new XmlIntegerRestriction(sType, complex); + case BTC_LONG: + return new XmlLongRestriction(sType, complex); + case BTC_INT: + return new XmlIntRestriction(sType, complex); + case BTC_SHORT: + return new XmlShortImpl(sType, complex); + case BTC_BYTE: + return new XmlByteImpl(sType, complex); + case BTC_NON_POSITIVE_INTEGER: + return new XmlNonPositiveIntegerImpl(sType, complex); + case BTC_NEGATIVE_INTEGER: + return new XmlNegativeIntegerImpl(sType, complex); + case BTC_NON_NEGATIVE_INTEGER: + return new XmlNonNegativeIntegerImpl(sType, complex); + case BTC_POSITIVE_INTEGER: + return new XmlPositiveIntegerImpl(sType, complex); + case BTC_UNSIGNED_LONG: + return new XmlUnsignedLongImpl(sType, complex); + case BTC_UNSIGNED_INT: + return new XmlUnsignedIntImpl(sType, complex); + case BTC_UNSIGNED_SHORT: + return new XmlUnsignedShortImpl(sType, complex); + case BTC_UNSIGNED_BYTE: + return new XmlUnsignedByteImpl(sType, complex); + case BTC_NORMALIZED_STRING: + return new XmlNormalizedStringImpl(sType, complex); + case BTC_TOKEN: + return new XmlTokenImpl(sType, complex); + case BTC_NAME: + return new XmlNameImpl(sType, complex); + case BTC_NCNAME: + return new XmlNCNameImpl(sType, complex); + case BTC_LANGUAGE: + return new XmlLanguageImpl(sType, complex); + case BTC_ID: + return new XmlIdImpl(sType, complex); + case BTC_IDREF: + return new XmlIdRefImpl(sType, complex); + case BTC_IDREFS: + return new XmlIdRefsImpl(sType, complex); + case BTC_ENTITY: + return new XmlEntityImpl(sType, complex); + case BTC_ENTITIES: + return new XmlEntitiesImpl(sType, complex); + case BTC_NMTOKEN: + return new XmlNmTokenImpl(sType, complex); + case BTC_NMTOKENS: + return new XmlNmTokensImpl(sType, complex); + default: + throw new IllegalStateException("Unrecognized builtin type: " + getBuiltinTypeCode()); + } + } + + public SchemaType getCommonBaseType(SchemaType type) + { + // null type is treated as the no-type + if (this == BuiltinSchemaTypeSystem.ST_ANY_TYPE || type == null || type.isNoType()) + return this; + + // any type is the universal base type; noType is the universal derived type + if (type == BuiltinSchemaTypeSystem.ST_ANY_TYPE || isNoType()) + return type; + + // the regular case: + SchemaTypeImpl sImpl1 = (SchemaTypeImpl)type; + while (sImpl1.getBaseDepth() > getBaseDepth()) + sImpl1 = (SchemaTypeImpl)sImpl1.getBaseType(); + SchemaTypeImpl sImpl2 = this; + while (sImpl2.getBaseDepth() > sImpl1.getBaseDepth()) + sImpl2 = (SchemaTypeImpl)sImpl2.getBaseType(); + for (;;) + { + if (sImpl1.equals(sImpl2)) + break; + sImpl1 = (SchemaTypeImpl)sImpl1.getBaseType(); + sImpl2 = (SchemaTypeImpl)sImpl2.getBaseType(); + assert(sImpl1 != null && sImpl2 != null); // must meet at anyType + } + return sImpl1; + } + + public boolean isAssignableFrom(SchemaType type) + { + if (type == null || type.isNoType()) + return true; + + if (isNoType()) + return false; + + if (getSimpleVariety() == UNION) + { + SchemaType[] members = getUnionMemberTypes(); + for (int i = 0; i < members.length; i++) + if (members[i].isAssignableFrom(type)) + return true; + } + + int depth = ((SchemaTypeImpl)type).getBaseDepth() - getBaseDepth(); + if (depth < 0) + return false; + while (depth > 0) + { + type = type.getBaseType(); + depth -= 1; + } + return (type.equals(this)); + } + + + public String toString() + { + if (getName() != null) + return "T=" + QNameHelper.pretty(getName()); + + if (isDocumentType()) + return "D=" + QNameHelper.pretty(getDocumentElementName()); + + if (isAttributeType()) + return "R=" + QNameHelper.pretty(getAttributeTypeAttributeName()); + + String prefix; + + if (getContainerField() != null) + { + prefix = (getContainerField().getName().getNamespaceURI().length() > 0 ? + (getContainerField().isAttribute() ? "Q=" : "E=") : + (getContainerField().isAttribute() ? "A=" : "U=")) + + getContainerField().getName().getLocalPart(); + if (getOuterType() == null) + return prefix + "@" + getContainerField().getName().getNamespaceURI(); + } + else if (isNoType()) + return "N="; + else if (getOuterType() == null) + return "noouter"; + else if (getOuterType().getBaseType() == this) + prefix = "B="; + else if (getOuterType().getContentBasedOnType() == this) + prefix = "S="; + else if (getOuterType().getSimpleVariety() == SchemaType.LIST) + prefix = "I="; + else if (getOuterType().getSimpleVariety() == SchemaType.UNION) + prefix = "M=" + getAnonymousUnionMemberOrdinal(); + else + prefix = "strange="; + + return prefix + "|" + getOuterType().toString(); + } + + private XmlObject _parseObject; + private String _parseTNS; + private String _elemFormDefault; + private String _attFormDefault; + private boolean _chameleon; + private boolean _redefinition; + + public void setParseContext(XmlObject parseObject, String targetNamespace, boolean chameleon, String elemFormDefault, String attFormDefault, boolean redefinition) + { + _parseObject = parseObject; + _parseTNS = targetNamespace; + _chameleon = chameleon; + _elemFormDefault = elemFormDefault; + _attFormDefault = attFormDefault; + _redefinition = redefinition; + } + + public XmlObject getParseObject() + { return _parseObject; } + + public String getTargetNamespace() + { return _parseTNS; } + + public boolean isChameleon ( ) + { return _chameleon; } + + public String getElemFormDefault() + { return _elemFormDefault; } + + public String getAttFormDefault() + { return _attFormDefault; } + + public String getChameleonNamespace() + { return _chameleon ? _parseTNS : null; } + + public boolean isRedefinition() + { return _redefinition; } + + private SchemaType.Ref _selfref = new SchemaType.Ref(this); + + public SchemaType.Ref getRef() + { return _selfref; } + + public SchemaComponent.Ref getComponentRef() + { return getRef(); } + + /** + * Gives access to the internals of element validation + */ + private static class SequencerImpl implements SchemaTypeElementSequencer + { + private SchemaTypeVisitorImpl _visitor; + + private SequencerImpl(SchemaTypeVisitorImpl visitor) + { + _visitor = visitor; + } + + public boolean next(QName elementName) + { + if (_visitor == null) + return false; + + return _visitor.visit(elementName); + } + + public boolean peek(QName elementName) + { + if (_visitor == null) + return false; + + return _visitor.testValid(elementName); + } + } + + /** + * Returns a QNameSet of elements that may exist in wildcard + * buchets and are not explicitly defined in this schema type. + * Note: In this example: + * + * + * + * + * + * + * the returned QNameSet will not contain the qname of 'someElement'. + * @return the constructed QNameSet + */ + public QNameSet qnameSetForWildcardElements() + { + SchemaParticle model = this.getContentModel(); + QNameSetBuilder wildcardSet = new QNameSetBuilder(); + computeWildcardSet(model, wildcardSet); + + QNameSetBuilder qnsb = new QNameSetBuilder( wildcardSet ); + SchemaProperty[] props = this.getElementProperties(); + + for (int i = 0; i < props.length; i++) + { + SchemaProperty prop = props[i]; + qnsb.remove(prop.getName()); + } + + return qnsb.toQNameSet(); + } + + private static void computeWildcardSet(SchemaParticle model, QNameSetBuilder result) + { + if (model.getParticleType() == SchemaParticle.WILDCARD) + { + QNameSet cws = model.getWildcardSet(); + result.addAll(cws); + return; + } + for (int i = 0; i < model.countOfParticleChild(); i++) + { + SchemaParticle child = model.getParticleChild(i); + computeWildcardSet(child, result); + } + } + + /** + * Returns a QNameSet of attributes that may exist in wildcard + * buchets and are not explicitly defined in this schema type. + * Note: In this example: + * + * ... + * + * + * + * the returned QNameSet will not contain the qname of 'someAttribute'. + * @return the constructed QNameSet + */ + public QNameSet qnameSetForWildcardAttributes() + { + SchemaAttributeModel model = this.getAttributeModel(); + QNameSet wildcardSet = model.getWildcardSet(); + + if (wildcardSet==null) + return QNameSet.EMPTY; + + QNameSetBuilder qnsb = new QNameSetBuilder( wildcardSet ); + + SchemaProperty[] props = this.getAttributeProperties(); + + for (int i = 0; i < props.length; i++) + { + SchemaProperty prop = props[i]; + qnsb.remove(prop.getName()); + } + + return qnsb.toQNameSet(); + } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaTypeLoaderBase.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaTypeLoaderBase.java new file mode 100644 index 000000000..d0c2b46bd --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaTypeLoaderBase.java @@ -0,0 +1,609 @@ +/* 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.impl.common.QNameHelper; +import org.apache.xmlbeans.impl.validator.ValidatingXMLInputStream; + +import org.apache.xmlbeans.impl.store.Locale; + +import org.apache.xmlbeans.SchemaAttributeGroup; +import org.apache.xmlbeans.SchemaField; +import org.apache.xmlbeans.SchemaGlobalAttribute; +import org.apache.xmlbeans.SchemaGlobalElement; +import org.apache.xmlbeans.SchemaModelGroup; +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.SchemaTypeLoader; +import org.apache.xmlbeans.XmlSaxHandler; +import org.apache.xmlbeans.XmlException; +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.XmlOptions; +import org.apache.xmlbeans.XmlFactoryHook; +import org.apache.xmlbeans.XmlBeans; + +import java.lang.reflect.Method; +import java.lang.reflect.InvocationTargetException; +import java.io.InputStream; +import java.io.Reader; +import java.io.File; +import java.io.IOException; +import java.io.FileInputStream; +import java.util.List; +import java.util.ArrayList; +import java.net.URL; +import java.net.URLConnection; +import java.net.HttpURLConnection; +import java.security.DigestInputStream; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamReader; + +import org.w3c.dom.Node; +import org.w3c.dom.DOMImplementation; + +import org.apache.xmlbeans.xml.stream.XMLInputStream; +import org.apache.xmlbeans.xml.stream.XMLStreamException; + +public abstract class SchemaTypeLoaderBase implements SchemaTypeLoader +{ + private static final String USER_AGENT = "XMLBeans/" + XmlBeans.getVersion() + " (" + XmlBeans.getTitle() + ")"; + + private static final Method _pathCompiler = getMethod( "org.apache.xmlbeans.impl.store.Path", "compilePath", new Class[] { String.class, XmlOptions.class } ); + private static final Method _queryCompiler = getMethod( "org.apache.xmlbeans.impl.store.Query", "compileQuery", new Class[] { String.class, XmlOptions.class } ); + + private static Method getMethod ( String className, String methodName, Class[] args ) + { + try + { + return + Class.forName( className ). + getDeclaredMethod( methodName, args ); + } + catch (Exception e) + { + throw new IllegalStateException( + "Cannot find " + className + "." + methodName + + ". verify that xmlstore " + + "(from xbean.jar) is on classpath" ); + } + } + + private static Object invokeMethod ( Method method, Object[] args ) + { + try + { + return method.invoke( method, args ); + } + catch ( InvocationTargetException e ) + { + Throwable t = e.getCause(); + IllegalStateException ise = new IllegalStateException( t.getMessage() ); + ise.initCause( t ); // need initCause() to support Java1.4 + throw ise; + } + catch ( Exception e ) + { + IllegalStateException ise = new IllegalStateException( e.getMessage() ); + ise.initCause( e ); + throw ise; + } + } + + private static String doCompilePath ( String pathExpr, XmlOptions options ) + { + return (String) invokeMethod( _pathCompiler, new Object[] { pathExpr, options } ); + } + + private static String doCompileQuery ( String queryExpr, XmlOptions options ) + { + return (String) invokeMethod( _queryCompiler, new Object[] { queryExpr, options } ); + } + + public SchemaType findType(QName name) + { + SchemaType.Ref ref = findTypeRef(name); + if (ref == null) + return null; + SchemaType result = ref.get(); + assert(result != null); + return result; + } + + public SchemaType findDocumentType(QName name) + { + SchemaType.Ref ref = findDocumentTypeRef(name); + if (ref == null) + return null; + SchemaType result = ref.get(); + assert(result != null); + return result; + } + + public SchemaType findAttributeType(QName name) + { + SchemaType.Ref ref = findAttributeTypeRef(name); + if (ref == null) + return null; + SchemaType result = ref.get(); + assert(result != null); + return result; + } + + public SchemaModelGroup findModelGroup(QName name) + { + SchemaModelGroup.Ref ref = findModelGroupRef(name); + if (ref == null) + return null; + SchemaModelGroup result = ref.get(); + assert(result != null); + return result; + } + + public SchemaAttributeGroup findAttributeGroup(QName name) + { + SchemaAttributeGroup.Ref ref = findAttributeGroupRef(name); + if (ref == null) + return null; + SchemaAttributeGroup result = ref.get(); + assert(result != null); + return result; + } + + public SchemaGlobalElement findElement(QName name) + { + SchemaGlobalElement.Ref ref = findElementRef(name); + if (ref == null) + return null; + SchemaGlobalElement result = ref.get(); + assert(result != null); + return result; + } + + public SchemaGlobalAttribute findAttribute(QName name) + { + SchemaGlobalAttribute.Ref ref = findAttributeRef(name); + if (ref == null) + return null; + SchemaGlobalAttribute result = ref.get(); + assert(result != null); + return result; + } + + // + // + // + + public XmlObject newInstance ( SchemaType type, XmlOptions options ) + { + XmlFactoryHook hook = XmlFactoryHook.ThreadContext.getHook(); + + if (hook != null) + return hook.newInstance( this, type, options ); + + return Locale.newInstance( this, type, options ); + } + + public XmlObject parse ( String xmlText, SchemaType type, XmlOptions options ) throws XmlException + { + XmlFactoryHook hook = XmlFactoryHook.ThreadContext.getHook(); + + if (hook != null) + return hook.parse( this, xmlText, type, options ); + + return Locale.parseToXmlObject( this, xmlText, type, options ); + } + + /** + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public XmlObject parse ( XMLInputStream xis, SchemaType type, XmlOptions options ) throws XmlException, XMLStreamException + { + XmlFactoryHook hook = XmlFactoryHook.ThreadContext.getHook(); + + if (hook != null) + return hook.parse( this, xis, type, options ); + + return Locale.parseToXmlObject( this, xis, type, options ); + } + + public XmlObject parse ( XMLStreamReader xsr, SchemaType type, XmlOptions options ) throws XmlException + { + XmlFactoryHook hook = XmlFactoryHook.ThreadContext.getHook(); + + if (hook != null) + return hook.parse( this, xsr, type, options ); + + return Locale.parseToXmlObject( this, xsr, type, options ); + } + + public XmlObject parse ( File file, SchemaType type, XmlOptions options ) throws XmlException, IOException + { + if (options == null) + { + options = new XmlOptions(); + options.put( XmlOptions.DOCUMENT_SOURCE_NAME, file.toURI().normalize().toString() ); + } + + else if (! options.hasOption(XmlOptions.DOCUMENT_SOURCE_NAME)) + { + options = new XmlOptions( options ); + options.put( XmlOptions.DOCUMENT_SOURCE_NAME, file.toURI().normalize().toString() ); + } + + InputStream fis = new FileInputStream( file ); + + try + { + return parse( fis, type, options ); + } + finally + { + fis.close(); + } + } + + public XmlObject parse ( URL url, SchemaType type, XmlOptions options ) throws XmlException, IOException + { + if (options == null) + { + options = new XmlOptions(); + options.put( XmlOptions.DOCUMENT_SOURCE_NAME, url.toString() ); + } + + else if (! options.hasOption(XmlOptions.DOCUMENT_SOURCE_NAME)) + { + options = new XmlOptions( options ); + options.put( XmlOptions.DOCUMENT_SOURCE_NAME, url.toString() ); + } + + URLConnection conn = null; + InputStream stream = null; + download: try + { + + boolean redirected = false; + int count = 0; + + do { + conn = url.openConnection(); + conn.addRequestProperty("User-Agent", USER_AGENT); + conn.addRequestProperty("Accept", "application/xml, text/xml, */*"); + if (conn instanceof HttpURLConnection) + { + HttpURLConnection httpcon = (HttpURLConnection)conn; + int code = httpcon.getResponseCode(); + redirected = (code == HttpURLConnection.HTTP_MOVED_PERM || code == HttpURLConnection.HTTP_MOVED_TEMP); + if (redirected && count > 5) + redirected = false; + + if (redirected) + { + String newLocation = httpcon.getHeaderField("Location"); + if (newLocation == null) + redirected = false; + else + { + url = new URL(newLocation); + count ++; + } + } + } + } while (redirected); + + stream = conn.getInputStream(); + return parse( stream, type, options ); + } + finally + { + if (stream != null) + stream.close(); + } + } + + public XmlObject parse ( InputStream jiois, SchemaType type, XmlOptions options ) throws XmlException, IOException + { + XmlFactoryHook hook = XmlFactoryHook.ThreadContext.getHook(); + + DigestInputStream digestStream = null; + + setupDigest: + if (options != null && options.hasOption( XmlOptions.LOAD_MESSAGE_DIGEST )) + { + MessageDigest sha; + + try + { + sha = MessageDigest.getInstance("SHA"); + } + catch (NoSuchAlgorithmException e) + { + break setupDigest; + } + + digestStream = new DigestInputStream( jiois, sha ); + jiois = digestStream; + } + + if (hook != null) + return hook.parse( this, jiois, type, options ); + + XmlObject result = Locale.parseToXmlObject( this, jiois, type, options ); + + if (digestStream != null) + result.documentProperties().setMessageDigest( digestStream.getMessageDigest().digest() ); + + return result; + } + + public XmlObject parse ( Reader jior, SchemaType type, XmlOptions options ) throws XmlException, IOException + { + XmlFactoryHook hook = XmlFactoryHook.ThreadContext.getHook(); + + if (hook != null) + return hook.parse( this, jior, type, options ); + + return Locale.parseToXmlObject( this, jior, type, options ); + } + + public XmlObject parse ( Node node, SchemaType type, XmlOptions options ) throws XmlException + { + XmlFactoryHook hook = XmlFactoryHook.ThreadContext.getHook(); + + if (hook != null) + return hook.parse( this, node, type, options ); + + return Locale.parseToXmlObject( this, node, type, options ); + } + + public XmlSaxHandler newXmlSaxHandler ( SchemaType type, XmlOptions options ) + { + XmlFactoryHook hook = XmlFactoryHook.ThreadContext.getHook(); + + if (hook != null) + return hook.newXmlSaxHandler( this, type, options ); + + return Locale.newSaxHandler( this, type, options ); + } + + public DOMImplementation newDomImplementation ( XmlOptions options ) + { + return Locale.newDomImplementation( this, options ); + } + + /** + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public XMLInputStream newValidatingXMLInputStream ( XMLInputStream xis, SchemaType type, XmlOptions options ) throws XmlException, XMLStreamException + { + return new ValidatingXMLInputStream( xis, this, type, options ); + } + + // + // + // + + public String compilePath ( String pathExpr ) + { + return compilePath( pathExpr, null ); + } + + public String compilePath ( String pathExpr, XmlOptions options ) + { + return doCompilePath( pathExpr, options ); + } + + public String compileQuery ( String queryExpr ) + { + return compileQuery( queryExpr, null ); + } + + public String compileQuery ( String queryExpr, XmlOptions options ) + { + return doCompileQuery( queryExpr, options ); + } + + /** + * Utility function to load a type from a signature. + * + * A signature is the string you get from type.toString(). + */ + public SchemaType typeForSignature(String signature) + { + int end = signature.indexOf('@'); + String uri; + + if (end < 0) + { + uri = ""; + end = signature.length(); + } + else + { + uri = signature.substring(end + 1); + } + + List parts = new ArrayList(); + + for (int index = 0; index < end; ) + { + int nextc = signature.indexOf(':', index); + int nextd = signature.indexOf('|', index); + int next = (nextc < 0 ? nextd : nextd < 0 ? nextc : nextc < nextd ? nextc : nextd); + if (next < 0 || next > end) + next = end; + String part = signature.substring(index, next); + parts.add(part); + index = next + 1; + } + + SchemaType curType = null; + + outer: for (int i = parts.size() - 1; i >= 0; i -= 1) + { + String part = (String)parts.get(i); + if (part.length() < 1) + throw new IllegalArgumentException(); + int offset = (part.length() >= 2 && part.charAt(1) == '=') ? 2 : 1; + cases: switch (part.charAt(0)) + { + case 'T': + if (curType != null) + throw new IllegalArgumentException(); + curType = findType(QNameHelper.forLNS(part.substring(offset), uri)); + if (curType == null) + return null; + break; + + case 'D': + if (curType != null) + throw new IllegalArgumentException(); + curType = findDocumentType(QNameHelper.forLNS(part.substring(offset), uri)); + if (curType == null) + return null; + break; + + case 'C': // deprecated + case 'R': // current + if (curType != null) + throw new IllegalArgumentException(); + curType = findAttributeType(QNameHelper.forLNS(part.substring(offset), uri)); + if (curType == null) + return null; + break; + + case 'E': + case 'U': // distinguish qualified/unqualified TBD + if (curType != null) + { + if (curType.getContentType() < SchemaType.ELEMENT_CONTENT) + return null; + SchemaType[] subTypes = curType.getAnonymousTypes(); + String localName = part.substring(offset); + for (int j = 0; j < subTypes.length; j++) + { + SchemaField field = subTypes[j].getContainerField(); + if (field != null && !field.isAttribute() && field.getName().getLocalPart().equals(localName)) + { + curType = subTypes[j]; + break cases; + } + } + return null; + } + else + { + SchemaGlobalElement elt = findElement(QNameHelper.forLNS(part.substring(offset), uri)); + if (elt == null) + return null; + curType = elt.getType(); + } + break; + + case 'A': + case 'Q': // distinguish qualified/unqualified TBD + if (curType != null) + { + if (curType.isSimpleType()) + return null; + SchemaType[] subTypes = curType.getAnonymousTypes(); + String localName = part.substring(offset); + for (int j = 0; j < subTypes.length; j++) + { + SchemaField field = subTypes[j].getContainerField(); + if (field != null && field.isAttribute() && field.getName().getLocalPart().equals(localName)) + { + curType = subTypes[j]; + break cases; + } + } + return null; + } + else + { + SchemaGlobalAttribute attr = findAttribute(QNameHelper.forLNS(part.substring(offset), uri)); + if (attr == null) + return null; + curType = attr.getType(); + } + break; + + case 'B': + if (curType == null) + { + throw new IllegalArgumentException(); + } + else + { + if (curType.getSimpleVariety() != SchemaType.ATOMIC) + return null; + SchemaType[] subTypes = curType.getAnonymousTypes(); + if (subTypes.length != 1) + return null; + curType = subTypes[0]; + } + break; + + case 'I': + if (curType == null) + { + throw new IllegalArgumentException(); + } + else + { + if (curType.getSimpleVariety() != SchemaType.LIST) + return null; + SchemaType[] subTypes = curType.getAnonymousTypes(); + if (subTypes.length != 1) + return null; + curType = subTypes[0]; + } + break; + + case 'M': + if (curType == null) + { + throw new IllegalArgumentException(); + } + else + { + int index; + try + { + index = Integer.parseInt(part.substring(offset)); + } + catch (Exception e) + { + throw new IllegalArgumentException(); + } + + if (curType.getSimpleVariety() != SchemaType.UNION) + return null; + SchemaType[] subTypes = curType.getAnonymousTypes(); + if (subTypes.length <= index) + return null; + curType = subTypes[index]; + } + break; + + default: + throw new IllegalArgumentException(); + } + } + return curType; + } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaTypeLoaderImpl.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaTypeLoaderImpl.java new file mode 100644 index 000000000..b669069f4 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaTypeLoaderImpl.java @@ -0,0 +1,615 @@ +/* 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.SchemaTypeLoader; +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.SchemaGlobalElement; +import org.apache.xmlbeans.SchemaGlobalAttribute; +import org.apache.xmlbeans.SchemaModelGroup; +import org.apache.xmlbeans.SchemaAttributeGroup; +import org.apache.xmlbeans.SchemaTypeSystem; +import org.apache.xmlbeans.SchemaIdentityConstraint; +import org.apache.xmlbeans.ResourceLoader; +import org.apache.xmlbeans.impl.common.SystemCache; +import org.apache.xmlbeans.impl.common.QNameHelper; +import org.apache.xmlbeans.impl.common.XBeanDebug; +import javax.xml.namespace.QName; + +import java.io.InputStream; +import java.util.Map; +import java.util.HashMap; +import java.util.Collections; +import java.util.ArrayList; +import java.util.List; +import java.util.IdentityHashMap; + +import java.lang.ref.SoftReference; + +public class SchemaTypeLoaderImpl extends SchemaTypeLoaderBase +{ + private ResourceLoader _resourceLoader; + private ClassLoader _classLoader; + private SchemaTypeLoader[] _searchPath; + + private Map _classpathTypeSystems; + private Map _classLoaderTypeSystems; + private Map _elementCache; + private Map _attributeCache; + private Map _modelGroupCache; + private Map _attributeGroupCache; + private Map _idConstraintCache; + private Map _typeCache; + private Map _documentCache; + private Map _attributeTypeCache; + private Map _classnameCache; + + public static String METADATA_PACKAGE_LOAD = SchemaTypeSystemImpl.METADATA_PACKAGE_GEN; + private static final Object CACHED_NOT_FOUND = new Object(); + + private static class SchemaTypeLoaderCache extends SystemCache + { + // The following maintains a cache of SchemaTypeLoaders per ClassLoader per Thread. + // I use soft references to allow the garbage collector to reclain the type loaders + // and/pr class loaders at will. + + private ThreadLocal _cachedTypeSystems = + new ThreadLocal() { protected Object initialValue() { return new ArrayList(); } }; + + public SchemaTypeLoader getFromTypeLoaderCache(ClassLoader cl) + { + ArrayList a = (ArrayList) _cachedTypeSystems.get(); + + int candidate = -1; + SchemaTypeLoaderImpl result = null; + + for ( int i = 0 ; i < a.size() ; i++ ) + { + SchemaTypeLoaderImpl tl = (SchemaTypeLoaderImpl) ((SoftReference) a.get( i )).get(); + + if (tl == null) + { + assert i > candidate; + a.remove( i-- ); + } + else if (tl._classLoader == cl) + { + assert candidate == -1 && result == null; + + candidate = i; + result = tl; + + break; + } + } + + // Make sure the most recently accessed entry is at the beginning of the array + + if (candidate > 0) + { + Object t = a.get( 0 ); + a.set( 0, a.get( candidate ) ); + a.set( candidate, t ); + } + + return result; + } + + public void addToTypeLoaderCache(SchemaTypeLoader stl, ClassLoader cl) + { + assert (stl instanceof SchemaTypeLoaderImpl) && + ((SchemaTypeLoaderImpl) stl)._classLoader == cl; + + ArrayList a = (ArrayList) _cachedTypeSystems.get(); + // Make sure this entry is at the top of the stack + if (a.size() > 0) + { + Object t = a.get( 0 ); + a.set( 0, new SoftReference( stl ) ); + a.add( t ); + } + else + a.add( new SoftReference( stl ) ); + } + } + + public static SchemaTypeLoaderImpl getContextTypeLoader ( ) + { + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + SchemaTypeLoaderImpl result = (SchemaTypeLoaderImpl) + SystemCache.get().getFromTypeLoaderCache(cl); + + if (result == null) + { + result = + new SchemaTypeLoaderImpl( + new SchemaTypeLoader[] { BuiltinSchemaTypeSystem.get() }, null, cl ); + SystemCache.get().addToTypeLoaderCache(result, cl); + } + + return result; + } + + public static SchemaTypeLoader build(SchemaTypeLoader[] searchPath, ResourceLoader resourceLoader, ClassLoader classLoader) + { + if (searchPath == null) + { + searchPath = EMPTY_SCHEMATYPELOADER_ARRAY; + } + else + { + // assemble a flattened search path with no duplicates + SubLoaderList list = new SubLoaderList(); + for (int i = 0; i < searchPath.length; i++) + { + if (searchPath[i] == null) + throw new IllegalArgumentException("searchPath[" + i + "] is null"); + if (!(searchPath[i] instanceof SchemaTypeLoaderImpl)) + list.add(searchPath[i]); + else + { + SchemaTypeLoaderImpl sub = (SchemaTypeLoaderImpl)searchPath[i]; + if (sub._classLoader != null || sub._resourceLoader != null) + list.add(sub); + else for (int j = 0; j < sub._searchPath.length; j++) + list.add(sub._searchPath[j]); + } + } + searchPath = list.toArray(); + } + + if (searchPath.length == 1 && resourceLoader == null && classLoader == null) + return searchPath[0]; + + return new SchemaTypeLoaderImpl(searchPath, resourceLoader, classLoader); + } + + /** + * Just used to avoid duplicate path entries + */ + private static class SubLoaderList + { + private List theList = new ArrayList(); + private Map seen = new IdentityHashMap(); + + private boolean add(SchemaTypeLoader loader) + { + if (seen.containsKey(loader)) + return false; + theList.add(loader); + seen.put(loader, null); + return true; + } + + private SchemaTypeLoader[] toArray() + { + return (SchemaTypeLoader[])theList.toArray(EMPTY_SCHEMATYPELOADER_ARRAY); + } + } + + /** + * Constructs a SchemaTypeLoaderImpl that searches for objects + * in the following order: + * + * (1) First on the searchPath of other SchemaTypeSystems supplied, + * in order that they are listed. + * (2) Next on the classpath of .jar files or directories supplied, + * in the order that they are listed. When types are returned in + * this way, they are instantiated from a private typesystem. + * In other words, if a type is loaded from another SchemaTypeLoaderImpl + * that was initialized on the same file, the instance of the type will + * be different. + * (3) Finally on the classloader supplied. + */ + private SchemaTypeLoaderImpl(SchemaTypeLoader[] searchPath, ResourceLoader resourceLoader, ClassLoader classLoader) + { + if (searchPath == null) + _searchPath = EMPTY_SCHEMATYPELOADER_ARRAY; + else + _searchPath = searchPath; + _resourceLoader = resourceLoader; + _classLoader = classLoader; + + initCaches(); + } + + /** + * Initializes the caches. + */ + private final void initCaches() + { + _classpathTypeSystems = Collections.synchronizedMap(new HashMap()); + _classLoaderTypeSystems = Collections.synchronizedMap(new HashMap()); + _elementCache = Collections.synchronizedMap(new HashMap()); + _attributeCache = Collections.synchronizedMap(new HashMap()); + _modelGroupCache = Collections.synchronizedMap(new HashMap()); + _attributeGroupCache = Collections.synchronizedMap(new HashMap()); + _idConstraintCache = Collections.synchronizedMap(new HashMap()); + _typeCache = Collections.synchronizedMap(new HashMap()); + _documentCache = Collections.synchronizedMap(new HashMap()); + _attributeTypeCache = Collections.synchronizedMap(new HashMap()); + _classnameCache = Collections.synchronizedMap(new HashMap()); + } + + SchemaTypeSystemImpl typeSystemForComponent(String searchdir, QName name) + { + String searchfor = searchdir + QNameHelper.hexsafedir(name) + ".xsb"; + String tsname = null; + + if (_resourceLoader != null) + tsname = crackEntry(_resourceLoader, searchfor); + + if (_classLoader != null) + tsname = crackEntry(_classLoader, searchfor); + + if (tsname != null) + return (SchemaTypeSystemImpl)typeSystemForName(tsname); + + return null; + } + + public SchemaTypeSystem typeSystemForName(String name) + { + if (_resourceLoader != null) + { + SchemaTypeSystem result = getTypeSystemOnClasspath(name); + if (result != null) + return result; + } + + if (_classLoader != null) + { + SchemaTypeSystem result = getTypeSystemOnClassloader(name); + if (result != null) + return result; + } + return null; + } + + SchemaTypeSystemImpl typeSystemForClassname(String searchdir, String name) + { + String searchfor = searchdir + name.replace('.', '/') + ".xsb"; + + if (_resourceLoader != null) + { + String tsname = crackEntry(_resourceLoader, searchfor); + if (tsname != null) + return getTypeSystemOnClasspath(tsname); + } + + if (_classLoader != null) + { + String tsname = crackEntry(_classLoader, searchfor); + if (tsname != null) + return getTypeSystemOnClassloader(tsname); + } + + return null; + } + + SchemaTypeSystemImpl getTypeSystemOnClasspath(String name) + { + SchemaTypeSystemImpl result = (SchemaTypeSystemImpl)_classpathTypeSystems.get(name); + if (result == null) + { + result = new SchemaTypeSystemImpl(_resourceLoader, name, this); + _classpathTypeSystems.put(name, result); + } + return result; + } + + SchemaTypeSystemImpl getTypeSystemOnClassloader(String name) + { + XBeanDebug.trace(XBeanDebug.TRACE_SCHEMA_LOADING, "Finding type system " + name + " on classloader", 0); + SchemaTypeSystemImpl result = (SchemaTypeSystemImpl)_classLoaderTypeSystems.get(name); + if (result == null) + { + XBeanDebug.trace(XBeanDebug.TRACE_SCHEMA_LOADING, "Type system " + name + " not cached - consulting field", 0); + result = SchemaTypeSystemImpl.forName(name, _classLoader); + _classLoaderTypeSystems.put(name, result); + } + return result; + } + + static String crackEntry(ResourceLoader loader, String searchfor) + { + InputStream is = loader.getResourceAsStream(searchfor); + if (is == null) + return null; + return crackPointer(is); + } + + static String crackEntry(ClassLoader loader, String searchfor) + { + InputStream stream = loader.getResourceAsStream(searchfor); + if (stream == null) + return null; + return crackPointer(stream); + } + + static String crackPointer(InputStream stream) + { + return SchemaTypeSystemImpl.crackPointer(stream); + } + + public boolean isNamespaceDefined(String namespace) + { + for (int i = 0; i < _searchPath.length; i++) + if (_searchPath[i].isNamespaceDefined(namespace)) + return true; + + SchemaTypeSystem sts = typeSystemForComponent("schema" + METADATA_PACKAGE_LOAD + "/namespace/", new QName(namespace, "xmlns")); + return (sts != null); + } + + public SchemaType.Ref findTypeRef(QName name) + { + /** + * The maps are synchronized, we use two accesses to the cache (one read + * and one write), but the code inbetween is not synchronized. The + * assumption is that the underlying datastructures (the search path and + * the classloader) do not change, so two threads running the code in + * parallel will come up with the same result. + */ + Object cached = _typeCache.get(name); + if (cached == CACHED_NOT_FOUND) + return null; + SchemaType.Ref result = (SchemaType.Ref) cached; + if (result == null) + { + for (int i = 0; i < _searchPath.length; i++) + if (null != (result = _searchPath[i].findTypeRef(name))) + break; + if (result == null) + { + SchemaTypeSystem ts = typeSystemForComponent("schema" + METADATA_PACKAGE_LOAD + "/type/", name); + if (ts != null) + { + result = ts.findTypeRef(name); + assert(result != null) : "Type system registered type " + QNameHelper.pretty(name) + " but does not return it"; + } + } + _typeCache.put(name, result == null ? CACHED_NOT_FOUND : result); + } + return result; + } + + public SchemaType typeForClassname(String classname) + { + classname = classname.replace('$', '.'); + + Object cached = _classnameCache.get(classname); + if (cached == CACHED_NOT_FOUND) + return null; + SchemaType result = (SchemaType) cached; + if (result == null) + { + for (int i = 0; i < _searchPath.length; i++) + if (null != (result = _searchPath[i].typeForClassname(classname))) + break; + if (result == null) + { + SchemaTypeSystem ts = typeSystemForClassname("schema" + METADATA_PACKAGE_LOAD + "/javaname/", classname); + if (ts != null) + { + result = ts.typeForClassname(classname); + assert(result != null) : "Type system registered type " + classname + " but does not return it"; + } + } + _classnameCache.put(classname, result == null ? CACHED_NOT_FOUND : result); + } + return result; + } + + public SchemaType.Ref findDocumentTypeRef(QName name) + { + Object cached = _documentCache.get(name); + if (cached == CACHED_NOT_FOUND) + return null; + SchemaType.Ref result = (SchemaType.Ref) cached; + if (result == null) + { + for (int i = 0; i < _searchPath.length; i++) + if (null != (result = _searchPath[i].findDocumentTypeRef(name))) + break; + if (result == null) + { + SchemaTypeSystem ts = typeSystemForComponent("schema" + METADATA_PACKAGE_LOAD + "/element/", name); + if (ts != null) + { + result = ts.findDocumentTypeRef(name); + assert(result != null) : "Type system registered element " + QNameHelper.pretty(name) + " but does not contain document type"; + } + } + _documentCache.put(name, result == null ? CACHED_NOT_FOUND : result); + } + return result; + } + + public SchemaType.Ref findAttributeTypeRef(QName name) + { + Object cached = _attributeTypeCache.get(name); + if (cached == CACHED_NOT_FOUND) + return null; + SchemaType.Ref result = (SchemaType.Ref) cached; + if (result == null) + { + for (int i = 0; i < _searchPath.length; i++) + if (null != (result = _searchPath[i].findAttributeTypeRef(name))) + break; + if (result == null) + { + SchemaTypeSystem ts = typeSystemForComponent("schema" + METADATA_PACKAGE_LOAD + "/attribute/", name); + if (ts != null) + { + result = ts.findAttributeTypeRef(name); + assert(result != null) : "Type system registered attribute " + QNameHelper.pretty(name) + " but does not contain attribute type"; + } + } + _attributeTypeCache.put(name, result == null ? CACHED_NOT_FOUND : result); + } + return result; + } + + public SchemaGlobalElement.Ref findElementRef(QName name) + { + Object cached = _elementCache.get(name); + if (cached == CACHED_NOT_FOUND) + return null; + SchemaGlobalElement.Ref result = (SchemaGlobalElement.Ref) cached; + if (result == null) + { + for (int i = 0; i < _searchPath.length; i++) + if (null != (result = _searchPath[i].findElementRef(name))) + break; + if (result == null) + { + SchemaTypeSystem ts = typeSystemForComponent("schema" + METADATA_PACKAGE_LOAD + "/element/", name); + if (ts != null) + { + result = ts.findElementRef(name); + assert(result != null) : "Type system registered element " + QNameHelper.pretty(name) + " but does not return it"; + } + } + _elementCache.put(name, result == null ? CACHED_NOT_FOUND : result); + } + return result; + } + + public SchemaGlobalAttribute.Ref findAttributeRef(QName name) + { + Object cached = _attributeCache.get(name); + if (cached == CACHED_NOT_FOUND) + return null; + SchemaGlobalAttribute.Ref result = (SchemaGlobalAttribute.Ref) cached; + if (result == null) + { + for (int i = 0; i < _searchPath.length; i++) + if (null != (result = _searchPath[i].findAttributeRef(name))) + break; + if (result == null) + { + SchemaTypeSystem ts = typeSystemForComponent("schema" + METADATA_PACKAGE_LOAD + "/attribute/", name); + if (ts != null) + { + result = ts.findAttributeRef(name); + assert(result != null) : "Type system registered attribute " + QNameHelper.pretty(name) + " but does not return it"; + } + } + _attributeCache.put(name, result == null ? CACHED_NOT_FOUND : result); + } + return result; + } + + public SchemaModelGroup.Ref findModelGroupRef(QName name) + { + Object cached = _modelGroupCache.get(name); + if (cached == CACHED_NOT_FOUND) + return null; + SchemaModelGroup.Ref result = (SchemaModelGroup.Ref) cached; + if (result == null) + { + for (int i = 0; i < _searchPath.length; i++) + if (null != (result = _searchPath[i].findModelGroupRef(name))) + break; + if (result == null) + { + SchemaTypeSystem ts = typeSystemForComponent("schema" + METADATA_PACKAGE_LOAD + "/modelgroup/", name); + if (ts != null) + { + result = ts.findModelGroupRef(name); + assert(result != null) : "Type system registered model group " + QNameHelper.pretty(name) + " but does not return it"; + } + } + _modelGroupCache.put(name, result == null ? CACHED_NOT_FOUND : result); + } + return result; + } + + public SchemaAttributeGroup.Ref findAttributeGroupRef(QName name) + { + Object cached = _attributeGroupCache.get(name); + if (cached == CACHED_NOT_FOUND) + return null; + SchemaAttributeGroup.Ref result = (SchemaAttributeGroup.Ref) cached; + if (result == null) + { + for (int i = 0; i < _searchPath.length; i++) + if (null != (result = _searchPath[i].findAttributeGroupRef(name))) + break; + if (result == null) + { + SchemaTypeSystem ts = typeSystemForComponent("schema" + METADATA_PACKAGE_LOAD + "/attributegroup/", name); + if (ts != null) + { + result = ts.findAttributeGroupRef(name); + assert(result != null) : "Type system registered attribute group " + QNameHelper.pretty(name) + " but does not return it"; + } + } + _attributeGroupCache.put(name, result == null ? CACHED_NOT_FOUND : result); + } + return result; + } + + public SchemaIdentityConstraint.Ref findIdentityConstraintRef(QName name) + { + Object cached = _idConstraintCache.get(name); + if (cached == CACHED_NOT_FOUND) + return null; + SchemaIdentityConstraint.Ref result = (SchemaIdentityConstraint.Ref) cached; + if (result == null) + { + for (int i = 0; i < _searchPath.length; i++) + if (null != (result = _searchPath[i].findIdentityConstraintRef(name))) + break; + if (result == null) + { + SchemaTypeSystem ts = typeSystemForComponent("schema" + METADATA_PACKAGE_LOAD + "/identityconstraint/", name); + if (ts != null) + { + result = ts.findIdentityConstraintRef(name); + assert(result != null) : "Type system registered identity constraint " + QNameHelper.pretty(name) + " but does not return it"; + } + } + _idConstraintCache.put(name, result == null ? CACHED_NOT_FOUND : result); + } + return result; + } + + public InputStream getSourceAsStream(String sourceName) + { + InputStream result = null; + + if (!sourceName.startsWith("/")) + sourceName = "/" + sourceName; + + if (_resourceLoader != null) + result = _resourceLoader.getResourceAsStream("schema" + METADATA_PACKAGE_LOAD + "/src" + sourceName); + + if (result == null && _classLoader != null) + return _classLoader.getResourceAsStream("schema" + METADATA_PACKAGE_LOAD + "/src" + sourceName); + + return result; + } + + private static final SchemaTypeLoader[] EMPTY_SCHEMATYPELOADER_ARRAY = new SchemaTypeLoader[0]; + + static + { + if (SystemCache.get() instanceof SystemCache) + SystemCache.set(new SchemaTypeLoaderCache()); + } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaTypeSystemCompiler.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaTypeSystemCompiler.java new file mode 100644 index 000000000..6f2e7349f --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaTypeSystemCompiler.java @@ -0,0 +1,491 @@ +/* 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.XmlBeans; +import org.apache.xmlbeans.SchemaTypeLoader; +import org.apache.xmlbeans.XmlException; +import org.apache.xmlbeans.XmlErrorCodes; +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.XmlOptions; +import org.apache.xmlbeans.SchemaTypeSystem; +import org.apache.xmlbeans.Filer; +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.BindingConfig; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.HashMap; +import java.util.Map; +import java.util.List; +import java.util.Set; +import java.util.Arrays; +import java.net.URI; + +import org.apache.xmlbeans.impl.xb.xsdschema.SchemaDocument.Schema; +import org.apache.xmlbeans.impl.xb.xsdschema.SchemaDocument; +import org.apache.xmlbeans.impl.common.XmlErrorWatcher; + +import java.util.Collection; +import java.util.Iterator; +import java.io.File; +import java.io.IOException; +import java.io.Writer; + +public class SchemaTypeSystemCompiler +{ + public static class Parameters + { + private SchemaTypeSystem existingSystem; + private String name; + private Schema[] schemas; + private BindingConfig config; + private SchemaTypeLoader linkTo; + private XmlOptions options; + private Collection errorListener; + private boolean javaize; + private URI baseURI; + private Map sourcesToCopyMap; + private File schemasDir; + + public SchemaTypeSystem getExistingTypeSystem() + { + return existingSystem; + } + + public void setExistingTypeSystem(SchemaTypeSystem system) + { + this.existingSystem = system; + } + + public String getName() + { + return name; + } + + public void setName(String name) + { + this.name = name; + } + + public SchemaDocument.Schema[] getSchemas() + { + return schemas; + } + + public void setSchemas(SchemaDocument.Schema[] schemas) + { + this.schemas = schemas; + } + + public BindingConfig getConfig() + { + return config; + } + + public void setConfig(BindingConfig config) + { + this.config = config; + } + + public SchemaTypeLoader getLinkTo() + { + return linkTo; + } + + public void setLinkTo(SchemaTypeLoader linkTo) + { + this.linkTo = linkTo; + } + + public XmlOptions getOptions() + { + return options; + } + + public void setOptions(XmlOptions options) + { + this.options = options; + } + + public Collection getErrorListener() + { + return errorListener; + } + + public void setErrorListener(Collection errorListener) + { + this.errorListener = errorListener; + } + + public boolean isJavaize() + { + return javaize; + } + + public void setJavaize(boolean javaize) + { + this.javaize = javaize; + } + + public URI getBaseURI() + { + return baseURI; + } + + public void setBaseURI(URI baseURI) + { + this.baseURI = baseURI; + } + + public Map getSourcesToCopyMap() + { + return sourcesToCopyMap; + } + + public void setSourcesToCopyMap(Map sourcesToCopyMap) + { + this.sourcesToCopyMap = sourcesToCopyMap; + } + + public File getSchemasDir() + { + return schemasDir; + } + + public void setSchemasDir(File schemasDir) + { + this.schemasDir = schemasDir; + } + + } + + /** + * Compiles a SchemaTypeSystem. Use XmlBeans.compileXmlBeans() if you can. + */ + public static SchemaTypeSystem compile(Parameters params) + { + return compileImpl(params.getExistingTypeSystem(), params.getName(), + params.getSchemas(), params.getConfig(), params.getLinkTo(), + params.getOptions(), params.getErrorListener(), params.isJavaize(), + params.getBaseURI(), params.getSourcesToCopyMap(), params.getSchemasDir()); + } + + /** + * Please do not invoke this method directly as the signature could change unexpectedly. + * Use one of + * {@link XmlBeans#loadXsd(XmlObject[])}, + * {@link XmlBeans#compileXsd(XmlObject[], SchemaTypeLoader, XmlOptions)}, + * or + * {@link XmlBeans#compileXmlBeans(String, SchemaTypeSystem, XmlObject[], BindingConfig, SchemaTypeLoader, Filer, XmlOptions)} + */ + public static SchemaTypeSystemImpl compile(String name, SchemaTypeSystem existingSTS, + XmlObject[] input, BindingConfig config, SchemaTypeLoader linkTo, Filer filer, XmlOptions options) + throws XmlException + { + options = XmlOptions.maskNull(options); + ArrayList schemas = new ArrayList(); + + if (input != null) + { + 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 + throw new XmlException("Thread " + Thread.currentThread().getName() + ": The " + i + "th supplied input is not a schema document: its type is " + input[i].schemaType()); + } + } + + Collection userErrors = (Collection)options.get(XmlOptions.ERROR_LISTENER); + XmlErrorWatcher errorWatcher = new XmlErrorWatcher(userErrors); + + SchemaTypeSystemImpl stsi = compileImpl(existingSTS, name, + (Schema[])schemas.toArray(new Schema[schemas.size()]), + config, linkTo, options, errorWatcher, filer!=null, (URI) options.get(XmlOptions.BASE_URI), + null, null); + + // if there is an error and compile didn't recover (stsi==null), throw exception + if (errorWatcher.hasError() && stsi == null) + { + throw new XmlException(errorWatcher.firstError()); + } + + if (stsi != null && !stsi.isIncomplete() && filer != null) + { + stsi.save(filer); + generateTypes(stsi, filer, options); + } + + return stsi; + } + + // + // Compiles a SchemaTypeSystem + // + /* package */ static SchemaTypeSystemImpl compileImpl( SchemaTypeSystem system, String name, + Schema[] schemas, BindingConfig config, SchemaTypeLoader linkTo, + XmlOptions options, Collection outsideErrors, boolean javaize, + URI baseURI, Map sourcesToCopyMap, File schemasDir) + { + if (linkTo == null) + throw new IllegalArgumentException("Must supply linkTo"); + + XmlErrorWatcher errorWatcher = new XmlErrorWatcher(outsideErrors); + boolean incremental = system != null; + + // construct the state + StscState state = StscState.start(); + boolean validate = (options == null || !options.hasOption(XmlOptions.COMPILE_NO_VALIDATION)); + try + { + state.setErrorListener(errorWatcher); + state.setBindingConfig(config); + state.setOptions(options); + state.setGivenTypeSystemName(name); + state.setSchemasDir(schemasDir); + if (baseURI != null) + state.setBaseUri(baseURI); + + // construct the classpath (you always get the builtin types) + linkTo = SchemaTypeLoaderImpl.build(new SchemaTypeLoader[] { BuiltinSchemaTypeSystem.get(), linkTo }, null, null); + state.setImportingTypeLoader(linkTo); + + List validSchemas = new ArrayList(schemas.length); + + // load all the xsd files into it + if (validate) + { + XmlOptions validateOptions = new XmlOptions().setErrorListener(errorWatcher); + if (options.hasOption(XmlOptions.VALIDATE_TREAT_LAX_AS_SKIP)) + validateOptions.setValidateTreatLaxAsSkip(); + for (int i = 0; i < schemas.length; i++) + { + if (schemas[i].validate(validateOptions)) + validSchemas.add(schemas[i]); + } + } + else + { + validSchemas.addAll(Arrays.asList(schemas)); + } + + Schema[] startWith = (Schema[])validSchemas.toArray(new Schema[validSchemas.size()]); + + if (incremental) + { + Set namespaces = new HashSet(); + startWith = getSchemasToRecompile((SchemaTypeSystemImpl)system, startWith, namespaces); + state.initFromTypeSystem((SchemaTypeSystemImpl)system, namespaces); + } + else + { + state.setDependencies(new SchemaDependencies()); + } + + // deal with imports and includes + StscImporter.SchemaToProcess[] schemasAndChameleons = StscImporter.resolveImportsAndIncludes(startWith, incremental); + + // call the translator so that it may also perform magic + StscTranslator.addAllDefinitions(schemasAndChameleons); + + // call the resolver to do its magic + StscResolver.resolveAll(); + + // call the checker to check both restrictions and defaults + StscChecker.checkAll(); + + // call the javaizer to do its magic + StscJavaizer.javaizeAllTypes(javaize); + + // construct the loader out of the state + state.get().sts().loadFromStscState(state); + + // fill in the source-copy map + if (sourcesToCopyMap != null) + sourcesToCopyMap.putAll(state.sourceCopyMap()); + + if (errorWatcher.hasError()) + { + // EXPERIMENTAL: recovery from compilation errors and partial type system + if (state.allowPartial() && state.getRecovered() == errorWatcher.size()) + { + // if partial type system allowed and all errors were recovered + state.get().sts().setIncomplete(true); + } + else + { + // if any non-recoverable errors, return null + return null; + } + } + + if (system != null) + ((SchemaTypeSystemImpl) system).setIncomplete(true); + + return state.get().sts(); + } + finally + { + StscState.end(); + } + } + + /** + * Get the list of Schemas to be recompiled, based on the list of Schemas that + * were modified. + * We make use of the depencency information that we stored in the typesystem + * and of the entity resolvers that have been set up + */ + private static Schema[] getSchemasToRecompile(SchemaTypeSystemImpl system, + Schema[] modified, Set namespaces) + { + Set modifiedFiles = new HashSet(); + Map haveFile = new HashMap(); + List result = new ArrayList(); + for (int i = 0; i < modified.length; i++) + { + String fileURL = modified[i].documentProperties().getSourceName(); + if (fileURL == null) + throw new IllegalArgumentException("One of the Schema files passed in" + + " doesn't have the source set, which prevents it to be incrementally" + + " compiled"); + modifiedFiles.add(fileURL); + haveFile.put(fileURL, modified[i]); + result.add(modified[i]); + } + SchemaDependencies dep = system.getDependencies(); + List nss = dep.getNamespacesTouched(modifiedFiles); + namespaces.addAll(dep.computeTransitiveClosure(nss)); + List needRecompilation = dep.getFilesTouched(namespaces); + StscState.get().setDependencies(new SchemaDependencies(dep, namespaces)); + for (int i = 0; i < needRecompilation.size(); i++) + { + String url = (String) needRecompilation.get(i); + Schema have = (Schema) haveFile.get(url); + if (have == null) + { + // We have to load the file from the entity resolver + try + { + XmlObject xdoc = StscImporter.DownloadTable. + downloadDocument(StscState.get().getS4SLoader(), null, url); + XmlOptions voptions = new XmlOptions(); + voptions.setErrorListener(StscState.get().getErrorListener()); + if (!(xdoc instanceof SchemaDocument) || !xdoc.validate(voptions)) + { + StscState.get().error("Referenced document is not a valid schema, URL = " + url, XmlErrorCodes.CANNOT_FIND_RESOURCE, null); + continue; + } + + SchemaDocument sDoc = (SchemaDocument)xdoc; + + result.add(sDoc.getSchema()); + } + catch (java.net.MalformedURLException mfe) + { + StscState.get().error(XmlErrorCodes.EXCEPTION_LOADING_URL, new Object[] { "MalformedURLException", url, mfe.getMessage() }, null); + continue; + } + catch (java.io.IOException ioe) + { + StscState.get().error(XmlErrorCodes.EXCEPTION_LOADING_URL, new Object[] { "IOException", url, ioe.getMessage() }, null); + continue; + } + catch (XmlException xmle) + { + StscState.get().error(XmlErrorCodes.EXCEPTION_LOADING_URL, new Object[] { "XmlException", url, xmle.getMessage() }, null); + continue; + } + } + } + return (Schema[]) result.toArray(new Schema[result.size()]); + } + + + /** + * Generate java source files for a SchemaTypeSystem. + * Please do not invoke this method directly as the signature could change unexpectedly. + * Use {@link org.apache.xmlbeans.XmlBeans#compileXmlBeans} + * + * @param system the SchemaTypeSystem to generated java source for + * @param filer to create the java source files + * @param options See {@link XmlOptions#setSchemaCodePrinter(org.apache.xmlbeans.SchemaCodePrinter)} + * @return true if saving the generated source succeeded. + */ + public static boolean generateTypes(SchemaTypeSystem system, Filer filer, XmlOptions options) + { + // partial type systems not allowed to be saved + if (system instanceof SchemaTypeSystemImpl && ((SchemaTypeSystemImpl)system).isIncomplete()) + return false; + + boolean success = true; + + List types = new ArrayList(); + types.addAll(Arrays.asList(system.globalTypes())); + types.addAll(Arrays.asList(system.documentTypes())); + types.addAll(Arrays.asList(system.attributeTypes())); + + for (Iterator i = types.iterator(); i.hasNext(); ) + { + SchemaType type = (SchemaType)i.next(); + if (type.isBuiltinType()) + continue; + if (type.getFullJavaName() == null) + continue; + + String fjn = type.getFullJavaName(); + + Writer writer = null; + + try + { + // Generate interface class + writer = filer.createSourceFile(fjn); + SchemaTypeCodePrinter.printType(writer, type, options); + } + catch (IOException e) + { + System.err.println("IO Error " + e); + success = false; + } + finally { + try { if (writer != null) writer.close(); } catch (IOException e) {} + } + + try + { + // Generate Implementation class + fjn = type.getFullJavaImplName(); + writer = filer.createSourceFile(fjn); + + SchemaTypeCodePrinter.printTypeImpl(writer, type, options); + } + catch (IOException e) + { + System.err.println("IO Error " + e); + success = false; + } + finally { + try { if (writer != null) writer.close(); } catch (IOException e) {} + } + } + + return success; + } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaTypeSystemImpl.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaTypeSystemImpl.java new file mode 100644 index 000000000..fd6f25070 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaTypeSystemImpl.java @@ -0,0 +1,3807 @@ +/* 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.Filer; +import org.apache.xmlbeans.QNameSet; +import org.apache.xmlbeans.SchemaAnnotation; +import org.apache.xmlbeans.SchemaAttributeGroup; +import org.apache.xmlbeans.SchemaAttributeModel; +import org.apache.xmlbeans.SchemaComponent; +import org.apache.xmlbeans.SchemaField; +import org.apache.xmlbeans.SchemaGlobalAttribute; +import org.apache.xmlbeans.SchemaGlobalElement; +import org.apache.xmlbeans.SchemaIdentityConstraint; +import org.apache.xmlbeans.SchemaLocalAttribute; +import org.apache.xmlbeans.SchemaLocalElement; +import org.apache.xmlbeans.SchemaModelGroup; +import org.apache.xmlbeans.SchemaParticle; +import org.apache.xmlbeans.SchemaProperty; +import org.apache.xmlbeans.SchemaStringEnumEntry; +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.SchemaTypeLoader; +import org.apache.xmlbeans.SchemaTypeLoaderException; +import org.apache.xmlbeans.SchemaTypeSystem; +import org.apache.xmlbeans.SimpleValue; +import org.apache.xmlbeans.SystemProperties; +import org.apache.xmlbeans.XmlAnySimpleType; +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.XmlOptions; +import org.apache.xmlbeans.ResourceLoader; +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.util.FilerImpl; +import org.apache.xmlbeans.impl.util.HexBin; +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 repackage.Repackager; + +import javax.xml.namespace.QName; +import java.io.ByteArrayOutputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Random; +import java.util.Set; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; + +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 = 24; // 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; + + /** + * This is to support the feature of a separate/private XMLBeans + * distribution that will not colide with the public org apache + * xmlbeans one. + * METADATA_PACKAGE_GEN will be "" for the original and something like + * com_mycompany_private_xmlbeans for a private distribution of XMLBeans. + * + * There are two properties: + * METADATA_PACKAGE_GEN - used for generating metadata + * and METADATA_PACKAGE_LOAD - used for loading the metadata. + * Most of the time they have the same value, with one exception, during the + * repackage process scomp needs to load from old package and generate into + * a new package. + */ + public static String METADATA_PACKAGE_GEN; + static + { + // fix for maven classloader + Package stsPackage = SchemaTypeSystem.class.getPackage(); + String stsPackageName = (stsPackage==null) ? + SchemaTypeSystem.class.getName().substring(0, SchemaTypeSystem.class.getName().lastIndexOf(".")) : + stsPackage.getName(); + + METADATA_PACKAGE_GEN = stsPackageName.replaceAll("\\.", "_"); + } + + 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); + try + { + initFromHeader(); + } + catch (RuntimeException e) + { + XBeanDebug.logException(e); + throw e; + } + catch (Error e) + { + XBeanDebug.logException(e); + throw e; + } + XBeanDebug.trace(XBeanDebug.TRACE_SCHEMA_LOADING, "Finished loading type system " + _name, -1); + } + + 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 + List typeNames = new ArrayList(); + List modelGroupNames = new ArrayList(); + List attributeGroupNames = new ArrayList(); + if (reader.atLeast(2, 15, 0)) + { + _redefinedGlobalTypes = reader.readQNameRefMapAsList(typeNames); + _redefinedModelGroups = reader.readQNameRefMapAsList(modelGroupNames); + _redefinedAttributeGroups = reader.readQNameRefMapAsList(attributeGroupNames); + } + if (reader.atLeast(2, 19, 0)) + { + _annotations = reader.readAnnotations(); + } + + buildContainers(typeNames, modelGroupNames, attributeGroupNames); + } + 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" + METADATA_PACKAGE_GEN + "/element/"); + savePointersForComponents(globalAttributes(), "schema" + METADATA_PACKAGE_GEN + "/attribute/"); + savePointersForComponents(modelGroups(), "schema" + METADATA_PACKAGE_GEN + "/modelgroup/"); + savePointersForComponents(attributeGroups(), "schema" + METADATA_PACKAGE_GEN + "/attributegroup/"); + savePointersForComponents(globalTypes(), "schema" + METADATA_PACKAGE_GEN + "/type/"); + savePointersForComponents(identityConstraints(), "schema" + METADATA_PACKAGE_GEN + "/identityconstraint/"); + savePointersForNamespaces(_namespaces, "schema" + METADATA_PACKAGE_GEN + "/namespace/"); + savePointersForClassnames(_typeRefsByClassname.keySet(), "schema" + METADATA_PACKAGE_GEN + "/javaname/"); + savePointersForComponents(redefinedModelGroups(), "schema" + METADATA_PACKAGE_GEN + "/redefinedmodelgroup/"); + savePointersForComponents(redefinedAttributeGroups(), "schema" + METADATA_PACKAGE_GEN + "/redefinedattributegroup/"); + savePointersForComponents(redefinedGlobalTypes(), "schema" + METADATA_PACKAGE_GEN + "/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(); + } + + /** + * The strategy here is to copy the compiled TypeSystemHolder.template class + * to a new TypeSystemHolder.class needed by the schema type system. When + * saving a loader, we read the TypeSystemHolder.template class file and + * swap out the utf8 string constants with new ones to create a new + * TypeSystemHolder class file. This saves us the need to rely on javac + * to compile a generated .java file into the class file. + * + * See the JVM spec on how to interpret the bytes of a class file. + */ + void saveLoader() + { + String indexClassName = SchemaTypeCodePrinter.indexClassForSystem(this); + String[] replace = makeClassStrings(indexClassName); + assert replace.length == HOLDER_TEMPLATE_NAMES.length; + + InputStream is = null; + OutputStream os = null; + + DataInputStream in = null; + DataOutputStream out = null; + + Repackager repackager = null; + if (_filer instanceof FilerImpl) + repackager = ((FilerImpl)_filer).getRepackager(); + + try + { + is = SchemaTypeSystemImpl.class.getResourceAsStream(HOLDER_TEMPLATE_CLASSFILE); + if (is == null) + throw new SchemaTypeLoaderException("couldn't find resource: " + HOLDER_TEMPLATE_CLASSFILE, _name, null, SchemaTypeLoaderException.IO_EXCEPTION); + in = new DataInputStream(is); + + os = _filer.createBinaryFile(indexClassName.replace('.', '/') + ".class"); + out = new DataOutputStream(os); + + // java magic + out.writeInt(in.readInt()); + + // java minor and major version + out.writeShort(in.readUnsignedShort()); + out.writeShort(in.readUnsignedShort()); + + int poolsize = in.readUnsignedShort(); + out.writeShort(poolsize); + + // the constant pool is indexed from 1 to poolsize-1 + for (int i = 1; i < poolsize; i++) + { + int tag = in.readUnsignedByte(); + out.writeByte(tag); + + switch (tag) + { + case CONSTANT_UTF8: + String value = in.readUTF(); + out.writeUTF(repackageConstant(value, replace, repackager)); + break; + + case CONSTANT_CLASS: + case CONSTANT_STRING: + out.writeShort(in.readUnsignedShort()); + break; + + case CONSTANT_NAMEANDTYPE: + case CONSTANT_METHOD: + case CONSTANT_FIELD: + case CONSTANT_INTERFACEMETHOD: + out.writeShort(in.readUnsignedShort()); + out.writeShort(in.readUnsignedShort()); + break; + + case CONSTANT_INTEGER: + case CONSTANT_FLOAT: + out.writeInt(in.readInt()); + break; + + case CONSTANT_LONG: + case CONSTANT_DOUBLE: + out.writeInt(in.readInt()); + out.writeInt(in.readInt()); + break; + + default: + throw new RuntimeException("Unexpected constant type: " + tag); + } + } + + // we're done with the class' constant pool, + // we can just copy the rest of the bytes + try + { + while (true) + out.writeByte(in.readByte()); + } + catch (java.io.EOFException e) + { + // ok + } + + } + catch (IOException e) + { + // ok + } + finally + { + if (is != null) try { is.close(); } catch (Exception e) { } + if (os != null) try { os.close(); } catch (Exception e) { } + } + } + + private static final String HOLDER_TEMPLATE_CLASS = "org.apache.xmlbeans.impl.schema.TypeSystemHolder"; + private static final String HOLDER_TEMPLATE_CLASSFILE = "TypeSystemHolder.template"; + private static final String[] HOLDER_TEMPLATE_NAMES = makeClassStrings(HOLDER_TEMPLATE_CLASS); + + // constant pool entry types + private static final int CONSTANT_UTF8 = 1; + private static final int CONSTANT_UNICODE = 2; + private static final int CONSTANT_INTEGER = 3; + private static final int CONSTANT_FLOAT = 4; + private static final int CONSTANT_LONG = 5; + private static final int CONSTANT_DOUBLE = 6; + private static final int CONSTANT_CLASS = 7; + private static final int CONSTANT_STRING = 8; + private static final int CONSTANT_FIELD = 9; + private static final int CONSTANT_METHOD = 10; + private static final int CONSTANT_INTERFACEMETHOD = 11; + private static final int CONSTANT_NAMEANDTYPE = 12; + + // MAX_UNSIGNED_SHORT + private static final int MAX_UNSIGNED_SHORT = Short.MAX_VALUE * 2 + 1; + + private static String repackageConstant(String value, String[] replace, Repackager repackager) + { + for (int i = 0; i < HOLDER_TEMPLATE_NAMES.length; i++) + if (HOLDER_TEMPLATE_NAMES[i].equals(value)) + return replace[i]; + + if (repackager != null) + return repackager.repackage(new StringBuffer(value)).toString(); + + return value; + } + + /** + * Construct an array of Strings found in a class file for a classname. + * For the class name 'a.b.C' it will generate an array of: + * 'a.b.C', 'a/b/C', 'La/b/C;', and 'class$a$b$C'. + */ + private static String[] makeClassStrings(String classname) + { + String[] result = new String[4]; + + result[0] = classname; + result[1] = classname.replace('.', '/'); + result[2] = "L" + result[1] + ";"; + result[3] = "class$" + classname.replace('.', '$'); + + return result; + } + + /** + * 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 List buildComponentRefList(SchemaComponent[] components) + { + List result = new ArrayList(); + for (int i = 0; i < components.length; i++) + result.add(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; + } + + // Container operation + private SchemaContainer getContainer(String namespace) + { + return (SchemaContainer) _containers.get(namespace); + } + + private void addContainer(String namespace) + { + SchemaContainer c = new SchemaContainer(namespace); + c.setTypeSystem(this); + _containers.put(namespace, c); + } + + private SchemaContainer getContainerNonNull(String namespace) + { + SchemaContainer result = getContainer(namespace); + if (result == null) + { + addContainer(namespace); + result = getContainer(namespace); + } + return result; + } + + // Only called during init + private void buildContainers(List redefTypeNames, List redefModelGroupNames, List redefAttributeGroupNames) + { + // This method walks the reference maps and copies said references + // into the appropriate container + for (Iterator it = _globalElements.entrySet().iterator(); it.hasNext(); ) + { + Map.Entry entry = (Map.Entry) it.next(); + String ns = ((QName) entry.getKey()).getNamespaceURI(); + getContainerNonNull(ns).addGlobalElement((SchemaGlobalElement.Ref) entry.getValue()); + } + for (Iterator it = _globalAttributes.entrySet().iterator(); it.hasNext(); ) + { + Map.Entry entry = (Map.Entry) it.next(); + String ns = ((QName) entry.getKey()).getNamespaceURI(); + getContainerNonNull(ns).addGlobalAttribute((SchemaGlobalAttribute.Ref) entry.getValue()); + } + for (Iterator it = _modelGroups.entrySet().iterator(); it.hasNext(); ) + { + Map.Entry entry = (Map.Entry) it.next(); + String ns = ((QName) entry.getKey()).getNamespaceURI(); + getContainerNonNull(ns).addModelGroup((SchemaModelGroup.Ref) entry.getValue()); + } + for (Iterator it = _attributeGroups.entrySet().iterator(); it.hasNext(); ) + { + Map.Entry entry = (Map.Entry) it.next(); + String ns = ((QName) entry.getKey()).getNamespaceURI(); + getContainerNonNull(ns).addAttributeGroup((SchemaAttributeGroup.Ref) entry.getValue()); + } + for (Iterator it = _identityConstraints.entrySet().iterator(); it.hasNext(); ) + { + Map.Entry entry = (Map.Entry) it.next(); + String ns = ((QName) entry.getKey()).getNamespaceURI(); + getContainerNonNull(ns).addIdentityConstraint((SchemaIdentityConstraint.Ref) entry.getValue()); + } + for (Iterator it = _globalTypes.entrySet().iterator(); it.hasNext(); ) + { + Map.Entry entry = (Map.Entry) it.next(); + String ns = ((QName) entry.getKey()).getNamespaceURI(); + getContainerNonNull(ns).addGlobalType((SchemaType.Ref) entry.getValue()); + } + for (Iterator it = _documentTypes.entrySet().iterator(); it.hasNext(); ) + { + Map.Entry entry = (Map.Entry) it.next(); + String ns = ((QName) entry.getKey()).getNamespaceURI(); + getContainerNonNull(ns).addDocumentType((SchemaType.Ref) entry.getValue()); + } + for (Iterator it = _attributeTypes.entrySet().iterator(); it.hasNext(); ) + { + Map.Entry entry = (Map.Entry) it.next(); + String ns = ((QName) entry.getKey()).getNamespaceURI(); + getContainerNonNull(ns).addAttributeType((SchemaType.Ref) entry.getValue()); + } + // Some earlier .xsb versions don't have records for redefinitions + if (_redefinedGlobalTypes != null && _redefinedModelGroups != null && + _redefinedAttributeGroups != null) + { + assert _redefinedGlobalTypes.size() == redefTypeNames.size(); + for (Iterator it = _redefinedGlobalTypes.iterator(), itname = redefTypeNames.iterator(); it.hasNext(); ) + { + String ns = ((QName) itname.next()).getNamespaceURI(); + getContainerNonNull(ns).addRedefinedType((SchemaType.Ref) it.next()); + } + for (Iterator it = _redefinedModelGroups.iterator(), itname = redefModelGroupNames.iterator(); it.hasNext(); ) + { + String ns = ((QName) itname.next()).getNamespaceURI(); + getContainerNonNull(ns).addRedefinedModelGroup((SchemaModelGroup.Ref) it.next()); + } + for (Iterator it = _redefinedAttributeGroups.iterator(), itname = redefAttributeGroupNames.iterator(); it.hasNext(); ) + { + String ns = ((QName) itname.next()).getNamespaceURI(); + getContainerNonNull(ns).addRedefinedAttributeGroup((SchemaAttributeGroup.Ref) it.next()); + } + } + // Some earlier .xsb versions don't have records for annotations + if (_annotations != null) + { + for (Iterator it = _annotations.iterator(); it.hasNext(); ) + { + SchemaAnnotation ann = (SchemaAnnotation) it.next(); + // BUGBUG(radup) + getContainerNonNull("").addAnnotation(ann); + } + } + for (Iterator it = _containers.values().iterator(); it.hasNext(); ) + ((SchemaContainer) it.next()).setImmutable(); + } + + /** + * This is the crux of the container work and role. + * It makes a sweep over all containers and fixes each container's + * typesystem to point to this typesystem. + * Because SchemaComponents have a link to their containers, this has as + * effect all components now indirectly pointing to this typesystem + * even though they (as well as the typesystem itself) are immutable. + */ + private void fixupContainers() + { + for (Iterator it = _containers.values().iterator(); it.hasNext(); ) + { + SchemaContainer container = (SchemaContainer) it.next(); + container.setTypeSystem(this); + container.setImmutable(); + } + } + + private void assertContainersSynchronized() + { + boolean assertEnabled = false; + // This code basically checks whether asserts are enabled so we don't do + // all the work if they arent + assert assertEnabled = true; + if (!assertEnabled) + return; + // global elements + Map temp = new HashMap(); + for (Iterator it = _containers.values().iterator(); it.hasNext(); ) + temp.putAll(buildComponentRefMap((SchemaComponent[]) ((SchemaContainer) it.next()).globalElements().toArray(new SchemaComponent[0]))); + assert _globalElements.equals(temp); + // global attributes + temp = new HashMap(); + for (Iterator it = _containers.values().iterator(); it.hasNext(); ) + temp.putAll(buildComponentRefMap((SchemaComponent[]) ((SchemaContainer) it.next()).globalAttributes().toArray(new SchemaComponent[0]))); + assert _globalAttributes.equals(temp); + // model groups + temp = new HashMap(); + for (Iterator it = _containers.values().iterator(); it.hasNext(); ) + temp.putAll(buildComponentRefMap((SchemaComponent[]) ((SchemaContainer) it.next()).modelGroups().toArray(new SchemaComponent[0]))); + assert _modelGroups.equals(temp); + // redefined model groups + Set temp2 = new HashSet(); + for (Iterator it = _containers.values().iterator(); it.hasNext(); ) + temp2.addAll(buildComponentRefList((SchemaComponent[]) ((SchemaContainer) it.next()).redefinedModelGroups().toArray(new SchemaComponent[0]))); + assert new HashSet(_redefinedModelGroups).equals(temp2); + // attribute groups + temp = new HashMap(); + for (Iterator it = _containers.values().iterator(); it.hasNext(); ) + temp.putAll(buildComponentRefMap((SchemaComponent[]) ((SchemaContainer) it.next()).attributeGroups().toArray(new SchemaComponent[0]))); + assert _attributeGroups.equals(temp); + // redefined attribute groups + temp2 = new HashSet(); + for (Iterator it = _containers.values().iterator(); it.hasNext(); ) + temp2.addAll(buildComponentRefList((SchemaComponent[]) ((SchemaContainer) it.next()).redefinedAttributeGroups().toArray(new SchemaComponent[0]))); + assert new HashSet(_redefinedAttributeGroups).equals(temp2); + // global types + temp = new HashMap(); + for (Iterator it = _containers.values().iterator(); it.hasNext(); ) + temp.putAll(buildComponentRefMap((SchemaComponent[]) ((SchemaContainer) it.next()).globalTypes().toArray(new SchemaComponent[0]))); + assert _globalTypes.equals(temp); + // redefined global types + temp2 = new HashSet(); + for (Iterator it = _containers.values().iterator(); it.hasNext(); ) + temp2.addAll(buildComponentRefList((SchemaComponent[]) ((SchemaContainer) it.next()).redefinedGlobalTypes().toArray(new SchemaComponent[0]))); + assert new HashSet(_redefinedGlobalTypes).equals(temp2); + // document types + temp = new HashMap(); + for (Iterator it = _containers.values().iterator(); it.hasNext(); ) + temp.putAll(buildDocumentMap((SchemaType[]) ((SchemaContainer) it.next()).documentTypes().toArray(new SchemaType[0]))); + assert _documentTypes.equals(temp); + // attribute types + temp = new HashMap(); + for (Iterator it = _containers.values().iterator(); it.hasNext(); ) + temp.putAll(buildAttributeTypeMap((SchemaType[]) ((SchemaContainer) it.next()).attributeTypes().toArray(new SchemaType[0]))); + assert _attributeTypes.equals(temp); + // identity constraints + temp = new HashMap(); + for (Iterator it = _containers.values().iterator(); it.hasNext(); ) + temp.putAll(buildComponentRefMap((SchemaComponent[]) ((SchemaContainer) it.next()).identityConstraints().toArray(new SchemaComponent[0]))); + assert _identityConstraints.equals(temp); + // annotations + temp2 = new HashSet(); + for (Iterator it = _containers.values().iterator(); it.hasNext(); ) + temp2.addAll(((SchemaContainer) it.next()).annotations()); + assert new HashSet(_annotations).equals(temp2); + // namespaces + temp2 = new HashSet(); + for (Iterator it = _containers.values().iterator(); it.hasNext(); ) + temp2.add(((SchemaContainer) it.next()).getNamespace()); + assert _namespaces.equals(temp2); + } + + 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 = SystemProperties.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" + METADATA_PACKAGE_GEN + ".system." + nameForSystem; + _basePackage = nameToPathString(_name); + _classloader = null; + //System.out.println(" _base: " + _basePackage); + } + + 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 = buildAttributeTypeMap(attributeTypes); + _typeRefsByClassname = buildTypeRefsByClassname(); + buildContainers(Collections.EMPTY_LIST, Collections.EMPTY_LIST, + Collections.EMPTY_LIST); + _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 = buildComponentRefList(state.redefinedModelGroups()); + _attributeGroups = buildComponentRefMap(state.attributeGroups()); + _redefinedAttributeGroups = buildComponentRefList(state.redefinedAttributeGroups()); + _globalTypes = buildComponentRefMap(state.globalTypes()); + _redefinedGlobalTypes = buildComponentRefList(state.redefinedGlobalTypes()); + _documentTypes = buildDocumentMap(state.documentTypes()); + _attributeTypes = buildAttributeTypeMap(state.attributeTypes()); + _typeRefsByClassname = buildTypeRefsByClassname(state.typesByClassname()); + _identityConstraints = buildComponentRefMap(state.idConstraints()); + _annotations = state.annotations(); + _namespaces = new HashSet(Arrays.asList(state.getNamespaces())); + _containers = state.getContainerMap(); + fixupContainers(); + // Checks that data in the containers matches the lookup maps + assertContainersSynchronized(); + setDependencies(state.getDependencies()); + } + + final SchemaTypeSystemImpl getTypeSystem() + { + return this; + } + + void setDependencies(SchemaDependencies deps) + { _deps = deps; } + + SchemaDependencies getDependencies() + { return _deps; } + + // EXPERIMENTAL + public boolean isIncomplete() { return _incomplete; } + + // EXPERIMENTAL + void setIncomplete(boolean incomplete) { _incomplete = incomplete; } + + 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() >= MAX_UNSIGNED_SHORT) + 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.readUnsignedShort(); + 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; + + // EXPERIMENTAL: recovery from compilation errors and partial type systems + private boolean _incomplete = false; + + // 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 Filer _filer; + + // top-level annotations + private List _annotations; + + // container + private Map _containers = new HashMap(); + // dependencies + private SchemaDependencies _deps; + + private List _redefinedModelGroups; + private List _redefinedAttributeGroups; + private List _redefinedGlobalTypes; + + // actual type system data, map QNames -> SchemaComponent.Ref + 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]; + static private final SchemaAnnotation[] EMPTY_ANN_ARRAY = new SchemaAnnotation[0]; + + public void saveToDirectory(File classDir) + { + save(new FilerImpl(classDir, null, null, false, false)); + } + + public void save(Filer filer) + { + if (_incomplete) + throw new IllegalStateException("Incomplete SchemaTypeSystems cannot be saved."); + + if (filer == null) + throw new IllegalArgumentException("filer must not be null"); + _filer = filer; + + _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(); + + saveLoader(); + } + + 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) + { + if (_incomplete) + throw new IllegalStateException("This SchemaTypeSystem cannot be saved."); + for (int i = 0; i < elts.length; i++) + { + saveGlobalElement(elts[i]); + } + } + + public void saveGlobalAttributes(SchemaGlobalAttribute[] attrs) + { + if (_incomplete) + throw new IllegalStateException("This SchemaTypeSystem cannot be saved."); + for (int i = 0; i < attrs.length; i++) + { + saveGlobalAttribute(attrs[i]); + } + } + + public void saveModelGroups(SchemaModelGroup[] groups) + { + if (_incomplete) + throw new IllegalStateException("This SchemaTypeSystem cannot be saved."); + for (int i = 0; i < groups.length; i++) + { + saveModelGroup(groups[i]); + } + } + + public void saveAttributeGroups(SchemaAttributeGroup[] groups) + { + if (_incomplete) + throw new IllegalStateException("This SchemaTypeSystem cannot be saved."); + for (int i = 0; i < groups.length; i++) + { + saveAttributeGroup(groups[i]); + } + } + + public void saveIdentityConstraints(SchemaIdentityConstraint[] idcs) + { + if (_incomplete) + throw new IllegalStateException("This SchemaTypeSystem cannot be saved."); + for (int i = 0; i < idcs.length; i++) + { + saveIdentityConstraint(idcs[i]); + } + } + + public void saveGlobalElement(SchemaGlobalElement elt) + { + if (_incomplete) + throw new IllegalStateException("This SchemaTypeSystem cannot be saved."); + 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) + { + if (_incomplete) + throw new IllegalStateException("This SchemaTypeSystem cannot be saved."); + 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) + { + if (_incomplete) + throw new IllegalStateException("This SchemaTypeSystem cannot be saved."); + 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) + { + if (_incomplete) + throw new IllegalStateException("This SchemaTypeSystem cannot be saved."); + 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) + { + if (_incomplete) + throw new IllegalStateException("This SchemaTypeSystem cannot be saved."); + 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 != 0xFFFF) + 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()); + writeAnnotations(annotations()); + } + + 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(); + int 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); + } + } + + int readShort() + { + try + { + return _input.readUnsignedShort(); + } + catch (IOException e) + { + throw new SchemaTypeLoaderException(e.getMessage(), _name, _handle, SchemaTypeLoaderException.IO_EXCEPTION); + } + } + + 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.", _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()); + } + } + + void writeAnnotation(SchemaAnnotation a) + { + // Write attributes + if (a == null) + { + writeInt(-1); + return; + } + SchemaAnnotation.Attribute[] attributes = a.getAttributes(); + writeInt(attributes.length); + for (int i = 0; i < attributes.length; i++) + { + QName name = attributes[i].getName(); + String value = attributes[i].getValue(); + String valueURI = attributes[i].getValueUri(); + writeQName(name); + writeString(value); + writeString(valueURI); + } + + // Write documentation items + XmlObject[] documentationItems = a.getUserInformation(); + writeInt(documentationItems.length); + XmlOptions opt = new XmlOptions().setSaveOuter(). + setSaveAggressiveNamespaces(); + for (int i = 0; i < documentationItems.length; i++) + { + XmlObject doc = documentationItems[i]; + writeString(doc.xmlText(opt)); + } + + // Write application info items + XmlObject[] appInfoItems = a.getApplicationInformation(); + writeInt(appInfoItems.length); + for (int i = 0; i < appInfoItems.length; i++) + { + XmlObject doc = appInfoItems[i]; + 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 (int i = 0; i < anns.length; i++) + writeAnnotation(anns[i]); + } + + List readAnnotations() + { + int n = readInt(); + List result = new ArrayList(n); + // BUGBUG(radup) + SchemaContainer container = 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 _localHandles.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 _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 + // deprecated: replaced by _XY_ + SchemaGlobalAttribute attr = _linker.findAttribute(QNameHelper.forPretty(handle, 4)); + if (attr == null) + throw new SchemaTypeLoaderException("Cannot resolve attribute for handle " + handle, _name, _handle, SchemaTypeLoaderException.BAD_HANDLE); + return attr.getType().getRef(); + case 'S': // _XS_ - external ref to element's type + // deprecated: replaced by _XY_ + SchemaGlobalElement elem = _linker.findElement(QNameHelper.forPretty(handle, 4)); + if (elem == null) + throw new SchemaTypeLoaderException("Cannot resolve element for handle " + handle, _name, _handle, SchemaTypeLoaderException.BAD_HANDLE); + return elem.getType().getRef(); + case 'O': // _XO_ - external ref to document type + return _linker.findDocumentTypeRef(QNameHelper.forPretty(handle, 4)); + case 'Y': // _XY_ - external ref to any possible type + SchemaType type = _linker.typeForSignature(handle.substring(4)); + if (type == null) + throw new SchemaTypeLoaderException("Cannot resolve type for handle " + handle, _name, _handle, SchemaTypeLoaderException.BAD_HANDLE); + return type.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 + // 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.toString()); + } + + 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; + } + + List readQNameRefMapAsList(List names) + { + int size = readShort(); + List 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 (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) + { + try + { + return _filer.createBinaryFile(name); + } + catch (IOException e) + { + throw new SchemaTypeLoaderException(e.getMessage(), _name, _handle, SchemaTypeLoaderException.IO_EXCEPTION); + } + } + + InputStream getLoaderStream(String resourcename) + { + return _resourceLoader.getResourceAsStream(resourcename); + } + + 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() + { + String handle = null; + try + { + int particleType = readShort(); + if (particleType != SchemaParticle.ELEMENT) + throw new SchemaTypeLoaderException("Wrong particle type ", _name, _handle, SchemaTypeLoaderException.BAD_PARTICLE_TYPE); + int particleFlags = readShort(); + BigInteger minOccurs = readBigInteger(); + BigInteger maxOccurs = readBigInteger(); + QNameSet transitionRules = readQNameSet(); + QName name = readQName(); + SchemaContainer container = 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", _name, handle, SchemaTypeLoaderException.NESTED_EXCEPTION, e); + } + finally + { + readEnd(); + } + } + + public SchemaGlobalAttribute finishLoadingAttribute() + { + try + { + QName name = readQName(); + SchemaContainer container = 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", _name, _handle, SchemaTypeLoaderException.NESTED_EXCEPTION, e); + } + finally + { + readEnd(); + } + } + + SchemaModelGroup finishLoadingModelGroup() + { + QName name = readQName(); + SchemaContainer container = 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 : false, + 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", _name, _handle, SchemaTypeLoaderException.NESTED_EXCEPTION, e); + } + finally + { + readEnd(); + } + } + + SchemaIdentityConstraint finishLoadingIdentityConstraint() + { + try { + QName name = readQName(); + SchemaContainer container = 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 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", _name, _handle, SchemaTypeLoaderException.NESTED_EXCEPTION, e); + } + finally + { + readEnd(); + } + } + + SchemaAttributeGroup finishLoadingAttributeGroup() + { + QName name = readQName(); + SchemaContainer container = 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 : false, + 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", _name, _handle, SchemaTypeLoaderException.NESTED_EXCEPTION, e); + } + finally + { + readEnd(); + } + } + + public SchemaType finishLoadingType() + { + try + { + SchemaContainer cNonNull = 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 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", _name, _handle, SchemaTypeLoaderException.WRONG_PROPERTY_TYPE); + attrProperties.put(prop.getName(), prop); + } + + SchemaParticle contentModel = null; + Map 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", _name, _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", _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) + { + 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 = 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()); + // Set the container for global, attribute or document types + if (impl.getName() != null) + { + SchemaContainer container = getContainer(impl.getName().getNamespaceURI()); + checkContainerNotNull(container, impl.getName()); + impl.setContainer(container); + } + else if (impl.isDocumentType()) + { + QName name = impl.getDocumentElementName(); + if (name != null) + { + SchemaContainer container = getContainer(name.getNamespaceURI()); + checkContainerNotNull(container, name); + impl.setContainer(container); + } + } + else if (impl.isAttributeType()) + { + QName name = impl.getAttributeTypeAttributeName(); + if (name != null) + { + SchemaContainer container = 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", _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()); + 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 (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, 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 (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); + } + 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 (int i = 0; i < spa.length; i++) + writeParticleData(spa[i]); + } + + 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 ", _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()); + writeAnnotation(lpart.getAnnotation()); + 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()); + 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(); + 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()); + 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); + 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 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() + { + int flag = readShort(); + + Set uriSet = new HashSet(); + int uriCount = readShort(); + for (int i = 0; i < uriCount; i++) + uriSet.add(readString()); + + Set qnameSet1 = new HashSet(); + int qncount1 = readShort(); + for (int i = 0; i < qncount1; i++) + qnameSet1.add(readQName()); + + Set 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 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 + { + int 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, 0xFFFF); + 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 == null || _redefinedGlobalTypes.isEmpty()) + return EMPTY_ST_ARRAY; + + SchemaType[] result = new SchemaType[_redefinedGlobalTypes.size()]; + int j = 0; + for (Iterator i = _redefinedGlobalTypes.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" + METADATA_PACKAGE_GEN + "/src" + sourceName); + } + + SchemaContainer[] containers() + { + SchemaContainer[] result = new SchemaContainer[_containers.size()]; + int j = 0; + for (Iterator i = _containers.values().iterator(); i.hasNext(); j++) + result[j] = (SchemaContainer) i.next(); + return result; + } + + 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 == null || _redefinedModelGroups.isEmpty()) + return EMPTY_MG_ARRAY; + + SchemaModelGroup[] result = new SchemaModelGroup[_redefinedModelGroups.size()]; + int j = 0; + for (Iterator i = _redefinedModelGroups.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 == null || _redefinedAttributeGroups.isEmpty()) + return EMPTY_AG_ARRAY; + + SchemaAttributeGroup[] result = new SchemaAttributeGroup[_redefinedAttributeGroups.size()]; + int j = 0; + for (Iterator i = _redefinedAttributeGroups.iterator(); i.hasNext(); j++) + result[j] = ((SchemaAttributeGroup.Ref)i.next()).get(); + return result; + } + + public SchemaAnnotation[] annotations() + { + if (_annotations == null || _annotations.isEmpty()) + return EMPTY_ANN_ARRAY; + + SchemaAnnotation[] result = new SchemaAnnotation[_annotations.size()]; + result = (SchemaAnnotation[]) _annotations.toArray(result); + 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 output 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; + } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaTypeVisitorImpl.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaTypeVisitorImpl.java new file mode 100644 index 000000000..39c0418ce --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SchemaTypeVisitorImpl.java @@ -0,0 +1,514 @@ +/* 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.impl.values.TypeStoreVisitor; +import org.apache.xmlbeans.impl.values.TypeStore; +import javax.xml.namespace.QName; +import org.apache.xmlbeans.SchemaParticle; +import org.apache.xmlbeans.SchemaLocalElement; +import org.apache.xmlbeans.SchemaField; + +import java.util.Arrays; + +/** + * This state machine validates element order based on a deterministic + * content model. + */ +public class SchemaTypeVisitorImpl implements TypeStoreVisitor +{ + /** + * Construct it by passing the root of the content model. + */ + public SchemaTypeVisitorImpl(SchemaParticle part) + { + init(part); + } + + public SchemaTypeVisitorImpl() + { + + } + + public void init(SchemaParticle part) + { + if (_stack == null) + { + _stack = expand(null); + } + if (_rollback == null) + { + _rollback = expand(null); + } + + _stackSize = 0; + _rollbackSize = 0; + + if (part != null) + { + push(part); + _rollbackIndex = 1; + } + } + + public VisitorState[] expand(VisitorState[] orig) + { + int newsize = (orig == null ? 4 : orig.length * 2); + VisitorState[] result = new VisitorState[newsize]; + if (orig != null) + System.arraycopy(orig, 0, result, 0, orig.length); + for (int i = (orig == null ? 0 : orig.length); i < newsize; i++) + { + result[i] = new VisitorState(); + } + return result; + } + + + final static boolean PROBE_VALIDITY = true; + final static boolean CHECK_VALIDITY = false; + + private VisitorState[] _stack; + private VisitorState[] _rollback; + int _stackSize; + int _rollbackSize; + private boolean _isValid; + private SchemaParticle _matchedParticle; + private VisitorState _top; + private int _rollbackIndex; + + private static class VisitorState + { + public void copy(VisitorState orig) + { + _curPart = orig._curPart; + _curCount = orig._curCount; + _curMin = orig._curMin; + _curMax = orig._curMax; + _processedChildCount = orig._processedChildCount; + _childCount = orig._childCount; + if (orig._seen != null) + { + _seen = new boolean[orig._seen.length]; + System.arraycopy(orig._seen, 0, _seen, 0, orig._seen.length); + } + } + + public void init(SchemaParticle part) + { + _curPart = part; + _curMin = part.getIntMinOccurs(); + _curMax = part.getIntMaxOccurs(); + _curCount = 0; + _processedChildCount = 0; + _childCount = part.countOfParticleChild(); + _seen = part.getParticleType() == SchemaParticle.ALL ? + new boolean[_childCount] : null; + } + + SchemaParticle _curPart; + int _curCount; + int _curMax; + int _curMin; + int _processedChildCount; + int _childCount; + boolean[] _seen; + } + + VisitorState topRef() + { + return _stack[_stackSize - 1]; + } + + void saveCopy(VisitorState ref) + { + if (_rollback.length == _rollbackSize) + _rollback = expand(_rollback); + + _rollback[_rollbackSize].copy(ref); + _rollbackSize += 1; + } + + void addParticle(SchemaParticle part) + { + if (_stack.length == _stackSize) + _stack = expand(_stack); + _stack[_stackSize].init(part); + _stackSize += 1; + } + + /** + * Precondition: + * stack: (R1 R2 R3 R4) + * top: null or discardable due to pop in progress + * rollback: (R8 R7 R6 R5) (empty at the start of "visit") + * + * Postcondition: + * stack: (R1 R2 R3) + * top: D4 = mutable copy of R4 + * rollback (R8 R7 R6 R5 R4) + */ + boolean prepare() + { + if (_rollbackIndex == 0) + { + _top = null; + return false; + } + + _top = topRef(); + saveCopy(_top); + _rollbackIndex = _stackSize - 1; + return true; + } + + /** + * Precondition: + * stack: (R1 R2 R3 R4 D5 D6) + * top: D7 + * rollback: (R8 R7 R6 R5) + * + * Postcondition: + * stack: (R1 R2 R3 R4 D5 D6 D7) + * top: D8 = new state based on part + * rollback (R8 R7 R6 R5) + */ + void push(SchemaParticle part) + { + addParticle(part); + _top = topRef(); + } + + /** + * Precondition: + * stack: (R1 R2 R3 R4 D5 D6) + * top: D7 is discardable + * rollback: (R8 R7 R6 R5) + * + * Postcondition: + * stack: (R1 R2 R3 R4 D5) + * top: D6 (see prepare in case it's an R state) + * rollback (R8 R7 R6 R5) + */ + boolean pop() + { + _stackSize -= 1; + if (_stackSize <= _rollbackIndex) + return prepare(); + _top = topRef(); + return true; + } + + /** + * Precondition: + * stack: (R1 R2 R3 R4 D5 D6) + * top: D7 + * rollback: (R8 R7 R6 R5) + * + * Postcondition: + * stack: (R1 R2 R3 R4 D5 D6 D7) -> and rename to D's to R's + * top: null + * rollback () + */ + void commit() + { + _top = null; + _rollbackIndex = _stackSize; + _rollbackSize = 0; + } + + /** + * Precondition: + * stack: (R1 R2 R3 R4 D5 D6) + * top: D7 is discardable + * rollback: (R8 R7 R6 R5) + * + * Postcondition: + * stack: (R1 R2 R3 R4 R5 R6 R7 R8) + * top: null + * rollback () + */ + void rollback() + { + while (_rollbackSize > 0) + { + _rollbackSize -= 1; + VisitorState temp = _stack[_rollbackIndex]; + _stack[_rollbackIndex] = _rollback[_rollbackSize]; + _rollback[_rollbackSize] = temp; + _rollbackIndex += 1; + } + _stackSize = _rollbackIndex; + _top = null; + } + + /** + * When no valid next state can be found, then "notValid" + * is returned. It rolls back any changes to the state + * machine stack, sets to false the valid bit, and clears + * the matched element state before returning false. + */ + boolean notValid() + { + _isValid = false; + _matchedParticle = null; + rollback(); + return false; + } + + /** + * When a valid state transition has been done, then "ok" + * is returned. It commits the changed state machine state, + * stores the matched element state, and returns true. + */ + boolean ok(SchemaParticle part, boolean testValidity) + { + if ( ! testValidity ) + { + _matchedParticle = part; + commit(); + } + else + { + rollback(); + } + return true; + } + + /*== VISITOR IMPLEMENTATION ==*/ + + /** + * Traverses a deterministic content model, checking for + * validity at any given point. + * + * Call visit(null) once at the end if you're checking for + * complete validity of the sequence of elements. + * + * This is a wrapper for the actual visit implementation. + */ + public boolean visit(QName eltName) + { + return visit(eltName, CHECK_VALIDITY); + } + + /** + * The actual implementation that + * traverses a deterministic content model, checking for + * validity at any given point. + * + * When testValidity is false then this method will change states + * if the current state is valid + * + * When testValidity is true then this method will not change states + * and will return if a particular state is valid or invalid + */ + + public boolean visit(QName eltName, boolean testValidity) + { + if (!prepare()) + return notValid(); + + // init with some values out of processedChildCount and stackSize range + int lastAtProcessedChildCount = -2; + int lastAtStackSize = -2; + + traversing: for (;;) + { + // optimization for cases where state doesn't change between _top._curMin and _top._curMax + // check for state change see JIRA bug XMLBEANS-37 + if (_top._curCount>_top._curMin && + lastAtProcessedChildCount==_top._processedChildCount && + lastAtStackSize==_stackSize) + { + _top._curCount = _top._curMax; + } + + // save state + lastAtProcessedChildCount = _top._processedChildCount; + lastAtStackSize = _stackSize; + + while (_top._curCount >= _top._curMax) + { + if (!pop()) + break traversing; + } + + minmax: switch (_top._curPart.getParticleType()) + { + default: + assert(false); + + case SchemaParticle.WILDCARD: + if (!_top._curPart.canStartWithElement(eltName)) + { + if (_top._curCount < _top._curMin) + return notValid(); + break minmax; + } + _top._curCount++; + return ok(_top._curPart, testValidity); + + case SchemaParticle.ELEMENT: + if (!_top._curPart.canStartWithElement(eltName)) + { + if (_top._curCount < _top._curMin) + return notValid(); + break minmax; + } + _top._curCount++; + return ok(_top._curPart, testValidity); + + case SchemaParticle.SEQUENCE: + for (int i = _top._processedChildCount; i < _top._childCount; i++) + { + SchemaParticle candidate = _top._curPart.getParticleChild(i); + if (candidate.canStartWithElement(eltName)) + { + _top._processedChildCount = i + 1; + push(candidate); + continue traversing; + } + if (!candidate.isSkippable()) + { + if (_top._processedChildCount != 0 || _top._curCount < _top._curMin) + return notValid(); + break minmax; + } + } + _top._curCount++; + _top._processedChildCount = 0; + + continue traversing; + + + case SchemaParticle.CHOICE: + for (int i = 0; i < _top._childCount; i++) + { + SchemaParticle candidate = _top._curPart.getParticleChild(i); + if (candidate.canStartWithElement(eltName)) + { + _top._curCount++; + push(candidate); + continue traversing; + } + } + if (_top._curCount < _top._curMin && !_top._curPart.isSkippable()) + return notValid(); + break minmax; + + case SchemaParticle.ALL: + + int skipped = _top._processedChildCount; + allscan: for (int i = 0; i < _top._childCount; i++) + { + if (_top._seen[i]) + continue allscan; + + SchemaParticle candidate = _top._curPart.getParticleChild(i); + if (candidate.canStartWithElement(eltName)) + { + _top._processedChildCount++; + _top._seen[i] = true; + push(candidate); + continue traversing; + } + else if (candidate.isSkippable()) + { + skipped += 1; + } + } + if (skipped < _top._childCount) + { + if (_top._curCount < _top._curMin) + return notValid(); + break minmax; + } + _top._curCount++; + _top._processedChildCount = 0; + Arrays.fill(_top._seen, false); + continue traversing; + } + + // somebody called "break minmax", so pop out of loop + if (!pop()) + break traversing; + } + + // we've completed the outermost loop + if (eltName == null) + return ok(null, testValidity); + + // this means we have extra elements at the end + return notValid(); + } + + public boolean testValid(QName eltName) + { + return visit(eltName,PROBE_VALIDITY); + } + + /** + * Constructs elementflags + */ + public int get_elementflags() + { + if (currentParticle() == null || currentParticle().getParticleType() != SchemaParticle.ELEMENT) + return 0; + + SchemaLocalElement elt = (SchemaLocalElement)currentParticle(); + + return (elt.isNillable() ? TypeStore.NILLABLE : 0) | + (elt.isDefault() ? TypeStore.HASDEFAULT : 0) | + (elt.isFixed() ? TypeStore.FIXED : 0); + } + + /** + * Returns default text + */ + public String get_default_text() + { + if (currentParticle() == null || currentParticle().getParticleType() != SchemaParticle.ELEMENT) + return null; + + return ((SchemaLocalElement)currentParticle()).getDefaultText(); + } + + /** + * Returns the schema field for this field. + */ + public SchemaField get_schema_field() { + if (currentParticle() instanceof SchemaField) + return (SchemaField)currentParticle(); + + return null; + } + + /** + * Returns the current schema element + */ + public SchemaParticle currentParticle() + { + return _matchedParticle; + } + + /** + * Returns true if the entire content up to now is valid. + */ + public boolean isAllValid() + { + return _isValid; + } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SoapEncSchemaTypeSystem.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SoapEncSchemaTypeSystem.java new file mode 100644 index 000000000..0bb9edbc1 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/SoapEncSchemaTypeSystem.java @@ -0,0 +1,348 @@ +/* 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 java.io.InputStream; +import java.io.File; +import java.math.BigInteger; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Collections; +import javax.xml.namespace.QName; + +import org.apache.xmlbeans.QNameSet; +import org.apache.xmlbeans.SchemaAnnotation; +import org.apache.xmlbeans.SchemaAttributeGroup; +import org.apache.xmlbeans.SchemaAttributeGroup; +import org.apache.xmlbeans.SchemaAttributeModel; +import org.apache.xmlbeans.SchemaComponent; +import org.apache.xmlbeans.SchemaGlobalAttribute; +import org.apache.xmlbeans.SchemaGlobalAttribute; +import org.apache.xmlbeans.SchemaGlobalElement; +import org.apache.xmlbeans.SchemaGlobalElement; +import org.apache.xmlbeans.SchemaIdentityConstraint; +import org.apache.xmlbeans.SchemaLocalAttribute; +import org.apache.xmlbeans.SchemaModelGroup; +import org.apache.xmlbeans.SchemaModelGroup; +import org.apache.xmlbeans.SchemaParticle; +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.SchemaTypeLoader; +import org.apache.xmlbeans.SchemaTypeSystem; +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.Filer; + +public class SoapEncSchemaTypeSystem extends SchemaTypeLoaderBase + implements SchemaTypeSystem +{ + public static final String SOAPENC = "http://schemas.xmlsoap.org/soap/encoding/"; + public static final String SOAP_ARRAY = "Array"; + public static final String ARRAY_TYPE = "arrayType"; + private static final String ATTR_ID = "id"; + private static final String ATTR_HREF = "href"; + private static final String ATTR_OFFSET = "offset"; + + private static final SchemaType[] EMPTY_SCHEMATYPE_ARRAY = new SchemaType[0]; + private static final SchemaGlobalElement[] EMPTY_SCHEMAELEMENT_ARRAY = new SchemaGlobalElement[0]; + private static final SchemaModelGroup[] EMPTY_SCHEMAMODELGROUP_ARRAY = new SchemaModelGroup[0]; + private static final SchemaAttributeGroup[] EMPTY_SCHEMAATTRIBUTEGROUP_ARRAY = new SchemaAttributeGroup[0]; + private static final SchemaAnnotation[] EMPTY_SCHEMAANNOTATION_ARRAY = new SchemaAnnotation[0]; + + // The global builtin type system + public static SchemaTypeSystem get() + { return _global; } + + private static SoapEncSchemaTypeSystem _global = new SoapEncSchemaTypeSystem(); + + private SchemaTypeImpl soapArray; + private SchemaGlobalAttributeImpl arrayType; + private Map _handlesToObjects = new HashMap(); + private String soapArrayHandle; + private SchemaContainer _container = new SchemaContainer(SOAPENC); + + private SoapEncSchemaTypeSystem() + { + // soapenc:Array + _container.setTypeSystem(this); + soapArray = new SchemaTypeImpl(_container, true); + _container.addGlobalType(soapArray.getRef()); + soapArray.setName(new QName(SOAPENC, SOAP_ARRAY)); + soapArrayHandle = SOAP_ARRAY.toLowerCase() + "type"; + soapArray.setComplexTypeVariety(SchemaType.ELEMENT_CONTENT); + soapArray.setBaseTypeRef(BuiltinSchemaTypeSystem.ST_ANY_TYPE.getRef()); + soapArray.setBaseDepth(1); + soapArray.setDerivationType(SchemaType.DT_EXTENSION); + soapArray.setSimpleTypeVariety(SchemaType.NOT_SIMPLE); + SchemaParticleImpl contentModel = new SchemaParticleImpl(); + contentModel.setParticleType(SchemaParticle.SEQUENCE); + contentModel.setMinOccurs(BigInteger.ZERO); + contentModel.setMaxOccurs(BigInteger.ONE); + contentModel.setTransitionRules(QNameSet.ALL, true); + SchemaParticleImpl[] children = new SchemaParticleImpl[1]; + contentModel.setParticleChildren(children); + SchemaParticleImpl contentModel2 = new SchemaParticleImpl(); + contentModel2.setParticleType(SchemaParticle.WILDCARD); + contentModel2.setWildcardSet(QNameSet.ALL); + contentModel2.setWildcardProcess(SchemaParticle.LAX); + contentModel2.setMinOccurs(BigInteger.ZERO); + contentModel2.setMaxOccurs(null); + contentModel2.setTransitionRules(QNameSet.ALL, true); + children[0] = contentModel2; + + SchemaAttributeModelImpl attrModel = new SchemaAttributeModelImpl(); + attrModel.setWildcardProcess(SchemaAttributeModel.LAX); + HashSet excludedURI = new HashSet(); + excludedURI.add(SOAPENC); + attrModel.setWildcardSet(QNameSet.forSets(excludedURI, null, Collections.EMPTY_SET, + Collections.EMPTY_SET)); + SchemaLocalAttributeImpl attr = new SchemaLocalAttributeImpl(); + attr.init(new QName("", ATTR_ID), BuiltinSchemaTypeSystem.ST_ID.getRef(), + SchemaLocalAttribute.OPTIONAL, null, null, null, false, null, null, null); + attrModel.addAttribute(attr); + attr = new SchemaLocalAttributeImpl(); + attr.init(new QName("", ATTR_HREF), BuiltinSchemaTypeSystem.ST_ANY_URI.getRef(), + SchemaLocalAttributeImpl.OPTIONAL, null, null, null, false, null, null, null); + attrModel.addAttribute(attr); + attr = new SchemaLocalAttributeImpl(); + attr.init(new QName(SOAPENC, ARRAY_TYPE), BuiltinSchemaTypeSystem.ST_STRING.getRef(), + SchemaLocalAttributeImpl.OPTIONAL, null, null, null, false, null, null, null); + attrModel.addAttribute(attr); + attr = new SchemaLocalAttributeImpl(); + attr.init(new QName(SOAPENC, ATTR_OFFSET), BuiltinSchemaTypeSystem.ST_STRING.getRef(), + SchemaLocalAttributeImpl.OPTIONAL, null, null, null, false, null, null, null); + attrModel.addAttribute(attr); + soapArray.setContentModel(contentModel, attrModel, Collections.EMPTY_MAP, Collections.EMPTY_MAP, false); + + // soapenc:arrayType + arrayType = new SchemaGlobalAttributeImpl(_container); + _container.addGlobalAttribute(arrayType.getRef()); + arrayType.init(new QName(SOAPENC, ARRAY_TYPE), BuiltinSchemaTypeSystem.ST_STRING.getRef(), + SchemaLocalAttributeImpl.OPTIONAL, null, null, null, false, null, null, null); + _handlesToObjects.put(soapArrayHandle, soapArray); + _handlesToObjects.put(ARRAY_TYPE.toLowerCase() + "attribute", arrayType); + _container.setImmutable(); + } + + /** + * Returns the name of this loader. + */ + public String getName() + { + return "schema.typesystem.soapenc.builtin"; + } + + public SchemaType findType(QName qName) + { + if (SOAPENC.equals(qName.getNamespaceURI()) && + SOAP_ARRAY.equals(qName.getLocalPart())) + return soapArray; + else + return null; + } + + public SchemaType findDocumentType(QName qName) + { + return null; + } + + public SchemaType findAttributeType(QName qName) + { + return null; + } + + public SchemaGlobalElement findElement(QName qName) + { + return null; + } + + public SchemaGlobalAttribute findAttribute(QName qName) + { + if (SOAPENC.equals(qName.getNamespaceURI()) && + ARRAY_TYPE.equals(qName.getLocalPart())) + return arrayType; + else + return null; + } + + public SchemaModelGroup findModelGroup(QName qName) + { + return null; + } + + public SchemaAttributeGroup findAttributeGroup(QName qName) + { + return null; + } + + public boolean isNamespaceDefined(String string) + { + return SOAPENC.equals(string); + } + + public SchemaType.Ref findTypeRef(QName qName) + { + SchemaType type = findType(qName); + return (type == null ? null : type.getRef()); + } + + public SchemaType.Ref findDocumentTypeRef(QName qName) + { + return null; + } + + public SchemaType.Ref findAttributeTypeRef(QName qName) + { + return null; + } + + public SchemaGlobalElement.Ref findElementRef(QName qName) + { + return null; + } + + public SchemaGlobalAttribute.Ref findAttributeRef(QName qName) + { + SchemaGlobalAttribute attr = findAttribute(qName); + return (attr == null ? null : attr.getRef()); + } + + public SchemaModelGroup.Ref findModelGroupRef(QName qName) + { + return null; + } + + public SchemaAttributeGroup.Ref findAttributeGroupRef(QName qName) + { + return null; + } + + public SchemaIdentityConstraint.Ref findIdentityConstraintRef(QName qName) + { + return null; + } + + public SchemaType typeForClassname(String string) + { + return null; + } + + public InputStream getSourceAsStream(String string) + { + return null; // no source + } + + /** + * Returns the classloader used by this loader for resolving types. + */ + public ClassLoader getClassLoader() + { + return SoapEncSchemaTypeSystem.class.getClassLoader(); + } + + /** + * Describe resolve method here. + * + */ + public void resolve() + { + // don't need to do anything; already resolved + } + + /** + * @return an array consisting of a single type + */ + public SchemaType[] globalTypes() + { + return new SchemaType[] {soapArray}; + } + + public SchemaType[] documentTypes() + { + return EMPTY_SCHEMATYPE_ARRAY; + } + + public SchemaType[] attributeTypes() + { + return EMPTY_SCHEMATYPE_ARRAY; + } + + public SchemaGlobalElement[] globalElements() + { + return EMPTY_SCHEMAELEMENT_ARRAY; + } + + public SchemaGlobalAttribute[] globalAttributes() + { + return new SchemaGlobalAttribute[] {arrayType}; + } + + public SchemaModelGroup[] modelGroups() + { + return EMPTY_SCHEMAMODELGROUP_ARRAY; + } + + public SchemaAttributeGroup[] attributeGroups() + { + return EMPTY_SCHEMAATTRIBUTEGROUP_ARRAY; + } + + public SchemaAnnotation[] annotations() + { + return EMPTY_SCHEMAANNOTATION_ARRAY; + } + + /** + * Returns the handle for the given type within this loader. + */ + public String handleForType(SchemaType type) + { + if (soapArray.equals(type)) + return soapArrayHandle; + else + return null; + } + + /** + * + */ + public SchemaComponent resolveHandle(String string) + { + return (SchemaComponent) _handlesToObjects.get(string); + } + + /** + * + */ + public SchemaType typeForHandle(String string) + { + return (SchemaType) _handlesToObjects.get(string); + } + + /** + * Describe saveToDirectory method here. + * + * @param file a File value + */ + public void saveToDirectory(File file) + { + throw new UnsupportedOperationException("The builtin soap encoding schema type system cannot be saved."); + } + + public void save(Filer filer) + { + throw new UnsupportedOperationException("The builtin soap encoding schema type system cannot be saved."); + } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/StscChecker.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/StscChecker.java new file mode 100644 index 000000000..ebcf97907 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/StscChecker.java @@ -0,0 +1,1732 @@ +/* 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.SchemaType; +import org.apache.xmlbeans.SchemaParticle; +import org.apache.xmlbeans.XmlError; +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.XmlOptions; +import org.apache.xmlbeans.SchemaLocalElement; +import org.apache.xmlbeans.SchemaIdentityConstraint; +import org.apache.xmlbeans.SchemaAttributeModel; +import org.apache.xmlbeans.SchemaLocalAttribute; +import org.apache.xmlbeans.SchemaGlobalElement; +import org.apache.xmlbeans.XmlID; +import org.apache.xmlbeans.XmlAnySimpleType; +import org.apache.xmlbeans.XmlErrorCodes; +import org.apache.xmlbeans.XmlNOTATION; +import org.apache.xmlbeans.XmlString; +import org.apache.xmlbeans.impl.common.XBeanDebug; +import org.apache.xmlbeans.impl.common.QNameHelper; + +import javax.xml.namespace.QName; +import java.util.List; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; +import java.math.BigInteger; + +public class StscChecker +{ + public static void checkAll() + { + // walk the tree of types + StscState state = StscState.get(); + + List allSeenTypes = new ArrayList(); + allSeenTypes.addAll(Arrays.asList(state.documentTypes())); + allSeenTypes.addAll(Arrays.asList(state.attributeTypes())); + allSeenTypes.addAll(Arrays.asList(state.redefinedGlobalTypes())); + allSeenTypes.addAll(Arrays.asList(state.globalTypes())); + + for (int i = 0; i < allSeenTypes.size(); i++) + { + SchemaType gType = (SchemaType)allSeenTypes.get(i); + if (!state.noPvr() && // option to turn off particle restriction checking + !gType.isDocumentType()) // Don't check doc types for restriction. + { + checkRestriction((SchemaTypeImpl)gType); + } + checkFields((SchemaTypeImpl)gType); + allSeenTypes.addAll(Arrays.asList(gType.getAnonymousTypes())); + } + + checkSubstitutionGroups(state.globalElements()); + } + + /** + * The following code checks rule #5 of http://www.w3.org/TR/xmlschema-1/#coss-ct + * as well as attribute + element default/fixed validity.

    + * Checks that xs:NOTATION is not used directly + */ + public static void checkFields(SchemaTypeImpl sType) + { + if (sType.isSimpleType()) + return; + + XmlObject location = sType.getParseObject(); + + SchemaAttributeModel sAttrModel = sType.getAttributeModel(); + if (sAttrModel != null) + { + SchemaLocalAttribute[] sAttrs = sAttrModel.getAttributes(); + QName idAttr = null; + for (int i = 0; i < sAttrs.length; i++) + { + XmlObject attrLocation = ((SchemaLocalAttributeImpl)sAttrs[i])._parseObject; + if (XmlID.type.isAssignableFrom(sAttrs[i].getType())) + { + if (idAttr == null) + { + idAttr = sAttrs[i].getName(); + } + else + { + StscState.get().error(XmlErrorCodes.ATTR_GROUP_PROPERTIES$TWO_IDS, + new Object[]{ QNameHelper.pretty(idAttr), sAttrs[i].getName() }, + attrLocation != null ? attrLocation : location); + } + if (sAttrs[i].getDefaultText() != null) + { + StscState.get().error(XmlErrorCodes.ATTR_PROPERTIES$ID_FIXED_OR_DEFAULT, + null, attrLocation != null ? attrLocation : location); + } + } + else if (XmlNOTATION.type.isAssignableFrom(sAttrs[i].getType())) + { + if (sAttrs[i].getType().getBuiltinTypeCode() == SchemaType.BTC_NOTATION) + { + StscState.get().recover(XmlErrorCodes.ATTR_NOTATION_TYPE_FORBIDDEN, + new Object[]{ QNameHelper.pretty(sAttrs[i].getName()) }, + attrLocation != null ? attrLocation : location); + } + else + { + if (sAttrs[i].getType().getSimpleVariety() == SchemaType.UNION) + { + SchemaType[] members = sAttrs[i].getType().getUnionConstituentTypes(); + for (int j = 0; j < members.length; j++) + if (members[j].getBuiltinTypeCode() == SchemaType.BTC_NOTATION) + StscState.get().recover(XmlErrorCodes.ATTR_NOTATION_TYPE_FORBIDDEN, + new Object[]{ QNameHelper.pretty(sAttrs[i].getName()) }, + attrLocation != null ? attrLocation : location); + } + // Check that the Schema in which this is present doesn't have a targetNS + boolean hasNS; + if (sType.isAttributeType()) + hasNS = sAttrs[i].getName().getNamespaceURI().length() > 0; + else + { + SchemaType t = sType; + while (t.getOuterType() != null) + t = t.getOuterType(); + if (t.isDocumentType()) + hasNS = t.getDocumentElementName().getNamespaceURI().length() > 0; + else hasNS = t.getName().getNamespaceURI().length() > 0; + } + if (hasNS) + StscState.get().warning(XmlErrorCodes.ATTR_COMPATIBILITY_TARGETNS, + new Object[] {QNameHelper.pretty(sAttrs[i].getName()) }, + attrLocation != null ? attrLocation : location); + } + } + else + { + String valueConstraint = sAttrs[i].getDefaultText(); + if (valueConstraint != null) + { + try + { + XmlAnySimpleType val = sAttrs[i].getDefaultValue(); + if (!val.validate()) + throw new Exception(); + + SchemaPropertyImpl sProp = (SchemaPropertyImpl)sType.getAttributeProperty(sAttrs[i].getName()); + if (sProp != null && sProp.getDefaultText() != null) + { + sProp.setDefaultValue(new XmlValueRef(val)); + } + } + catch (Exception e) + { + // move to 'fixed' or 'default' attribute on the attribute definition + String constraintName = (sAttrs[i].isFixed() ? "fixed" : "default"); + XmlObject constraintLocation = location; + if (attrLocation != null) + { + constraintLocation = attrLocation.selectAttribute("", constraintName); + if (constraintLocation == null) + constraintLocation = attrLocation; + } + + StscState.get().error(XmlErrorCodes.ATTR_PROPERTIES$CONSTRAINT_VALID, + new Object[] { QNameHelper.pretty(sAttrs[i].getName()), + constraintName, + valueConstraint, + QNameHelper.pretty(sAttrs[i].getType().getName()) }, + constraintLocation); + } + } + } + } + } + + checkElementDefaults(sType.getContentModel(), location, sType); + } + + /** + * Checks the default values of elements.

    You can specify options to RegularExpression(regex, options) + * or setPattern(regex, options). + * This options parameter consists of the following characters. + *

    + * Also checks that the type of elements is not one of ID, IDREF, IDREFS, ENTITY, ENTITIES or + * NOTATION as per XMLSchema part 2. + * @param model + * @param location + * @param parentType + */ + private static void checkElementDefaults(SchemaParticle model, XmlObject location, SchemaType parentType) + { + if (model == null) + return; + switch (model.getParticleType()) + { + case SchemaParticle.SEQUENCE: + case SchemaParticle.CHOICE: + case SchemaParticle.ALL: + SchemaParticle[] children = model.getParticleChildren(); + for (int i = 0; i < children.length; i++) + { + checkElementDefaults(children[i], location, parentType); + } + break; + case SchemaParticle.ELEMENT: + String valueConstraint = model.getDefaultText(); + if (valueConstraint != null) + { + if (model.getType().isSimpleType() || model.getType().getContentType() == SchemaType.SIMPLE_CONTENT) + { + try + { + XmlAnySimpleType val = model.getDefaultValue(); + XmlOptions opt = new XmlOptions(); + opt.put(XmlOptions.VALIDATE_TEXT_ONLY); + if (!val.validate(opt)) + throw new Exception(); + + SchemaPropertyImpl sProp = (SchemaPropertyImpl)parentType.getElementProperty(model.getName()); + if (sProp != null && sProp.getDefaultText() != null) + { + sProp.setDefaultValue(new XmlValueRef(val)); + } + } + catch (Exception e) + { + // move to 'fixed' or 'default' attribute on the element definition + String constraintName = (model.isFixed() ? "fixed" : "default"); + XmlObject constraintLocation = location.selectAttribute("", constraintName); + + StscState.get().error(XmlErrorCodes.ELEM_PROPERTIES$CONSTRAINT_VALID, + new Object[] { QNameHelper.pretty(model.getName()), + constraintName, + valueConstraint, + QNameHelper.pretty(model.getType().getName()) }, + (constraintLocation==null ? location : constraintLocation)); + } + } + else if (model.getType().getContentType() == SchemaType.MIXED_CONTENT) + { + if (!model.getType().getContentModel().isSkippable()) + { + String constraintName = (model.isFixed() ? "fixed" : "default"); + XmlObject constraintLocation = location.selectAttribute("", constraintName); + + StscState.get().error(XmlErrorCodes.ELEM_DEFAULT_VALID$MIXED_AND_EMPTIABLE, + new Object[] { QNameHelper.pretty(model.getName()), + constraintName, + valueConstraint }, + (constraintLocation==null ? location : constraintLocation)); + } + else + { + // Element Default Valid (Immediate): cos-valid-default.2.2.2 + // no need to validate the value; type is a xs:string + SchemaPropertyImpl sProp = (SchemaPropertyImpl)parentType.getElementProperty(model.getName()); + if (sProp != null && sProp.getDefaultText() != null) + { + sProp.setDefaultValue(new XmlValueRef(XmlString.type.newValue(valueConstraint))); + } + } + } + else if (model.getType().getContentType() == SchemaType.ELEMENT_CONTENT) + { + XmlObject constraintLocation = location.selectAttribute("", "default"); + StscState.get().error(XmlErrorCodes.ELEM_DEFAULT_VALID$SIMPLE_TYPE_OR_MIXED, + new Object[] { QNameHelper.pretty(model.getName()), + valueConstraint, + "element" }, + (constraintLocation==null ? location : constraintLocation)); + } + else if (model.getType().getContentType() == SchemaType.EMPTY_CONTENT) + { + XmlObject constraintLocation = location.selectAttribute("", "default"); + StscState.get().error(XmlErrorCodes.ELEM_DEFAULT_VALID$SIMPLE_TYPE_OR_MIXED, + new Object[] { QNameHelper.pretty(model.getName()), + valueConstraint, + "empty" }, + (constraintLocation==null ? location : constraintLocation)); + } + } + // Checks if the type is one of the "attribute-specific" types + String warningType = null; + if (BuiltinSchemaTypeSystem.ST_ID.isAssignableFrom(model.getType())) + warningType = BuiltinSchemaTypeSystem.ST_ID.getName().getLocalPart(); + else if (BuiltinSchemaTypeSystem.ST_IDREF.isAssignableFrom(model.getType())) + warningType = BuiltinSchemaTypeSystem.ST_IDREF.getName().getLocalPart(); + else if (BuiltinSchemaTypeSystem.ST_IDREFS.isAssignableFrom(model.getType())) + warningType = BuiltinSchemaTypeSystem.ST_IDREFS.getName().getLocalPart(); + else if (BuiltinSchemaTypeSystem.ST_ENTITY.isAssignableFrom(model.getType())) + warningType = BuiltinSchemaTypeSystem.ST_ENTITY.getName().getLocalPart(); + else if (BuiltinSchemaTypeSystem.ST_ENTITIES.isAssignableFrom(model.getType())) + warningType = BuiltinSchemaTypeSystem.ST_ENTITIES.getName().getLocalPart(); + else if (BuiltinSchemaTypeSystem.ST_NOTATION.isAssignableFrom(model.getType())) + { + if (model.getType().getBuiltinTypeCode() == SchemaType.BTC_NOTATION) + { + StscState.get().recover(XmlErrorCodes.ELEM_NOTATION_TYPE_FORBIDDEN, + new Object[]{ QNameHelper.pretty(model.getName()) }, + ((SchemaLocalElementImpl) model)._parseObject == null ? location : + ((SchemaLocalElementImpl) model)._parseObject.selectAttribute("", "type")); + } + else + { + if (model.getType().getSimpleVariety() == SchemaType.UNION) + { + SchemaType[] members = model.getType().getUnionConstituentTypes(); + for (int i = 0; i < members.length; i++) + if (members[i].getBuiltinTypeCode() == SchemaType.BTC_NOTATION) + StscState.get().recover(XmlErrorCodes.ELEM_NOTATION_TYPE_FORBIDDEN, + new Object[]{ QNameHelper.pretty(model.getName()) }, + ((SchemaLocalElementImpl) model)._parseObject == null ? location : + ((SchemaLocalElementImpl) model)._parseObject.selectAttribute("", "type")); + } + warningType = BuiltinSchemaTypeSystem.ST_NOTATION.getName().getLocalPart(); + } + + // Check that the Schema in which this is present doesn't have a targetNS + boolean hasNS; + SchemaType t = parentType; + while (t.getOuterType() != null) + t = t.getOuterType(); + if (t.isDocumentType()) + hasNS = t.getDocumentElementName().getNamespaceURI().length() > 0; + else + hasNS = t.getName().getNamespaceURI().length() > 0; + if (hasNS) + StscState.get().warning(XmlErrorCodes.ELEM_COMPATIBILITY_TARGETNS, + new Object[] {QNameHelper.pretty(model.getName()) }, + ((SchemaLocalElementImpl) model)._parseObject == null ? location : + ((SchemaLocalElementImpl) model)._parseObject); + } + + if (warningType != null) + StscState.get().warning(XmlErrorCodes.ELEM_COMPATIBILITY_TYPE, new Object[] + { QNameHelper.pretty(model.getName()), warningType }, + ((SchemaLocalElementImpl) model)._parseObject == null ? location : + ((SchemaLocalElementImpl) model)._parseObject.selectAttribute("", "type")); + + break; + + default: + // nothing to do. + break; + } + } + + /** + * The following code only checks rule #5 of http://www.w3.org/TR/xmlschema-1/#derivation-ok-restriction + * (Everything else can and should be done in StscResolver, because we can give more detailed line # info there + */ + public static boolean checkRestriction(SchemaTypeImpl sType) + { + if (sType.getDerivationType() == SchemaType.DT_RESTRICTION && !sType.isSimpleType()) + { + StscState state = StscState.get(); + + // we don't remember very precise line number information, but it's better than nothin. + XmlObject location = sType.getParseObject(); + + SchemaType baseType = sType.getBaseType(); + if (baseType.isSimpleType()) + { + state.error(XmlErrorCodes.SCHEMA_COMPLEX_TYPE$COMPLEX_CONTENT, + new Object[] { QNameHelper.pretty(baseType.getName()) }, + location); + return false; + } + + // 5 The appropriate case among the following must be true: + switch (sType.getContentType()) + { + case SchemaType.SIMPLE_CONTENT: + // 5.1 If the {content type} of the complex type definition is a simple type definition, then one of the following must be true: + switch (baseType.getContentType()) + { + case SchemaType.SIMPLE_CONTENT: + // 5.1.1 The {content type} of the {base type definition} must be a simple type definition of which the {content type} is a �valid restriction� as defined in Derivation Valid (Restriction, Simple) (�3.14.6). + SchemaType cType = sType.getContentBasedOnType(); + if (cType != baseType) + { + // We have to check that the contentType is legally derived + // from the base simple type in the hierarchy + SchemaType bType = baseType; + while (bType != null && !bType.isSimpleType()) + bType = bType.getContentBasedOnType(); + if (bType != null && !bType.isAssignableFrom(cType)) + { + state.error(XmlErrorCodes.COMPLEX_TYPE_RESTRICTION$SC_NOT_DERIVED, + null, location); + return false; + } + } + break; + + case SchemaType.MIXED_CONTENT: + // 5.1.2 The {base type definition} must be mixed and have a particle which is �emptiable� as defined in Particle Emptiable (�3.9.6). + if (baseType.getContentModel() != null && !baseType.getContentModel().isSkippable()) + { + state.error(XmlErrorCodes.COMPLEX_TYPE_RESTRICTION$SC_AND_MIXED_EMPTIABLE, + null, location); + return false; + } + break; + + default: + state.error(XmlErrorCodes.COMPLEX_TYPE_RESTRICTION$SC_AND_SIMPLE_TYPE_OR_MIXED, + null, location); + return false; + } + break; + + case SchemaType.EMPTY_CONTENT: + // 5.2 If the {content type} of the complex type itself is empty , then one of the following must be true: + switch (baseType.getContentType()) + { + case SchemaType.EMPTY_CONTENT: + // 5.2.1 The {content type} of the {base type definition} must also be empty. + break; + case SchemaType.MIXED_CONTENT: + case SchemaType.ELEMENT_CONTENT: + // 5.2.2 The {content type} of the {base type definition} must be elementOnly or mixed and have a particle which is �emptiable� as defined in Particle Emptiable (�3.9.6). + if (baseType.getContentModel() != null && !baseType.getContentModel().isSkippable()) + { + state.error(XmlErrorCodes.COMPLEX_TYPE_RESTRICTION$EMPTY_AND_ELEMENT_OR_MIXED_EMPTIABLE, + null, location); + return false; + } + break; + default: + state.error(XmlErrorCodes.COMPLEX_TYPE_RESTRICTION$EMPTY_AND_NOT_SIMPLE, + null, location); + return false; + } + break; + + case SchemaType.MIXED_CONTENT: + // 5.3 If the {content type} of the {base type definition} is mixed... + if (baseType.getContentType() != SchemaType.MIXED_CONTENT) + { + state.error(XmlErrorCodes.COMPLEX_TYPE_RESTRICTION$ELEMENT_OR_MIXED_AND_MIXED, + null, location); + return false; + } + + // FALLTHROUGH + case SchemaType.ELEMENT_CONTENT: + // 5.3 ... or the {content type} of the complex type definition itself is element-only,... + if (baseType.getContentType() == SchemaType.EMPTY_CONTENT) + { + state.error(XmlErrorCodes.COMPLEX_TYPE_RESTRICTION$ELEMENT_OR_MIXED_AND_EMPTY, + null, location); + return false; + } + if (baseType.getContentType() == SchemaType.SIMPLE_CONTENT) + { + state.error(XmlErrorCodes.COMPLEX_TYPE_RESTRICTION$ELEMENT_OR_MIXED_AND_SIMPLE, + null, location); + return false; + } + + // 5.3 ... then the particle of the complex type definition itself must be a �valid restriction� of the particle of the {content type} of the {base type definition} + SchemaParticle baseModel = baseType.getContentModel(); + SchemaParticle derivedModel = sType.getContentModel(); + + if ( derivedModel == null && sType.getDerivationType()==SchemaType.DT_RESTRICTION ) + { + // it is ok to have an empty contentModel if it's a restriction + // see Particle Valid (Restriction) (3.9.6) all three bulets 2.2.1 + return true; + } + else if (baseModel == null || derivedModel == null) + { + XBeanDebug.logStackTrace("Null models that weren't caught by EMPTY_CONTENT: " + baseType + " (" + baseModel + "), " + sType + " (" + derivedModel + ")"); + state.error(XmlErrorCodes.COMPLEX_TYPE_RESTRICTION$ELEMENT_OR_MIXED_AND_VALID, null, location); + return false; + } + + // 5.3 ... as defined in Particle Valid (Restriction) (�3.9.6). + List errors = new ArrayList(); + boolean isValid = isParticleValidRestriction(baseModel, derivedModel, errors, location); + if (!isValid) + { + // we only add the last error, because isParticleValidRestriction may add errors + // to the collection that it later changes its mind about, or it may (inadvertently) + // forget to describe an error into the collection.... + if (errors.size() == 0) + state.error(XmlErrorCodes.COMPLEX_TYPE_RESTRICTION$ELEMENT_OR_MIXED_AND_VALID, null, location); + else + state.getErrorListener().add(errors.get(errors.size() - 1)); + //state.getErrorListener().addAll(errors); + return false; // KHK: should return false, right? + } + } + } + return true; + } + + /** + * This function takes in two schema particle types, a baseModel, and a derived model and returns true if the + * derivedModel can be egitimately be used for restriction. Errors are put into the errors collections. + * @param baseModel - The base schema particle + * @param derivedModel - The derived (restricted) schema particle + * @param errors - Invalid restriction errors are put into this collection + * @param context + * @return boolean, true if valid restruction, false if invalid restriction + * @ + */ + public static boolean isParticleValidRestriction(SchemaParticle baseModel, SchemaParticle derivedModel, Collection errors, XmlObject context) { + boolean restrictionValid = false; + // 1 They are the same particle. + if (baseModel.equals(derivedModel)) { + restrictionValid = true; + } else { + // Implement table defined in schema spec on restrictions at: + // http://www.w3.org/TR/xmlschema-1/#cos-particle-restrict + switch (baseModel.getParticleType()) { + case SchemaParticle.ELEMENT: + switch (derivedModel.getParticleType()) { + case SchemaParticle.ELEMENT: + restrictionValid = nameAndTypeOK((SchemaLocalElement) baseModel, (SchemaLocalElement) derivedModel, errors, context); + break; + case SchemaParticle.WILDCARD: + case SchemaParticle.ALL: + case SchemaParticle.CHOICE: + case SchemaParticle.SEQUENCE: + errors.add(XmlError.forObject(XmlErrorCodes.PARTICLE_RESTRICTION$INVALID_RESTRICTION, + new Object[] { printParticle(derivedModel), printParticle(baseModel) }, context)); + restrictionValid = false; + break; + default: + assert false : XBeanDebug.logStackTrace("Unknown schema type for Derived Type"); + } + break; + case SchemaParticle.WILDCARD: + switch (derivedModel.getParticleType()) { + case SchemaParticle.ELEMENT: + restrictionValid = nsCompat(baseModel, (SchemaLocalElement) derivedModel, errors, context); + break; + case SchemaParticle.WILDCARD: + restrictionValid = nsSubset(baseModel, derivedModel, errors, context); + break; + case SchemaParticle.ALL: + restrictionValid = nsRecurseCheckCardinality(baseModel, derivedModel, errors, context); + break; + case SchemaParticle.CHOICE: + restrictionValid = nsRecurseCheckCardinality(baseModel, derivedModel, errors, context); + break; + case SchemaParticle.SEQUENCE: + restrictionValid = nsRecurseCheckCardinality(baseModel, derivedModel, errors, context); + break; + default: + assert false : XBeanDebug.logStackTrace("Unknown schema type for Derived Type"); + } + break; + case SchemaParticle.ALL: + switch (derivedModel.getParticleType()) { + case SchemaParticle.ELEMENT: + restrictionValid = recurseAsIfGroup(baseModel, derivedModel, errors, context); + break; + case SchemaParticle.WILDCARD: + case SchemaParticle.CHOICE: + errors.add(XmlError.forObject(XmlErrorCodes.PARTICLE_RESTRICTION$INVALID_RESTRICTION, + new Object[] { printParticle(derivedModel), printParticle(baseModel) }, context)); + restrictionValid = false; + break; + case SchemaParticle.ALL: + restrictionValid = recurse(baseModel, derivedModel, errors, context); + break; + case SchemaParticle.SEQUENCE: + restrictionValid = recurseUnordered(baseModel, derivedModel, errors, context); + break; + default: + assert false : XBeanDebug.logStackTrace("Unknown schema type for Derived Type"); + } + break; + case SchemaParticle.CHOICE: + switch (derivedModel.getParticleType()) { + case SchemaParticle.ELEMENT: + restrictionValid = recurseAsIfGroup(baseModel, derivedModel, errors, context); + break; + case SchemaParticle.WILDCARD: + case SchemaParticle.ALL: + errors.add(XmlError.forObject(XmlErrorCodes.PARTICLE_RESTRICTION$INVALID_RESTRICTION, + new Object[] { printParticle(derivedModel), printParticle(baseModel) }, context)); + restrictionValid = false; + break; + case SchemaParticle.CHOICE: + restrictionValid = recurseLax(baseModel, derivedModel, errors, context); + break; + case SchemaParticle.SEQUENCE: + restrictionValid = mapAndSum(baseModel, derivedModel, errors, context); + break; + default: + assert false : XBeanDebug.logStackTrace("Unknown schema type for Derived Type"); + } + break; + case SchemaParticle.SEQUENCE: + switch (derivedModel.getParticleType()) { + case SchemaParticle.ELEMENT: + restrictionValid = recurseAsIfGroup(baseModel, derivedModel, errors, context); + break; + case SchemaParticle.WILDCARD: + case SchemaParticle.ALL: + case SchemaParticle.CHOICE: + errors.add(XmlError.forObject(XmlErrorCodes.PARTICLE_RESTRICTION$INVALID_RESTRICTION, + new Object[] { printParticle(derivedModel), printParticle(baseModel) }, context)); + restrictionValid = false; + break; + case SchemaParticle.SEQUENCE: + restrictionValid = recurse(baseModel, derivedModel, errors, context); + break; + default: + assert false : XBeanDebug.logStackTrace("Unknown schema type for Derived Type"); + } + break; + default: + assert false : XBeanDebug.logStackTrace("Unknown schema type for Base Type"); + + } + } + + return restrictionValid; + } + + private static boolean mapAndSum(SchemaParticle baseModel, SchemaParticle derivedModel, Collection errors, XmlObject context) { + // mapAndSum is call if base: CHOICE, derived: SEQUENCE + assert baseModel.getParticleType() == SchemaParticle.CHOICE; + assert derivedModel.getParticleType() == SchemaParticle.SEQUENCE; + boolean mapAndSumValid = true; + // Schema Component Constraint: Particle Derivation OK (Sequence:Choice -- MapAndSum) + // For a sequence group particle to be a �valid restriction� of a choice group particle all of the following + // must be true: + // 1 There is a complete functional mapping from the particles in the {particles} of R to the particles in the + // {particles} of B such that each particle in the {particles} of R is a �valid restriction� of the particle in + // the {particles} of B it maps to as defined by Particle Valid (Restriction) (�3.9.6). + // interpretation: each particle child in derived should have a match in base. + // 2 The pair consisting of the product of the {min occurs} of R and the length of its {particles} and unbounded + // if {max occurs} is unbounded otherwise the product of the {max occurs} of R and the length of its {particles} + // is a valid restriction of B's occurrence range as defined by Occurrence Range OK (�3.9.6). + // NOTE: This clause is in principle more restrictive than absolutely necessary, but in practice will cover + // all the likely cases, and is much easier to specify than the fully general version. + // NOTE: This case allows the "unfolding" of iterated disjunctions into sequences. It may be particularly useful + // when the disjunction is an implicit one arising from the use of substitution groups. + + // Map step - for each member of the derived model's particle children search base model's particle children + // for match + SchemaParticle[] derivedParticleArray = derivedModel.getParticleChildren(); + SchemaParticle[] baseParticleArray = baseModel.getParticleChildren(); + for (int i = 0; i < derivedParticleArray.length; i++) { + SchemaParticle derivedParticle = derivedParticleArray[i]; + boolean foundMatch = false; + for (int j = 0; j < baseParticleArray.length; j++) { + SchemaParticle baseParticle = baseParticleArray[j]; + // recurse to check if there is a match + if (isParticleValidRestriction(baseParticle, derivedParticle, errors, context)) { + // if there is a match then no need to check base particles anymore + foundMatch = true; + break; + } + } + if (!foundMatch) { + mapAndSumValid = false; + errors.add(XmlError.forObject(XmlErrorCodes.PARTICLE_DERIVATION_MAP_AND_SUM$MAP, + new Object[] { printParticle(derivedParticle) }, + context)); + // KHK: if we don't return false now, this error may get swallowed by an error produced below + return false; + //break; + } + } + + // Sum step + BigInteger derivedRangeMin = derivedModel.getMinOccurs().multiply(BigInteger.valueOf(derivedModel.getParticleChildren().length)); + BigInteger derivedRangeMax = null; + BigInteger UNBOUNDED = null; + if (derivedModel.getMaxOccurs() == UNBOUNDED) { + derivedRangeMax = null; + } else { + derivedRangeMax = derivedModel.getMaxOccurs().multiply(BigInteger.valueOf(derivedModel.getParticleChildren().length)); + } + + // Now check derivedRange (derivedRangeMin and derivedRangeMax) against base model occurrence range + // Schema Component Constraint: Occurrence Range OK + // For a particle's occurrence range to be a valid restriction of another's occurrence range all of the following must be true: + // 1 Its {min occurs} is greater than or equal to the other's {min occurs}. + // 2 one of the following must be true: + // 2.1 The other's {max occurs} is unbounded. + // 2.2 Both {max occurs} are numbers, and the particle's is less than or equal to the other's. + + if (derivedRangeMin.compareTo(baseModel.getMinOccurs()) < 0) { + mapAndSumValid = false; + errors.add(XmlError.forObject(XmlErrorCodes.PARTICLE_DERIVATION_MAP_AND_SUM$SUM_MIN_OCCURS_GTE_MIN_OCCURS, + new Object[] { derivedRangeMin.toString(), baseModel.getMinOccurs().toString() }, + context)); + } else if (baseModel.getMaxOccurs() != UNBOUNDED && (derivedRangeMax == UNBOUNDED || derivedRangeMax.compareTo(baseModel.getMaxOccurs()) > 0)) { + mapAndSumValid = false; + errors.add(XmlError.forObject(XmlErrorCodes.PARTICLE_DERIVATION_MAP_AND_SUM$SUM_MAX_OCCURS_LTE_MAX_OCCURS, + new Object[] { derivedRangeMax == UNBOUNDED ? "unbounded" : derivedRangeMax.toString(), baseModel.getMaxOccurs().toString() }, + context)); + } + + return mapAndSumValid; + } + + private static boolean recurseAsIfGroup(SchemaParticle baseModel, SchemaParticle derivedModel, Collection errors, XmlObject context) { + // recurseAsIfGroup is called if: + // base: ALL, derived: ELEMENT + // base: CHOICE, derived: ELEMENT + // base: SEQUENCE, derived: ELEMENT + assert (baseModel.getParticleType() == SchemaParticle.ALL && derivedModel.getParticleType() == SchemaParticle.ELEMENT) + || (baseModel.getParticleType() == SchemaParticle.CHOICE && derivedModel.getParticleType() == SchemaParticle.ELEMENT) + || (baseModel.getParticleType() == SchemaParticle.SEQUENCE && derivedModel.getParticleType() == SchemaParticle.ELEMENT); + // Schema Component Constraint: Particle Derivation OK (Elt:All/Choice/Sequence -- RecurseAsIfGroup) + + // For an element declaration particle to be a �valid restriction� of a group particle + // (all, choice or sequence) a group particle of the variety corresponding to B's, with {min occurs} and + // {max occurs} of 1 and with {particles} consisting of a single particle the same as the element declaration + // must be a �valid restriction� of the group as defined by Particle Derivation OK + // (All:All,Sequence:Sequence -- Recurse) (�3.9.6), Particle Derivation OK (Choice:Choice -- RecurseLax) + // (�3.9.6) or Particle Derivation OK (All:All,Sequence:Sequence -- Recurse) (�3.9.6), depending on whether + // the group is all, choice or sequence + + // interpretation: make a fake group of the right type, with min occurs and max occurs of 1 + SchemaParticleImpl asIfPart = new SchemaParticleImpl(); + asIfPart.setParticleType(baseModel.getParticleType()); + asIfPart.setMinOccurs(BigInteger.ONE); + asIfPart.setMaxOccurs(BigInteger.ONE); + asIfPart.setParticleChildren(new SchemaParticle[] { derivedModel }); + + // the recurse + return isParticleValidRestriction(baseModel, asIfPart, errors, context); + } + + private static boolean recurseLax(SchemaParticle baseModel, SchemaParticle derivedModel, Collection errors, XmlObject context) { + // recurseLax is called if base: CHOICE, derived: CHOICE + assert baseModel.getParticleType() == SchemaParticle.CHOICE && derivedModel.getParticleType() == SchemaParticle.CHOICE; + boolean recurseLaxValid = true; + //Schema Component Constraint: Particle Derivation OK (Choice:Choice -- RecurseLax) + // For a choice group particle to be a �valid restriction� of another choice group particle all of the + // following must be true: + // 1 R's occurrence range is a valid restriction of B's occurrence range as defined by Occurrence + // Range OK (�3.9.6); + // 2 There is a complete �order-preserving� functional mapping from the particles in the {particles} of R + // to the particles in the {particles} of B such that each particle in the {particles} of R is a + // �valid restriction� of the particle in the {particles} of B it maps to as defined by + // Particle Valid (Restriction) (�3.9.6). + // NOTE: Although the �validation� semantics of a choice group does not depend on the order of its particles, + // derived choice groups are required to match the order of their base in order to simplify + // checking that the derivation is OK. + // interpretation: check derived choices for match in order, must get an in order match on a base particle, + // don't need to check if base particles are skippable. a lot like recurse + + if (!occurrenceRangeOK(baseModel, derivedModel, errors, context)) { + return false; + } + // cycle thru both derived particle children and base particle children looking for matches + // if the derived particle does not match the base particle then base particle can be skipped + + SchemaParticle[] derivedParticleArray = derivedModel.getParticleChildren(); + SchemaParticle[] baseParticleArray = baseModel.getParticleChildren(); + int i = 0, j = 0; + for (; i < derivedParticleArray.length && j < baseParticleArray.length;) { + SchemaParticle derivedParticle = derivedParticleArray[i]; + SchemaParticle baseParticle = baseParticleArray[j]; + // try to match the two particles by recursing + if (isParticleValidRestriction(baseParticle, derivedParticle, errors, context)) { + // cool found a match, increment both indexes + i++; + j++; + } else { + // did not match, increment the base particle array index only + // Ok, let's skip this base particle, increment base particle array index only + j++; + } + } + + // ok, got to the end of one of the arrays + // if at end of base particle array and not at the end of derived particle array then remaining derived + // particles must not match + if (i < derivedParticleArray.length) { + recurseLaxValid = false; + //String message = "Found derived particles that are not matched in the base content model."; + //errors.add(XmlError.forObject(formatDerivedMappingError(message, baseModel, derivedModel), context)); + errors.add(XmlError.forObject(XmlErrorCodes.PARTICLE_DERIVATION_RECURSE_LAX$MAP, + new Object[] { printParticles(baseParticleArray, i) }, + context)); + } + + + return recurseLaxValid; + } + + private static boolean recurseUnordered(SchemaParticle baseModel, SchemaParticle derivedModel, Collection errors, XmlObject context) { + // recurseUnorder is called when base: ALL and derived: SEQ + assert baseModel.getParticleType() == SchemaParticle.ALL && derivedModel.getParticleType() == SchemaParticle.SEQUENCE; + boolean recurseUnorderedValid = true; + // Schema Component Constraint: Particle Derivation OK (Sequence:All -- RecurseUnordered) + // For a sequence group particle to be a �valid restriction� of an all group particle all of the + // following must be true: + // 1 R's occurrence range is a valid restriction of B's occurrence range as defined by + // Occurrence Range OK (�3.9.6). + // 2 There is a complete functional mapping from the particles in the {particles} of R to the particles + // in the {particles} of B such that all of the following must be true: + // 2.1 No particle in the {particles} of B is mapped to by more than one of the particles in + // the {particles} of R; + // 2.2 Each particle in the {particles} of R is a �valid restriction� of the particle in the {particles} of B + // it maps to as defined by Particle Valid (Restriction) (�3.9.6); + // 2.3 All particles in the {particles} of B which are not mapped to by any particle in the {particles} + // of R are �emptiable� as defined by Particle Emptiable (�3.9.6). + // NOTE: Although this clause allows reordering, because of the limits on the contents of all groups the + // checking process can still be deterministic. + // 1, 2.2, and 2.3 are the same as recurse, so do 2.1 and then call recurse + + if (!occurrenceRangeOK(baseModel, derivedModel, errors, context)) { + return false; + } + + // read baseParticle array QNames into hashmap + SchemaParticle[] baseParticles = baseModel.getParticleChildren(); + HashMap baseParticleMap = new HashMap(10); + Object MAPPED = new Object(); + // Initialize the hashmap + for (int i = 0; i < baseParticles.length; i++) + baseParticleMap.put(baseParticles[i].getName(), baseParticles[i]); + + // go thru the sequence (derived model's children) and check off from base particle map + SchemaParticle[] derivedParticles = derivedModel.getParticleChildren(); + for (int i = 0; i < derivedParticles.length; i++) { + Object baseParticle = baseParticleMap.get(derivedParticles[i].getName()); + if (baseParticle == null) { + recurseUnorderedValid = false; + errors.add(XmlError.forObject(XmlErrorCodes.PARTICLE_DERIVATION_RECURSE_UNORDERED$MAP, + new Object[] { printParticle(derivedParticles[i]) }, context )); + break; + } else { + // got a match + if (baseParticle == MAPPED) { + // whoa, this base particle has already been matched (see 2.1 above) + recurseUnorderedValid = false; + errors.add(XmlError.forObject(XmlErrorCodes.PARTICLE_DERIVATION_RECURSE_UNORDERED$MAP_UNIQUE, + new Object[] { printParticle(derivedParticles[i]) }, context )); + break; + } else { + SchemaParticle matchedBaseParticle = (SchemaParticle)baseParticle; + if (derivedParticles[i].getMaxOccurs() == null || + derivedParticles[i].getMaxOccurs().compareTo(BigInteger.ONE) > 0) { + // no derived particles can have a max occurs greater than 1 + recurseUnorderedValid = false; + errors.add(XmlError.forObject(XmlErrorCodes.PARTICLE_DERIVATION_RECURSE_UNORDERED$MAP_MAX_OCCURS_1, + new Object[] { printParticle(derivedParticles[i]), printMaxOccurs(derivedParticles[i].getMinOccurs()) }, + context)); + break; + } + if (!isParticleValidRestriction(matchedBaseParticle, derivedParticles[i], errors, context)) + { + // already have an error + recurseUnorderedValid = false; + break; + } + // everything is cool, got a match, update to MAPPED + baseParticleMap.put(derivedParticles[i].getName(), MAPPED); + } + } + } + + // if everything is cool so far then check to see if any base particles are not matched + if (recurseUnorderedValid) { + // get all the hashmap keys and loop thru looking for NOT_MAPPED + Set baseParticleCollection = baseParticleMap.keySet(); + for (Iterator iterator = baseParticleCollection.iterator(); iterator.hasNext();) { + QName baseParticleQName = (QName) iterator.next(); + if (baseParticleMap.get(baseParticleQName) != MAPPED && !((SchemaParticle)baseParticleMap.get(baseParticleQName)).isSkippable()) { + // this base particle was not mapped and is not "particle emptiable" (skippable) + recurseUnorderedValid = false; + errors.add(XmlError.forObject(XmlErrorCodes.PARTICLE_DERIVATION_RECURSE_UNORDERED$UNMAPPED_ARE_EMPTIABLE, + new Object[] { printParticle((SchemaParticle)baseParticleMap.get(baseParticleQName)) }, + context)); + } + } + } + + return recurseUnorderedValid; + } + + private static boolean recurse(SchemaParticle baseModel, SchemaParticle derivedModel, Collection errors, XmlObject context) { + // recurse is called when base: ALL derived: ALL or base: SEQUENCE derived: SEQUENCE + boolean recurseValid = true; + // For an all or sequence group particle to be a �valid restriction� of another group particle with the same + // {compositor} all of the following must be true: + // 1 R's occurrence range is a valid restriction of B's occurrence range as defined by + // Occurrence Range OK (�3.9.6). + // 2 There is a complete �order-preserving� functional mapping from the particles in the {particles} of R to + // the particles in the {particles} of B such that all of the following must be true: + // 2.1 Each particle in the {particles} of R is a �valid restriction� of the particle in the {particles} + // of B it maps to as defined by Particle Valid (Restriction) (�3.9.6). + // 2.2 All particles in the {particles} of B which are not mapped to by any particle in the {particles} + // of R are �emptiable� as defined by Particle Emptiable (�3.9.6). + // NOTE: Although the �validation� semantics of an all group does not depend on the order of its particles, + // derived all groups are required to match the order of their base in order to simplify checking that + // the derivation is OK. + // [Definition:] A complete functional mapping is order-preserving if each particle r in the domain R maps + // to a particle b in the range B which follows (not necessarily immediately) the particle in the range B + // mapped to by the predecessor of r, if any, where "predecessor" and "follows" are defined with respect to + // the order of the lists which constitute R and B. + + if (!occurrenceRangeOK(baseModel, derivedModel, errors, context)) { + // error message is formatted in occurrencRangeOK ... + return false; + } + // cycle thru both derived particle children and base particle children looking for matches + // if the derived particle does not match the base particle then base particle can be skipped if it is + // skippable (same as "particle emptiable") otherwise is an invalid restriction. + // after the derived particles have been cycled if there are any base particles left over then they + // must be skippable or invalid restriction + + SchemaParticle[] derivedParticleArray = derivedModel.getParticleChildren(); + SchemaParticle[] baseParticleArray = baseModel.getParticleChildren(); + int i = 0, j = 0; + for (; i < derivedParticleArray.length && j < baseParticleArray.length;) { + SchemaParticle derivedParticle = derivedParticleArray[i]; + SchemaParticle baseParticle = baseParticleArray[j]; + // try to match the two particles by recursing + if (isParticleValidRestriction(baseParticle, derivedParticle, errors, context)) { + // cool found a match, increment both indexes + i++; + j++; + } else { + // did not match, increment the base particle array index only + // that's ok if the base particle is skippable + if (baseParticle.isSkippable()) { + // Ok, let's skip this base particle, increment base particle array index only + j++; + } else { + // whoa, particles are not valid restrictions and base is not skippable - ERROR + recurseValid = false; + errors.add(XmlError.forObject(XmlErrorCodes.PARTICLE_DERIVATION_RECURSE$MAP_VALID, + new Object[] { printParticle(derivedParticle), printParticle(derivedModel), + printParticle(baseParticle), printParticle(baseModel) }, + context)); + break; + } + } + } + + // ok, got to the end of one of the arrays + // if at end of base particle array and not at the end of derived particle array then remaining derived + // particles must not match + if (i < derivedParticleArray.length) { + recurseValid = false; + errors.add(XmlError.forObject(XmlErrorCodes.PARTICLE_DERIVATION_RECURSE$MAP, + new Object[] { printParticle(derivedModel), printParticle(baseModel), printParticles(derivedParticleArray, i) }, + context)); + } else { + // if at end of derived particle array and not at end of base particle array then chck remaining + // base particles to assure they are skippable + if (j < baseParticleArray.length) { + ArrayList particles = new ArrayList(baseParticleArray.length); + for (int k = j; k < baseParticleArray.length; k++) { + if (!baseParticleArray[k].isSkippable()) { + particles.add(baseParticleArray[k]); + } + } + if (particles.size() > 0) + { + recurseValid = false; + errors.add(XmlError.forObject(XmlErrorCodes.PARTICLE_DERIVATION_RECURSE$UNMAPPED_ARE_EMPTIABLE, + new Object[] { printParticle(baseModel), printParticle(derivedModel), printParticles(particles)}, context)); + } + } + } + + return recurseValid; + } + + private static boolean nsRecurseCheckCardinality(SchemaParticle baseModel, SchemaParticle derivedModel, Collection errors, XmlObject context) { + // nsRecurseCheckCardinality is called when: + // base: ANY, derived: ALL + // base: ANY, derived: CHOICE + // base: ANY, derived: SEQUENCE + assert baseModel.getParticleType() == SchemaParticle.WILDCARD; + assert (derivedModel.getParticleType() == SchemaParticle.ALL) + || (derivedModel.getParticleType() == SchemaParticle.CHOICE) + || (derivedModel.getParticleType() == SchemaParticle.SEQUENCE); + boolean nsRecurseCheckCardinality = true; + // For a group particle to be a �valid restriction� of a wildcard particle all of the following must be true: + // 1 Every member of the {particles} of the group is a �valid restriction� of the wildcard as defined by Particle Valid (Restriction) (�3.9.6). + // Note: not positive what this means. Interpreting to mean that every particle of the group must adhere to wildcard derivation rules + // in a recursive manner + // Loop thru the children particles of the group and invoke the appropriate function to check for wildcard restriction validity + + // BAU - an errata should be submitted on this clause of the spec, because the + // spec makes no sense, as the xstc particlesR013.xsd test exemplifies. + // what we _should_ so is an "as if" on the wildcard, allowing it minOccurs="0" maxOccurs="unbounded" + // before recursing + SchemaParticleImpl asIfPart = new SchemaParticleImpl(); + asIfPart.setParticleType(baseModel.getParticleType()); + asIfPart.setWildcardProcess(baseModel.getWildcardProcess()); + asIfPart.setWildcardSet(baseModel.getWildcardSet()); + asIfPart.setMinOccurs(BigInteger.ZERO); + asIfPart.setMaxOccurs(null); + asIfPart.setTransitionRules(baseModel.getWildcardSet(), true); + asIfPart.setTransitionNotes(baseModel.getWildcardSet(), true); + + SchemaParticle[] particleChildren = derivedModel.getParticleChildren(); + for (int i = 0; i < particleChildren.length; i++) { + SchemaParticle particle = particleChildren[i]; + switch (particle.getParticleType()) { + case SchemaParticle.ELEMENT: + // Check for valid Wildcard/Element derivation + nsRecurseCheckCardinality = nsCompat(asIfPart, (SchemaLocalElement) particle, errors, context); + break; + case SchemaParticle.WILDCARD: + // Check for valid Wildcard/Wildcard derivation + nsRecurseCheckCardinality = nsSubset(asIfPart, particle, errors, context); + break; + case SchemaParticle.ALL: + case SchemaParticle.CHOICE: + case SchemaParticle.SEQUENCE: + // Check for valid Wildcard/Group derivation + nsRecurseCheckCardinality = nsRecurseCheckCardinality(asIfPart, particle, errors, context); + break; + } + // If any particle is invalid then break the loop + if (!nsRecurseCheckCardinality) { + break; + } + } + + // 2 The effective total range of the group, as defined by Effective Total Range (all and sequence) (�3.8.6) + // (if the group is all or sequence) or Effective Total Range (choice) (�3.8.6) (if it is choice) is a valid + // restriction of B's occurrence range as defined by Occurrence Range OK (�3.9.6). + + if (nsRecurseCheckCardinality) { + nsRecurseCheckCardinality = checkGroupOccurrenceOK(baseModel, derivedModel, errors, context); + } + + return nsRecurseCheckCardinality; + } + + private static boolean checkGroupOccurrenceOK(SchemaParticle baseModel, SchemaParticle derivedModel, Collection errors, XmlObject context) { + boolean groupOccurrenceOK = true; + BigInteger minRange = BigInteger.ZERO; + BigInteger maxRange = BigInteger.ZERO; + switch (derivedModel.getParticleType()) { + case SchemaParticle.ALL: + case SchemaParticle.SEQUENCE: + minRange = getEffectiveMinRangeAllSeq(derivedModel); + maxRange = getEffectiveMaxRangeAllSeq(derivedModel); + break; + case SchemaParticle.CHOICE: + minRange = getEffectiveMinRangeChoice(derivedModel); + maxRange = getEffectiveMaxRangeChoice(derivedModel); + break; + } + + // Check min occurs for validity + // derived min occurs is valid if its {min occurs} is greater than or equal to the other's {min occurs}. + if (minRange.compareTo(baseModel.getMinOccurs()) < 0) { + groupOccurrenceOK = false; + errors.add(XmlError.forObject(XmlErrorCodes.OCCURRENCE_RANGE$MIN_GTE_MIN, + new Object[] { printParticle(derivedModel), printParticle(baseModel) }, + context)); + } + // Check max occurs for validity + // one of the following must be true: + // The base model's {max occurs} is unbounded. + // or both {max occurs} are numbers, and the particle's is less than or equal to the other's + BigInteger UNBOUNDED = null; + if (baseModel.getMaxOccurs() != UNBOUNDED) { + if (maxRange == UNBOUNDED) { + groupOccurrenceOK = false; + errors.add(XmlError.forObject(XmlErrorCodes.OCCURRENCE_RANGE$MAX_LTE_MAX, + new Object[] { printParticle(derivedModel), printParticle(baseModel) }, + context)); + } else { + if (maxRange.compareTo(baseModel.getMaxOccurs()) > 0) { + groupOccurrenceOK = false; + errors.add(XmlError.forObject(XmlErrorCodes.OCCURRENCE_RANGE$MAX_LTE_MAX, + new Object[] { printParticle(derivedModel), printParticle(baseModel) }, + context)); + } + } + } + return groupOccurrenceOK; + } + + private static BigInteger getEffectiveMaxRangeChoice(SchemaParticle derivedModel) { + BigInteger maxRange = BigInteger.ZERO; + BigInteger UNBOUNDED = null; + // Schema Component Constraint: Effective Total Range (choice) + // The effective total range of a particle whose {term} is a group whose {compositor} is choice + // is a pair of minimum and maximum, as follows: + // MAXIMUM + // 1) unbounded if the {max occurs} of any wildcard or element declaration particle in the group's {particles} or + // the maximum part of the effective total range of any of the group particles in the group's {particles} is + // unbounded (note: seems to be the same as Max Range All or Sequence), + // or 2) if any of those is non-zero and the {max occurs} of the particle itself is unbounded, + // otherwise 3) the product of the particle's {max occurs} and the maximum of the {max occurs} of every + // wildcard or element declaration particle in the group's {particles} and the *maximum* (note: this is the difference + // between MaxRange Choice ans MaxRange All or Sequence) part of the + // effective total range of each of the group particles in the group's {particles} + // (or 0 if there are no {particles}). + + boolean nonZeroParticleChildFound = false; + BigInteger maxOccursInWildCardOrElement = BigInteger.ZERO; + BigInteger maxOccursInGroup = BigInteger.ZERO; + SchemaParticle[] particleChildren = derivedModel.getParticleChildren(); + for (int i = 0; i < particleChildren.length; i++) { + SchemaParticle particle = particleChildren[i]; + switch (particle.getParticleType()) { + case SchemaParticle.WILDCARD: + case SchemaParticle.ELEMENT: + // if unbounded then maxoccurs will be null + if (particle.getMaxOccurs() == UNBOUNDED) { + maxRange = UNBOUNDED; + } else { + if (particle.getIntMaxOccurs() > 0) { + // show tht at least one non-zero particle is found for later test + nonZeroParticleChildFound = true; + if (particle.getMaxOccurs().compareTo(maxOccursInWildCardOrElement) > 0) { + maxOccursInWildCardOrElement = particle.getMaxOccurs(); + } + } + } + break; + case SchemaParticle.ALL: + case SchemaParticle.SEQUENCE: + maxRange = getEffectiveMaxRangeAllSeq(particle); + if (maxRange != UNBOUNDED) { + // keep highest maxoccurs found + if (maxRange.compareTo(maxOccursInGroup) > 0) { + maxOccursInGroup = maxRange; + } + } + break; + case SchemaParticle.CHOICE: + maxRange = getEffectiveMaxRangeChoice(particle); + if (maxRange != UNBOUNDED) { + // keep highest maxoccurs found + if (maxRange.compareTo(maxOccursInGroup) > 0) { + maxOccursInGroup = maxRange; + } + } + break; + } + // if an unbounded has been found then we are done + if (maxRange == UNBOUNDED) { + break; + } + } + + // 1) unbounded if the {max occurs} of any wildcard or element declaration particle in the group's {particles} or + // the maximum part of the effective total range of any of the group particles in the group's {particles} is + // unbounded + if (maxRange != UNBOUNDED) { + // 2) if any of those is non-zero and the {max occurs} of the particle itself is unbounded + if (nonZeroParticleChildFound && derivedModel.getMaxOccurs() == UNBOUNDED) { + maxRange = UNBOUNDED; + } else { + // 3) the product of the particle's {max occurs} and the maximum of the {max occurs} of every + // wildcard or element declaration particle in the group's {particles} and the *maximum* + // part of the effective total range of each of the group particles in the group's {particles} + maxRange = derivedModel.getMaxOccurs().multiply(maxOccursInWildCardOrElement.add(maxOccursInGroup)); + } + } + + return maxRange; + } + + private static BigInteger getEffectiveMaxRangeAllSeq(SchemaParticle derivedModel) { + BigInteger maxRange = BigInteger.ZERO; + BigInteger UNBOUNDED = null; + // Schema Component Constraint: Effective Total Range (all and sequence) + // The effective total range of a particle whose {term} is a group whose {compositor} is all or sequence is a + // pair of minimum and maximum, as follows: + // MAXIMUM + // 1) unbounded if the {max occurs} of any wildcard or element declaration particle in the group's {particles} or + // the maximum part of the effective total range of any of the group particles in the group's {particles} is + // unbounded, or 2) if any of those is non-zero and the {max occurs} of the particle itself is unbounded, otherwise + // 3) the product of the particle's {max occurs} and the *sum* of the {max occurs} of every wildcard or element + // declaration particle in the group's {particles} and the maximum part of the effective total range of each of + // the group particles in the group's {particles} (or 0 if there are no {particles}). + + boolean nonZeroParticleChildFound = false; + BigInteger maxOccursTotal = BigInteger.ZERO; + BigInteger maxOccursInGroup = BigInteger.ZERO; + SchemaParticle[] particleChildren = derivedModel.getParticleChildren(); + for (int i = 0; i < particleChildren.length; i++) { + SchemaParticle particle = particleChildren[i]; + switch (particle.getParticleType()) { + case SchemaParticle.WILDCARD: + case SchemaParticle.ELEMENT: + // if unbounded then maxoccurs will be null + if (particle.getMaxOccurs() == UNBOUNDED) { + maxRange = UNBOUNDED; + } else { + if (particle.getIntMaxOccurs() > 0) { + // show tht at least one non-zero particle is found for later test + nonZeroParticleChildFound = true; + maxOccursTotal = maxOccursTotal.add(particle.getMaxOccurs()); + } + } + break; + case SchemaParticle.ALL: + case SchemaParticle.SEQUENCE: + maxRange = getEffectiveMaxRangeAllSeq(particle); + if (maxRange != UNBOUNDED) { + // keep highest maxoccurs found + if (maxRange.compareTo(maxOccursInGroup) > 0) { + maxOccursInGroup = maxRange; + } + } + break; + case SchemaParticle.CHOICE: + maxRange = getEffectiveMaxRangeChoice(particle); + if (maxRange != UNBOUNDED) { + // keep highest maxoccurs found + if (maxRange.compareTo(maxOccursInGroup) > 0) { + maxOccursInGroup = maxRange; + } + } + break; + } + // if an unbounded has been found then we are done + if (maxRange == UNBOUNDED) { + break; + } + } + + // 1) unbounded if the {max occurs} of any wildcard or element declaration particle in the group's {particles} or + // the maximum part of the effective total range of any of the group particles in the group's {particles} is + // unbounded + if (maxRange != UNBOUNDED) { + // 2) if any of those is non-zero and the {max occurs} of the particle itself is unbounded + if (nonZeroParticleChildFound && derivedModel.getMaxOccurs() == UNBOUNDED) { + maxRange = UNBOUNDED; + } else { + // 3) the product of the particle's {max occurs} and the sum of the {max occurs} of every wildcard or element + // declaration particle in the group's {particles} and the maximum part of the effective total range of each of + // the group particles in the group's {particles} + maxRange = derivedModel.getMaxOccurs().multiply(maxOccursTotal.add(maxOccursInGroup)); + } + } + + return maxRange; + + } + + private static BigInteger getEffectiveMinRangeChoice(SchemaParticle derivedModel) { + // Schema Component Constraint: Effective Total Range (choice) + // The effective total range of a particle whose {term} is a group whose {compositor} is choice is a pair of + // minimum and maximum, as follows: + // MINIMUM + // The product of the particle's {min occurs} + // and the *minimum* of the {min occurs} of every wildcard or element + // declaration particle in the group's {particles} and the minimum part of the effective total range of each of + // the group particles in the group's {particles} (or 0 if there are no {particles}). + SchemaParticle[] particleChildren = derivedModel.getParticleChildren(); + if (particleChildren.length == 0) + return BigInteger.ZERO; + BigInteger minRange = null; + // get the minimum of every wildcard or element + // total up the effective total range for each group + for (int i = 0; i < particleChildren.length; i++) { + SchemaParticle particle = particleChildren[i]; + switch (particle.getParticleType()) { + case SchemaParticle.WILDCARD: + case SchemaParticle.ELEMENT: + if (minRange == null || minRange.compareTo(particle.getMinOccurs()) > 0) { + minRange = particle.getMinOccurs(); + } + break; + case SchemaParticle.ALL: + case SchemaParticle.SEQUENCE: + BigInteger mrs = getEffectiveMinRangeAllSeq(particle); + if (minRange == null || minRange.compareTo(mrs) > 0) { + minRange = mrs; + } + break; + case SchemaParticle.CHOICE: + BigInteger mrc = getEffectiveMinRangeChoice(particle); + if (minRange == null || minRange.compareTo(mrc) > 0) { + minRange = mrc; + } + break; + } + } + if (minRange == null) + minRange = BigInteger.ZERO; + + // calculate the total + minRange = derivedModel.getMinOccurs().multiply(minRange); + return minRange; + } + + private static BigInteger getEffectiveMinRangeAllSeq(SchemaParticle derivedModel) { + BigInteger minRange = BigInteger.ZERO; + // Schema Component Constraint: Effective Total Range (all and sequence) + // The effective total range of a particle whose {term} is a group whose {compositor} is all or sequence is a + // pair of minimum and maximum, as follows: + // MINIMUM + // The product of the particle's {min occurs} + // and the *sum* of the {min occurs} of every wildcard or element + // declaration particle in the group's {particles} + // and the minimum part of the effective total range of each + // of the group particles in the group's {particles} (or 0 if there are no {particles}). + SchemaParticle[] particleChildren = derivedModel.getParticleChildren(); + BigInteger particleTotalMinOccurs = BigInteger.ZERO; + for (int i = 0; i < particleChildren.length; i++) { + SchemaParticle particle = particleChildren[i]; + switch (particle.getParticleType()) { + case SchemaParticle.WILDCARD: + case SchemaParticle.ELEMENT: + particleTotalMinOccurs = particleTotalMinOccurs.add(particle.getMinOccurs()); + break; + case SchemaParticle.ALL: + case SchemaParticle.SEQUENCE: + particleTotalMinOccurs = particleTotalMinOccurs.add(getEffectiveMinRangeAllSeq(particle)); + break; + case SchemaParticle.CHOICE: + particleTotalMinOccurs = particleTotalMinOccurs.add(getEffectiveMinRangeChoice(particle)); + break; + } + } + + minRange = derivedModel.getMinOccurs().multiply(particleTotalMinOccurs); + + return minRange; + } + + private static boolean nsSubset(SchemaParticle baseModel, SchemaParticle derivedModel, Collection errors, XmlObject context) { + // nsSubset is called when base: ANY, derived: ANY + assert baseModel.getParticleType() == SchemaParticle.WILDCARD; + assert derivedModel.getParticleType() == SchemaParticle.WILDCARD; + boolean nsSubset = false; + // For a wildcard particle to be a �valid restriction� of another wildcard particle all of the following must be true: + // 1 R's occurrence range must be a valid restriction of B's occurrence range as defined by Occurrence Range OK (�3.9.6). + if (occurrenceRangeOK(baseModel, derivedModel, errors, context)) { + // 2 R's {namespace constraint} must be an intensional subset of B's {namespace constraint} as defined + // by Wildcard Subset (�3.10.6). + if (baseModel.getWildcardSet().inverse().isDisjoint(derivedModel.getWildcardSet())) { + nsSubset = true; + } else { + nsSubset = false; + errors.add(XmlError.forObject(XmlErrorCodes.PARTICLE_DERIVATION_NS_SUBST$WILDCARD_SUBSET, + new Object[] { printParticle(derivedModel), printParticle(baseModel) }, context)); + } + } else { + nsSubset = false; + // error already produced by occurrenceRangeOK + //errors.add(XmlError.forObject(formatNSIsNotSubsetError(baseModel, derivedModel), context)); + } + + + return nsSubset; + } + + private static boolean nsCompat(SchemaParticle baseModel, SchemaLocalElement derivedElement, Collection errors, XmlObject context) { + // nsCompat is called when base: ANY, derived: ELEMENT + assert baseModel.getParticleType() == SchemaParticle.WILDCARD; + boolean nsCompat = false; + // For an element declaration particle to be a �valid restriction� of a wildcard particle all of the following must be true: + // 1 The element declaration's {target namespace} is �valid� with respect to the wildcard's {namespace constraint} + // as defined by Wildcard allows Namespace Name (�3.10.4). + if (baseModel.getWildcardSet().contains(derivedElement.getName())) { + // 2 R's occurrence range is a valid restriction of B's occurrence range as defined by Occurrence Range OK (�3.9.6). + if (occurrenceRangeOK(baseModel, (SchemaParticle) derivedElement, errors, context)) { + nsCompat = true; + } else { + // error already produced by occurrenceRangeOK + //errors.add(XmlError.forObject(formatOccurenceRangeMinError(baseModel, (SchemaParticle) derivedElement), context)); + } + } else { + nsCompat = false; + errors.add(XmlError.forObject(XmlErrorCodes.PARTICLE_DERIVATION_NS_COMPAT$WILDCARD_VALID, + new Object[] { printParticle((SchemaParticle)derivedElement), printParticle(baseModel) }, + context)); + } + + + return nsCompat; + } + + private static boolean nameAndTypeOK(SchemaLocalElement baseElement, SchemaLocalElement derivedElement, Collection errors, XmlObject context) { + // nameAndTypeOK called when base: ELEMENT and derived: ELEMENT + + // Schema Component Constraint: Particle Restriction OK (Elt:Elt -- NameAndTypeOK) + // 1 The declarations' {name}s and {target namespace}s are the same. + if (!((SchemaParticle)baseElement).canStartWithElement(derivedElement.getName())) { + errors.add(XmlError.forObject(XmlErrorCodes.PARTICLE_RESTRICTION_NAME_AND_TYPE$NAME, + new Object[] { printParticle((SchemaParticle)derivedElement), printParticle((SchemaParticle)baseElement) }, context)); + return false; + } + + // 2 Either B's {nillable} is true or R's {nillable} is false. + if (!baseElement.isNillable() && derivedElement.isNillable()) { + errors.add(XmlError.forObject(XmlErrorCodes.PARTICLE_RESTRICTION_NAME_AND_TYPE$NILLABLE, + new Object[] { printParticle((SchemaParticle)derivedElement), printParticle((SchemaParticle)baseElement) }, context)); + return false; + } + + // 3 R's occurrence range is a valid restriction of B's occurrence range as defined by Occurrence Range OK (�3.9.6). + if (!occurrenceRangeOK((SchemaParticle) baseElement, (SchemaParticle) derivedElement, errors, context)) { + // error already produced + return false; + } + + // 4 either B's declaration's {value constraint} is absent, or is not fixed, + // or R's declaration's {value constraint} is fixed with the same value. + if (!checkFixed(baseElement, derivedElement, errors, context)) + { + // error already produced + return false; + } + + // 5 R's declaration's {identity-constraint definitions} is a subset of B's declaration's {identity-constraint definitions}, if any. + if (!checkIdentityConstraints(baseElement, derivedElement, errors, context)) + { + // error already produced + return false; + } + + // 7 R's {type definition} is validly derived given {extension, list, union} from B's {type definition} as + // defined by Type Derivation OK (Complex) (�3.4.6) or Type Derivation OK (Simple) (�3.14.6), as appropriate. + if (!typeDerivationOK(baseElement.getType(), derivedElement.getType(), errors, context)) + { + // error already produced + return false; + } + + // 6 R's declaration's {disallowed substitutions} is a superset of B's declaration's {disallowed substitutions}. + if (!blockSetOK(baseElement, derivedElement, errors, context)) + { + // error already produced + return false; + } + + return true; + } + + private static boolean blockSetOK(SchemaLocalElement baseElement, SchemaLocalElement derivedElement, Collection errors, XmlObject context) + { + if (baseElement.blockRestriction() && !derivedElement.blockRestriction()) + { + errors.add(XmlError.forObject(XmlErrorCodes.PARTICLE_RESTRICTION_NAME_AND_TYPE$DISALLOWED_SUBSTITUTIONS, + new Object[] { printParticle((SchemaParticle)derivedElement), "restriction", printParticle((SchemaParticle)baseElement) }, + context)); + return false; + } + if (baseElement.blockExtension() && !derivedElement.blockExtension()) + { + errors.add(XmlError.forObject(XmlErrorCodes.PARTICLE_RESTRICTION_NAME_AND_TYPE$DISALLOWED_SUBSTITUTIONS, + new Object[] { printParticle((SchemaParticle)derivedElement), "extension", printParticle((SchemaParticle)baseElement) }, + context)); + return false; + } + if (baseElement.blockSubstitution() && !derivedElement.blockSubstitution()) + { + errors.add(XmlError.forObject(XmlErrorCodes.PARTICLE_RESTRICTION_NAME_AND_TYPE$DISALLOWED_SUBSTITUTIONS, + new Object[] { printParticle((SchemaParticle)derivedElement), "substitution", printParticle((SchemaParticle)baseElement) }, + context)); + return false; + } + return true; + } + + private static boolean typeDerivationOK(SchemaType baseType, SchemaType derivedType, Collection errors, XmlObject context){ + boolean typeDerivationOK = false; + // 1 If B and D are not the same type definition, then the {derivation method} of D must not be in the subset. + // 2 One of the following must be true: + // 2.1 B and D must be the same type definition. + // 2.2 B must be D's {base type definition}. + // 2.3 All of the following must be true: + // 2.3.1 D's {base type definition} must not be the �ur-type definition�. + // 2.3.2 The appropriate case among the following must be true: + // 2.3.2.1 If D's {base type definition} is complex, then it must be validly derived from B given the subset as defined by this constraint. + // 2.3.2.2 If D's {base type definition} is simple, then it must be validly derived from B given the subset as defined in Type Derivation OK (Simple) (�3.14.6). + // This line will check if derivedType is a subType of baseType (should handle all of the 2.xx checks above) + if (baseType.isAssignableFrom(derivedType)) { + // Ok derived type is subtype but need to make sure that all of the derivations between the two types are by + // Restriction. + typeDerivationOK = checkAllDerivationsForRestriction(baseType, derivedType, errors, context); + } else { + // derived type is not a sub-type of base type + typeDerivationOK = false; + errors.add(XmlError.forObject(XmlErrorCodes.PARTICLE_RESTRICTION_NAME_AND_TYPE$TYPE_VALID, + new Object[] { printType(derivedType), printType(baseType) }, context)); + } + + return typeDerivationOK; + } + + private static boolean checkAllDerivationsForRestriction(SchemaType baseType, SchemaType derivedType, Collection errors, XmlObject context) { + boolean allDerivationsAreRestrictions = true; + SchemaType currentType = derivedType; + + // XMLBEANS-66: if baseType is a union, check restriction is of one of the constituant types + Set possibleTypes = null; + if (baseType.getSimpleVariety() == SchemaType.UNION) + possibleTypes = new HashSet(Arrays.asList(baseType.getUnionConstituentTypes())); + + // run up the types hierarchy from derived Type to base Type and make sure that all are derived by + // restriction. If any are not then this is not a valid restriction. + while (!baseType.equals(currentType) && + possibleTypes != null && !possibleTypes.contains(currentType)) { + if (currentType.getDerivationType() == SchemaType.DT_RESTRICTION) { + currentType = currentType.getBaseType(); + } else { + allDerivationsAreRestrictions = false; + errors.add(XmlError.forObject(XmlErrorCodes.PARTICLE_RESTRICTION_NAME_AND_TYPE$TYPE_RESTRICTED, + new Object[] { printType(derivedType), printType(baseType), printType(currentType) }, context)); + break; + } + } + return allDerivationsAreRestrictions; + } + + private static boolean checkIdentityConstraints(SchemaLocalElement baseElement, SchemaLocalElement derivedElement, Collection errors, XmlObject context) { + // 5 R's declaration's {identity-constraint definitions} is a subset of B's declaration's {identity-constraint definitions}, if any. + boolean identityConstraintsOK = true; + + SchemaIdentityConstraint[] baseConstraints = baseElement.getIdentityConstraints(); + SchemaIdentityConstraint[] derivedConstraints = derivedElement.getIdentityConstraints(); + // cycle thru derived's identity constraints and check each to assure they in the array of base constraints + for (int i = 0; i < derivedConstraints.length; i++) { + SchemaIdentityConstraint derivedConstraint = derivedConstraints[i]; + if (checkForIdentityConstraintExistence(baseConstraints, derivedConstraint)) { + identityConstraintsOK = false; + errors.add(XmlError.forObject(XmlErrorCodes.PARTICLE_RESTRICTION_NAME_AND_TYPE$IDENTITY_CONSTRAINTS, + new Object[] { printParticle((SchemaParticle)derivedElement), printParticle((SchemaParticle)baseElement) }, + context)); + break; + } + } + return identityConstraintsOK; + } + + private static boolean checkForIdentityConstraintExistence(SchemaIdentityConstraint[] baseConstraints, SchemaIdentityConstraint derivedConstraint) { + // spin thru the base identity constraints check to see if derived constraint exists + boolean identityConstraintExists = false; + for (int i = 0; i < baseConstraints.length; i++) { + SchemaIdentityConstraint baseConstraint = baseConstraints[i]; + if (baseConstraint.getName().equals(derivedConstraint.getName())) { + identityConstraintExists = true; + break; + } + } + return identityConstraintExists; + } + + + private static boolean checkFixed(SchemaLocalElement baseModel, SchemaLocalElement derivedModel, Collection errors, XmlObject context) { + // 4 either B's declaration's {value constraint} is absent, or is not fixed, + // or R's declaration's {value constraint} is fixed with the same value. + boolean checkFixed = false; + if (baseModel.isFixed()) { + if (baseModel.getDefaultText().equals(derivedModel.getDefaultText())) { + // R's declaration's {value constraint} is fixed with the same value. + checkFixed = true; + } else { + // The derived element has a fixed value that is different than the base element + errors.add(XmlError.forObject(XmlErrorCodes.PARTICLE_RESTRICTION_NAME_AND_TYPE$FIXED, + new Object[] { printParticle((SchemaParticle)derivedModel), derivedModel.getDefaultText(), + printParticle((SchemaParticle)baseModel), baseModel.getDefaultText() }, + context)); + checkFixed = false; + } + } else { + // B's declaration's {value constraint} is absent, or is not fixed, + checkFixed = true; + } + return checkFixed; + } + + private static boolean occurrenceRangeOK(SchemaParticle baseParticle, SchemaParticle derivedParticle, Collection errors, XmlObject context) { + boolean occurrenceRangeOK = false; + // Note: in the following comments (from the schema spec) other is the baseModel + // 1 Its {min occurs} is greater than or equal to the other's {min occurs}. + if (derivedParticle.getMinOccurs().compareTo(baseParticle.getMinOccurs()) >= 0) { + // 2 one of the following must be true: + // 2.1 The other's {max occurs} is unbounded. + if (baseParticle.getMaxOccurs() == null) { + occurrenceRangeOK = true; + } else { + // 2.2 Both {max occurs} are numbers, and the particle's is less than or equal to the other's. + if (derivedParticle.getMaxOccurs() != null && baseParticle.getMaxOccurs() != null && + derivedParticle.getMaxOccurs().compareTo(baseParticle.getMaxOccurs()) <= 0) { + occurrenceRangeOK = true; + } else { + occurrenceRangeOK = false; + errors.add(XmlError.forObject(XmlErrorCodes.OCCURRENCE_RANGE$MAX_LTE_MAX, + new Object[] { printParticle(derivedParticle), printMaxOccurs(derivedParticle.getMaxOccurs()), + printParticle(baseParticle), printMaxOccurs(baseParticle.getMaxOccurs()) }, + context)); + } + } + } else { + occurrenceRangeOK = false; + errors.add(XmlError.forObject(XmlErrorCodes.OCCURRENCE_RANGE$MIN_GTE_MIN, + new Object[] { printParticle(derivedParticle), derivedParticle.getMinOccurs().toString(), + printParticle(baseParticle), baseParticle.getMinOccurs().toString() }, + context)); + } + return occurrenceRangeOK; + } + + private static String printParticles(List parts) + { + return printParticles((SchemaParticle[])parts.toArray(new SchemaParticle[parts.size()])); + } + + private static String printParticles(SchemaParticle[] parts) + { + return printParticles(parts, 0, parts.length); + } + + private static String printParticles(SchemaParticle[] parts, int start) + { + return printParticles(parts, start, parts.length); + } + + private static String printParticles(SchemaParticle[] parts, int start, int end) + { + StringBuffer buf = new StringBuffer(parts.length * 30); + for (int i = start; i < end; ) + { + buf.append(printParticle(parts[i])); + if (++i != end) + buf.append(", "); + } + return buf.toString(); + } + + private static String printParticle(SchemaParticle part) + { + switch (part.getParticleType()) { + case SchemaParticle.ALL: + return ""; + case SchemaParticle.CHOICE: + return ""; + case SchemaParticle.ELEMENT: + return ""; + case SchemaParticle.SEQUENCE: + return ""; + case SchemaParticle.WILDCARD: + return ""; + default : + return "??"; + } + } + + private static String printMaxOccurs(BigInteger bi) + { + if (bi == null) + return "unbounded"; + return bi.toString(); + } + + private static String printType(SchemaType type) + { + if (type.getName() != null) + return QNameHelper.pretty(type.getName()); + return type.toString(); + } + + private static void checkSubstitutionGroups(SchemaGlobalElement[] elts) + { + StscState state = StscState.get(); + + for (int i = 0 ; i < elts.length ; i++) + { + SchemaGlobalElement elt = elts[i]; + SchemaGlobalElement head = elt.substitutionGroup(); + + if (head != null) + { + SchemaType headType = head.getType(); + SchemaType tailType = elt.getType(); + XmlObject parseTree = ((SchemaGlobalElementImpl)elt)._parseObject; + + if (! headType.isAssignableFrom(tailType)) + { + state.error(XmlErrorCodes.ELEM_PROPERTIES$SUBSTITUTION_VALID, + new Object[] {QNameHelper.pretty(elt.getName()), + QNameHelper.pretty(head.getName())}, + parseTree); + } + else if (head.finalExtension() && head.finalRestriction()) + { + state.error(XmlErrorCodes.ELEM_PROPERTIES$SUBSTITUTION_FINAL, + new Object[] {QNameHelper.pretty(elt.getName()), + QNameHelper.pretty(head.getName()), + "#all"}, parseTree); + } + else if (! headType.equals(tailType)) + { + if (head.finalExtension() && + tailType.getDerivationType() == SchemaType.DT_EXTENSION) + { + state.error(XmlErrorCodes.ELEM_PROPERTIES$SUBSTITUTION_FINAL, + new Object[] {QNameHelper.pretty(elt.getName()), + QNameHelper.pretty(head.getName()), + "extension"}, parseTree); + } + else if (head.finalRestriction() && + tailType.getDerivationType() == SchemaType.DT_RESTRICTION) + { + state.error(XmlErrorCodes.ELEM_PROPERTIES$SUBSTITUTION_FINAL, + new Object[] {QNameHelper.pretty(elt.getName()), + QNameHelper.pretty(head.getName()), + "restriction"}, parseTree); + } + } + } + + } + } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/StscComplexTypeResolver.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/StscComplexTypeResolver.java new file mode 100644 index 000000000..5f2b758a7 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/StscComplexTypeResolver.java @@ -0,0 +1,2128 @@ +/* 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 java.math.BigInteger; +import java.util.*; +import java.util.List; + +import org.apache.xmlbeans.impl.xb.xsdschema.*; +import org.apache.xmlbeans.impl.xb.xsdschema.SchemaDocument.Schema; +import org.apache.xmlbeans.impl.xb.xsdschema.AnyDocument.Any; +import javax.xml.namespace.QName; +import org.apache.xmlbeans.XmlErrorCodes; +import org.apache.xmlbeans.impl.common.QNameHelper; +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.QNameSetBuilder; +import org.apache.xmlbeans.XmlInteger; +import org.apache.xmlbeans.SchemaField; +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.SchemaParticle; +import org.apache.xmlbeans.XmlCursor; +import org.apache.xmlbeans.SchemaAttributeModel; +import org.apache.xmlbeans.SchemaProperty; +import org.apache.xmlbeans.QNameSet; +import org.apache.xmlbeans.XmlNonNegativeInteger; +import org.apache.xmlbeans.SchemaLocalAttribute; +import org.apache.xmlbeans.SchemaLocalElement; +import org.apache.xmlbeans.QNameSetSpecification; + +public class StscComplexTypeResolver +{ + public static Group getContentModel(ComplexType parseCt) + { + if (parseCt.getAll() != null) + return parseCt.getAll(); + + if (parseCt.getSequence() != null) + return parseCt.getSequence(); + + if (parseCt.getChoice() != null) + return parseCt.getChoice(); + + if (parseCt.getGroup() != null) + return parseCt.getGroup(); + + return null; + } + + public static Group getContentModel(ComplexRestrictionType parseRest) + { + if (parseRest.getAll() != null) + return parseRest.getAll(); + + if (parseRest.getSequence() != null) + return parseRest.getSequence(); + + if (parseRest.getChoice() != null) + return parseRest.getChoice(); + + if (parseRest.getGroup() != null) + return parseRest.getGroup(); + + return null; + + } + + public static Group getContentModel(ExtensionType parseExt) + { + if (parseExt.getAll() != null) + return parseExt.getAll(); + + if (parseExt.getSequence() != null) + return parseExt.getSequence(); + + if (parseExt.getChoice() != null) + return parseExt.getChoice(); + + if (parseExt.getGroup() != null) + return parseExt.getGroup(); + + return null; + + } + + static Schema getSchema(XmlObject o) + { + XmlCursor c = o.newCursor(); + + try + { + while ( c.toParent() ) + { + o = c.getObject(); + + if (o.schemaType().equals(Schema.type)) + return (Schema) o; + } + } + finally + { + c.dispose(); + } + + return null; + } + + public static void resolveComplexType(SchemaTypeImpl sImpl) + { + ComplexType parseCt = (ComplexType)sImpl.getParseObject(); + StscState state = StscState.get(); + Schema schema = getSchema(parseCt); + + // Set abstract & final flags + boolean abs = parseCt.isSetAbstract() ? parseCt.getAbstract() : false; + boolean finalExt = false; + boolean finalRest = false; + boolean finalList = false; + boolean finalUnion = false; + + Object ds = null; + if (parseCt.isSetFinal()) + { + ds = parseCt.getFinal(); + } + // Inspect the final default attribute on the schema + else if (schema != null && schema.isSetFinalDefault()) + { + ds = schema.getFinalDefault(); + } + + if (ds != null) + { + if (ds instanceof String && ds.equals("#all")) + { + // #ALL value + finalExt = finalRest = finalList = finalUnion = true; + } + else if (ds instanceof List) + { + if (((List)ds).contains("extension")) + finalExt = true; + + if (((List)ds).contains("restriction")) + finalRest = true; + +// Since complex types don't participate in list and unions, these can remain +// false. Perhaps we should throw an error. + +// if (((List)ds).contains("list")) +// finalList = true; +// +// if (((List)ds).contains("union")) +// finalUnion = true; + } + } + + sImpl.setAbstractFinal(abs, finalExt, finalRest, finalList, finalUnion); + + // Set block flags + boolean blockExt = false; + boolean blockRest = false; + Object block = null; + + if (parseCt.isSetBlock()) + block = parseCt.getBlock(); + else if (schema != null && schema.isSetBlockDefault()) + block = schema.getBlockDefault(); + + if (block != null) + { + if (block instanceof String && block.equals("#all")) + { + // #ALL value + blockExt = blockRest = true; + } + else if (block instanceof List) + { + if (((List)block).contains("extension")) + blockExt = true; + if (((List)block).contains("restriction")) + blockRest = true; + } + } + + sImpl.setBlock(blockExt, blockRest); + + // Verify: have simpleContent, complexContent, or direct stuff + ComplexContentDocument.ComplexContent parseCc = parseCt.getComplexContent(); + SimpleContentDocument.SimpleContent parseSc = parseCt.getSimpleContent(); + Group parseGroup = getContentModel(parseCt); + int count = + (parseCc != null ? 1 : 0) + + (parseSc != null ? 1 : 0) + + (parseGroup != null ? 1 : 0); + if (count > 1) + { + // KHK: s4s should catch this? + state.error("A complex type must define either a content model, " + + "or a simpleContent or complexContent derivation: " + + "more than one found.", + XmlErrorCodes.REDUNDANT_CONTENT_MODEL, parseCt); + // recovery: treat it as the first of complexContent, simpleContent, model + parseGroup = null; + if (parseCc != null && parseSc != null) + parseSc = null; + } + + if (parseCc != null) + { + // KHK: s4s should catch this? + if (parseCc.getExtension() != null && parseCc.getRestriction() != null) + state.error("Restriction conflicts with extension", XmlErrorCodes.REDUNDANT_CONTENT_MODEL, parseCc.getRestriction()); + + // Mixed can be specified in two places: the rules are that Cc wins over Ct if present + // http://www.w3.org/TR/xmlschema-1/#c-mve + boolean mixed = parseCc.isSetMixed() ? parseCc.getMixed() : parseCt.getMixed(); + + if (parseCc.getExtension() != null) + resolveCcExtension(sImpl, parseCc.getExtension(), mixed); + else if (parseCc.getRestriction() != null) + resolveCcRestriction(sImpl, parseCc.getRestriction(), mixed); + else + { + // KHK: s4s should catch this? + state.error("Missing restriction or extension", XmlErrorCodes.MISSING_RESTRICTION_OR_EXTENSION, parseCc); + resolveErrorType(sImpl); + } + return; + } + else if (parseSc != null) + { + // KHK: s4s should catch this? + if (parseSc.getExtension() != null && parseSc.getRestriction() != null) + state.error("Restriction conflicts with extension", XmlErrorCodes.REDUNDANT_CONTENT_MODEL, parseSc.getRestriction()); + + if (parseSc.getExtension() != null) + resolveScExtension(sImpl, parseSc.getExtension()); + else if (parseSc.getRestriction() != null) + resolveScRestriction(sImpl, parseSc.getRestriction()); + else + { + // KHK: s4s should catch this? + state.error("Missing restriction or extension", XmlErrorCodes.MISSING_RESTRICTION_OR_EXTENSION, parseSc); + resolveErrorType(sImpl); + } + return; + } + else + resolveBasicComplexType(sImpl); + } + + static void resolveErrorType(SchemaTypeImpl sImpl) + { + throw new RuntimeException("This type of error recovery not yet implemented."); + } + + private static SchemaType.Ref[] makeRefArray(Collection typeList) + { + SchemaType.Ref[] result = new SchemaType.Ref[typeList.size()]; + int j = 0; + for (Iterator i = typeList.iterator(); i.hasNext(); j++) + result[j] = ((SchemaType)i.next()).getRef(); + return result; + } + + + static void resolveBasicComplexType(SchemaTypeImpl sImpl) + { + List anonymousTypes = new ArrayList(); + ComplexType parseTree = (ComplexType)sImpl.getParseObject(); + String targetNamespace = sImpl.getTargetNamespace(); + boolean chameleon = (sImpl.getChameleonNamespace() != null); + Group parseGroup = getContentModel(parseTree); + + if (sImpl.isRedefinition()) + { + StscState.get().error(XmlErrorCodes.SCHEMA_REDEFINE$EXTEND_OR_RESTRICT, + new Object[] { "" }, parseTree); + // recovery: oh well. + } + + int particleCode = translateParticleCode(parseGroup); + + // used to ensure consistency (doesn't become part of the result) + Map elementModel = new LinkedHashMap(); + + // build content model and anonymous types + SchemaParticle contentModel = translateContentModel(sImpl, + parseGroup, targetNamespace, chameleon, + sImpl.getElemFormDefault(), sImpl.getAttFormDefault(), + particleCode, anonymousTypes, elementModel, false, null); + + // detect the nonempty "all" case (empty doesn't count - it needs to be eliminated to match XSD test cases) + boolean isAll = contentModel != null && contentModel.getParticleType() == SchemaParticle.ALL; + + // build attr model and anonymous types + SchemaAttributeModelImpl attrModel = new SchemaAttributeModelImpl(); + translateAttributeModel(parseTree, targetNamespace, chameleon, sImpl.getAttFormDefault(), + anonymousTypes, sImpl, null, attrModel, null, true, null); + + // summarize wildcard information + WildcardResult wcElt = summarizeEltWildcards(contentModel); + WildcardResult wcAttr = summarizeAttrWildcards(attrModel); + + // build state machine and verify that content model is deterministic + if (contentModel != null) + { + buildStateMachine(contentModel); + if (!StscState.get().noUpa() && !((SchemaParticleImpl)contentModel).isDeterministic()) + StscState.get().error(XmlErrorCodes.UNIQUE_PARTICLE_ATTRIBUTION, null, parseGroup); + } + + // build property model + // emitDBG("Building content Model for " + sImpl); + Map elementPropertyModel = buildContentPropertyModelByQName(contentModel, sImpl); + + // add attribute property model + Map attributePropertyModel = buildAttributePropertyModelByQName(attrModel, sImpl); + + // figure out content type + int complexVariety = + parseTree.getMixed() + ? SchemaType.MIXED_CONTENT + : contentModel == null + ? SchemaType.EMPTY_CONTENT + : SchemaType.ELEMENT_CONTENT; + + // now fill in the actual schema type implementation + sImpl.setBaseTypeRef(BuiltinSchemaTypeSystem.ST_ANY_TYPE.getRef()); + sImpl.setBaseDepth(BuiltinSchemaTypeSystem.ST_ANY_TYPE.getBaseDepth() + 1); + sImpl.setDerivationType(SchemaType.DT_EXTENSION); + sImpl.setComplexTypeVariety(complexVariety); + sImpl.setContentModel(contentModel, attrModel, elementPropertyModel, attributePropertyModel, isAll); + sImpl.setAnonymousTypeRefs(makeRefArray(anonymousTypes)); + sImpl.setWildcardSummary(wcElt.typedWildcards, wcElt.hasWildcards, wcAttr.typedWildcards, wcAttr.hasWildcards); + } + + static void resolveCcRestriction(SchemaTypeImpl sImpl, ComplexRestrictionType parseTree, boolean mixed) + { + StscState state = StscState.get(); + String targetNamespace = sImpl.getTargetNamespace(); + boolean chameleon = (sImpl.getChameleonNamespace() != null); + + // BUGBUG: NOT YET REALLY IMPLEMENTED + // throw new RuntimeException("Not yet implemented."); + + SchemaType baseType; + if (parseTree.getBase() == null) + { + // KHK: s4s + state.error("A complexContent must define a base type", XmlErrorCodes.MISSING_BASE, parseTree); + baseType = null; // recovery: no inheritance. + } + else + { + if (sImpl.isRedefinition()) + { + baseType = state.findRedefinedGlobalType(parseTree.getBase(), sImpl.getChameleonNamespace(), sImpl); + if (baseType != null && !baseType.getName().equals(sImpl.getName())) + { + state.error(XmlErrorCodes.SCHEMA_REDEFINE$SAME_TYPE, + new Object[] { "", + QNameHelper.pretty(baseType.getName()), + QNameHelper.pretty(sImpl.getName()) + }, + parseTree); + } + } + else + { + baseType = state.findGlobalType(parseTree.getBase(), sImpl.getChameleonNamespace(), targetNamespace); + } + + if (baseType == null) + state.notFoundError(parseTree.getBase(), SchemaType.TYPE, parseTree.xgetBase(), true); + } + + if (baseType == null) + baseType = BuiltinSchemaTypeSystem.ST_ANY_TYPE; + + if (baseType != null && baseType.finalRestriction()) + { + state.error(XmlErrorCodes.COMPLEX_TYPE_RESTRICTION$FINAL, + new Object[] { QNameHelper.pretty(baseType.getName()), QNameHelper.pretty(sImpl.getName()) }, + parseTree.xgetBase()); + // recovery: just keep going + } + + // Recursion + if (baseType != null) + { + if (!StscResolver.resolveType((SchemaTypeImpl)baseType)) + baseType = null; // circular dependency: no inheritance + } + + List anonymousTypes = new ArrayList(); + Group parseEg = getContentModel(parseTree); + + // detect the "all" case + int particleCode = translateParticleCode(parseEg); + + // used to ensure consistency (doesn't become part of the result) + Map elementModel = new LinkedHashMap(); + + // build content model and anonymous types + SchemaParticle contentModel = translateContentModel( sImpl, + parseEg, targetNamespace, chameleon, + sImpl.getElemFormDefault(), sImpl.getAttFormDefault(), + particleCode, anonymousTypes, elementModel, false, null); + + // detect the nonempty "all" case (empty doesn't count - it needs to be eliminated to match XSD test cases) + boolean isAll = contentModel != null && contentModel.getParticleType() == SchemaParticle.ALL; + + // build attr model and anonymous types + SchemaAttributeModelImpl attrModel; + if (baseType == null) + attrModel = new SchemaAttributeModelImpl(); + else + attrModel = new SchemaAttributeModelImpl(baseType.getAttributeModel()); + translateAttributeModel(parseTree, targetNamespace, chameleon, sImpl.getAttFormDefault(), + anonymousTypes, sImpl, null, attrModel, baseType, false, null); + + // summarize wildcard information + WildcardResult wcElt = summarizeEltWildcards(contentModel); + WildcardResult wcAttr = summarizeAttrWildcards(attrModel); + + // build state machine and verify that content model is deterministic + if (contentModel != null) + { + buildStateMachine(contentModel); + if (!StscState.get().noUpa() && !((SchemaParticleImpl)contentModel).isDeterministic()) + StscState.get().error(XmlErrorCodes.UNIQUE_PARTICLE_ATTRIBUTION, null, parseEg); + } + + // build property model + // emitDBG("Building content Model for " + sImpl); + Map elementPropertyModel = buildContentPropertyModelByQName(contentModel, sImpl); + + // add attribute property model + Map attributePropertyModel = buildAttributePropertyModelByQName(attrModel, sImpl); + + // compute empty/element/mixed + // fix for XMLBEANS-414 + int complexVariety = (mixed ? SchemaType.MIXED_CONTENT : + (contentModel == null ? SchemaType.EMPTY_CONTENT : SchemaType.ELEMENT_CONTENT)); + + // now fill in the actual schema type implementation + sImpl.setBaseTypeRef(baseType.getRef()); + sImpl.setBaseDepth(((SchemaTypeImpl)baseType).getBaseDepth() + 1); + sImpl.setDerivationType(SchemaType.DT_RESTRICTION); + sImpl.setComplexTypeVariety(complexVariety); + sImpl.setContentModel(contentModel, attrModel, elementPropertyModel, attributePropertyModel, isAll); + sImpl.setAnonymousTypeRefs(makeRefArray(anonymousTypes)); + sImpl.setWildcardSummary(wcElt.typedWildcards, wcElt.hasWildcards, wcAttr.typedWildcards, wcAttr.hasWildcards); + } + + static Map extractElementModel(SchemaType sType) + { + Map elementModel = new HashMap(); + if (sType != null) + { + SchemaProperty[] sProps = sType.getProperties(); + for (int i = 0; i < sProps.length; i++) + { + if (sProps[i].isAttribute()) + continue; + elementModel.put(sProps[i].getName(), + sProps[i].getType()); + } + } + return elementModel; + } + + static void resolveCcExtension(SchemaTypeImpl sImpl, ExtensionType parseTree, boolean mixed) + { + SchemaType baseType; + StscState state = StscState.get(); + String targetNamespace = sImpl.getTargetNamespace(); + boolean chameleon = (sImpl.getChameleonNamespace() != null); + + if (parseTree.getBase() == null) + { + // KHK: s4s + state.error("A complexContent must define a base type", XmlErrorCodes.MISSING_BASE, parseTree); + baseType = null; // recovery: no inheritance. + } + else + { + if (sImpl.isRedefinition()) + { + baseType = state.findRedefinedGlobalType(parseTree.getBase(), sImpl.getChameleonNamespace(), sImpl); + if (baseType != null && !baseType.getName().equals(sImpl.getName())) + { + state.error(XmlErrorCodes.SCHEMA_REDEFINE$SAME_TYPE, + new Object[] { "", + QNameHelper.pretty(baseType.getName()), + QNameHelper.pretty(sImpl.getName()) + }, + parseTree); + } + } + else + { + baseType = state.findGlobalType(parseTree.getBase(), sImpl.getChameleonNamespace(), targetNamespace); + } + if (baseType == null) + state.notFoundError(parseTree.getBase(), SchemaType.TYPE, parseTree.xgetBase(), true); + } + + // Recursion + if (baseType != null) + { + if (!StscResolver.resolveType((SchemaTypeImpl)baseType)) + baseType = null; // circular dependency: no inheritance + } + + if (baseType != null && baseType.isSimpleType()) + { + state.recover(XmlErrorCodes.SCHEMA_COMPLEX_TYPE$COMPLEX_CONTENT, + new Object[] { QNameHelper.pretty(baseType.getName()) }, + parseTree.xgetBase()); + baseType = null; // recovery: no inheritance. + } + + if (baseType != null && baseType.finalExtension()) + { + state.error(XmlErrorCodes.COMPLEX_TYPE_EXTENSION$FINAL, + new Object[] { QNameHelper.pretty(baseType.getName()), QNameHelper.pretty(sImpl.getName()) }, + parseTree.xgetBase()); + // recovery: just keep going + } + + // get base content model + SchemaParticle baseContentModel = (baseType == null ? null : baseType.getContentModel()); + // TODO: attribute model also + + List anonymousTypes = new ArrayList(); + Map baseElementModel = extractElementModel(baseType); + Group parseEg = getContentModel(parseTree); + + if (baseType != null && + (baseType.getContentType() == SchemaType.SIMPLE_CONTENT)) + if (parseEg != null) + { + // if this type has complexContent, baseType is complexType + // but with non-empty simpleContent then this type cannot + // add extra elements + state.recover(XmlErrorCodes.COMPLEX_TYPE_EXTENSION$EXTENDING_SIMPLE_CONTENT, + new Object[] { QNameHelper.pretty(baseType.getName()) }, + parseTree.xgetBase()); + baseType = null; // recovery: no inheritance. + } + else + { + // No extra elements, the type is a complex type with simple content + resolveScExtensionPart2(sImpl, baseType, parseTree, targetNamespace, chameleon); + return; + } + + // build extension model + SchemaParticle extensionModel = translateContentModel(sImpl, + parseEg, targetNamespace, chameleon, + sImpl.getElemFormDefault(), sImpl.getAttFormDefault(), + translateParticleCode(parseEg), anonymousTypes, baseElementModel, false, null); + + // apply rule #2 near http://www.w3.org/TR/xmlschema-1/#c-mve: empty ext model -> mixed taken from base + if (extensionModel == null && !mixed) + mixed = (baseType != null && baseType.getContentType() == SchemaType.MIXED_CONTENT); + + // apply Derivation Valid (Extension) rule 1.4.2.2 + if (baseType != null && (baseType.getContentType() != SchemaType.EMPTY_CONTENT) && + ((baseType.getContentType() == SchemaType.MIXED_CONTENT) != mixed)) + { + state.error(XmlErrorCodes.COMPLEX_TYPE_EXTENSION$BOTH_ELEMEMENT_OR_MIXED, null, parseTree.xgetBase()); + // recovery: just keep going + } + + // detect the "all" base case + if (baseType != null && baseType.hasAllContent() && extensionModel != null) + { + // KHK: which rule? cos-particle-extend.2 or cos-all-limited.1.2. I think the limited one. + state.error("Cannot extend a type with 'all' content model", XmlErrorCodes.CANNOT_EXTEND_ALL, parseTree.xgetBase()); + extensionModel = null; // recovery: drop extension + } + + // build content model and anonymous types + SchemaParticle contentModel = extendContentModel(baseContentModel, extensionModel, parseTree); + + // detect the nonempty "all" case (empty doesn't count - it needs to be eliminated to match XSD test cases) + boolean isAll = contentModel != null && contentModel.getParticleType() == SchemaParticle.ALL; + + // build attr model and anonymous types + SchemaAttributeModelImpl attrModel; + if (baseType == null) + attrModel = new SchemaAttributeModelImpl(); + else + attrModel = new SchemaAttributeModelImpl(baseType.getAttributeModel()); + translateAttributeModel(parseTree, targetNamespace, chameleon, sImpl.getAttFormDefault(), + anonymousTypes, sImpl, null, attrModel, baseType, true, null); + + // summarize wildcard information + WildcardResult wcElt = summarizeEltWildcards(contentModel); + WildcardResult wcAttr = summarizeAttrWildcards(attrModel); + + // build state machine and verify that content model is deterministic + if (contentModel != null) + { + buildStateMachine(contentModel); + if (!StscState.get().noUpa() && !((SchemaParticleImpl)contentModel).isDeterministic()) + StscState.get().error(XmlErrorCodes.UNIQUE_PARTICLE_ATTRIBUTION, null, parseEg); + } + + // build property model + // emitDBG("Building content Model for " + sImpl); + Map elementPropertyModel = buildContentPropertyModelByQName(contentModel, sImpl); + + // add attribute property model + Map attributePropertyModel = buildAttributePropertyModelByQName(attrModel, sImpl); + + // compute empty/element/mixed + int complexVariety; + if (contentModel == null && baseType != null && + baseType.getContentType() == SchemaType.SIMPLE_CONTENT) + { + complexVariety = SchemaType.SIMPLE_CONTENT; + sImpl.setContentBasedOnTypeRef(baseType.getContentBasedOnType().getRef()); + } + else + complexVariety = ( mixed ? SchemaType.MIXED_CONTENT : + (contentModel == null ? SchemaType.EMPTY_CONTENT : SchemaType.ELEMENT_CONTENT)); + + // now fill in the actual schema type implementation + if (baseType == null) + baseType = XmlObject.type; + sImpl.setBaseTypeRef(baseType.getRef()); + sImpl.setBaseDepth(((SchemaTypeImpl)baseType).getBaseDepth() + 1); + sImpl.setDerivationType(SchemaType.DT_EXTENSION); + sImpl.setComplexTypeVariety(complexVariety); + sImpl.setContentModel(contentModel, attrModel, elementPropertyModel, attributePropertyModel, isAll); + sImpl.setAnonymousTypeRefs(makeRefArray(anonymousTypes)); + sImpl.setWildcardSummary(wcElt.typedWildcards, wcElt.hasWildcards, wcAttr.typedWildcards, wcAttr.hasWildcards); + } + + static void resolveScRestriction(SchemaTypeImpl sImpl, SimpleRestrictionType parseTree) + { + SchemaType baseType; + SchemaType contentType = null; + StscState state = StscState.get(); + String targetNamespace = sImpl.getTargetNamespace(); + boolean chameleon = (sImpl.getChameleonNamespace() != null); + List anonymousTypes = new ArrayList(); + if (parseTree.getSimpleType() != null) + { + LocalSimpleType typedef = parseTree.getSimpleType(); + SchemaTypeImpl anonType = StscTranslator. + translateAnonymousSimpleType(typedef, targetNamespace, chameleon, + sImpl.getElemFormDefault(), sImpl.getAttFormDefault(), + anonymousTypes, sImpl); + contentType = anonType; + } + if (parseTree.getBase() == null) + { + state.error("A simpleContent restriction must define a base type", XmlErrorCodes.MISSING_BASE, parseTree); + // recovery: extends ANY_SIMPLE type + baseType = BuiltinSchemaTypeSystem.ST_ANY_SIMPLE; + } + else + { + if (sImpl.isRedefinition()) + { + baseType = state.findRedefinedGlobalType(parseTree.getBase(), sImpl.getChameleonNamespace(), sImpl); + if (baseType != null && !baseType.getName().equals(sImpl.getName())) + { + state.error(XmlErrorCodes.SCHEMA_REDEFINE$SAME_TYPE, + new Object[] { "", + QNameHelper.pretty(baseType.getName()), + QNameHelper.pretty(sImpl.getName()) + }, + parseTree); + } + } + else + { + baseType = state.findGlobalType(parseTree.getBase(), sImpl.getChameleonNamespace(), targetNamespace); + } + if (baseType == null) + { + state.notFoundError(parseTree.getBase(), SchemaType.TYPE, parseTree.xgetBase(), true); + // recovery: extends ANY_SIMPLE type + baseType = BuiltinSchemaTypeSystem.ST_ANY_SIMPLE; + } + } + + // Recursion + StscResolver.resolveType((SchemaTypeImpl)baseType); + if (contentType != null) + StscResolver.resolveType((SchemaTypeImpl)contentType); + else + contentType = baseType; + + if (baseType.isSimpleType()) + { + // src-ct.2: complex types with simple content cannot restrict simple types + state.recover(XmlErrorCodes.COMPLEX_TYPE_PROPERTIES$SIMPLE_TYPE_EXTENSION, + new Object[] { QNameHelper.pretty(baseType.getName()) }, + parseTree); + // recovery: extends ANY_SIMPLE type + baseType = BuiltinSchemaTypeSystem.ST_ANY_SIMPLE; + } + else if (baseType.getContentType() != SchemaType.SIMPLE_CONTENT && + contentType == null) + { + // recovery: extends ANY_SIMPLE type + baseType = BuiltinSchemaTypeSystem.ST_ANY_SIMPLE; + } + + if (baseType != null && baseType.finalRestriction()) + { + state.error(XmlErrorCodes.COMPLEX_TYPE_RESTRICTION$FINAL, + new Object[] { QNameHelper.pretty(baseType.getName()), QNameHelper.pretty(sImpl.getName()) }, + parseTree.xgetBase()); + // recovery: just keep going + } + + // build attr model and anonymous types + SchemaAttributeModelImpl attrModel; + if (baseType == null) + attrModel = new SchemaAttributeModelImpl(); + else + attrModel = new SchemaAttributeModelImpl(baseType.getAttributeModel()); + translateAttributeModel(parseTree, targetNamespace, chameleon, sImpl.getAttFormDefault(), + anonymousTypes, sImpl, null, attrModel, baseType, false, null); + + // summarize wildcard information + WildcardResult wcAttr = summarizeAttrWildcards(attrModel); + + // add attribute property model + Map attributePropertyModel = buildAttributePropertyModelByQName(attrModel, sImpl); + + // now fill in the actual schema type implementation + sImpl.setBaseTypeRef(baseType.getRef()); + sImpl.setBaseDepth(((SchemaTypeImpl)baseType).getBaseDepth() + 1); + sImpl.setContentBasedOnTypeRef(contentType.getRef()); + sImpl.setDerivationType(SchemaType.DT_RESTRICTION); + sImpl.setAnonymousTypeRefs(makeRefArray(anonymousTypes)); + sImpl.setWildcardSummary(QNameSet.EMPTY, false, wcAttr.typedWildcards, wcAttr.hasWildcards); + sImpl.setComplexTypeVariety(SchemaType.SIMPLE_CONTENT); + sImpl.setContentModel(null, attrModel, null, attributePropertyModel, false); + sImpl.setSimpleTypeVariety(contentType.getSimpleVariety()); + sImpl.setPrimitiveTypeRef(contentType.getPrimitiveType() == null ? null : contentType.getPrimitiveType().getRef()); + switch (sImpl.getSimpleVariety()) + { + case SchemaType.LIST: + sImpl.setListItemTypeRef(contentType.getListItemType().getRef()); + break; + + case SchemaType.UNION: + sImpl.setUnionMemberTypeRefs(makeRefArray(Arrays.asList(contentType.getUnionMemberTypes()))); + break; + } + + // deal with facets + StscSimpleTypeResolver.resolveFacets(sImpl, parseTree, (SchemaTypeImpl) contentType); + + // now compute our intrinsic properties + StscSimpleTypeResolver.resolveFundamentalFacets(sImpl); + } + + static void resolveScExtension(SchemaTypeImpl sImpl, SimpleExtensionType parseTree) + { + SchemaType baseType; + StscState state = StscState.get(); + String targetNamespace = sImpl.getTargetNamespace(); + boolean chameleon = (sImpl.getChameleonNamespace() != null); + if (parseTree.getBase() == null) + { + state.error("A simpleContent extension must define a base type", XmlErrorCodes.MISSING_BASE, parseTree); + // recovery: extends ANY_SIMPLE type + baseType = BuiltinSchemaTypeSystem.ST_ANY_SIMPLE; + } + else + { + if (sImpl.isRedefinition()) + { + baseType = state.findRedefinedGlobalType(parseTree.getBase(), sImpl.getChameleonNamespace(), sImpl); + if (baseType != null && !baseType.getName().equals(sImpl.getName())) + { + state.error(XmlErrorCodes.SCHEMA_REDEFINE$SAME_TYPE, + new Object[] { "", + QNameHelper.pretty(baseType.getName()), + QNameHelper.pretty(sImpl.getName()) + }, + parseTree); + } + } + else + { + baseType = state.findGlobalType(parseTree.getBase(), sImpl.getChameleonNamespace(), targetNamespace); + } + if (baseType == null) + { + state.notFoundError(parseTree.getBase(), SchemaType.TYPE, parseTree.xgetBase(), true); + // recovery: extends ANY_SIMPLE type + baseType = BuiltinSchemaTypeSystem.ST_ANY_SIMPLE; + } + } + + // Recursion + StscResolver.resolveType((SchemaTypeImpl)baseType); + + if (!baseType.isSimpleType() && baseType.getContentType() != SchemaType.SIMPLE_CONTENT) + { + // src-ct.2: complex types with simple content can only extend simple types + state.error(XmlErrorCodes.SCHEMA_COMPLEX_TYPE$SIMPLE_CONTENT, + new Object[] { QNameHelper.pretty(baseType.getName()) } , + parseTree); + // recovery: extends ANY_SIMPLE type + baseType = BuiltinSchemaTypeSystem.ST_ANY_SIMPLE; + } + + if (baseType != null && baseType.finalExtension()) + { + state.error(XmlErrorCodes.COMPLEX_TYPE_EXTENSION$FINAL, + new Object[] { QNameHelper.pretty(baseType.getName()), QNameHelper.pretty(sImpl.getName()) }, + parseTree.xgetBase()); + // recovery: just keep going + } + + resolveScExtensionPart2(sImpl, baseType, parseTree, targetNamespace, chameleon); + } + + static void resolveScExtensionPart2(SchemaTypeImpl sImpl, SchemaType baseType, ExtensionType parseTree, + String targetNamespace, boolean chameleon) + { + // build attr model and anonymous types + List anonymousTypes = new ArrayList(); + SchemaAttributeModelImpl attrModel; + attrModel = new SchemaAttributeModelImpl(baseType.getAttributeModel()); + translateAttributeModel(parseTree, targetNamespace, chameleon, sImpl.getAttFormDefault(), anonymousTypes, sImpl, null, attrModel, baseType, true, null); + + // summarize wildcard information + WildcardResult wcAttr = summarizeAttrWildcards(attrModel); + + // add attribute property model + Map attributePropertyModel = buildAttributePropertyModelByQName(attrModel, sImpl); + + // now fill in the actual schema type implementation + sImpl.setBaseTypeRef(baseType.getRef()); + sImpl.setBaseDepth(((SchemaTypeImpl)baseType).getBaseDepth() + 1); + sImpl.setContentBasedOnTypeRef(baseType.getRef()); + sImpl.setDerivationType(SchemaType.DT_EXTENSION); + sImpl.setAnonymousTypeRefs(makeRefArray(anonymousTypes)); + sImpl.setWildcardSummary(QNameSet.EMPTY, false, wcAttr.typedWildcards, wcAttr.hasWildcards); + sImpl.setComplexTypeVariety(SchemaType.SIMPLE_CONTENT); + sImpl.setContentModel(null, attrModel, null, attributePropertyModel, false); + sImpl.setSimpleTypeVariety(baseType.getSimpleVariety()); + sImpl.setPrimitiveTypeRef(baseType.getPrimitiveType() == null ? null : baseType.getPrimitiveType().getRef()); + switch (sImpl.getSimpleVariety()) + { + case SchemaType.LIST: + sImpl.setListItemTypeRef(baseType.getListItemType().getRef()); + break; + + case SchemaType.UNION: + sImpl.setUnionMemberTypeRefs(makeRefArray(Arrays.asList(baseType.getUnionMemberTypes()))); + break; + } + + // deal with facets + StscSimpleTypeResolver.resolveFacets(sImpl, null, (SchemaTypeImpl)baseType); + + // now compute our intrinsic properties + StscSimpleTypeResolver.resolveFundamentalFacets(sImpl); + } + + static class WildcardResult + { + WildcardResult(QNameSet typedWildcards, boolean hasWildcards) + { + this.typedWildcards = typedWildcards; + this.hasWildcards = hasWildcards; + } + QNameSet typedWildcards; + boolean hasWildcards; + } + + static WildcardResult summarizeAttrWildcards(SchemaAttributeModel attrModel) + { + if (attrModel.getWildcardProcess() == SchemaAttributeModel.NONE) + return new WildcardResult(QNameSet.EMPTY, false); + if (attrModel.getWildcardProcess() == SchemaAttributeModel.SKIP) + return new WildcardResult(QNameSet.EMPTY, true); + return new WildcardResult(attrModel.getWildcardSet(), true); + } + + static WildcardResult summarizeEltWildcards(SchemaParticle contentModel) + { + if (contentModel == null) + { + return new WildcardResult(QNameSet.EMPTY, false); + } + + switch (contentModel.getParticleType()) + { + case SchemaParticle.ALL: + case SchemaParticle.SEQUENCE: + case SchemaParticle.CHOICE: + QNameSetBuilder set = new QNameSetBuilder(); + boolean hasWildcards = false; + for (int i = 0; i < contentModel.countOfParticleChild(); i++) + { + WildcardResult inner = summarizeEltWildcards(contentModel.getParticleChild(i)); + set.addAll(inner.typedWildcards); + hasWildcards |= inner.hasWildcards; + } + return new WildcardResult(set.toQNameSet(), hasWildcards); + case SchemaParticle.WILDCARD: + return new WildcardResult( + (contentModel.getWildcardProcess() == SchemaParticle.SKIP) ? + QNameSet.EMPTY : contentModel.getWildcardSet(), true); + // otherwise fallthrough + + default: + return new WildcardResult(QNameSet.EMPTY, false); + } + } + + static void translateAttributeModel(XmlObject parseTree, + String targetNamespace, boolean chameleon, String formDefault, + List anonymousTypes, SchemaType outerType, + Set seenAttributes, SchemaAttributeModelImpl result, + SchemaType baseType, boolean extension, + SchemaAttributeGroupImpl redefinitionFor) + { + StscState state = StscState.get(); + if (seenAttributes == null) + seenAttributes = new HashSet(); + boolean seenWildcard = false; + boolean seenRedefinition = false; + SchemaAttributeModel baseModel = null; + if (baseType != null) + baseModel = baseType.getAttributeModel(); + + XmlCursor cur = parseTree.newCursor(); + + for (boolean more = cur.toFirstChild(); more; more = cur.toNextSibling()) + { + switch (translateAttributeCode(cur.getName())) + { + case ATTRIBUTE_CODE: + { + Attribute xsdattr = (Attribute)cur.getObject(); + + SchemaLocalAttribute sAttr = StscTranslator.translateAttribute(xsdattr, targetNamespace, formDefault, chameleon, anonymousTypes, outerType, baseModel, true); + if (sAttr == null) + continue; + + if (seenAttributes.contains(sAttr.getName())) + { + state.error(XmlErrorCodes.COMPLEX_TYPE_PROPERTIES$DUPLICATE_ATTRIBUTE, + new Object[] { QNameHelper.pretty(sAttr.getName()), QNameHelper.pretty(outerType.getName()) }, + xsdattr.xgetName()); + continue; // ignore the duplicate attr + } + + seenAttributes.add(sAttr.getName()); + + if (baseModel != null) + { + SchemaLocalAttribute baseAttr = baseModel.getAttribute(sAttr.getName()); + if (baseAttr == null) + { + if (!extension) + { + if (!baseModel.getWildcardSet().contains(sAttr.getName())) + state.error(XmlErrorCodes.COMPLEX_TYPE_RESTRICTION$ATTR_IN_BASE_WILDCARD_SET, + new Object[] { QNameHelper.pretty(sAttr.getName()), QNameHelper.pretty(outerType.getName()) }, xsdattr); + } + } + else + { + if (extension) + { + // KHK: cos-ct-extends.1.2? + if (sAttr.getUse() == SchemaLocalAttribute.PROHIBITED) + state.error("An extension cannot prohibit an attribute from the base type; use restriction instead.", XmlErrorCodes.DUPLICATE_ATTRIBUTE_NAME, xsdattr.xgetUse()); + } + else + { + if (sAttr.getUse() != SchemaLocalAttribute.REQUIRED) + { + if (baseAttr.getUse() == SchemaLocalAttribute.REQUIRED) + state.error(XmlErrorCodes.COMPLEX_TYPE_RESTRICTION$ATTR_REQUIRED, + new Object[] { QNameHelper.pretty(sAttr.getName()), QNameHelper.pretty(outerType.getName()) }, xsdattr); + + if (sAttr.getUse() == SchemaLocalAttribute.PROHIBITED) + result.removeProhibitedAttribute(sAttr.getName()); + } + } + } + } + + if (sAttr.getUse() != SchemaLocalAttribute.PROHIBITED) + { + result.addAttribute(sAttr); + } + else + { + // attribute is prohibited. If it has an anonymous type remove + // it from the list (this will prevent inclusion of any anonymous + // types defined within the prohibited attribute which would + // otherwise attempt to refer to the prohibited attribute at + // save() time) + SchemaType attrType = sAttr.getType(); + if (anonymousTypes != null && anonymousTypes.contains(attrType)) + { + anonymousTypes.remove(attrType); + } + } + + if (sAttr.getDefaultText() != null && !sAttr.isFixed()) + { + if (sAttr.getUse() != SchemaLocalAttribute.OPTIONAL) + state.error(XmlErrorCodes.SCHEMA_ATTR$DEFAULT_AND_USE_OPTIONAL, + new Object[] { QNameHelper.pretty(sAttr.getName()) }, xsdattr); + } + + + break; + } + case ANY_ATTRIBUTE_CODE: + { + Wildcard xsdwc = (Wildcard)cur.getObject(); + if (seenWildcard) + { + // KHK: ? + state.error("Only one attribute wildcard allowed", XmlErrorCodes.DUPLICATE_ANY_ATTRIBUTE, xsdwc); + continue; // ignore the extra wildcard + } + seenWildcard = true; + NamespaceList nsList = xsdwc.xgetNamespace(); + String nsText; + if (nsList == null) + nsText = "##any"; + else + nsText = nsList.getStringValue(); + QNameSet wcset = QNameSet.forWildcardNamespaceString(nsText, targetNamespace); + + if (baseModel != null && !extension) + { + if (baseModel.getWildcardSet() == null) + { + state.error(XmlErrorCodes.COMPLEX_TYPE_RESTRICTION$BASE_HAS_ATTR_WILDCARD, null, xsdwc); + continue; // ignore the extra wildcard + } + else if (!baseModel.getWildcardSet().containsAll(wcset)) + { + state.error(XmlErrorCodes.COMPLEX_TYPE_RESTRICTION$ATTR_WILDCARD_SUBSET, + new Object[] { nsText }, xsdwc); + continue; // ignore the restriction + } + } + + int wcprocess = translateWildcardProcess(xsdwc.xgetProcessContents()); + if (result.getWildcardProcess() == SchemaAttributeModel.NONE) + { + result.setWildcardSet(wcset); + result.setWildcardProcess(wcprocess); + } + else + { + if (extension) + { + result.setWildcardSet(wcset.union(result.getWildcardSet())); + result.setWildcardProcess(wcprocess); + } + else + { + result.setWildcardSet(wcset.intersect(result.getWildcardSet())); + // keep old process + } + } + break; + } + case ATTRIBUTE_GROUP_CODE: + { + AttributeGroupRef xsdag = (AttributeGroupRef)cur.getObject(); + QName ref = xsdag.getRef(); + if (ref == null) + { + // KHK: s4s + state.error("Attribute group reference must have a ref attribute", XmlErrorCodes.ATTRIBUTE_GROUP_MISSING_REF, xsdag); + continue; + } + SchemaAttributeGroupImpl group; + if (redefinitionFor != null) + { + group = state.findRedefinedAttributeGroup(ref, chameleon ? targetNamespace : null, redefinitionFor); + if (group != null && + redefinitionFor.getName().equals(group.getName())) + { + if (seenRedefinition) + state.error(XmlErrorCodes.SCHEMA_REDEFINE$ATTR_GROUP_SELF_REF, + new Object[] { QNameHelper.pretty(redefinitionFor.getName()) }, xsdag); + seenRedefinition = true; + } + } + else + { + group = state.findAttributeGroup(ref, chameleon ? targetNamespace : null, targetNamespace); + } + if (group == null) + { + state.notFoundError(ref, SchemaType.ATTRIBUTE_GROUP, xsdag.xgetRef(), true); + continue; + } + if (state.isProcessing(group)) + { + state.error(XmlErrorCodes.SCHEMA_ATTR_GROUP$SELF_REF, + new Object[] { QNameHelper.pretty(group.getName()) },group.getParseObject()); + continue; + } + String subTargetNamespace = targetNamespace; + if (group.getTargetNamespace() != null) + { + subTargetNamespace = group.getTargetNamespace(); + chameleon = group.getChameleonNamespace() != null; + } + + state.startProcessing(group); + SchemaAttributeGroupImpl nestedRedefinitionFor = null; + if (group.isRedefinition()) + nestedRedefinitionFor = group; + translateAttributeModel(group.getParseObject(), subTargetNamespace, chameleon, + group.getFormDefault(), + anonymousTypes, outerType, seenAttributes, result, baseType, + extension, nestedRedefinitionFor); + state.finishProcessing(group); + break; + } + default: + { + continue; // skip things that are not part of the attribute model. + } + } + } + // If this is restriction and no wildcard was present, then + // we have to erase the inherited wildcards + if (!extension && !seenWildcard) + { + result.setWildcardSet(null); + result.setWildcardProcess(SchemaAttributeModel.NONE); + } + } + + static SchemaParticle extendContentModel(SchemaParticle baseContentModel, SchemaParticle extendedContentModel, XmlObject parseTree) + { + // http://www.w3.org/TR/xmlschema-1/#element-complexContent::extension + + // 2.1 If the explicit content is empty, then the {content type} of the type definition resolved to by the �actual value� of the base [attribute] + if (extendedContentModel == null) + return baseContentModel; + + // 2.2 If the type definition resolved to by the actual value of the base [attribute] has a {content type} of empty, then a pair of mixed or elementOnly (determined as per clause 1.2.1 above) and the explicit content itself; + if (baseContentModel == null) + return extendedContentModel; + + // 2.3 otherwise a pair of mixed or elementOnly (determined as per clause 1.2.1 above) and a particle whose properties are as follows: + SchemaParticleImpl sPart = new SchemaParticleImpl(); + sPart.setParticleType(SchemaParticle.SEQUENCE); + + List accumulate = new ArrayList(); + addMinusPointlessParticles(accumulate, baseContentModel, SchemaParticle.SEQUENCE); + addMinusPointlessParticles(accumulate, extendedContentModel, SchemaParticle.SEQUENCE); + sPart.setMinOccurs(BigInteger.ONE); + sPart.setMaxOccurs(BigInteger.ONE); + sPart.setParticleChildren((SchemaParticle[]) + accumulate.toArray(new SchemaParticle[accumulate.size()])); + + return filterPointlessParticlesAndVerifyAllParticles(sPart, parseTree); + } + + static BigInteger extractMinOccurs(XmlNonNegativeInteger nni) + { + if (nni == null) + return BigInteger.ONE; + BigInteger result = nni.getBigIntegerValue(); + if (result == null) + return BigInteger.ONE; + return result; + } + + static BigInteger extractMaxOccurs(AllNNI allNNI) + { + if (allNNI == null) + return BigInteger.ONE; + + if (allNNI.instanceType().getPrimitiveType().getBuiltinTypeCode() == SchemaType.BTC_DECIMAL) + return ((XmlInteger)allNNI).getBigIntegerValue(); + else + return null; + } + + private static class RedefinitionForGroup + { + private SchemaModelGroupImpl group; + private boolean seenRedefinition = false; + + public RedefinitionForGroup(SchemaModelGroupImpl group) + { + this.group = group; + } + + public SchemaModelGroupImpl getGroup() + { + return group; + } + + public boolean isSeenRedefinition() + { + return seenRedefinition; + } + + public void setSeenRedefinition(boolean seenRedefinition) + { + this.seenRedefinition = seenRedefinition; + } + } + + static SchemaParticle translateContentModel( + SchemaType outerType, + XmlObject parseTree, String targetNamespace, boolean chameleon, + String elemFormDefault, String attFormDefault, + int particleCode, List anonymousTypes, Map elementModel, + boolean allowElt, RedefinitionForGroup redefinitionFor) + { + if (parseTree == null || particleCode == 0) + return null; + + StscState state = StscState.get(); + + // emitDBG("Translating content model for " + outerType); + // indentDBG(); + assert(particleCode != 0); + + boolean hasChildren = false; + BigInteger minOccurs; + BigInteger maxOccurs; + SchemaModelGroupImpl group = null; + + SchemaParticleImpl sPart; + + if (particleCode == SchemaParticle.ELEMENT) + { + if (!allowElt) + state.error("Must be a sequence, choice or all here", XmlErrorCodes.EXPLICIT_GROUP_NEEDED, parseTree); + + // TODO: detect substitution group for this element and construct a choice + + LocalElement parseElt = (LocalElement)parseTree; + sPart = StscTranslator.translateElement(parseElt, targetNamespace, chameleon, + elemFormDefault, attFormDefault, anonymousTypes, outerType); + if (sPart == null) + return null; + minOccurs = extractMinOccurs(parseElt.xgetMinOccurs()); + maxOccurs = extractMaxOccurs(parseElt.xgetMaxOccurs()); + + SchemaType oldType = (SchemaType)elementModel.get(sPart.getName()); + if (oldType == null) + { + elementModel.put(sPart.getName(), sPart.getType()); + } + else if (!sPart.getType().equals(oldType)) + { + state.error(XmlErrorCodes.ELEM_CONSISTANT, new Object[] { QNameHelper.pretty(sPart.getName()) }, parseTree); + return null; + } + } + else if (particleCode == SchemaParticle.WILDCARD) + { + if (!allowElt) + state.error("Must be a sequence, choice or all here", XmlErrorCodes.EXPLICIT_GROUP_NEEDED, parseTree); + Any parseAny = (Any)parseTree; + sPart = new SchemaParticleImpl(); + sPart.setParticleType(SchemaParticle.WILDCARD); + QNameSet wcset; + NamespaceList nslist = parseAny.xgetNamespace(); + if (nslist == null) + wcset = QNameSet.ALL; + else + wcset = QNameSet.forWildcardNamespaceString(nslist.getStringValue(), targetNamespace); + sPart.setWildcardSet(wcset); + sPart.setWildcardProcess(translateWildcardProcess(parseAny.xgetProcessContents())); + minOccurs = extractMinOccurs(parseAny.xgetMinOccurs()); + maxOccurs = extractMaxOccurs(parseAny.xgetMaxOccurs()); + } + else + { + Group parseGroup = (Group)parseTree; + sPart = new SchemaParticleImpl(); + + // grab min/maxOccurs before dereferencign group ref + minOccurs = extractMinOccurs(parseGroup.xgetMinOccurs()); + maxOccurs = extractMaxOccurs(parseGroup.xgetMaxOccurs()); + + if (particleCode == MODEL_GROUP_CODE) + { + QName ref = parseGroup.getRef(); + if (ref == null) + { + // KHK: s4s + state.error("Group reference must have a ref attribute", XmlErrorCodes.GROUP_MISSING_REF, parseTree); + return null; + } + + if (redefinitionFor != null) + { + group = state.findRedefinedModelGroup(ref, chameleon ? targetNamespace : null, redefinitionFor.getGroup()); + if (group != null && group.getName().equals(redefinitionFor.getGroup().getName())) + { + if (redefinitionFor.isSeenRedefinition()) + state.error(XmlErrorCodes.SCHEMA_REDEFINE$GROUP_SELF_REF, + new Object[] { QNameHelper.pretty(group.getName()) }, parseTree); + if (!BigInteger.ONE.equals(maxOccurs) || !BigInteger.ONE.equals(minOccurs)) + state.error(XmlErrorCodes.SCHEMA_REDEFINE$GROUP_SELF_REF_MIN_MAX_1, + new Object[] { QNameHelper.pretty(group.getName()) }, parseTree); + redefinitionFor.setSeenRedefinition(true); + } + } + else + { + group = state.findModelGroup(ref, chameleon ? targetNamespace : null, targetNamespace); + } + if (group == null) + { + state.notFoundError(ref, SchemaType.MODEL_GROUP, ((Group)parseTree).xgetRef(), true); + return null; + } + if (state.isProcessing(group)) + { + state.error(XmlErrorCodes.MODEL_GROUP_PROPERTIES$CIRCULAR, + new Object[] { QNameHelper.pretty(group.getName()) }, group.getParseObject()); + return null; + } + + // no go to the child. + XmlCursor cur = group.getParseObject().newCursor(); + for (boolean more = cur.toFirstChild(); more; more = cur.toNextSibling()) + { + particleCode = translateParticleCode(cur.getName()); + if (particleCode != 0) + { + parseTree = parseGroup = (Group)cur.getObject(); + break; + } + } + if (particleCode == 0) + { + // KHK: s4s + state.error("Model group " + QNameHelper.pretty(group.getName()) + " is empty", XmlErrorCodes.EXPLICIT_GROUP_NEEDED, group.getParseObject()); + return null; + } + if (particleCode != SchemaParticle.ALL && particleCode != SchemaParticle.SEQUENCE && particleCode != SchemaParticle.CHOICE) + { + // KHK: s4s + state.error("Model group " + QNameHelper.pretty(group.getName()) + " is not a sequence, all, or choice", XmlErrorCodes.EXPLICIT_GROUP_NEEDED, group.getParseObject()); + } + + String newTargetNamespace = group.getTargetNamespace(); + if (newTargetNamespace != null) + targetNamespace = newTargetNamespace; + elemFormDefault = group.getElemFormDefault(); + attFormDefault = group.getAttFormDefault(); + chameleon = group.getChameleonNamespace() != null; + } + + switch (particleCode) + { + case SchemaParticle.ALL: + case SchemaParticle.SEQUENCE: + case SchemaParticle.CHOICE: + sPart.setParticleType(particleCode); + hasChildren = true; + break; + + default: + assert(false); + throw new IllegalStateException(); + } + } + + if (maxOccurs != null && minOccurs.compareTo(maxOccurs) > 0) + { + state.error(XmlErrorCodes.PARTICLE_PROPERTIES$MIN_LTE_MAX, null, parseTree); + maxOccurs = minOccurs; // remedy: pin max up to min + } + + if (maxOccurs != null && maxOccurs.compareTo(BigInteger.ONE) < 0) + { + state.warning(XmlErrorCodes.PARTICLE_PROPERTIES$MAX_GTE_1, null, parseTree); + + // remove from the list of anonymous types if it was added + anonymousTypes.remove(sPart.getType()); + return null; // maxOccurs == minOccurs == 0, same as no particle at all. + } + + sPart.setMinOccurs(minOccurs); + sPart.setMaxOccurs(maxOccurs); + + if (group != null) + { + state.startProcessing(group); + redefinitionFor = null; + if (group.isRedefinition()) + redefinitionFor = new RedefinitionForGroup(group); + } + + if (hasChildren) + { + XmlCursor cur = parseTree.newCursor(); + List accumulate = new ArrayList(); + for (boolean more = cur.toFirstChild(); more; more = cur.toNextSibling()) + { + int code = translateParticleCode(cur.getName()); + if (code == 0) + continue; + addMinusPointlessParticles(accumulate, + translateContentModel(outerType, + cur.getObject(), targetNamespace, chameleon, + elemFormDefault, attFormDefault, code, + anonymousTypes, elementModel, true, redefinitionFor), + sPart.getParticleType()); + } + sPart.setParticleChildren((SchemaParticle[]) + accumulate.toArray(new SchemaParticle[accumulate.size()])); + cur.dispose(); + } + + + SchemaParticle result = filterPointlessParticlesAndVerifyAllParticles(sPart, parseTree); + + if (group != null) + { + state.finishProcessing(group); + } + // outdentDBG(); + return result; + } + + static int translateWildcardProcess(Any.ProcessContents process) + { + if (process == null) + return SchemaParticle.STRICT; + + String processValue = process.getStringValue(); + + if ("lax".equals(processValue)) + return SchemaParticle.LAX; + + if ("skip".equals(processValue)) + return SchemaParticle.SKIP; + + return SchemaParticle.STRICT; + } + + static SchemaParticle filterPointlessParticlesAndVerifyAllParticles(SchemaParticle part, XmlObject parseTree) + { + if (part.getMaxOccurs() != null && part.getMaxOccurs().signum() == 0) + return null; + + switch (part.getParticleType()) + { + case SchemaParticle.SEQUENCE: + case SchemaParticle.ALL: + if (part.getParticleChildren().length == 0) + return null; + if (part.isSingleton() && part.countOfParticleChild() == 1) + return part.getParticleChild(0); + break; + + case SchemaParticle.CHOICE: + if (part.getParticleChildren().length == 0 && + part.getMinOccurs().compareTo(BigInteger.ZERO) == 0) + return null; + if (part.isSingleton() && part.countOfParticleChild() == 1) + return part.getParticleChild(0); + break; + + case SchemaParticle.ELEMENT: + case SchemaParticle.WILDCARD: + return part; + + default: + assert(false); + throw new IllegalStateException(); + } + + boolean isAll = part.getParticleType() == SchemaParticle.ALL; + + if (isAll) + { + // http://www.w3.org/TR/xmlschema-1/#cos-all-limited + if (part.getMaxOccurs() == null || part.getMaxOccurs().compareTo(BigInteger.ONE) > 0) + { + // An all group must have maxOccurs <= 1 + // KHK: review + StscState.get().error(XmlErrorCodes.ALL_GROUP_LIMITED$IN_MIN_MAX_1_PARTICLE, null, parseTree); + } + } + + for (int i = 0; i < part.countOfParticleChild(); i++) + { + SchemaParticle child = part.getParticleChild(i); + if (child.getParticleType() == SchemaParticle.ALL) + { + // An all group is only allowed at the top level of the content model + // KHK: review + StscState.get().error(XmlErrorCodes.ALL_GROUP_LIMITED$IN_COMPLEX_TYPE_DEF_PARTICLE, null, parseTree); + } + else if (isAll && (child.getParticleType() != SchemaParticle.ELEMENT || child.getMaxOccurs() == null || child.getMaxOccurs().compareTo(BigInteger.ONE) > 0)) + { + // An all group can contain only element particles with maxOccurs <= 1 + // KHK: review + StscState.get().error(XmlErrorCodes.ALL_GROUP_LIMITED$CHILD_PARTICLES_MAX_LTE_1, null, parseTree); + } + } + + return part; + } + + static void addMinusPointlessParticles( + List list, SchemaParticle part, int parentParticleType) + { + if (part == null) + return; + + switch (part.getParticleType()) + { + case SchemaParticle.SEQUENCE: + if (parentParticleType == SchemaParticle.SEQUENCE && part.isSingleton()) + { + // emitDBG("dropping redundant sequence"); + list.addAll(Arrays.asList(part.getParticleChildren())); + return; + } + break; + + case SchemaParticle.CHOICE: + if (parentParticleType == SchemaParticle.CHOICE && part.isSingleton()) + { + // emitDBG("dropping redundant choice"); + list.addAll(Arrays.asList(part.getParticleChildren())); + return; + } + break; + + case SchemaParticle.ALL: + default: + } + list.add(part); + } + + static Map buildAttributePropertyModelByQName(SchemaAttributeModel attrModel, SchemaType owner) + { + Map result = new LinkedHashMap(); + SchemaLocalAttribute[] attruses = attrModel.getAttributes(); + + for (int i = 0; i < attruses.length; i++) + result.put(attruses[i].getName(), buildUseProperty(attruses[i], owner)); + + return result; + } + + static Map buildContentPropertyModelByQName(SchemaParticle part, SchemaType owner) + { + if (part == null) + return Collections.EMPTY_MAP; + + boolean asSequence = false; + Map model = null; + + switch (part.getParticleType()) + { + case SchemaParticle.ALL: + case SchemaParticle.SEQUENCE: + asSequence = true; + break; + case SchemaParticle.CHOICE: + asSequence = false; + break; + case SchemaParticle.ELEMENT: + model = buildElementPropertyModel((SchemaLocalElement)part, owner); + break; + case SchemaParticle.WILDCARD: + model = Collections.EMPTY_MAP; + break; + default: + assert(false); + throw new IllegalStateException(); + } + + if (model == null) + { + // build model for children + model = new LinkedHashMap(); + SchemaParticle[] children = part.getParticleChildren(); + + for (int i = 0; i < children.length; i++) + { + // indentDBG(); + Map childModel = buildContentPropertyModelByQName(children[i], owner); + // outdentDBG(); + for (Iterator j = childModel.values().iterator(); j.hasNext(); ) + { + SchemaProperty iProp = (SchemaProperty)j.next(); + SchemaPropertyImpl oProp = (SchemaPropertyImpl)model.get(iProp.getName()); + if (oProp == null) + { + if (!asSequence) + ((SchemaPropertyImpl)iProp).setMinOccurs(BigInteger.ZERO); + model.put(iProp.getName(), iProp); + continue; + } + // consistency verified in an earlier step + assert(oProp.getType().equals(iProp.getType())); + + mergeProperties(oProp, iProp, asSequence); + } + } + + // finally deal with minOccurs, maxOccurs over whole group + BigInteger min = part.getMinOccurs(); + BigInteger max = part.getMaxOccurs(); + + for (Iterator j = model.values().iterator(); j.hasNext(); ) + { + SchemaProperty oProp = (SchemaProperty)j.next(); + BigInteger minOccurs = oProp.getMinOccurs(); + BigInteger maxOccurs = oProp.getMaxOccurs(); + + minOccurs = minOccurs.multiply(min); + if (max != null && max.equals(BigInteger.ZERO)) + maxOccurs = BigInteger.ZERO; + else if (maxOccurs != null && !maxOccurs.equals(BigInteger.ZERO)) + maxOccurs = max == null ? null : maxOccurs.multiply(max); + + ((SchemaPropertyImpl)oProp).setMinOccurs(minOccurs); + ((SchemaPropertyImpl)oProp).setMaxOccurs(maxOccurs); + } + } + + return model; + } + + static Map buildElementPropertyModel(SchemaLocalElement epart, SchemaType owner) + { + Map result = new HashMap(1); + + SchemaProperty sProp = buildUseProperty(epart, owner); + result.put(sProp.getName(), sProp); + return result; + } + + static SchemaProperty buildUseProperty(SchemaField use, SchemaType owner) + { + SchemaPropertyImpl sPropImpl = new SchemaPropertyImpl(); + sPropImpl.setName(use.getName()); + sPropImpl.setContainerTypeRef(owner.getRef()); + sPropImpl.setTypeRef(use.getType().getRef()); + sPropImpl.setAttribute(use.isAttribute()); + sPropImpl.setDefault(use.isDefault() ? SchemaProperty.CONSISTENTLY : SchemaProperty.NEVER); + sPropImpl.setFixed(use.isFixed() ? SchemaProperty.CONSISTENTLY : SchemaProperty.NEVER); + sPropImpl.setNillable(use.isNillable() ? SchemaProperty.CONSISTENTLY : SchemaProperty.NEVER); + sPropImpl.setDefaultText(use.getDefaultText()); + sPropImpl.setMinOccurs(use.getMinOccurs()); + sPropImpl.setMaxOccurs(use.getMaxOccurs()); + + if (use instanceof SchemaLocalElementImpl) + { + SchemaLocalElementImpl elt = (SchemaLocalElementImpl)use; + sPropImpl.setAcceptedNames(elt.acceptedStartNames()); + } + + return sPropImpl; + } + + static void mergeProperties(SchemaPropertyImpl into, SchemaProperty from, boolean asSequence) + { + // minoccur, maxoccur + BigInteger minOccurs = into.getMinOccurs(); + BigInteger maxOccurs = into.getMaxOccurs(); + if (asSequence) + { + minOccurs = minOccurs.add(from.getMinOccurs()); + if (maxOccurs != null) + maxOccurs = (from.getMaxOccurs() == null ? null : + maxOccurs.add(from.getMaxOccurs())); + } + else + { + minOccurs = minOccurs.min(from.getMinOccurs()); + if (maxOccurs != null) + maxOccurs = (from.getMaxOccurs() == null ? null : + maxOccurs.max(from.getMaxOccurs())); + } + into.setMinOccurs(minOccurs); + into.setMaxOccurs(maxOccurs); + + // nillable, default, fixed + if (from.hasNillable() != into.hasNillable()) + into.setNillable(SchemaProperty.VARIABLE); + if (from.hasDefault() != into.hasDefault()) + into.setDefault(SchemaProperty.VARIABLE); + if (from.hasFixed() != into.hasFixed()) + into.setFixed(SchemaProperty.VARIABLE); + + // default value + if (into.getDefaultText() != null) + { + if (from.getDefaultText() == null || + !into.getDefaultText().equals(from.getDefaultText())) + into.setDefaultText(null); + } + } + + static SchemaParticle[] ensureStateMachine(SchemaParticle[] children) + { + for (int i = 0; i < children.length; i++) + { + buildStateMachine(children[i]); + } + return children; + } + + static void buildStateMachine(SchemaParticle contentModel) + { + if (contentModel == null) + return; + + SchemaParticleImpl partImpl = (SchemaParticleImpl)contentModel; + if (partImpl.hasTransitionNotes()) + return; + + QNameSetBuilder start = new QNameSetBuilder(); + QNameSetBuilder excludenext = new QNameSetBuilder(); + boolean deterministic = true; + SchemaParticle[] children = null; + boolean canskip = (partImpl.getMinOccurs().signum() == 0); + + switch (partImpl.getParticleType()) + { + case SchemaParticle.ELEMENT: + // compute start and excludeNext; canskip is already correct + if (partImpl.hasTransitionRules()) + start.addAll(partImpl.acceptedStartNames()); + else + start.add(partImpl.getName()); + + break; + + case SchemaParticle.WILDCARD: + // compute start and excludeNext; canskip is already correct + start.addAll(partImpl.getWildcardSet()); + break; + + case SchemaParticle.SEQUENCE: + children = ensureStateMachine(partImpl.getParticleChildren()); + + // adjust canskip if all children are skippable + canskip = true; + for (int i = 0; canskip && i < children.length; i++) + { + if (!(children[i]).isSkippable()) + canskip = false; + } + + // bubble up nondeterministic bit + for (int i = 0; deterministic && i < children.length; i++) + { + if (!((SchemaParticleImpl)children[i]).isDeterministic()) + deterministic = false; + } + + // verify deterministic and compute excludeNext set + for (int i = 1; i < children.length; i++) + { + excludenext.addAll(((SchemaParticleImpl)children[i - 1]).getExcludeNextSet()); + if (deterministic && !excludenext.isDisjoint((children[i]).acceptedStartNames())) + deterministic = false; + if ((children[i]).isSkippable()) + excludenext.addAll((children[i]).acceptedStartNames()); + else + excludenext.clear(); + } + + // next, compute start set + for (int i = 0; i < children.length; i++) + { + start.addAll((children[i]).acceptedStartNames()); + if (!(children[i]).isSkippable()) + break; + } + break; + + case SchemaParticle.CHOICE: + children = ensureStateMachine(partImpl.getParticleChildren()); + + // adjust canskip if any children are skippable + canskip = false; + for (int i = 0; !canskip && i < children.length; i++) + { + if ((children[i]).isSkippable()) + canskip = true; + } + + // bubble up nondeterministic bit + for (int i = 0; deterministic && i < children.length; i++) + { + if (!((SchemaParticleImpl)children[i]).isDeterministic()) + deterministic = false; + } + + // compute start and excludeNext sets, verify deterministic + for (int i = 0; i < children.length; i++) + { + if (deterministic && !start.isDisjoint((children[i]).acceptedStartNames())) + deterministic = false; + start.addAll((children[i]).acceptedStartNames()); + excludenext.addAll(((SchemaParticleImpl)children[i]).getExcludeNextSet()); + } + + break; + + case SchemaParticle.ALL: + children = ensureStateMachine(partImpl.getParticleChildren()); + + // adjust canskip if all children are skippable + canskip = true; + for (int i = 0; !canskip && i < children.length; i++) + { + if (!(children[i]).isSkippable()) + canskip = false; + } + + // bubble up nondeterministic bit + for (int i = 0; deterministic && i < children.length; i++) + { + if (!((SchemaParticleImpl)children[i]).isDeterministic()) + deterministic = false; + } + + // compute start and excludeNext sets, verify deterministic + for (int i = 0; i < children.length; i++) + { + if (deterministic && !start.isDisjoint((children[i]).acceptedStartNames())) + deterministic = false; + start.addAll((children[i]).acceptedStartNames()); + excludenext.addAll(((SchemaParticleImpl)children[i]).getExcludeNextSet()); + } + if (canskip) + excludenext.addAll(start); + + break; + + default: + throw new IllegalStateException("Unrecognized schema particle"); + } + + // apply looping logic + + BigInteger minOccurs = partImpl.getMinOccurs(); + BigInteger maxOccurs = partImpl.getMaxOccurs(); + boolean canloop = (maxOccurs == null || maxOccurs.compareTo(BigInteger.ONE) > 0); + boolean varloop = (maxOccurs == null || minOccurs.compareTo(maxOccurs) < 0); + + if (canloop && deterministic && !excludenext.isDisjoint(start)) + { + // we have a possible looping nondeterminism. + // let's take some time now to see if it's actually caused + // by non-unique-particle-attribute or not. + QNameSet suspectSet = excludenext.intersect(start); + + // compute the set of all particles that could start this group + Map startMap = new HashMap(); + particlesMatchingStart(partImpl, suspectSet, startMap, new QNameSetBuilder()); + + // compute the set of all particles that could have been repeated rather than ending this group + Map afterMap = new HashMap(); + particlesMatchingAfter(partImpl, suspectSet, afterMap, new QNameSetBuilder(), true); + + // see if we can find a member of after that is not a member of start + // if we can, then particle attribution is not unique + deterministic = afterMapSubsumedByStartMap(startMap, afterMap); + } + + if (varloop) + excludenext.addAll(start); + + canskip = canskip || minOccurs.signum() == 0; + + partImpl.setTransitionRules(start.toQNameSet(), canskip); + partImpl.setTransitionNotes(excludenext.toQNameSet(), deterministic); + } + + private static boolean afterMapSubsumedByStartMap(Map startMap, Map afterMap) + { + if (afterMap.size() > startMap.size()) + return false; + + if (afterMap.isEmpty()) + return true; + + for (Iterator i = startMap.keySet().iterator(); i.hasNext(); ) + { + SchemaParticle part = (SchemaParticle)i.next(); + if (part.getParticleType() == SchemaParticle.WILDCARD) + { + if (afterMap.containsKey(part)) + { + QNameSet startSet = (QNameSet)startMap.get(part); + QNameSet afterSet = (QNameSet)afterMap.get(part); + if (!startSet.containsAll(afterSet)) + return false; + } + } + afterMap.remove(part); + if (afterMap.isEmpty()) + return true; + } + return (afterMap.isEmpty()); + } + + private static void particlesMatchingStart(SchemaParticle part, QNameSetSpecification suspectSet, Map result, QNameSetBuilder eliminate) + { + switch (part.getParticleType()) + { + case SchemaParticle.ELEMENT: + if (!suspectSet.contains(part.getName())) + return; + result.put(part, null); + eliminate.add(part.getName()); + return; + + case SchemaParticle.WILDCARD: + if (suspectSet.isDisjoint(part.getWildcardSet())) + return; + result.put(part, part.getWildcardSet().intersect(suspectSet)); + eliminate.addAll(part.getWildcardSet()); + return; + + case SchemaParticle.CHOICE: + case SchemaParticle.ALL: + { + SchemaParticle[] children = part.getParticleChildren(); + for (int i = 0; i < children.length; i++) + particlesMatchingStart(children[i], suspectSet, result, eliminate); + return; + } + + case SchemaParticle.SEQUENCE: + { + SchemaParticle[] children = part.getParticleChildren(); + if (children.length == 0) + return; + if (!children[0].isSkippable()) + { + particlesMatchingStart(children[0], suspectSet, result, eliminate); + return; + } + QNameSetBuilder remainingSuspects = new QNameSetBuilder(suspectSet); + QNameSetBuilder suspectsToEliminate = new QNameSetBuilder(); + for (int i = 0; i < children.length; i++) + { + particlesMatchingStart(children[i], remainingSuspects, result, suspectsToEliminate); + eliminate.addAll(suspectsToEliminate); + if (!children[i].isSkippable()) + return; + remainingSuspects.removeAll(suspectsToEliminate); + if (remainingSuspects.isEmpty()) + return; + suspectsToEliminate.clear(); + } + return; + } + } + } + + private static void particlesMatchingAfter(SchemaParticle part, QNameSetSpecification suspectSet, Map result, QNameSetBuilder eliminate, boolean top) + { + recurse: switch (part.getParticleType()) + { + case SchemaParticle.CHOICE: + case SchemaParticle.ALL: + { + SchemaParticle[] children = part.getParticleChildren(); + for (int i = 0; i < children.length; i++) + particlesMatchingAfter(children[i], suspectSet, result, eliminate, false); + break recurse; + } + + case SchemaParticle.SEQUENCE: + { + SchemaParticle[] children = part.getParticleChildren(); + if (children.length == 0) + break recurse; + if (!children[children.length - 1].isSkippable()) + { + particlesMatchingAfter(children[0], suspectSet, result, eliminate, false); + break recurse; + } + QNameSetBuilder remainingSuspects = new QNameSetBuilder(suspectSet); + QNameSetBuilder suspectsToEliminate = new QNameSetBuilder(); + for (int i = children.length - 1; i >= 0; i--) + { + particlesMatchingAfter(children[i], remainingSuspects, result, suspectsToEliminate, false); + eliminate.addAll(suspectsToEliminate); + if (!children[i].isSkippable()) + break recurse; + remainingSuspects.removeAll(suspectsToEliminate); + if (remainingSuspects.isEmpty()) + break recurse; + suspectsToEliminate.clear(); + } + break recurse; + } + } + + if (!top) + { + BigInteger minOccurs = part.getMinOccurs(); + BigInteger maxOccurs = part.getMaxOccurs(); + boolean varloop = (maxOccurs == null || minOccurs.compareTo(maxOccurs) < 0); + if (varloop) + { + particlesMatchingStart(part, suspectSet, result, eliminate); + } + } + } + + private static class CodeForNameEntry + { + CodeForNameEntry(QName name, int code) + { this.name = name; this.code = code; } + public QName name; + public int code; + } + + private static final int MODEL_GROUP_CODE = 100; + + private static CodeForNameEntry[] particleCodes = new CodeForNameEntry[] + { + new CodeForNameEntry(QNameHelper.forLNS("all", "http://www.w3.org/2001/XMLSchema"), SchemaParticle.ALL), + new CodeForNameEntry(QNameHelper.forLNS("sequence", "http://www.w3.org/2001/XMLSchema"), SchemaParticle.SEQUENCE), + new CodeForNameEntry(QNameHelper.forLNS("choice", "http://www.w3.org/2001/XMLSchema"), SchemaParticle.CHOICE), + new CodeForNameEntry(QNameHelper.forLNS("element", "http://www.w3.org/2001/XMLSchema"), SchemaParticle.ELEMENT), + new CodeForNameEntry(QNameHelper.forLNS("any", "http://www.w3.org/2001/XMLSchema"), SchemaParticle.WILDCARD), + new CodeForNameEntry(QNameHelper.forLNS("group", "http://www.w3.org/2001/XMLSchema"), MODEL_GROUP_CODE), + }; + + private static Map particleCodeMap = buildParticleCodeMap(); + + private static Map buildParticleCodeMap() + { + Map result = new HashMap(); + for (int i = 0; i < particleCodes.length; i++) + result.put(particleCodes[i].name, new Integer(particleCodes[i].code)); + return result; + } + + private static int translateParticleCode(Group parseEg) + { + if (parseEg == null) + return 0; + return translateParticleCode(parseEg.newCursor().getName()); + } + + private static int translateParticleCode(QName name) + { + Integer result = (Integer)particleCodeMap.get(name); + if (result == null) + return 0; + return result.intValue(); + } + + private static final int ATTRIBUTE_CODE = 100; + private static final int ATTRIBUTE_GROUP_CODE = 101; + private static final int ANY_ATTRIBUTE_CODE = 102; + + private static CodeForNameEntry[] attributeCodes = new CodeForNameEntry[] + { + new CodeForNameEntry(QNameHelper.forLNS("attribute", "http://www.w3.org/2001/XMLSchema"), ATTRIBUTE_CODE), + new CodeForNameEntry(QNameHelper.forLNS("attributeGroup", "http://www.w3.org/2001/XMLSchema"), ATTRIBUTE_GROUP_CODE), + new CodeForNameEntry(QNameHelper.forLNS("anyAttribute", "http://www.w3.org/2001/XMLSchema"), ANY_ATTRIBUTE_CODE), + }; + + private static Map attributeCodeMap = buildAttributeCodeMap(); + + private static Map buildAttributeCodeMap() + { + Map result = new HashMap(); + for (int i = 0; i < attributeCodes.length; i++) + result.put(attributeCodes[i].name, new Integer(attributeCodes[i].code)); + return result; + } + + static int translateAttributeCode(QName currentName) + { + Integer result = (Integer)attributeCodeMap.get(currentName); + if (result == null) + return 0; + return result.intValue(); + } + + +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/StscImporter.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/StscImporter.java new file mode 100644 index 000000000..c47ba6794 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/StscImporter.java @@ -0,0 +1,1008 @@ +/* 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.impl.xb.xsdschema.RedefineDocument.Redefine; +import org.apache.xmlbeans.impl.xb.xsdschema.SchemaDocument.Schema; +import org.apache.xmlbeans.impl.xb.xsdschema.SchemaDocument; +import org.apache.xmlbeans.impl.xb.xsdschema.ImportDocument.Import; +import org.apache.xmlbeans.impl.xb.xsdschema.IncludeDocument.Include; + +import java.util.Map; +import java.util.List; +import java.util.LinkedList; +import java.util.Set; +import java.util.HashMap; +import java.util.HashSet; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.Arrays; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.net.MalformedURLException; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.Reader; +import java.io.InputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.CharArrayReader; +import java.io.Writer; +import java.io.CharArrayWriter; +import java.io.OutputStreamWriter; + +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.XmlException; +import org.apache.xmlbeans.XmlOptions; +import org.apache.xmlbeans.SchemaTypeLoader; +import org.apache.xmlbeans.XmlErrorCodes; +import org.apache.xmlbeans.impl.common.IOUtil; +import org.apache.xmlbeans.impl.common.XmlEncodingSniffer; +import org.xml.sax.EntityResolver; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +public class StscImporter +{ + public static SchemaToProcess[] resolveImportsAndIncludes(Schema[] startWith, boolean forceSrcSave) + { + DownloadTable engine = new DownloadTable(startWith); + return engine.resolveImportsAndIncludes(forceSrcSave); + } + + public static class SchemaToProcess + { + private Schema schema; + private String chameleonNamespace; + private List includes; // list of SchemaToProcess objects directly included by this + private List redefines; // list of SchemaToProcess objects directly redefined by this + private List redefineObjects; // list of Redefine objects associated to each redefinition + private Set indirectIncludes; // set of SchemaToProcess objects directly/indirectly included by this + private Set indirectIncludedBy; // set of SchemaToProcess objects that include this directly/indirectly + + public SchemaToProcess(Schema schema, String chameleonNamespace) + { + this.schema = schema; + this.chameleonNamespace = chameleonNamespace; + } + + /** + * The schema to parse. + */ + public Schema getSchema() + { + return schema; + } + + /** + * The base URI for this stp + */ + public String getSourceName() + { + return schema.documentProperties().getSourceName(); + } + + /** + * The chameleon namespace. Null if this schema is not being treated + * as a chameleon. (The ordinary targetNamespace will just be extracted + * from the syntax of the schema.) + */ + public String getChameleonNamespace() + { + return chameleonNamespace; + } + + /** + * This method and the remaining methods are used to represent a + * directed graph of includes/redefines. This is required in order + * to establish identity component by component, as required in + * xmlschema-1, chapter 4.2.2 + * @return + */ + public List getRedefines() + { + return redefines; + } + + public List getRedefineObjects() + { + return redefineObjects; + } + + private void addInclude(SchemaToProcess include) + { + if (includes == null) + includes = new ArrayList(); + includes.add(include); + } + + private void addRedefine(SchemaToProcess redefine, Redefine object) + { + if (redefines == null || redefineObjects == null) + { + redefines = new ArrayList(); + redefineObjects = new ArrayList(); + } + redefines.add(redefine); + redefineObjects.add(object); + } + + private void buildIndirectReferences() + { + if (includes != null) + for (int i = 0; i < includes.size(); i++) + { + SchemaToProcess schemaToProcess = (SchemaToProcess) includes.get(i); + /* We have a this-schemaToProcess vertex + * This means that all nodes accessible from schemaToProcess are + * also accessible from this and all nodes that have access to + * this also have access to schemaToProcess */ + this.addIndirectIncludes(schemaToProcess); + } + // Repeat the same algorithm for redefines, since redefines are also includes + if (redefines != null) + for (int i = 0; i < redefines.size(); i++) + { + SchemaToProcess schemaToProcess = (SchemaToProcess) redefines.get(i); + this.addIndirectIncludes(schemaToProcess); + } + } + + private void addIndirectIncludes(SchemaToProcess schemaToProcess) + { + if (indirectIncludes == null) + indirectIncludes = new HashSet(); + indirectIncludes.add(schemaToProcess); + if (schemaToProcess.indirectIncludedBy == null) + schemaToProcess.indirectIncludedBy = new HashSet(); + schemaToProcess.indirectIncludedBy.add(this); + addIndirectIncludesHelper(this, schemaToProcess); + if (indirectIncludedBy != null) + for (Iterator it = indirectIncludedBy.iterator(); it.hasNext();) + { + SchemaToProcess stp = (SchemaToProcess) it.next(); + stp.indirectIncludes.add(schemaToProcess); + schemaToProcess.indirectIncludedBy.add(stp); + addIndirectIncludesHelper(stp, schemaToProcess); + } + } + + private static void addIndirectIncludesHelper(SchemaToProcess including, + SchemaToProcess schemaToProcess) + { + if (schemaToProcess.indirectIncludes != null) + for (Iterator it = schemaToProcess.indirectIncludes.iterator(); it.hasNext();) + { + SchemaToProcess stp = (SchemaToProcess) it.next(); + including.indirectIncludes.add(stp); + stp.indirectIncludedBy.add(including); + } + } + + public boolean indirectIncludes(SchemaToProcess schemaToProcess) + { + return indirectIncludes != null && indirectIncludes.contains(schemaToProcess); + } + + public boolean equals(Object o) + { + if (this == o) return true; + if (!(o instanceof SchemaToProcess)) return false; + + final SchemaToProcess schemaToProcess = (SchemaToProcess) o; + + if (chameleonNamespace != null ? !chameleonNamespace.equals(schemaToProcess.chameleonNamespace) : schemaToProcess.chameleonNamespace != null) return false; + if (!(schema == schemaToProcess.schema)) return false; + + return true; + } + + public int hashCode() + { + int result; + result = schema.hashCode(); + result = 29 * result + (chameleonNamespace != null ? chameleonNamespace.hashCode() : 0); + return result; + } + } + + private final static String PROJECT_URL_PREFIX = "project://local"; + + private static String baseURLForDoc(XmlObject obj) + { + String path = obj.documentProperties().getSourceName(); + + if (path == null) + return null; + + if (path.startsWith("/")) + return PROJECT_URL_PREFIX + path.replace('\\', '/'); + + // looks like a URL? + int colon = path.indexOf(':'); + if (colon > 1 && path.substring(0, colon).matches("^\\w+$")) + return path; + + return PROJECT_URL_PREFIX + "/" + path.replace('\\', '/'); + } + + private static URI parseURI(String s) + { + if (s == null) + return null; + + try + { + return new URI(s); + } + catch (URISyntaxException syntax) + { + return null; + } + } + + //workaround for Sun bug # 4723726 + public static URI resolve(URI base, String child) + throws URISyntaxException + { + URI childUri = new URI(child); + URI ruri = base.resolve(childUri); + + // if the child fragment is relative (which we'll assume is the case + // if URI.resolve doesn't do anything useful with it) and the base + // URI is pointing at something nested inside a jar, we seem to have + // to this ourselves to make sure that the nested jar url gets + // resolved correctly + if (childUri.equals(ruri) && !childUri.isAbsolute() && + (base.getScheme().equals("jar") || base.getScheme().equals("zip"))) { + String r = base.toString(); + int lastslash = r.lastIndexOf('/'); + r = r.substring(0,lastslash) + "/" + childUri; + // Sun's implementation of URI doesn't support references to the + // parent directory ("/..") in the part after "!/" so we have to + // remove these ourselves + int exclPointSlashIndex = r.lastIndexOf("!/"); + if (exclPointSlashIndex > 0) + { + int slashDotDotIndex = r.indexOf("/..", exclPointSlashIndex); + while (slashDotDotIndex > 0) + { + int prevSlashIndex = r.lastIndexOf("/", slashDotDotIndex - 1); + if (prevSlashIndex >= exclPointSlashIndex) + { + String temp = r.substring(slashDotDotIndex + 3); + r = r.substring(0, prevSlashIndex).concat(temp); + } + slashDotDotIndex = r.indexOf("/..", exclPointSlashIndex); + } + } + return URI.create(r); + } + + //fix up normalization bug + if ("file".equals(ruri.getScheme()) && ! child.equals(ruri)) + { + if (base.getPath().startsWith("//") && !ruri.getPath().startsWith("//")) + { + String path = "///".concat(ruri.getPath()); + try + { + ruri = new URI("file", null, path, ruri.getQuery(), ruri.getFragment()); + } + catch(URISyntaxException uris) + {} + } + } + return ruri; + } + + public static class DownloadTable + { + /** + * Namespace/schemaLocation pair. + * + * Downloaded schemas are indexed by namespace, schemaLocation, and both. + * + * A perfect match is preferred, but a match-by-namespace is accepted. + * A match-by-schemaLocation is only accepted for includes (not imports). + */ + private static class NsLocPair + { + private String namespaceURI; + private String locationURL; + + public NsLocPair(String namespaceURI, String locationURL) + { + this.namespaceURI = namespaceURI; + this.locationURL = locationURL; + } + + /** + * Empty string for no-namespace, null for namespace-not-part-of-key + */ + public String getNamespaceURI() + { + return namespaceURI; + } + + public String getLocationURL() + { + return locationURL; + } + + public boolean equals(Object o) + { + if (this == o) return true; + if (!(o instanceof NsLocPair)) return false; + + final NsLocPair nsLocPair = (NsLocPair) o; + + if (locationURL != null ? !locationURL.equals(nsLocPair.locationURL) : nsLocPair.locationURL != null) return false; + if (namespaceURI != null ? !namespaceURI.equals(nsLocPair.namespaceURI) : nsLocPair.namespaceURI != null) return false; + + return true; + } + + public int hashCode() + { + int result; + result = (namespaceURI != null ? namespaceURI.hashCode() : 0); + result = 29 * result + (locationURL != null ? locationURL.hashCode() : 0); + return result; + } + } + + private static class DigestKey + { + byte[] _digest; + int _hashCode; + DigestKey(byte[] digest) + { + _digest = digest; + for (int i = 0; i < 4 && i < digest.length; i++) + { + _hashCode = _hashCode << 8; + _hashCode = _hashCode + digest[i]; + } + } + + public boolean equals(Object o) + { + if (this == o) return true; + if (!(o instanceof DigestKey)) return false; + return Arrays.equals(_digest, ((DigestKey)o)._digest); + } + + public int hashCode() + { + return _hashCode; + } + } + + private Map schemaByNsLocPair = new HashMap(); + private Map schemaByDigestKey = new HashMap(); + private LinkedList scanNeeded = new LinkedList(); + private Set emptyNamespaceSchemas = new HashSet(); + private Map scannedAlready = new HashMap(); + private Set failedDownloads = new HashSet(); + + private Schema downloadSchema(XmlObject referencedBy, String targetNamespace, String locationURL) + { + // no location URL provided? Then nothing to do. + if (locationURL == null) + return null; + + StscState state = StscState.get(); + + // First resolve relative URLs with respect to base URL for doc + URI baseURI = parseURI(baseURLForDoc(referencedBy)); + String absoluteURL = null; + try + { + absoluteURL = baseURI == null ? locationURL : resolve(baseURI, locationURL).toString(); + } + catch (URISyntaxException e) + { + state.error("Could not find resource - invalid location URL: " + e.getMessage(), XmlErrorCodes.CANNOT_FIND_RESOURCE, referencedBy); + return null; + } + + // probe 0: this url is already processed, from a previous compile + if (state.isFileProcessed(absoluteURL)) + return null; + + // probe 1: ns+url - perfect match + if (absoluteURL != null && targetNamespace != null) + { + Schema result = (Schema)schemaByNsLocPair.get(new NsLocPair(targetNamespace, absoluteURL)); + if (result != null) + return result; + } + + // probe 2: we have preexisting knowledge of this namespace, + // either from another schema file or from the linker. + // If we're not downloading the given URL, skip it silently if the + // namespace is already represented by a file we have. + // Also, suppress downloads of URLs to namespaces that are already + // known by the linker. + // (We never assume preexisting knowledge of the no-namespace, + // even if we have some definitions, since it's likely that + // more than one person is playing in the no-namespace at once.) + if (targetNamespace != null && !targetNamespace.equals("")) + { + // the URL is not one to download; should we assume we know about the namespace? + if (!state.shouldDownloadURI(absoluteURL)) + { + // If we already have a schema representing this namespace, + // then skip this URL silently without producing an error. + Schema result = (Schema)schemaByNsLocPair.get(new NsLocPair(targetNamespace, null)); + if (result != null) + return result; + } + + // If the linker already knows about this namespace, skip + // this URL. + if (state.linkerDefinesNamespace(targetNamespace)) + return null; + } + + // probe 3: url only + if (absoluteURL != null) + { + Schema result = (Schema)schemaByNsLocPair.get(new NsLocPair(null, absoluteURL)); + if (result != null) + return result; + } + + // no match: error if we can't or won't download. + if (absoluteURL == null) + { + state.error("Could not find resource - no valid location URL.", XmlErrorCodes.CANNOT_FIND_RESOURCE, referencedBy); + return null; + } + + if (previouslyFailedToDownload(absoluteURL)) + { + // an error message has already been produced. + return null; + } + + if (!state.shouldDownloadURI(absoluteURL)) + { + state.error("Could not load resource \"" + absoluteURL + "\" (network downloads disabled).", XmlErrorCodes.CANNOT_FIND_RESOURCE, referencedBy); + addFailedDownload(absoluteURL); + return null; + } + + // try to download + download: try + { + XmlObject xdoc = downloadDocument(state.getS4SLoader(), targetNamespace, absoluteURL); + + Schema result = findMatchByDigest(xdoc); + String shortname = state.relativize(absoluteURL); + if (result != null) + { + // if an exactly-the-same document has already been loaded, use the original and spew + String dupname = state.relativize(result.documentProperties().getSourceName()); + if (dupname != null) + state.info(shortname + " is the same as " + dupname + " (ignoring the duplicate file)"); + else + state.info(shortname + " is the same as another schema"); + } + else + { + // otherwise, it's a new document: validate it and grab the contents + XmlOptions voptions = new XmlOptions(); + voptions.setErrorListener(state.getErrorListener()); + if (!(xdoc instanceof SchemaDocument) || !xdoc.validate(voptions)) + { + state.error("Referenced document is not a valid schema", XmlErrorCodes.CANNOT_FIND_RESOURCE, referencedBy); + break download; + } + + SchemaDocument sDoc = (SchemaDocument)xdoc; + + result = sDoc.getSchema(); + state.info("Loading referenced file " + shortname); + } + NsLocPair key = new NsLocPair(emptyStringIfNull(result.getTargetNamespace()), absoluteURL); + addSuccessfulDownload(key, result); + return result; + } + catch (MalformedURLException malformed) + { + state.error("URL \"" + absoluteURL + "\" is not well-formed", XmlErrorCodes.CANNOT_FIND_RESOURCE, referencedBy); + } + catch (IOException connectionProblem) + { + state.error(connectionProblem.toString(), XmlErrorCodes.CANNOT_FIND_RESOURCE, referencedBy); + } + catch (XmlException e) + { + state.error("Problem parsing referenced XML resource - " + e.getMessage(), XmlErrorCodes.CANNOT_FIND_RESOURCE, referencedBy); + } + + // record failure so that we don't try to download this URL again + addFailedDownload(absoluteURL); + return null; + } + + static XmlObject downloadDocument(SchemaTypeLoader loader, String namespace, String absoluteURL) + throws MalformedURLException, IOException, XmlException + { + StscState state = StscState.get(); + + EntityResolver resolver = state.getEntityResolver(); + if (resolver != null) + { + InputSource source = null; + try + { + source = resolver.resolveEntity(namespace, absoluteURL); + } + catch (SAXException e) + { + throw new XmlException(e); + } + + if (source != null) + { + state.addSourceUri(absoluteURL, null); + + // first preference for InputSource contract: character stream + Reader reader = source.getCharacterStream(); + if (reader != null) + { + reader = copySchemaSource(absoluteURL, reader, state); + XmlOptions options = new XmlOptions(); + options.setLoadLineNumbers(); + options.setDocumentSourceName(absoluteURL); + return loader.parse(reader, null, options); + } + + // second preference for InputSource contract: + InputStream bytes = source.getByteStream(); + if (bytes != null) + { + bytes = copySchemaSource(absoluteURL, bytes, state); + String encoding = source.getEncoding(); + XmlOptions options = new XmlOptions(); + options.setLoadLineNumbers(); + options.setLoadMessageDigest(); + options.setDocumentSourceName(absoluteURL); + if (encoding != null) + options.setCharacterEncoding(encoding); + return loader.parse(bytes, null, options); + } + + // third preference: use the (possibly redirected) url + String urlToLoad = source.getSystemId(); + if (urlToLoad == null) + throw new IOException("EntityResolver unable to resolve " + absoluteURL + " (for namespace " + namespace + ")"); + + copySchemaSource(absoluteURL, state, false); + XmlOptions options = new XmlOptions(); + options.setLoadLineNumbers(); + options.setLoadMessageDigest(); + options.setDocumentSourceName(absoluteURL); + URL urlDownload = new URL(urlToLoad); + return loader.parse(urlDownload, null, options); + } + } + + // no resolver - just use the URL directly, no substitution + state.addSourceUri(absoluteURL, null); + copySchemaSource(absoluteURL, state, false); + + XmlOptions options = new XmlOptions(); + options.setLoadLineNumbers(); + options.setLoadMessageDigest(); + URL urlDownload = new URL(absoluteURL); + + return loader.parse(urlDownload, null, options); + } + + private void addSuccessfulDownload(NsLocPair key, Schema schema) + { + byte[] digest = schema.documentProperties().getMessageDigest(); + if (digest == null) + { + StscState.get().addSchemaDigest(null); + } + else + { + DigestKey dk = new DigestKey(digest); + if (!schemaByDigestKey.containsKey(dk)) + { + schemaByDigestKey.put(new DigestKey(digest), schema); + StscState.get().addSchemaDigest(digest); + } + } + + schemaByNsLocPair.put(key, schema); + NsLocPair key1 = new NsLocPair(key.getNamespaceURI(), null); + if (!schemaByNsLocPair.containsKey(key1)) + schemaByNsLocPair.put(key1, schema); + NsLocPair key2 = new NsLocPair(null, key.getLocationURL()); + if (!schemaByNsLocPair.containsKey(key2)) + schemaByNsLocPair.put(key2, schema); + } + + private Schema findMatchByDigest(XmlObject original) + { + byte[] digest = original.documentProperties().getMessageDigest(); + if (digest == null) + return null; + return (Schema)schemaByDigestKey.get(new DigestKey(digest)); + } + + private void addFailedDownload(String locationURL) + { + failedDownloads.add(locationURL); + } + + private boolean previouslyFailedToDownload(String locationURL) + { + return failedDownloads.contains(locationURL); + } + + private static boolean nullableStringsMatch(String s1, String s2) + { + if (s1 == null && s2 == null) + return true; + if (s1 == null || s2 == null) + return false; + return (s1.equals(s2)); + } + + private static String emptyStringIfNull(String s) + { + if (s == null) + return ""; + return s; + } + + private SchemaToProcess addScanNeeded(SchemaToProcess stp) + { + if (!scannedAlready.containsKey(stp)) + { + scannedAlready.put(stp, stp); + scanNeeded.add(stp); + return stp; + } + else + return (SchemaToProcess) scannedAlready.get(stp); + } + + private void addEmptyNamespaceSchema(Schema s) + { + emptyNamespaceSchemas.add(s); + } + + private void usedEmptyNamespaceSchema(Schema s) + { + emptyNamespaceSchemas.remove(s); + } + + private boolean fetchRemainingEmptyNamespaceSchemas() + { + if (emptyNamespaceSchemas.isEmpty()) + return false; + + for (Iterator i = emptyNamespaceSchemas.iterator(); i.hasNext();) + { + Schema schema = (Schema)i.next(); + addScanNeeded(new SchemaToProcess(schema, null)); + } + + emptyNamespaceSchemas.clear(); + return true; + } + + private boolean hasNextToScan() + { + return !scanNeeded.isEmpty(); + } + + private SchemaToProcess nextToScan() + { + SchemaToProcess next = (SchemaToProcess)scanNeeded.removeFirst(); + return next; + } + + public DownloadTable(Schema[] startWith) + { + for (int i = 0; i < startWith.length; i++) + { + String targetNamespace = startWith[i].getTargetNamespace(); + NsLocPair key = new NsLocPair(targetNamespace, baseURLForDoc(startWith[i])); + addSuccessfulDownload(key, startWith[i]); + if (targetNamespace != null) + addScanNeeded(new SchemaToProcess(startWith[i], null)); + else + addEmptyNamespaceSchema(startWith[i]); + } + } + + public SchemaToProcess[] resolveImportsAndIncludes(boolean forceSave) + { + StscState state = StscState.get(); + List result = new ArrayList(); + boolean hasRedefinitions = false; + + // algorithm is to scan through each schema document and + // 1. download each import and include (if not already downloaded) + // 2. queue each imported or included schema to be process (if not already queued) + + // The algorithm is run twice: first we begin with non-empty + // namespace schemas only. Then we repeat starting with any + // empty empty-namespace schemas that have NOT been chameleon- + // included by other schemas and process them. + + for (;;) + { + while (hasNextToScan()) + { + SchemaToProcess stp = nextToScan(); + String uri = stp.getSourceName(); + state.addSourceUri(uri, null); + result.add(stp); + copySchemaSource(uri, state, forceSave); + + { + // handle imports + Import[] imports = stp.getSchema().getImportArray(); + for (int i = 0; i < imports.length; i++) + { + Schema imported = downloadSchema(imports[i], emptyStringIfNull(imports[i].getNamespace()), imports[i].getSchemaLocation()); + + // if download fails, an error has already been reported. + if (imported == null) + continue; + + if (!nullableStringsMatch(imported.getTargetNamespace(), imports[i].getNamespace())) + { + StscState.get().error("Imported schema has a target namespace \"" + imported.getTargetNamespace() + "\" that does not match the specified \"" + imports[i].getNamespace() + "\"", XmlErrorCodes.MISMATCHED_TARGET_NAMESPACE, imports[i]); + } + else + { + addScanNeeded(new SchemaToProcess(imported, null)); + } + } + } + + { + // handle includes + Include[] includes = stp.getSchema().getIncludeArray(); + String sourceNamespace = stp.getChameleonNamespace(); + if (sourceNamespace == null) + sourceNamespace = emptyStringIfNull(stp.getSchema().getTargetNamespace()); + + for (int i = 0; i < includes.length; i++) + { + Schema included = downloadSchema(includes[i], null, includes[i].getSchemaLocation()); + // if download fails, an error has already been reported. + if (included == null) + continue; + + if (emptyStringIfNull(included.getTargetNamespace()).equals(sourceNamespace)) + { + // non-chameleon case - just like an import + SchemaToProcess s = addScanNeeded(new SchemaToProcess(included, null)); + stp.addInclude(s); + } + else if (included.getTargetNamespace() != null) + { + // illegal include: included schema in wrong namespace. + StscState.get().error("Included schema has a target namespace \"" + included.getTargetNamespace() + "\" that does not match the source namespace \"" + sourceNamespace + "\"", XmlErrorCodes.MISMATCHED_TARGET_NAMESPACE, includes[i]); + } + else + { + // chameleon include + SchemaToProcess s = addScanNeeded(new SchemaToProcess(included, sourceNamespace)); + stp.addInclude(s); + usedEmptyNamespaceSchema(included); + } + } + } + + { + // handle redefines + Redefine[] redefines = stp.getSchema().getRedefineArray(); + String sourceNamespace = stp.getChameleonNamespace(); + if (sourceNamespace == null) + sourceNamespace = emptyStringIfNull(stp.getSchema().getTargetNamespace()); + for (int i = 0; i < redefines.length; i++) + { + Schema redefined = downloadSchema(redefines[i], null, redefines[i].getSchemaLocation()); + // if download fails, an error has already been reported. + if (redefined == null) + continue; + + if (emptyStringIfNull(redefined.getTargetNamespace()).equals(sourceNamespace)) + { + // non-chameleon case + SchemaToProcess s = addScanNeeded(new SchemaToProcess(redefined, null)); + stp.addRedefine(s, redefines[i]); + hasRedefinitions = true; + } + else if (redefined.getTargetNamespace() != null) + { + // illegal include: included schema in wrong namespace. + StscState.get().error("Redefined schema has a target namespace \"" + redefined.getTargetNamespace() + "\" that does not match the source namespace \"" + sourceNamespace + "\"", XmlErrorCodes.MISMATCHED_TARGET_NAMESPACE, redefines[i]); + } + else + { + // chameleon redefine + SchemaToProcess s = addScanNeeded(new SchemaToProcess(redefined, sourceNamespace)); + stp.addRedefine(s, redefines[i]); + usedEmptyNamespaceSchema(redefined); + hasRedefinitions = true; + } + } + } + } + + if (!fetchRemainingEmptyNamespaceSchemas()) + break; + } + + // Build the lists of indirect references + // Make all the effort only if there are redefinitions + if (hasRedefinitions) + for (int i = 0; i < result.size(); i++) + { + SchemaToProcess schemaToProcess = (SchemaToProcess) result.get(i); + schemaToProcess.buildIndirectReferences(); + } + return (SchemaToProcess[])result.toArray(new SchemaToProcess[result.size()]); + } + + private static Reader copySchemaSource(String url, Reader reader, StscState state) + { + //Copy the schema file if it wasn't already copied + if (state.getSchemasDir() == null) + return reader; + + String schemalocation = state.sourceNameForUri(url); + File targetFile = new File(state.getSchemasDir(), schemalocation); + if (targetFile.exists()) + return reader; + + try + { + File parentDir = new File(targetFile.getParent()); + IOUtil.createDir(parentDir, null); + + CharArrayReader car = copy(reader); + XmlEncodingSniffer xes = new XmlEncodingSniffer(car, null); + Writer out = new OutputStreamWriter(new FileOutputStream(targetFile), xes.getXmlEncoding()); + IOUtil.copyCompletely(car, out); + + car.reset(); + return car; + } + catch (IOException e) + { + System.err.println("IO Error " + e); + return reader; + } + } + + private static InputStream copySchemaSource(String url, InputStream bytes, StscState state) + { + //Copy the schema file if it wasn't already copied + if (state.getSchemasDir() == null) + return bytes; + + String schemalocation = state.sourceNameForUri(url); + File targetFile = new File(state.getSchemasDir(), schemalocation); + if (targetFile.exists()) + return bytes; + + try + { + File parentDir = new File(targetFile.getParent()); + IOUtil.createDir(parentDir, null); + + ByteArrayInputStream bais = copy(bytes); + + FileOutputStream out = new FileOutputStream(targetFile); + IOUtil.copyCompletely(bais, out); + + bais.reset(); + return bais; + } + catch (IOException e) + { + System.err.println("IO Error " + e); + return bytes; + } + } + + private static void copySchemaSource(String urlLoc, StscState state, boolean forceCopy) + { + //Copy the schema file if it wasn't already copied + if (state.getSchemasDir()!=null) + { + String schemalocation = state.sourceNameForUri(urlLoc); + + File targetFile = new File(state.getSchemasDir(), schemalocation); + if (forceCopy || !targetFile.exists()) + { + try + { + File parentDir = new File(targetFile.getParent()); + IOUtil.createDir(parentDir, null); + + InputStream in = null; + URL url = new URL(urlLoc); + // Copy the file from filepath to schema[METADATA_PACKAGE_GEN]/src/ + try + { + in = url.openStream(); + } + catch (FileNotFoundException fnfe) + { + if (forceCopy && targetFile.exists()) + targetFile.delete(); + else + throw fnfe; + } + if (in != null) + { + FileOutputStream out = new FileOutputStream(targetFile); + IOUtil.copyCompletely(in, out); + } + } + catch (IOException e) + { + System.err.println("IO Error " + e); + // failure = true; - not cause for failure + } + } + } + } + + private static ByteArrayInputStream copy(InputStream is) throws IOException + { + byte [] buf = new byte[1024]; + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + int bytesRead; + while(( bytesRead = is.read(buf, 0, 1024)) > 0) + baos.write(buf, 0, bytesRead); + + return new ByteArrayInputStream(baos.toByteArray()); + } + + private static CharArrayReader copy(Reader is) throws IOException + { + char[] buf = new char[1024]; + CharArrayWriter baos = new CharArrayWriter(); + + int bytesRead; + while(( bytesRead = is.read(buf, 0, 1024)) > 0) + baos.write(buf, 0, bytesRead); + + return new CharArrayReader(baos.toCharArray()); + } + } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/StscJavaizer.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/StscJavaizer.java new file mode 100644 index 000000000..365f73e99 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/StscJavaizer.java @@ -0,0 +1,943 @@ +/* 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.impl.common.NameUtil; +import org.apache.xmlbeans.QNameSetBuilder; +import org.apache.xmlbeans.SchemaField; +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.SchemaParticle; +import org.apache.xmlbeans.SchemaProperty; +import org.apache.xmlbeans.QNameSet; +import org.apache.xmlbeans.UserType; +import org.apache.xmlbeans.XmlAnySimpleType; +import org.apache.xmlbeans.SchemaStringEnumEntry; +import org.apache.xmlbeans.XmlByte; +import org.apache.xmlbeans.XmlShort; +import org.apache.xmlbeans.InterfaceExtension; +import org.apache.xmlbeans.XmlError; +import org.apache.xmlbeans.PrePostExtension; +import org.apache.xmlbeans.BindingConfig; + +import java.util.*; +import java.math.BigInteger; + +import javax.xml.namespace.QName; + +public class StscJavaizer +{ + + /** + * XMLBEANS-307 + * if enumeration count is greater than 3668, + * xmlbeans scomp will fail with a code too large error + */ + private static final int MAX_ENUM_COUNT = 3668; + /** + * Does a topo walk of all the types to resolve them. + */ + public static void javaizeAllTypes(boolean javaize) + { + StscState state = StscState.get(); + + List allSeenTypes = new ArrayList(); + allSeenTypes.addAll(Arrays.asList(state.documentTypes())); + allSeenTypes.addAll(Arrays.asList(state.attributeTypes())); + allSeenTypes.addAll(Arrays.asList(state.globalTypes())); + + // First distribute the global names among the top entities. + if (javaize) + assignGlobalJavaNames(allSeenTypes); + + // now fully javaize everything deeply. + for (int i = 0; i < allSeenTypes.size(); i++) + { + SchemaType gType = (SchemaType)allSeenTypes.get(i); + if (javaize) + { + javaizeType((SchemaTypeImpl)gType); + String className = gType.getFullJavaName(); + if (className != null) + state.addClassname(className.replace('$', '.'), gType); + } + else + skipJavaizingType((SchemaTypeImpl)gType); + allSeenTypes.addAll(Arrays.asList(gType.getAnonymousTypes())); + // We need to javaize the anonymous types defined inside redefined types + // since redefined type do not get a Java class of their own. + // The exception is complex types derived by restriction, since in this case + // anonymous types are not inherited + addAnonymousTypesFromRedefinition(gType, allSeenTypes); + } + } + + static void assignGlobalJavaNames(Collection schemaTypes) + { + HashSet usedNames = new HashSet(); + StscState state = StscState.get(); + + for (Iterator i = schemaTypes.iterator(); i.hasNext(); ) + { + SchemaTypeImpl sImpl = (SchemaTypeImpl)i.next(); + QName topName = findTopName(sImpl); + String pickedName = state.getJavaname(topName, sImpl.isDocumentType() ? + BindingConfig.QNAME_DOCUMENT_TYPE : BindingConfig.QNAME_TYPE); + if (sImpl.isUnjavaized()) + { + sImpl.setFullJavaName(pickFullJavaClassName(usedNames, findTopName(sImpl), pickedName, sImpl.isDocumentType(), sImpl.isAttributeType())); + sImpl.setFullJavaImplName(pickFullJavaImplName(usedNames, sImpl.getFullJavaName())); + + setUserTypes(sImpl, state); + + setExtensions(sImpl, state); + } + } + + verifyInterfaceNameCollisions(usedNames, state); + } + + private static void verifyInterfaceNameCollisions(Set usedNames, StscState state) + { + BindingConfig config = state.getBindingConfig(); + if (config == null) + return; + + InterfaceExtension[] exts = config.getInterfaceExtensions(); + for (int i = 0; i < exts.length; i++) + { + if (usedNames.contains(exts[i].getInterface().toLowerCase())) + state.error("InterfaceExtension interface '" + exts[i].getInterface() + "' creates a name collision with one of the generated interfaces or classes.", XmlError.SEVERITY_ERROR, null); + + String handler = exts[i].getStaticHandler(); + if (handler != null && usedNames.contains(handler.toLowerCase())) + state.error("InterfaceExtension handler class '" + handler + "' creates a name collision with one of the generated interfaces or classes.", XmlError.SEVERITY_ERROR, null); + } + + PrePostExtension[] prepost = config.getPrePostExtensions(); + for (int i = 0; i < prepost.length; i++) + { + String handler = prepost[i].getStaticHandler(); + if (handler != null && usedNames.contains(handler.toLowerCase())) + state.error("PrePostExtension handler class '" + handler + "' creates a name collision with one of the generated interfaces or classes.", XmlError.SEVERITY_ERROR, null); + } + } + + private static void setUserTypes(SchemaTypeImpl sImpl, StscState state) + { + BindingConfig config = state.getBindingConfig(); + + if (config != null) + { + UserType utype = config.lookupUserTypeForQName(sImpl.getName()); + if (utype != null) + { + sImpl.setUserTypeName(utype.getJavaName()); + sImpl.setUserTypeHandlerName(utype.getStaticHandler()); + } + } + } + + private static void setExtensions(SchemaTypeImpl sImpl, StscState state) + { + String javaName = sImpl.getFullJavaName(); + BindingConfig config = state.getBindingConfig(); + + if (javaName != null && config != null) + { + sImpl.setInterfaceExtensions(config.getInterfaceExtensions(javaName)); + sImpl.setPrePostExtension(config.getPrePostExtension(javaName)); + } + } + + private static boolean isStringType(SchemaType type) + { + if (type == null || type.getSimpleVariety() != SchemaType.ATOMIC) + return false; + return (type.getPrimitiveType().getBuiltinTypeCode() == SchemaType.BTC_STRING); + } + + static String pickConstantName(Set usedNames, String words) + { + String base = NameUtil.upperCaseUnderbar(words); + + if (base.length() == 0) + { + base = "X"; + } + + if (base.startsWith("INT_")) // reserved for int codes + { + base = "X_" + base; + } + + String uniqName; + int index = 1; + for (uniqName = base; usedNames.contains(uniqName); ) + { + index++; + uniqName = base + "_" + index; + } + + usedNames.add(uniqName); + + return uniqName; + } + + static void skipJavaizingType(SchemaTypeImpl sImpl) + { + if (sImpl.isJavaized()) + return; + + SchemaTypeImpl baseType = (SchemaTypeImpl)sImpl.getBaseType(); + if (baseType != null) + skipJavaizingType(baseType); + + sImpl.startJavaizing(); + secondPassProcessType(sImpl); + sImpl.finishJavaizing(); + } + + static void secondPassProcessType(SchemaTypeImpl sImpl) + { + if (isStringType(sImpl)) + { + XmlAnySimpleType[] enumVals = sImpl.getEnumerationValues(); + + // if this is an enumerated string type, values are to be + // javaized as constants. + if (enumVals != null) + { + //ERROR is found at > 3668 + if (enumVals.length > MAX_ENUM_COUNT) + { + StscState.get().warning("SchemaType Enumeration found with too many enumeration values " + + "to create a Java enumeration. The base SchemaType \"" + + sImpl.getBaseEnumType() + "\" will be used instead", XmlError.SEVERITY_WARNING, null); + + sImpl = (SchemaTypeImpl) sImpl.getBaseEnumType(); + } + else + { + SchemaStringEnumEntry[] entryArray = new SchemaStringEnumEntry[enumVals.length]; + SchemaType basedOn = sImpl.getBaseEnumType(); + if (basedOn == sImpl) + { + Set usedNames = new HashSet(); + for (int i = 0; i < enumVals.length; i++) + { + String val = enumVals[i].getStringValue(); + + entryArray[i] = new SchemaStringEnumEntryImpl(val, i + 1, pickConstantName(usedNames, val)); + } + } + else + { + for (int i = 0; i < enumVals.length; i++) + { + String val = enumVals[i].getStringValue(); + entryArray[i] = basedOn.enumEntryForString(val); + } + } + sImpl.setStringEnumEntries(entryArray); + } + } + } + } + + static void javaizeType(SchemaTypeImpl sImpl) + { + if (sImpl.isJavaized()) + return; + + SchemaTypeImpl baseType = (SchemaTypeImpl)sImpl.getBaseType(); + if (baseType != null) + javaizeType(baseType); + if (sImpl.getContentBasedOnType() != null && sImpl.getContentBasedOnType() != baseType) + javaizeType((SchemaTypeImpl) sImpl.getContentBasedOnType()); + + sImpl.startJavaizing(); + + sImpl.setCompiled(true); + + secondPassProcessType(sImpl); + + if (!sImpl.isSimpleType()) + { + SchemaProperty[] eltProps = sImpl.getElementProperties(); + SchemaProperty[] attrProps = sImpl.getAttributeProperties(); + + // Handing out java names - this permits us to avoid collisions. + Set usedPropNames = new HashSet(); + + // First, copy all used property names from base, since these + // cannnot be changed at this point and they may be arbitrary + // because of derivation by restriction and the "nopvr" switch + SchemaProperty[] baseProps = baseType.getProperties(); + for (int i = 0; i < baseProps.length; i++) + { + String name = baseProps[i].getJavaPropertyName(); + assert !usedPropNames.contains(name); + usedPropNames.add(name); + } + + // count in the methods from extension interfaces + avoidExtensionMethods(usedPropNames, sImpl); + + // Assign names in two passes: first inherited names, then others. + for (boolean doInherited = true; ; doInherited = false) + { + if (eltProps.length > 0) + assignJavaPropertyNames(usedPropNames, eltProps, baseType, doInherited); + + assignJavaPropertyNames(usedPropNames, attrProps, baseType, doInherited); + + if (doInherited == false) + break; + } + + SchemaProperty[] allprops = sImpl.getProperties(); + + // determine whether order insensitive + boolean insensitive = isPropertyModelOrderInsensitive(allprops); + + // Fill in the java type codes now. + // This depends on recursive type information, so it's done in typechecking + assignJavaTypeCodes(allprops); + + sImpl.setOrderSensitive(!insensitive); + } + + // assign java type names to anonymous types + // for redefined types, this step was performed when javaizing the redefinition + if (sImpl.getFullJavaName() != null || sImpl.getOuterType() != null) + assignJavaAnonymousTypeNames(sImpl); + + sImpl.finishJavaizing(); + } + + private static final String[] PREFIXES = new String[]{"get", "xget", "isNil", "isSet", "sizeOf", "set", + "xset", "addNew", "setNil", "unset", "insert", "add", "insertNew", "addNew", "remove"}; + + private static void avoidExtensionMethods(Set usedPropNames, SchemaTypeImpl sImpl) + { + InterfaceExtension[] exts = sImpl.getInterfaceExtensions(); + if (exts != null) for (int i = 0; i < exts.length; i++) + { + InterfaceExtension ext = exts[i]; + InterfaceExtension.MethodSignature[] methods = ext.getMethods(); + for (int j = 0; j < methods.length; j++) + { + String methodName = methods[j].getName(); + for (int k = 0; k < PREFIXES.length; k++) + { + String prefix = PREFIXES[k]; + if (methodName.startsWith(prefix)) + usedPropNames.add(methodName.substring(prefix.length())); + } + } + } + } + + static void assignJavaAnonymousTypeNames(SchemaTypeImpl outerType) + { + Set usedTypeNames = new HashSet(); + SchemaType[] anonymousTypes = outerType.getAnonymousTypes(); + StscState state = StscState.get(); + + int nrOfAnonTypes = anonymousTypes.length; + if (outerType.isRedefinition()) + { + // We have to add the anonymous types for redefinitions to the list + // since they don't have another outer class + ArrayList list = new ArrayList(); + addAnonymousTypesFromRedefinition(outerType, list); + if (list.size() > 0) + { + SchemaType[] temp = new SchemaType[nrOfAnonTypes + list.size()]; + list.toArray(temp); + System.arraycopy(anonymousTypes, 0, temp, list.size(), nrOfAnonTypes); + anonymousTypes = temp; + } + } + + // Because we generate nested java interfaces, and nested + // interface names must not be the same as an ancestor, use up + // the ancestors + + for ( SchemaType scanOuterType = outerType ; + scanOuterType != null ; + scanOuterType = scanOuterType.getOuterType() ) + { + usedTypeNames.add( scanOuterType.getShortJavaName() ); + } + + for ( SchemaType scanOuterType = outerType ; + scanOuterType != null ; + scanOuterType = scanOuterType.getOuterType() ) + { + usedTypeNames.add( scanOuterType.getShortJavaImplName() ); + } + + // and because things are problematic if an inner type name + // is the same as a top-level package name, also get rid of that + // collision + usedTypeNames.add(getOutermostPackage(outerType.getFullJavaName())); + + // assign names + for (int i = 0; i < anonymousTypes.length; i++) + { + SchemaTypeImpl sImpl = (SchemaTypeImpl)anonymousTypes[i]; + if (sImpl == null) // already handled in first pass + continue; + if (sImpl.isSkippedAnonymousType()) + continue; + String localname = null; + String javaname = null; + + SchemaField containerField = sImpl.getContainerField(); + if (containerField != null) + { + QName qname = sImpl.getContainerField().getName(); + localname = qname.getLocalPart(); + javaname = state.getJavaname(sImpl.getContainerField().getName(), BindingConfig.QNAME_TYPE); + } + else + { + // not defined inside an Elt or Attr: must be a nested simple type + switch (sImpl.getOuterType().getSimpleVariety()) + { + case SchemaType.UNION: + javaname = "Member"; break; + case SchemaType.LIST: + javaname = "Item"; break; + case SchemaType.ATOMIC: + default: + assert(false) : "Weird type " + sImpl.toString(); + javaname = "Base"; break; + } + } + + if (i < nrOfAnonTypes) + { + sImpl.setShortJavaName( + pickInnerJavaClassName(usedTypeNames, localname, javaname)); + sImpl.setShortJavaImplName( + pickInnerJavaImplName(usedTypeNames, localname, javaname == null ? null : javaname + "Impl")); + } + else + { + // This comes from redefined types, so we have to compute the + // full name here + sImpl.setFullJavaName(outerType.getFullJavaName() + "$" + + pickInnerJavaClassName(usedTypeNames, localname, javaname)); + sImpl.setFullJavaImplName(outerType.getFullJavaImplName() + "$" + + pickInnerJavaImplName(usedTypeNames, localname, javaname == null ? null : javaname + "Impl")); + } + + // TODO(radup) why is this inside this loop here? + setExtensions(sImpl, state); + } + } + + static void assignJavaPropertyNames(Set usedNames, SchemaProperty[] props, SchemaType baseType, boolean doInherited) + { + StscState state = StscState.get(); + + // two passes: first deal with inherited properties, then with new ones. + // this ensures that we match up with base class definitions cleanly + // BUGBUG(radup) We have to look for particles that have been removed + // in the derivation tree for this type using derivation by restriction, + // because they have not been removed in Java and may collide with + // this type's properties. + + for (int i = 0; i < props.length; i++) + { + SchemaPropertyImpl sImpl = (SchemaPropertyImpl)props[i]; + + SchemaProperty baseProp = + (sImpl.isAttribute() ? + baseType.getAttributeProperty(sImpl.getName()) : + baseType.getElementProperty(sImpl.getName())); + + if ((baseProp != null) != doInherited) + continue; + + QName propQName = sImpl.getName(); + + String theName; + + if (baseProp == null) + theName = pickJavaPropertyName(usedNames, propQName.getLocalPart(), + state.getJavaname(propQName, sImpl.isAttribute() ? BindingConfig.QNAME_ACCESSOR_ATTRIBUTE : + BindingConfig.QNAME_ACCESSOR_ELEMENT)); + else + theName = baseProp.getJavaPropertyName(); + + sImpl.setJavaPropertyName(theName); + + boolean isArray = (sImpl.getMaxOccurs() == null || + sImpl.getMaxOccurs().compareTo(BigInteger.ONE) > 0); + boolean isSingleton = !isArray && (sImpl.getMaxOccurs().signum() > 0); + boolean isOption = isSingleton && (sImpl.getMinOccurs().signum() == 0); + SchemaType javaBasedOnType = sImpl.getType(); + + if (baseProp != null) + { + if (baseProp.extendsJavaArray()) + { + isSingleton = false; + isOption = false; + isArray = true; + } + if (baseProp.extendsJavaSingleton()) + { + isSingleton = true; + } + if (baseProp.extendsJavaOption()) + { + isOption = true; + } + javaBasedOnType = baseProp.javaBasedOnType(); + } + + sImpl.setExtendsJava(javaBasedOnType.getRef(), isSingleton, isOption, isArray); + } + + } + + static void assignJavaTypeCodes(SchemaProperty[] properties) + { + for (int i = 0; i < properties.length; i++) + { + SchemaPropertyImpl sImpl = (SchemaPropertyImpl)properties[i]; + SchemaType sType = sImpl.javaBasedOnType(); + sImpl.setJavaTypeCode(javaTypeCodeForType(sType)); + } + } + + static int javaTypeCodeInCommon(SchemaType[] types) + { + if (types == null || types.length == 0) + return SchemaProperty.XML_OBJECT; + + int code = javaTypeCodeForType(types[0]); + if (code == SchemaProperty.JAVA_OBJECT) + return code; + for (int i = 1; i < types.length; i++) + { + // if any two are different, the answer is java.lang.Object + if (code != javaTypeCodeForType(types[i])) + return SchemaProperty.JAVA_OBJECT; + } + return code; + } + + static int javaTypeCodeForType(SchemaType sType) + { + if (!sType.isSimpleType()) + return SchemaProperty.XML_OBJECT; + + if (((SchemaTypeImpl)sType).getUserTypeHandlerName() != null) + return SchemaProperty.JAVA_USER; + + if (sType.getSimpleVariety() == SchemaType.UNION) + { + // see if we can find an interesting common base type, e.g., for string enums + SchemaType baseType = sType.getUnionCommonBaseType(); + if (baseType != null && !baseType.isURType()) + sType = baseType; + else + return javaTypeCodeInCommon(sType.getUnionConstituentTypes()); + } + + if (sType.getSimpleVariety() == SchemaType.LIST) + return SchemaProperty.JAVA_LIST; + + if (sType.isURType()) + return SchemaProperty.XML_OBJECT; + + switch (sType.getPrimitiveType().getBuiltinTypeCode()) + { + case SchemaType.BTC_ANY_SIMPLE: + // return SchemaProperty.XML_OBJECT; + return SchemaProperty.JAVA_STRING; + + case SchemaType.BTC_BOOLEAN: + return SchemaProperty.JAVA_BOOLEAN; + + case SchemaType.BTC_BASE_64_BINARY: + return SchemaProperty.JAVA_BYTE_ARRAY; + + case SchemaType.BTC_HEX_BINARY: + return SchemaProperty.JAVA_BYTE_ARRAY; + + case SchemaType.BTC_ANY_URI: + return SchemaProperty.JAVA_STRING; + + case SchemaType.BTC_QNAME: + return SchemaProperty.JAVA_QNAME; + + case SchemaType.BTC_NOTATION: + return SchemaProperty.XML_OBJECT; + + case SchemaType.BTC_FLOAT: + return SchemaProperty.JAVA_FLOAT; + + case SchemaType.BTC_DOUBLE: + return SchemaProperty.JAVA_DOUBLE; + + case SchemaType.BTC_DECIMAL: + switch (sType.getDecimalSize()) + { + case SchemaType.SIZE_BYTE: + return SchemaProperty.JAVA_BYTE; + case SchemaType.SIZE_SHORT: + return SchemaProperty.JAVA_SHORT; + case SchemaType.SIZE_INT: + return SchemaProperty.JAVA_INT; + case SchemaType.SIZE_LONG: + return SchemaProperty.JAVA_LONG; + case SchemaType.SIZE_BIG_INTEGER: + return SchemaProperty.JAVA_BIG_INTEGER; + case SchemaType.SIZE_BIG_DECIMAL: + default: + return SchemaProperty.JAVA_BIG_DECIMAL; + } + + case SchemaType.BTC_STRING: + if (isStringType(sType.getBaseEnumType())) + { + // This is necessary for local types, etc. + // schema enums with > ~3668 cause a Java Src file to be created + // that cannot be compiled due to JVM restrictions + // FIXFIX: http://issues.apache.org/jira/browse/XMLBEANS-307 + // FIXFIX: XMLBeans scomp throws error "code too large" + if (sType.getEnumerationValues() != null && + sType.getEnumerationValues().length > MAX_ENUM_COUNT) + { + return SchemaProperty.JAVA_STRING; + } + else + { + return SchemaProperty.JAVA_ENUM; + } + } + return SchemaProperty.JAVA_STRING; + + case SchemaType.BTC_DURATION: + return SchemaProperty.JAVA_GDURATION; + + case SchemaType.BTC_DATE_TIME: + case SchemaType.BTC_DATE: + // return SchemaProperty.JAVA_DATE; // converted to calendar + + case SchemaType.BTC_TIME: + 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: + // return SchemaProperty.JAVA_GDATE; // converted to calendar (JAX-B) + return SchemaProperty.JAVA_CALENDAR; + + default: + assert(false) : "unrecognized code " + sType.getPrimitiveType().getBuiltinTypeCode(); + throw new IllegalStateException("unrecognized code " + sType.getPrimitiveType().getBuiltinTypeCode() + " of " + sType.getPrimitiveType().getName()); + } + } + + static boolean isPropertyModelOrderInsensitive(SchemaProperty[] properties) + { + for (int i = 0; i < properties.length; i++) + { + SchemaProperty prop = properties[i]; + if (prop.hasNillable() == SchemaProperty.VARIABLE) + return false; + if (prop.hasDefault() == SchemaProperty.VARIABLE) + return false; + if (prop.hasFixed() == SchemaProperty.VARIABLE) + return false; + if (prop.hasDefault() != SchemaProperty.NEVER && + prop.getDefaultText() == null) + return false; + } + return true; + } + + static boolean protectReservedGlobalClassNames(String name) + { + int i = name.lastIndexOf('.'); + String lastSegment = name.substring(i + 1); + if (lastSegment.endsWith("Document") && !lastSegment.equals("Document")) + return true; + return false; + } + + static boolean protectReservedInnerClassNames(String name) + { + return (name.equals("Enum") || name.equals("Factory")); + } + + static String[] PROTECTED_PROPERTIES = { + "StringValue", + "BooleanValue", + "ByteValue", + "ShortValue", + "IntValue", + "LongValue", + "BigIntegerValue", + "BigDecimalValue", + "FloatValue", + "DoubleValue", + "ByteArrayValue", + "EnumValue", + "CalendarValue", + "DateValue", + "GDateValue", + "GDurationValue", + "QNameValue", + "ListValue", + "ObjectValue", + "Class", + }; + static Set PROTECTED_PROPERTIES_SET = new HashSet(Arrays.asList(PROTECTED_PROPERTIES)); + + static boolean protectReservedPropertyNames(String name) + { + return PROTECTED_PROPERTIES_SET.contains(name) || + (name.endsWith("Array") && !name.equals("Array")); + } + + static String pickFullJavaClassName(Set usedNames, QName qName, String configname, boolean isDocument, boolean isAttrType) + { + String base; + boolean protect; + + if (configname != null && configname.indexOf('.') >= 0) + { + // a configname with dots defines the fully qualified java class name + base = configname; + protect = protectReservedGlobalClassNames(base); + } + else + { + StscState state = StscState.get(); + String uri = qName.getNamespaceURI(); + + base = NameUtil.getClassNameFromQName(qName); + + // Check to see if we have a mapping from namespace URI to Java package + // name. If so, apply the mapped package prefix at the beginning of + // the base name + + String pkgPrefix = state.getPackageOverride(uri); + + if (pkgPrefix != null) + { + // Form the new qualified class name from the new package name + // and the old class name + base = pkgPrefix + "." + base.substring(base.lastIndexOf('.') + 1); + } + + // See if there is a prefix... + String javaPrefix = state.getJavaPrefix(uri); + if (javaPrefix != null) + base = base.substring(0, base.lastIndexOf('.') + 1) + javaPrefix + base.substring(base.lastIndexOf('.') + 1); + + // a configname without dots may override the shortname part. + if (configname != null) + { + base = base.substring(0, base.lastIndexOf('.') + 1) + configname; + } + + protect = protectReservedGlobalClassNames(base); + if (configname == null) + { + // add special suffix + if (isDocument) + base = base + "Document"; + else if (isAttrType) + base = base + "Attribute"; + + // add configured suffix + String javaSuffix = state.getJavaSuffix(uri); + if (javaSuffix != null) + base = base + javaSuffix; + } + } + + String outermostPkg = getOutermostPackage(base); + + int index = 1; + String uniqName; + if (protect) + uniqName = base + index; + else + uniqName = base; + while (usedNames.contains(uniqName.toLowerCase()) || uniqName.equals(outermostPkg)) + { + index++; + uniqName = base + index; + } + + usedNames.add(uniqName.toLowerCase()); + + return uniqName; + } + + static String getOutermostPackage(String fqcn) + { + if (fqcn == null) + return ""; + + // remove class name + int lastdot = fqcn.indexOf('.'); + if (lastdot < 0) + return ""; + + // remove outer package names + return fqcn.substring(0, lastdot); + } + + static String pickFullJavaImplName(Set usedNames, String intfName) + { + // Strip off the package from the class name so we can replace it + String className = intfName; + String pkgName = null; + int index = intfName.lastIndexOf('.'); + if (index >= 0) + { + className = intfName.substring(index + 1); + pkgName = intfName.substring(0, index); + } + + // Form the new qualified class name from the new package name + // and the old class name + String base = pkgName + ".impl." + className + "Impl"; + + index = 1; + String uniqName = base; + while (usedNames.contains(uniqName.toLowerCase())) + { + index++; + uniqName = base + index; + } + + usedNames.add(uniqName.toLowerCase()); + + return uniqName; + } + + static String pickJavaPropertyName(Set usedNames, String localName, String javaName) + { + if (javaName == null) + javaName = NameUtil.upperCamelCase(localName); + boolean protect = protectReservedPropertyNames(javaName); + String uniqName; + int index = 1; + if (protect) + uniqName = javaName + index; + else + uniqName = javaName; + while (usedNames.contains(uniqName)) + { + index++; + uniqName = javaName + index; + } + + usedNames.add(uniqName); + + return uniqName; + } + + static String pickInnerJavaClassName(Set usedNames, String localName, String javaName) + { + if (javaName == null) + javaName = NameUtil.upperCamelCase(localName); + boolean protect = protectReservedInnerClassNames(javaName); + String uniqName; + int index = 1; + if (protect) + uniqName = javaName + index; + else + uniqName = javaName; + while (usedNames.contains(uniqName)) + { + index++; + uniqName = javaName + index; + } + + usedNames.add(uniqName); + + return uniqName; + } + + static String pickInnerJavaImplName(Set usedNames, String localName, String javaName) + { + if (javaName == null) + javaName = NameUtil.upperCamelCase(localName) + "Impl"; + String uniqName = javaName; + int index = 1; + while (usedNames.contains(uniqName)) + { + index++; + uniqName = javaName + index; + } + + usedNames.add(uniqName); + + return uniqName; + } + + static QName findTopName(SchemaType sType) + { + if (sType.getName() != null) + return sType.getName(); + + if (sType.isDocumentType()) + { + // A document type must have a content model consisting of a single elt + if (sType.getContentModel() == null || sType.getContentModel().getParticleType() != SchemaParticle.ELEMENT) + throw new IllegalStateException(); + return (sType.getDocumentElementName()); + } + + if (sType.isAttributeType()) + { + if (sType.getAttributeModel() == null || sType.getAttributeModel().getAttributes().length != 1) + throw new IllegalStateException(); + return sType.getAttributeTypeAttributeName(); + } + + SchemaField sElt = sType.getContainerField(); + assert(sElt != null); + assert(sType.getOuterType() == null); + return sElt.getName(); + } + + static void addAnonymousTypesFromRedefinition(SchemaType sType, List result) + { + while (((SchemaTypeImpl)sType).isRedefinition() && + (sType.getDerivationType() == SchemaType.DT_EXTENSION || + sType.isSimpleType())) + { + sType = sType.getBaseType(); + SchemaType[] newAnonTypes = sType.getAnonymousTypes(); + if (newAnonTypes.length > 0) + result.addAll(Arrays.asList(newAnonTypes)); + } + } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/StscResolver.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/StscResolver.java new file mode 100644 index 000000000..0c96d6670 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/StscResolver.java @@ -0,0 +1,303 @@ +/* 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.SchemaType; +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.SchemaParticle; +import org.apache.xmlbeans.QNameSet; +import org.apache.xmlbeans.XmlErrorCodes; + +import java.math.BigInteger; + +import java.util.*; + +import org.apache.xmlbeans.impl.xb.xsdschema.TopLevelElement; +import org.apache.xmlbeans.impl.xb.xsdschema.TopLevelAttribute; +import org.apache.xmlbeans.impl.xb.xsdschema.SimpleType; +import org.apache.xmlbeans.impl.xb.xsdschema.Attribute; +import org.apache.xmlbeans.impl.xb.xsdschema.Element; +import org.apache.xmlbeans.impl.xb.xsdschema.KeyrefDocument.Keyref; +import javax.xml.namespace.QName; + +public class StscResolver +{ + /** + * Does a topo walk of all the types to resolve them. + */ + public static void resolveAll() + { + // resolve tree of types + StscState state = StscState.get(); + + SchemaType[] documentTypes = state.documentTypes(); + for (int i = 0 ; i < documentTypes.length ; i++) + resolveSubstitutionGroup((SchemaTypeImpl)documentTypes[i]); + + List allSeenTypes = new ArrayList(); + allSeenTypes.addAll(Arrays.asList(state.documentTypes())); + allSeenTypes.addAll(Arrays.asList(state.attributeTypes())); + allSeenTypes.addAll(Arrays.asList(state.redefinedGlobalTypes())); + allSeenTypes.addAll(Arrays.asList(state.globalTypes())); + + for (int i = 0; i < allSeenTypes.size(); i++) + { + SchemaType gType = (SchemaType)allSeenTypes.get(i); + resolveType((SchemaTypeImpl)gType); + allSeenTypes.addAll(Arrays.asList(gType.getAnonymousTypes())); + } + + // Resolve all keyref refs + resolveIdentityConstraints(); + } + + public static boolean resolveType(SchemaTypeImpl sImpl) + { + if (sImpl.isResolved()) + return true; + if (sImpl.isResolving()) + { + StscState.get().error("Cyclic dependency error", XmlErrorCodes.CYCLIC_DEPENDENCY, sImpl.getParseObject()); + return false; // cyclic dependency error + } + // System.out.println("Resolving " + sImpl); + + sImpl.startResolving(); + + if (sImpl.isDocumentType()) + resolveDocumentType(sImpl); + else if (sImpl.isAttributeType()) + resolveAttributeType(sImpl); + else if (sImpl.isSimpleType()) + StscSimpleTypeResolver.resolveSimpleType(sImpl); + else + StscComplexTypeResolver.resolveComplexType(sImpl); + + sImpl.finishResolving(); + // System.out.println("Finished resolving " + sImpl); + return true; + } + + public static boolean resolveSubstitutionGroup(SchemaTypeImpl sImpl) + { + assert sImpl.isDocumentType(); + + if (sImpl.isSGResolved()) + return true; + if (sImpl.isSGResolving()) + { + StscState.get().error("Cyclic dependency error", XmlErrorCodes.CYCLIC_DEPENDENCY, sImpl.getParseObject()); + return false; // cyclic dependency error + } + + sImpl.startResolvingSGs(); + + // Resolve substitution group + + TopLevelElement elt = (TopLevelElement)sImpl.getParseObject(); + SchemaTypeImpl substitutionGroup = null; + QName eltName = new QName(sImpl.getTargetNamespace(), elt.getName()); + + // BUG: How do I tell if the type is in this compilation unit? + if (elt.isSetSubstitutionGroup()) + { + substitutionGroup = StscState.get().findDocumentType(elt.getSubstitutionGroup(), + sImpl.getChameleonNamespace(), sImpl.getTargetNamespace()); + + if (substitutionGroup == null) + StscState.get().notFoundError(elt.getSubstitutionGroup(), SchemaType.ELEMENT, elt.xgetSubstitutionGroup(), true); + // recovery - ignore substitution group + else if (! resolveSubstitutionGroup(substitutionGroup) ) + substitutionGroup = null; + else + sImpl.setSubstitutionGroup(elt.getSubstitutionGroup()); + } + + // Walk up the chain of subtitution groups adding this schematype to each head's + // member list + while (substitutionGroup != null) + { + + substitutionGroup.addSubstitutionGroupMember(eltName); + + if (substitutionGroup.getSubstitutionGroup() == null) + break; + + substitutionGroup = StscState.get().findDocumentType( + substitutionGroup.getSubstitutionGroup(), substitutionGroup.getChameleonNamespace(), null/*no dependency added*/); + + assert substitutionGroup != null : "Could not find document type for: " + substitutionGroup.getSubstitutionGroup(); + + if (! resolveSubstitutionGroup(substitutionGroup) ) + substitutionGroup = null; // cyclic dependency - no subst group + + } + + sImpl.finishResolvingSGs(); + return true; + + } + + public static void resolveDocumentType ( SchemaTypeImpl sImpl ) + { + assert sImpl.isResolving(); + + assert sImpl.isDocumentType(); + + + // translate the global element associated with this document type + // and construct a content model which allows just that element + + List anonTypes = new ArrayList(); + + SchemaGlobalElementImpl element = + (SchemaGlobalElementImpl) + StscTranslator.translateElement( + (Element) sImpl.getParseObject(), + sImpl.getTargetNamespace(), sImpl.isChameleon(), null, null, + anonTypes, sImpl ); + + SchemaLocalElementImpl contentModel = null; + + if (element != null) + { + StscState.get().addGlobalElement( element ); + + contentModel = new SchemaLocalElementImpl(); + + contentModel.setParticleType( SchemaParticle.ELEMENT ); + StscTranslator.copyGlobalElementToLocalElement( element, contentModel ); + contentModel.setMinOccurs( BigInteger.ONE ); + contentModel.setMaxOccurs( BigInteger.ONE ); + + contentModel.setTransitionNotes(QNameSet.EMPTY, true); + } + + Map elementPropertyModel = + StscComplexTypeResolver.buildContentPropertyModelByQName( + contentModel, sImpl ); + + SchemaTypeImpl baseType = sImpl.getSubstitutionGroup() == null ? + BuiltinSchemaTypeSystem.ST_ANY_TYPE : + StscState.get().findDocumentType(sImpl.getSubstitutionGroup(), + sImpl.isChameleon() ? sImpl.getTargetNamespace() : null, null/*already added*/) + ; + + sImpl.setBaseTypeRef( baseType.getRef() ); + sImpl.setBaseDepth( baseType.getBaseDepth() + 1 ); + sImpl.setDerivationType( SchemaType.DT_RESTRICTION ); + sImpl.setComplexTypeVariety( SchemaType.ELEMENT_CONTENT ); + + sImpl.setContentModel( + contentModel, new SchemaAttributeModelImpl(), + elementPropertyModel, Collections.EMPTY_MAP, false ); + + sImpl.setWildcardSummary( + QNameSet.EMPTY, false, QNameSet.EMPTY, false ); + + sImpl.setAnonymousTypeRefs( makeRefArray( anonTypes ) ); + + + + } + + public static void resolveAttributeType ( SchemaTypeImpl sImpl ) + { + assert sImpl.isResolving(); + + assert sImpl.isAttributeType(); + + List anonTypes = new ArrayList(); + + SchemaGlobalAttributeImpl attribute = + (SchemaGlobalAttributeImpl) StscTranslator.translateAttribute( + (Attribute) sImpl.getParseObject(), sImpl.getTargetNamespace(), null, + sImpl.isChameleon(), anonTypes, sImpl, null, false ); + + SchemaAttributeModelImpl attributeModel = new SchemaAttributeModelImpl(); + + if (attribute != null) + { + StscState.get().addGlobalAttribute( attribute ); + + SchemaLocalAttributeImpl attributeCopy = new SchemaLocalAttributeImpl(); + StscTranslator.copyGlobalAttributeToLocalAttribute( attribute, attributeCopy ); + attributeModel.addAttribute( attributeCopy ); + } + + sImpl.setBaseTypeRef( BuiltinSchemaTypeSystem.ST_ANY_TYPE.getRef() ); + sImpl.setBaseDepth( sImpl.getBaseDepth() + 1 ); + sImpl.setDerivationType( SchemaType.DT_RESTRICTION ); + sImpl.setComplexTypeVariety( SchemaType.EMPTY_CONTENT ); + + Map attributePropertyModel = + StscComplexTypeResolver.buildAttributePropertyModelByQName( + attributeModel, sImpl ); + + sImpl.setContentModel( + null, attributeModel, Collections.EMPTY_MAP, attributePropertyModel, false ); + + sImpl.setWildcardSummary( + QNameSet.EMPTY, false, QNameSet.EMPTY, false ); + + sImpl.setAnonymousTypeRefs( makeRefArray( anonTypes ) ); + } + + private static SchemaType.Ref[] makeRefArray(Collection typeList) + { + SchemaType.Ref[] result = new SchemaType.Ref[typeList.size()]; + int j = 0; + for (Iterator i = typeList.iterator(); i.hasNext(); j++) + result[j] = ((SchemaType)i.next()).getRef(); + return result; + } + + + public static void resolveIdentityConstraints() + { + StscState state = StscState.get(); + SchemaIdentityConstraintImpl[] idcs = state.idConstraints(); + + for (int i = 0 ; i < idcs.length ; i++) + { + if (!idcs[i].isResolved()) + { + Keyref xsdkr = (Keyref)idcs[i].getParseObject(); + QName keyName = xsdkr.getRefer(); + SchemaIdentityConstraintImpl key = null; + + key = state.findIdConstraint(keyName, idcs[i].getChameleonNamespace(), idcs[i].getTargetNamespace()); + if (key == null) + { + state.notFoundError(keyName, SchemaType.IDENTITY_CONSTRAINT, xsdkr, true); + } + else + { + if (key.getConstraintCategory() == SchemaIdentityConstraintImpl.CC_KEYREF) + state.error(XmlErrorCodes.IDENTITY_CONSTRAINT_PROPERTIES$KEYREF_REFERS_TO_KEYREF, + null, idcs[i].getParseObject()); + + if (key.getFields().length != idcs[i].getFields().length) + state.error(XmlErrorCodes.IDENTITY_CONSTRAINT_PROPERTIES$KEY_KEYREF_FIELD_COUNT_EQ, + null, idcs[i].getParseObject()); + + idcs[i].setReferencedKey(key.getRef()); + } + } + } + } + +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/StscSimpleTypeResolver.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/StscSimpleTypeResolver.java new file mode 100644 index 000000000..a3b51b8d5 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/StscSimpleTypeResolver.java @@ -0,0 +1,1247 @@ +/* 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 java.util.*; +import java.util.List; +import java.math.BigInteger; + +import javax.xml.namespace.QName; +import org.apache.xmlbeans.impl.values.XmlValueOutOfRangeException; +import org.apache.xmlbeans.impl.regex.RegularExpression; +import org.apache.xmlbeans.impl.regex.ParseException; +import org.apache.xmlbeans.impl.common.QNameHelper; +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.SimpleValue; +import org.apache.xmlbeans.XmlAnySimpleType; +import org.apache.xmlbeans.XmlByte; +import org.apache.xmlbeans.XmlCursor; +import org.apache.xmlbeans.XmlErrorCodes; +import org.apache.xmlbeans.XmlInteger; +import org.apache.xmlbeans.XmlNonNegativeInteger; +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.XmlPositiveInteger; +import org.apache.xmlbeans.XmlShort; +import org.apache.xmlbeans.XmlUnsignedByte; +import org.apache.xmlbeans.impl.xb.xsdschema.*; +import org.apache.xmlbeans.impl.xb.xsdschema.SchemaDocument.Schema; + +public class StscSimpleTypeResolver +{ + + /************************************************************************** + * SIMPLE TYPE RESOLUTION HERE + * + * Simple types can be declared as lists, unions, or restrictions. + * These three cases are treated separately in resolveListType, + * resolveUnionType, and resolveSimpleRestrictionType. + * + * The intricate work with facets is done in the restriction case, + * using method called resolveFacets (the union and list cases have + * trivial facet rules). Then all simple types call resolveProperties + * in the end to have their "fundamental facets" resolved. + */ + + public static void resolveSimpleType(SchemaTypeImpl sImpl) + { + SimpleType parseSt = (SimpleType)sImpl.getParseObject(); + + assert sImpl.isSimpleType(); + + Schema schema = StscComplexTypeResolver.getSchema(parseSt); + + // Verify: have list, union, or restriction, but not more than one + int count = + (parseSt.isSetList() ? 1 : 0) + + (parseSt.isSetUnion() ? 1 : 0) + + (parseSt.isSetRestriction() ? 1 : 0); + if (count > 1) + { + StscState.get().error( + "A simple type must define either a list, a union, or a restriction: more than one found.", + XmlErrorCodes.MALFORMED_SIMPLE_TYPE_DEFN, + parseSt); + // recovery: treat it as the first of list, union, restr + } + else if (count < 1) + { + StscState.get().error("A simple type must define either a list, a union, or a restriction: none was found.", + XmlErrorCodes.MALFORMED_SIMPLE_TYPE_DEFN, + parseSt); + // recovery: treat it as restriction of anySimpleType + resolveErrorSimpleType(sImpl); + return; + } + + // Set final flags + boolean finalRest = false; + boolean finalList = false; + boolean finalUnion = false; + + Object finalValue = null; + if (parseSt.isSetFinal()) + { + finalValue = parseSt.getFinal(); + } + // Inspect the finalDefault attribute on the schema + else if (schema != null && schema.isSetFinalDefault()) + { + finalValue = schema.getFinalDefault(); + } + + if (finalValue != null) + { + if (finalValue instanceof String) + { + if ("#all".equals((String)finalValue)) + { + finalRest = finalList = finalUnion = true; + } + } + else if (finalValue instanceof List) + { + List lFinalValue = (List) finalValue; + if (lFinalValue.contains("restriction")) + finalRest = true; + + if (lFinalValue.contains("list")) + finalList = true; + + if (lFinalValue.contains("union")) + finalUnion= true; + } + } + + sImpl.setSimpleFinal(finalRest, finalList, finalUnion); + + List anonTypes = new ArrayList(); + + if (parseSt.getList() != null) + resolveListType(sImpl, parseSt.getList(), anonTypes); + else if (parseSt.getUnion() != null) + resolveUnionType(sImpl, parseSt.getUnion(), anonTypes); + else if (parseSt.getRestriction() != null) + resolveSimpleRestrictionType(sImpl, parseSt.getRestriction(), anonTypes); + + sImpl.setAnonymousTypeRefs(makeRefArray(anonTypes)); + } + + private static SchemaType.Ref[] makeRefArray(Collection typeList) + { + SchemaType.Ref[] result = new SchemaType.Ref[typeList.size()]; + int j = 0; + for (Iterator i = typeList.iterator(); i.hasNext(); j++) + result[j] = ((SchemaType)i.next()).getRef(); + return result; + } + + static void resolveErrorSimpleType(SchemaTypeImpl sImpl) + { + sImpl.setSimpleTypeVariety(SchemaType.ATOMIC); + sImpl.setBaseTypeRef(BuiltinSchemaTypeSystem.ST_ANY_SIMPLE.getRef()); + sImpl.setBaseDepth(BuiltinSchemaTypeSystem.ST_ANY_SIMPLE.getBaseDepth() + 1); + sImpl.setPrimitiveTypeRef(BuiltinSchemaTypeSystem.ST_ANY_SIMPLE.getRef()); + } + + static void resolveListType(SchemaTypeImpl sImpl, org.apache.xmlbeans.impl.xb.xsdschema.ListDocument.List parseList, List anonTypes) + { + StscState state = StscState.get(); + + sImpl.setSimpleTypeVariety(SchemaType.LIST); + sImpl.setBaseTypeRef(BuiltinSchemaTypeSystem.ST_ANY_SIMPLE.getRef()); + sImpl.setBaseDepth(BuiltinSchemaTypeSystem.ST_ANY_SIMPLE.getBaseDepth() + 1); + sImpl.setDerivationType(SchemaType.DT_RESTRICTION); + + if (sImpl.isRedefinition()) + { + state.error(XmlErrorCodes.SCHEMA_REDEFINE$EXTEND_OR_RESTRICT, + new Object[] { "list" }, parseList); + // recovery: oh well. + } + + QName itemName = parseList.getItemType(); + LocalSimpleType parseInner = parseList.getSimpleType(); + + if (itemName != null && parseInner != null) + { + state.error(XmlErrorCodes.SCHEMA_SIMPLE_TYPE$LIST_HAS_BOTH_ITEM_OR_SIMPLE_TYPE, null, parseList); + // recovery: ignore the inner simple type. + parseInner = null; + } + + SchemaTypeImpl itemImpl; + XmlObject errorLoc; + + if (itemName != null) + { + itemImpl = state.findGlobalType(itemName, sImpl.getChameleonNamespace(), sImpl.getTargetNamespace()); + errorLoc = parseList.xgetItemType(); + if (itemImpl == null) + { + state.notFoundError(itemName, SchemaType.TYPE, parseList.xgetItemType(), true); + // recovery: treat it as a list of anySimpleType + itemImpl = BuiltinSchemaTypeSystem.ST_ANY_SIMPLE; + } + } + else if (parseInner != null) + { + itemImpl = StscTranslator.translateAnonymousSimpleType(parseInner, + sImpl.getTargetNamespace(), sImpl.getChameleonNamespace() != null, + sImpl.getElemFormDefault(), sImpl.getAttFormDefault(), anonTypes, sImpl); + errorLoc = parseInner; + } + else + { + state.error(XmlErrorCodes.SCHEMA_SIMPLE_TYPE$LIST_HAS_NEITHER_ITEM_OR_SIMPLE_TYPE, null, parseList); + // recovery: treat it as an extension of anySimpleType + resolveErrorSimpleType(sImpl); + return; + } + + // Verify final restrictions + if (itemImpl.finalList()) + state.error(XmlErrorCodes.SIMPLE_TYPE_PROPERTIES$LIST_FINAL, null, parseList); + + // Recursion... + StscResolver.resolveType(itemImpl); + + if (!itemImpl.isSimpleType()) + { + state.error(XmlErrorCodes.SIMPLE_TYPE_RESTRICTION$LIST_ITEM_NOT_SIMPLE, null, errorLoc); + // recovery: treat the item type as anySimpleType + sImpl = BuiltinSchemaTypeSystem.ST_ANY_SIMPLE; + } + + switch (itemImpl.getSimpleVariety()) + { + case SchemaType.LIST: + state.error(XmlErrorCodes.SIMPLE_TYPE_RESTRICTION$LIST_ITEM_IS_LIST, null, errorLoc); + // recovery: treat the list as an anySimpleType + resolveErrorSimpleType(sImpl); + return; + case SchemaType.UNION: + if (itemImpl.isUnionOfLists()) + { + state.error(XmlErrorCodes.SIMPLE_TYPE_RESTRICTION$LIST_ITEM_IS_UNION_OF_LIST, null, errorLoc); + resolveErrorSimpleType(sImpl); + return; + } + // fallthrough: nonlist unions are just like atomic items + case SchemaType.ATOMIC: + sImpl.setListItemTypeRef(itemImpl.getRef()); + // Check that the item type is not a plan NOTATION + if (sImpl.getBuiltinTypeCode() == SchemaType.BTC_NOTATION) + state.recover(XmlErrorCodes.DATATYPE_ENUM_NOTATION, null, errorLoc); + break; + default: + assert(false); + sImpl.setListItemTypeRef(BuiltinSchemaTypeSystem.ST_ANY_SIMPLE.getRef()); + } + + // now deal with facets + sImpl.setBasicFacets(StscState.FACETS_LIST, StscState.FIXED_FACETS_LIST); + sImpl.setWhiteSpaceRule( SchemaType.WS_COLLAPSE ); + + // now compute our intrinsic properties + resolveFundamentalFacets(sImpl); + } + + + + + static void resolveUnionType(SchemaTypeImpl sImpl, UnionDocument.Union parseUnion, List anonTypes) + { + sImpl.setSimpleTypeVariety(SchemaType.UNION); + sImpl.setBaseTypeRef(BuiltinSchemaTypeSystem.ST_ANY_SIMPLE.getRef()); + sImpl.setBaseDepth(BuiltinSchemaTypeSystem.ST_ANY_SIMPLE.getBaseDepth() + 1); + sImpl.setDerivationType(SchemaType.DT_RESTRICTION); + + StscState state = StscState.get(); + + if (sImpl.isRedefinition()) + { + state.error(XmlErrorCodes.SCHEMA_REDEFINE$EXTEND_OR_RESTRICT, + new Object[] { "union" }, parseUnion); + // recovery: oh well. + } + + List memberTypes = parseUnion.getMemberTypes(); + SimpleType[] simpleTypes = parseUnion.getSimpleTypeArray(); + + List memberImplList = new ArrayList(); + + if (simpleTypes.length == 0 && (memberTypes == null || memberTypes.size() == 0)) + { + state.error(XmlErrorCodes.SCHEMA_SIMPLE_TYPE$UNION_HAS_MEMBER_TYPES_OR_SIMPLE_TYPES, null, parseUnion); + // recovery: oh well, zero member types is fine. + } + + if (memberTypes != null) + { + for (Iterator mNames = memberTypes.iterator(); mNames.hasNext(); ) + { + QName mName = (QName)mNames.next(); + SchemaTypeImpl memberImpl = state.findGlobalType(mName, sImpl.getChameleonNamespace(), sImpl.getTargetNamespace()); + if (memberImpl == null) + // recovery: skip member + state.notFoundError(mName, SchemaType.TYPE, parseUnion.xgetMemberTypes(), true); + else + memberImplList.add(memberImpl); + } + } + + for (int i = 0; i < simpleTypes.length; i++) + { + // BUGBUG: see if non children can leak through + SchemaTypeImpl mImpl = StscTranslator.translateAnonymousSimpleType(simpleTypes[i], + sImpl.getTargetNamespace(), sImpl.getChameleonNamespace() != null, + sImpl.getElemFormDefault(), sImpl.getAttFormDefault(), anonTypes, sImpl); + memberImplList.add(mImpl); + mImpl.setAnonymousUnionMemberOrdinal(i + 1); + } + + // Recurse and resolve all member types + for (Iterator mImpls = memberImplList.iterator(); mImpls.hasNext(); ) + { + SchemaTypeImpl mImpl = (SchemaTypeImpl)mImpls.next(); + if (!StscResolver.resolveType(mImpl)) + { + // KHK: review + String memberName = ""; + XmlObject errorLoc; + if (mImpl.getOuterType().equals(sImpl)) + { + errorLoc = mImpl.getParseObject(); + } + else + { + memberName = QNameHelper.pretty(mImpl.getName()) + " "; + errorLoc = parseUnion.xgetMemberTypes(); + } + + state.error(XmlErrorCodes.SCHEMA_SIMPLE_TYPE$CYCLIC_UNION, new Object[] { memberName }, errorLoc); + + // recovery: ignore the errant union member + mImpls.remove(); + continue; + } + } + + // Now verify members + boolean isUnionOfLists = false; + + for (Iterator mImpls = memberImplList.iterator(); mImpls.hasNext(); ) + { + SchemaTypeImpl mImpl = (SchemaTypeImpl)mImpls.next(); + + if (!mImpl.isSimpleType()) + { + // KHK: review + String memberName = ""; + XmlObject errorLoc; + if (mImpl.getOuterType() != null && mImpl.getOuterType().equals(sImpl)) + { + errorLoc = mImpl.getParseObject(); + } + else + { + memberName = QNameHelper.pretty(mImpl.getName()) + " "; + errorLoc = parseUnion.xgetMemberTypes(); + } + + state.error(XmlErrorCodes.SIMPLE_TYPE_RESTRICTION$UNION_MEMBER_NOT_SIMPLE, new Object[] { memberName }, errorLoc); + + // recovery: ignore the errant union member + mImpls.remove(); + continue; + } + + if (mImpl.getSimpleVariety() == SchemaType.LIST || + mImpl.getSimpleVariety() == SchemaType.UNION && mImpl.isUnionOfLists()) + isUnionOfLists = true; + } + + // Verify any final restrictions + for (int i = 0 ; i < memberImplList.size() ; i++) + { + SchemaTypeImpl mImpl = (SchemaTypeImpl)memberImplList.get(i); + if (mImpl.finalUnion()) + state.error(XmlErrorCodes.SIMPLE_TYPE_PROPERTIES$UNION_FINAL, null, parseUnion); + } + + sImpl.setUnionOfLists(isUnionOfLists); + + sImpl.setUnionMemberTypeRefs(makeRefArray(memberImplList)); + + // now deal with facets + sImpl.setBasicFacets(StscState.FACETS_UNION, StscState.FIXED_FACETS_UNION); + + // now compute our intrinsic properties + resolveFundamentalFacets(sImpl); + } + + static void resolveSimpleRestrictionType(SchemaTypeImpl sImpl, RestrictionDocument.Restriction parseRestr, List anonTypes) + { + QName baseName = parseRestr.getBase(); + SimpleType parseInner = parseRestr.getSimpleType(); + StscState state = StscState.get(); + + if (baseName != null && parseInner != null) + { + state.error(XmlErrorCodes.SCHEMA_SIMPLE_TYPE$RESTRICTION_HAS_BOTH_BASE_OR_SIMPLE_TYPE, null, parseRestr); + // recovery: ignore the inner simple type. + parseInner = null; + } + + SchemaTypeImpl baseImpl; + + if (baseName != null) + { + if (sImpl.isRedefinition()) + { + baseImpl = state.findRedefinedGlobalType(parseRestr.getBase(), sImpl.getChameleonNamespace(), sImpl); + if (baseImpl != null && !baseImpl.getName().equals(sImpl.getName())) + { + state.error(XmlErrorCodes.SCHEMA_REDEFINE$SAME_TYPE, + new Object[] { "", + QNameHelper.pretty(baseName), + QNameHelper.pretty(sImpl.getName()) + }, + parseRestr); + } + } + else + { + baseImpl = state.findGlobalType(baseName, sImpl.getChameleonNamespace(), sImpl.getTargetNamespace()); + } + if (baseImpl == null) + { + state.notFoundError(baseName, SchemaType.TYPE, parseRestr.xgetBase(), true); + // recovery: treat it as an extension of anySimpleType + baseImpl = BuiltinSchemaTypeSystem.ST_ANY_SIMPLE; + } + } + else if (parseInner != null) + { + if (sImpl.isRedefinition()) + { + StscState.get().error(XmlErrorCodes.SCHEMA_REDEFINE$EXTEND_OR_RESTRICT, + new Object[] { "" }, parseInner); + // recovery: oh well. + } + + baseImpl = StscTranslator.translateAnonymousSimpleType(parseInner, + sImpl.getTargetNamespace(), sImpl.getChameleonNamespace() != null, + sImpl.getElemFormDefault(), sImpl.getAttFormDefault(), anonTypes, sImpl); + } + else + { + state.error(XmlErrorCodes.SCHEMA_SIMPLE_TYPE$RESTRICTION_HAS_NEITHER_BASE_OR_SIMPLE_TYPE, null, parseRestr); + // recovery: treat it as an extension of anySimpleType + baseImpl = BuiltinSchemaTypeSystem.ST_ANY_SIMPLE; + } + + // Recursion! + if (!StscResolver.resolveType(baseImpl)) + { + // cyclic dependency recovery: treat it as an extension of anySimpleType + baseImpl = BuiltinSchemaTypeSystem.ST_ANY_SIMPLE; + } + + if (baseImpl.finalRestriction()) + state.error(XmlErrorCodes.SIMPLE_TYPE_PROPERTIES$RESTRICTION_FINAL, null, parseRestr); + + sImpl.setBaseTypeRef(baseImpl.getRef()); + sImpl.setBaseDepth(baseImpl.getBaseDepth() + 1); + sImpl.setDerivationType(SchemaType.DT_RESTRICTION); + + if (!baseImpl.isSimpleType()) + { + state.error(XmlErrorCodes.SIMPLE_TYPE_RESTRICTION$ATOMIC_NOT_SIMPLE, null, parseRestr.xgetBase()); + // recovery: treat it as a restriction of anySimpleType + resolveErrorSimpleType(sImpl); + return; + } + + sImpl.setSimpleTypeVariety(baseImpl.getSimpleVariety()); + + // copy variety-specific properties + switch (baseImpl.getSimpleVariety()) + { + case SchemaType.ATOMIC: + sImpl.setPrimitiveTypeRef(baseImpl.getPrimitiveType().getRef()); + break; + case SchemaType.UNION: + sImpl.setUnionOfLists(baseImpl.isUnionOfLists()); + sImpl.setUnionMemberTypeRefs(makeRefArray(Arrays.asList(baseImpl.getUnionMemberTypes()))); + break; + case SchemaType.LIST: + sImpl.setListItemTypeRef(baseImpl.getListItemType().getRef()); + break; + } + + // deal with facets + resolveFacets(sImpl, parseRestr, baseImpl); + + // now compute our intrinsic properties + resolveFundamentalFacets(sImpl); + } + + static int translateWhitespaceCode(XmlAnySimpleType value) + { + // BUGBUG: add whitespace rule to textvalue. + String textval = value.getStringValue(); + + if (textval.equals("collapse")) + return SchemaType.WS_COLLAPSE; + + if (textval.equals("preserve")) + return SchemaType.WS_PRESERVE; + + if (textval.equals("replace")) + return SchemaType.WS_REPLACE; + + // KHK: s4s + StscState.get().error("Unrecognized whitespace value \"" + textval + "\"", XmlErrorCodes.FACET_VALUE_MALFORMED, value); + return SchemaType.WS_UNSPECIFIED; + } + + static boolean isMultipleFacet(int facetcode) + { + return (facetcode == SchemaType.FACET_ENUMERATION || + facetcode == SchemaType.FACET_PATTERN); + } + + static boolean facetAppliesToType(int facetCode, SchemaTypeImpl baseImpl) + { + switch (baseImpl.getSimpleVariety()) + { + case SchemaType.LIST: + switch (facetCode) + { + case SchemaType.FACET_LENGTH: + case SchemaType.FACET_MIN_LENGTH: + case SchemaType.FACET_MAX_LENGTH: + case SchemaType.FACET_ENUMERATION: + case SchemaType.FACET_PATTERN: + case SchemaType.FACET_WHITE_SPACE: + return true; + } + return false; + + case SchemaType.UNION: + switch (facetCode) + { + case SchemaType.FACET_ENUMERATION: + case SchemaType.FACET_PATTERN: + return true; + } + return false; + } + + // the atomic case + + switch (baseImpl.getPrimitiveType().getBuiltinTypeCode()) + { + case SchemaType.BTC_ANY_SIMPLE: + return false; + + case SchemaType.BTC_BOOLEAN: + switch (facetCode) + { + case SchemaType.FACET_PATTERN: + case SchemaType.FACET_WHITE_SPACE: + return true; + } + return false; + + case SchemaType.BTC_FLOAT: + case SchemaType.BTC_DOUBLE: + 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: + switch (facetCode) + { + case SchemaType.FACET_MIN_EXCLUSIVE: + case SchemaType.FACET_MIN_INCLUSIVE: + case SchemaType.FACET_MAX_INCLUSIVE: + case SchemaType.FACET_MAX_EXCLUSIVE: + case SchemaType.FACET_ENUMERATION: + case SchemaType.FACET_PATTERN: + case SchemaType.FACET_WHITE_SPACE: + return true; + } + return false; + + case SchemaType.BTC_DECIMAL: + switch (facetCode) + { + case SchemaType.FACET_MIN_EXCLUSIVE: + case SchemaType.FACET_MIN_INCLUSIVE: + case SchemaType.FACET_MAX_INCLUSIVE: + case SchemaType.FACET_MAX_EXCLUSIVE: + case SchemaType.FACET_TOTAL_DIGITS: + case SchemaType.FACET_FRACTION_DIGITS: + case SchemaType.FACET_ENUMERATION: + case SchemaType.FACET_PATTERN: + case SchemaType.FACET_WHITE_SPACE: + return true; + } + return false; + + case SchemaType.BTC_BASE_64_BINARY: + case SchemaType.BTC_HEX_BINARY: + case SchemaType.BTC_ANY_URI: + case SchemaType.BTC_QNAME: + case SchemaType.BTC_NOTATION: + case SchemaType.BTC_STRING: + switch (facetCode) + { + case SchemaType.FACET_LENGTH: + case SchemaType.FACET_MIN_LENGTH: + case SchemaType.FACET_MAX_LENGTH: + case SchemaType.FACET_ENUMERATION: + case SchemaType.FACET_PATTERN: + case SchemaType.FACET_WHITE_SPACE: + return true; + } + return false; + + default: + assert(false); + return false; + } + } + + private static int other_similar_limit(int facetcode) + { + switch (facetcode) + { + case SchemaType.FACET_MIN_EXCLUSIVE: + return SchemaType.FACET_MIN_INCLUSIVE; + case SchemaType.FACET_MIN_INCLUSIVE: + return SchemaType.FACET_MIN_EXCLUSIVE; + case SchemaType.FACET_MAX_INCLUSIVE: + return SchemaType.FACET_MAX_EXCLUSIVE; + case SchemaType.FACET_MAX_EXCLUSIVE: + return SchemaType.FACET_MAX_INCLUSIVE; + default: + assert(false); + throw new IllegalStateException(); + } + } + + static void resolveFacets(SchemaTypeImpl sImpl, XmlObject restriction, SchemaTypeImpl baseImpl) + { + StscState state = StscState.get(); + + boolean[] seenFacet = new boolean[SchemaType.LAST_FACET + 1]; + XmlAnySimpleType[] myFacets = baseImpl.getBasicFacets(); // makes a copy + boolean[] fixedFacets = baseImpl.getFixedFacets(); + int wsr = SchemaType.WS_UNSPECIFIED; + List enumeratedValues = null; + List patterns = null; + + if (restriction != null) + { + XmlCursor cur = restriction.newCursor(); + for (boolean more = cur.toFirstChild(); more; more = cur.toNextSibling()) + { + QName facetQName = cur.getName(); + String facetName = facetQName.getLocalPart(); + int code = translateFacetCode(facetQName); + if (code == -1) + continue; + + Facet facet = (Facet)cur.getObject(); + + if (!facetAppliesToType(code, baseImpl)) + { + state.error(XmlErrorCodes.FACETS_APPLICABLE, + new Object[] { facetName, QNameHelper.pretty(baseImpl.getName()) }, facet); + continue; + } + else if (baseImpl.getSimpleVariety() == SchemaType.ATOMIC && + baseImpl.getPrimitiveType().getBuiltinTypeCode() == SchemaType.BTC_NOTATION + && (code == SchemaType.FACET_LENGTH || code == SchemaType.FACET_MIN_LENGTH || + code == SchemaType.FACET_MAX_LENGTH)) + { + state.warning(XmlErrorCodes.FACETS_DEPRECATED_NOTATION, + new Object[] {facetName, QNameHelper.pretty(baseImpl.getName()) }, facet); + } + if (seenFacet[code] && !isMultipleFacet(code)) + { + state.error(XmlErrorCodes.DATATYPE_SINGLE_FACET_VALUE, null, facet); + continue; + } + seenFacet[code] = true; + + switch (code) + { + case SchemaType.FACET_LENGTH: +// if (myFacets[SchemaType.FACET_MIN_LENGTH] != null || +// myFacets[SchemaType.FACET_MAX_LENGTH] != null) +// { +// state.error(XmlErrorCodes.DATATYPE_LENGTH, null, facet); +// continue; +// } + XmlInteger len = StscTranslator.buildNnInteger(facet.getValue()); + if (len == null) + { + state.error("Must be a nonnegative integer", XmlErrorCodes.FACET_VALUE_MALFORMED, facet); + continue; + } + if (fixedFacets[code] && !myFacets[code].valueEquals(len)) + { + state.error(XmlErrorCodes.FACET_FIXED, new Object[] { facetName }, facet); + continue; + } + if (myFacets[SchemaType.FACET_MIN_LENGTH] != null) + { + // An error for 'length' and 'minLength' to be specified at the same time + // except if the base type had the same value for 'minLength' also + XmlAnySimpleType baseMinLength = baseImpl.getFacet(SchemaType.FACET_MIN_LENGTH); + if (!(baseMinLength != null && + baseMinLength.valueEquals(myFacets[SchemaType.FACET_MIN_LENGTH]) && + baseMinLength.compareValue(len) <= 0)) + { + state.error(XmlErrorCodes.DATATYPE_LENGTH, null, facet); + continue; + } + } + if (myFacets[SchemaType.FACET_MAX_LENGTH] != null) + { + // An error for 'length' and 'maxLength' to be specified at the same time + // except if the base type had the same value for 'maxLength' also + XmlAnySimpleType baseMaxLength = baseImpl.getFacet(SchemaType.FACET_MAX_LENGTH); + if (!(baseMaxLength != null && + baseMaxLength.valueEquals(myFacets[SchemaType.FACET_MAX_LENGTH]) && + baseMaxLength.compareValue(len) >= 0)) + { + state.error(XmlErrorCodes.DATATYPE_LENGTH, null, facet); + continue; + } + } + myFacets[code] = len; + break; + + case SchemaType.FACET_MIN_LENGTH: + case SchemaType.FACET_MAX_LENGTH: + XmlInteger mlen = StscTranslator.buildNnInteger(facet.getValue()); + if (mlen == null) + { + state.error("Must be a nonnegative integer", XmlErrorCodes.FACET_VALUE_MALFORMED, facet); + continue; + } + if (fixedFacets[code] && !myFacets[code].valueEquals(mlen)) + { + state.error(XmlErrorCodes.FACET_FIXED, new Object[] { facetName }, facet); + continue; + } + if (myFacets[SchemaType.FACET_LENGTH] != null) + { + // It's an error for 'length' and 'minLength'/'maxLength' to be + // specified at the same time, except for the case when + // the base type had the same value for 'minLength'/'maxLength' + // and the two values are consistent + XmlAnySimpleType baseMinMaxLength = baseImpl.getFacet(code); + if (!(baseMinMaxLength != null && + baseMinMaxLength.valueEquals(mlen) && + (code == SchemaType.FACET_MIN_LENGTH ? + baseMinMaxLength.compareTo(myFacets[SchemaType.FACET_LENGTH]) <= 0 : + baseMinMaxLength.compareTo(myFacets[SchemaType.FACET_LENGTH]) >= 0))) + { + state.error(XmlErrorCodes.DATATYPE_LENGTH, null, facet); + continue; + } + } + if (myFacets[SchemaType.FACET_MAX_LENGTH] != null) + { + if (mlen.compareValue(myFacets[SchemaType.FACET_MAX_LENGTH]) > 0) + { + state.error(XmlErrorCodes.DATATYPE_MAX_LENGTH_RESTRICTION, null, facet); + continue; + } + } + if (myFacets[SchemaType.FACET_MIN_LENGTH] != null) + { + if (mlen.compareValue(myFacets[SchemaType.FACET_MIN_LENGTH]) < 0) + { + state.error(XmlErrorCodes.DATATYPE_MIN_LENGTH_RESTRICTION, null, facet); + continue; + } + } + myFacets[code] = mlen; + break; + + case SchemaType.FACET_TOTAL_DIGITS: + XmlPositiveInteger dig = StscTranslator.buildPosInteger(facet.getValue()); + if (dig == null) + { + state.error("Must be a positive integer", XmlErrorCodes.FACET_VALUE_MALFORMED, facet); + break; + } + if (fixedFacets[code] && !myFacets[code].valueEquals(dig)) + { + state.error(XmlErrorCodes.FACET_FIXED, new Object[] { facetName }, facet); + continue; + } + if (myFacets[SchemaType.FACET_TOTAL_DIGITS] != null) + { + if (dig.compareValue(myFacets[SchemaType.FACET_TOTAL_DIGITS]) > 0) + state.error(XmlErrorCodes.DATATYPE_TOTAL_DIGITS_RESTRICTION, null, facet); + } + myFacets[code] = dig; + break; + + case SchemaType.FACET_FRACTION_DIGITS: + XmlNonNegativeInteger fdig = StscTranslator.buildNnInteger(facet.getValue()); + if (fdig == null) + { + state.error("Must be a nonnegative integer", XmlErrorCodes.FACET_VALUE_MALFORMED, facet); + break; + } + if (fixedFacets[code] && !myFacets[code].valueEquals(fdig)) + { + state.error(XmlErrorCodes.FACET_FIXED, new Object[] { facetName }, facet); + continue; + } + if (myFacets[SchemaType.FACET_FRACTION_DIGITS] != null) + { + if (fdig.compareValue(myFacets[SchemaType.FACET_FRACTION_DIGITS]) > 0) + state.error(XmlErrorCodes.DATATYPE_FRACTION_DIGITS_RESTRICTION, null, facet); + } + if (myFacets[SchemaType.FACET_TOTAL_DIGITS] != null) + { + if (fdig.compareValue(myFacets[SchemaType.FACET_TOTAL_DIGITS]) > 0) + state.error(XmlErrorCodes.DATATYPE_FRACTION_DIGITS_LE_TOTAL_DIGITS, null, facet); + } + myFacets[code] = fdig; + break; + + case SchemaType.FACET_MIN_EXCLUSIVE: + case SchemaType.FACET_MIN_INCLUSIVE: + case SchemaType.FACET_MAX_INCLUSIVE: + case SchemaType.FACET_MAX_EXCLUSIVE: + + if (seenFacet[other_similar_limit(code)]) + { + state.error("Cannot define both inclusive and exclusive limit in the same restriciton", XmlErrorCodes.FACET_DUPLICATED, facet); + continue; + } + boolean ismin = (code == SchemaType.FACET_MIN_EXCLUSIVE || code == SchemaType.FACET_MIN_INCLUSIVE); + boolean isexclusive = (code == SchemaType.FACET_MIN_EXCLUSIVE || code == SchemaType.FACET_MAX_EXCLUSIVE); + + XmlAnySimpleType limit; + try + { + limit = baseImpl.newValue(facet.getValue(), true); + } + catch (XmlValueOutOfRangeException e) + { + // note: this guarantees that the limit is a valid number in the + // base data type!! + switch (code) + { + case SchemaType.FACET_MIN_EXCLUSIVE: + state.error(XmlErrorCodes.DATATYPE_MIN_EXCLUSIVE_RESTRICTION, + new Object[] {e.getMessage()}, facet); + break; + case SchemaType.FACET_MIN_INCLUSIVE: + state.error(XmlErrorCodes.DATATYPE_MIN_INCLUSIVE_RESTRICTION, + new Object[] {e.getMessage()}, facet); + break; + case SchemaType.FACET_MAX_INCLUSIVE: + state.error(XmlErrorCodes.DATATYPE_MAX_INCLUSIVE_RESTRICTION, + new Object[] {e.getMessage()}, facet); + break; + case SchemaType.FACET_MAX_EXCLUSIVE: + state.error(XmlErrorCodes.DATATYPE_MAX_EXCLUSIVE_RESTRICTION, + new Object[] {e.getMessage()}, facet); + break; + } + + // BUGBUG: if there are actual schemas that redefine min/maxExclusive, + // they will need this rule relaxed for them!! + continue; + } + if (fixedFacets[code] && !myFacets[code].valueEquals(limit)) + { + state.error(XmlErrorCodes.FACET_FIXED, new Object[] { facetName }, facet); + continue; + } + if (myFacets[code] != null) + { + SchemaType limitSType = limit.schemaType(); + if ( limitSType!=null && !limitSType.isSimpleType() && + limitSType.getContentType()==SchemaType.SIMPLE_CONTENT) + { + // in the case of complex types with simple content that has facets + // we need to compare values based on the content type + limit = baseImpl.getContentBasedOnType().newValue(facet.getValue()); + } + + int comparison = limit.compareValue(myFacets[code]); + if (comparison == 2 || comparison == (ismin ? -1 : 1)) + { + state.error(ismin ? + (isexclusive ? + "Must be greater than or equal to previous minExclusive" : + "Must be greater than or equal to previous minInclusive") : + (isexclusive ? + "Must be less than or equal to previous maxExclusive" : + "Must be less than or equal to previous maxInclusive"), + XmlErrorCodes.FACET_VALUE_MALFORMED, facet); + continue; + } + } + myFacets[code] = limit; + myFacets[other_similar_limit(code)] = null; + break; + + case SchemaType.FACET_WHITE_SPACE: + wsr = translateWhitespaceCode(facet.getValue()); + if (baseImpl.getWhiteSpaceRule() > wsr) + { + wsr = SchemaType.WS_UNSPECIFIED; + state.error(XmlErrorCodes.DATATYPE_WHITESPACE_RESTRICTION, null, facet); + continue; + } + myFacets[code] = StscState.build_wsstring(wsr).get(); + break; + + case SchemaType.FACET_ENUMERATION: + XmlObject enumval; + try + { + enumval = baseImpl.newValue(facet.getValue(), true); + // enumval.set(facet.getValue()); + // ((XmlObjectBase)enumval).setImmutable(); + } + catch (XmlValueOutOfRangeException e) + { + state.error(XmlErrorCodes.DATATYPE_ENUM_RESTRICTION, new Object[] { facet.getValue().getStringValue(), e.getMessage() }, facet); + continue; + } + if (enumeratedValues == null) + enumeratedValues = new ArrayList(); + enumeratedValues.add(enumval); + break; + + case SchemaType.FACET_PATTERN: + RegularExpression p; + try { p = new RegularExpression(facet.getValue().getStringValue(), "X"); } + catch (ParseException e) + { + state.error(XmlErrorCodes.PATTERN_REGEX, new Object[] { facet.getValue().getStringValue(), e.getMessage() }, facet); + continue; + } + if (patterns == null) + patterns = new ArrayList(); + patterns.add(p); + break; + } + + if (facet.getFixed()) + fixedFacets[code] = true; + } + } + + // Store the array of basic facets + + sImpl.setBasicFacets(makeValueRefArray(myFacets), fixedFacets); + + // Update the numeric whitespace rule + if (wsr == SchemaType.WS_UNSPECIFIED) + wsr = baseImpl.getWhiteSpaceRule(); + sImpl.setWhiteSpaceRule(wsr); + + // store away the enumerated values + if (enumeratedValues != null) + { + sImpl.setEnumerationValues(makeValueRefArray((XmlAnySimpleType[]) + enumeratedValues.toArray(new XmlAnySimpleType[enumeratedValues.size()]))); + + SchemaType beType = sImpl; + if ( ((SchemaTypeImpl)sImpl).isRedefinition() ){ + beType = sImpl.getBaseType().getBaseEnumType(); + if( beType == null || sImpl.getBaseType() == beType ){ + beType = sImpl; + } + } + else if (sImpl.getBaseType().getBaseEnumType() != null) + beType = sImpl.getBaseType().getBaseEnumType(); + sImpl.setBaseEnumTypeRef(beType.getRef()); + } + else + { + sImpl.copyEnumerationValues(baseImpl); + } + + // store the pattern list + org.apache.xmlbeans.impl.regex.RegularExpression[] patternArray; + if (patterns != null) + patternArray = (org.apache.xmlbeans.impl.regex.RegularExpression[])patterns.toArray(EMPTY_REGEX_ARRAY); + else + patternArray = EMPTY_REGEX_ARRAY; + sImpl.setPatternFacet((patternArray.length > 0 || baseImpl.hasPatternFacet())); + sImpl.setPatterns(patternArray); + + // Check that, if the base type is NOTATION, there is an enumeration facet + // http://www.w3.org/TR/xmlschema-2/#NOTATION + if (baseImpl.getBuiltinTypeCode() == SchemaType.BTC_NOTATION) + if (sImpl.getEnumerationValues() == null) + state.recover(XmlErrorCodes.DATATYPE_ENUM_NOTATION, null, restriction); + } + + private static XmlValueRef[] makeValueRefArray(XmlAnySimpleType[] source) + { + XmlValueRef[] result = new XmlValueRef[source.length]; + for (int i = 0; i < result.length; i++) + result[i] = (source[i] == null ? null : new XmlValueRef(source[i])); + return result; + } + + private static final org.apache.xmlbeans.impl.regex.RegularExpression[] EMPTY_REGEX_ARRAY = new org.apache.xmlbeans.impl.regex.RegularExpression[0]; + + private static boolean isDiscreteType(SchemaTypeImpl sImpl) + { + if (sImpl.getFacet(SchemaType.FACET_FRACTION_DIGITS) != null) + return true; + // BUGBUG: spec is silent on enumerations; they're finite too. + switch (sImpl.getPrimitiveType().getBuiltinTypeCode()) + { + 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_BOOLEAN: + return true; + } + return false; + } + + private static boolean isNumericPrimitive(SchemaType sImpl) + { + switch (sImpl.getBuiltinTypeCode()) + { + case SchemaType.BTC_DECIMAL: + case SchemaType.BTC_FLOAT: + case SchemaType.BTC_DOUBLE: + return true; + } + return false; + } + + private static int decimalSizeOfType(SchemaTypeImpl sImpl) + { + int size = mathematicalSizeOfType(sImpl); + + // byte and short are inconvenient, because setByte((byte)4) requires a cast. + // So use "int" unless you're really a xs:byte, xs:short, or an xs:unsignedByte + // (the last case is included for alignment with JAXB) + + if (size == SchemaType.SIZE_BYTE && !XmlByte.type.isAssignableFrom(sImpl)) + size = SchemaType.SIZE_SHORT; + if (size == SchemaType.SIZE_SHORT && !XmlShort.type.isAssignableFrom(sImpl) && !XmlUnsignedByte.type.isAssignableFrom(sImpl)) + size = SchemaType.SIZE_INT; + + return size; + } + + private static int mathematicalSizeOfType(SchemaTypeImpl sImpl) + { + if (sImpl.getPrimitiveType().getBuiltinTypeCode() != SchemaType.BTC_DECIMAL) + return SchemaType.NOT_DECIMAL; + + if (sImpl.getFacet(SchemaType.FACET_FRACTION_DIGITS) == null || + ((SimpleValue)sImpl.getFacet(SchemaType.FACET_FRACTION_DIGITS)).getBigIntegerValue().signum() != 0) + return SchemaType.SIZE_BIG_DECIMAL; + + BigInteger min = null; + BigInteger max = null; + + if (sImpl.getFacet(SchemaType.FACET_MIN_EXCLUSIVE) != null) + min = ((SimpleValue)sImpl.getFacet(SchemaType.FACET_MIN_EXCLUSIVE)).getBigIntegerValue(); // .add(BigInteger.ONE); + if (sImpl.getFacet(SchemaType.FACET_MIN_INCLUSIVE) != null) + min = ((SimpleValue)sImpl.getFacet(SchemaType.FACET_MIN_INCLUSIVE)).getBigIntegerValue(); + if (sImpl.getFacet(SchemaType.FACET_MAX_INCLUSIVE) != null) + max = ((SimpleValue)sImpl.getFacet(SchemaType.FACET_MAX_INCLUSIVE)).getBigIntegerValue(); + if (sImpl.getFacet(SchemaType.FACET_MAX_EXCLUSIVE) != null) + max = ((SimpleValue)sImpl.getFacet(SchemaType.FACET_MAX_EXCLUSIVE)).getBigIntegerValue(); // .subtract(BigInteger.ONE); + + if (sImpl.getFacet(SchemaType.FACET_TOTAL_DIGITS) != null) + { + BigInteger peg = null; + try + { + BigInteger totalDigits = ((SimpleValue)sImpl.getFacet(SchemaType.FACET_TOTAL_DIGITS)).getBigIntegerValue(); + + switch (totalDigits.intValue()) + { + case 0: case 1: case 2: + peg = BigInteger.valueOf(99L); // BYTE size + break; + case 3: case 4: + peg = BigInteger.valueOf(9999L); // SHORT size + break; + case 5: case 6: case 7: case 8: case 9: + peg = BigInteger.valueOf(999999999L); // INT size + break; + case 10: case 11: case 12: case 13: case 14: + case 15: case 16: case 17: case 18: + peg = BigInteger.valueOf(999999999999999999L); // LONG size + break; + } + } + catch (XmlValueOutOfRangeException e) {} + if (peg != null) + { + min = (min == null ? peg.negate() : min.max(peg.negate())); + max = (max == null ? peg : max.min(peg)); + } + } + + if (min != null && max != null) + { + // find the largest "absolute value" number that must be dealt with + if (min.signum() < 0) + min = min.negate().subtract(BigInteger.ONE); + if (max.signum() < 0) + max = max.negate().subtract(BigInteger.ONE); + + max = max.max(min); + if (max.compareTo(BigInteger.valueOf(Byte.MAX_VALUE)) <= 0) + return SchemaType.SIZE_BYTE; + if (max.compareTo(BigInteger.valueOf(Short.MAX_VALUE)) <= 0) + return SchemaType.SIZE_SHORT; + if (max.compareTo(BigInteger.valueOf(Integer.MAX_VALUE)) <= 0) + return SchemaType.SIZE_INT; + if (max.compareTo(BigInteger.valueOf(Long.MAX_VALUE)) <= 0) + return SchemaType.SIZE_LONG; + } + + return SchemaType.SIZE_BIG_INTEGER; + } + + + static void resolveFundamentalFacets(SchemaTypeImpl sImpl) + { + // deal with, isOrdered, isBounded, isFinite, isNumeric + // also deal with + switch (sImpl.getSimpleVariety()) + { + case SchemaType.ATOMIC: + SchemaTypeImpl baseImpl = (SchemaTypeImpl)sImpl.getBaseType(); + sImpl.setOrdered(baseImpl.ordered()); + sImpl.setBounded( + (sImpl.getFacet(SchemaType.FACET_MIN_EXCLUSIVE) != null || + sImpl.getFacet(SchemaType.FACET_MIN_INCLUSIVE) != null) && + (sImpl.getFacet(SchemaType.FACET_MAX_INCLUSIVE) != null || + sImpl.getFacet(SchemaType.FACET_MAX_EXCLUSIVE) != null)); + sImpl.setFinite(baseImpl.isFinite() || + sImpl.isBounded() && isDiscreteType(sImpl)); + sImpl.setNumeric(baseImpl.isNumeric() || + isNumericPrimitive(sImpl.getPrimitiveType())); + sImpl.setDecimalSize(decimalSizeOfType(sImpl)); + break; + case SchemaType.UNION: + SchemaType[] mTypes = sImpl.getUnionMemberTypes(); + int ordered = SchemaType.UNORDERED; + boolean isBounded = true; + boolean isFinite = true; + boolean isNumeric = true; + // ordered if any is ordered, bounded if all are bounded. + for (int i = 0; i < mTypes.length; i++) + { + if (mTypes[i].ordered() != SchemaType.UNORDERED) + ordered = SchemaType.PARTIAL_ORDER; + if (!mTypes[i].isBounded()) + isBounded = false; + if (!mTypes[i].isFinite()) + isFinite = false; + if (!mTypes[i].isNumeric()) + isNumeric = false; + } + sImpl.setOrdered(ordered); + sImpl.setBounded(isBounded); + sImpl.setFinite(isFinite); + sImpl.setNumeric(isNumeric); + sImpl.setDecimalSize(SchemaType.NOT_DECIMAL); + break; + case SchemaType.LIST: + sImpl.setOrdered(SchemaType.UNORDERED); + // BUGBUG: the schema spec is wrong here: MIN_LENGTH is not needed, beause len >=0 + sImpl.setBounded(sImpl.getFacet(SchemaType.FACET_LENGTH) != null || + sImpl.getFacet(SchemaType.FACET_MAX_LENGTH) != null); + // BUGBUG: the schema spec is wrong here: finite cardinality requires item type is finite + sImpl.setFinite(sImpl.getListItemType().isFinite() && sImpl.isBounded()); + sImpl.setNumeric(false); + sImpl.setDecimalSize(SchemaType.NOT_DECIMAL); + break; + } + } + + private static class CodeForNameEntry + { + CodeForNameEntry(QName name, int code) + { this.name = name; this.code = code; } + public QName name; + public int code; + } + + private static CodeForNameEntry[] facetCodes = new CodeForNameEntry[] + { + new CodeForNameEntry(QNameHelper.forLNS("length", "http://www.w3.org/2001/XMLSchema"), SchemaType.FACET_LENGTH), + new CodeForNameEntry(QNameHelper.forLNS("minLength", "http://www.w3.org/2001/XMLSchema"), SchemaType.FACET_MIN_LENGTH), + new CodeForNameEntry(QNameHelper.forLNS("maxLength", "http://www.w3.org/2001/XMLSchema"), SchemaType.FACET_MAX_LENGTH), + new CodeForNameEntry(QNameHelper.forLNS("pattern", "http://www.w3.org/2001/XMLSchema"), SchemaType.FACET_PATTERN), + new CodeForNameEntry(QNameHelper.forLNS("enumeration", "http://www.w3.org/2001/XMLSchema"), SchemaType.FACET_ENUMERATION), + new CodeForNameEntry(QNameHelper.forLNS("whiteSpace", "http://www.w3.org/2001/XMLSchema"), SchemaType.FACET_WHITE_SPACE), + new CodeForNameEntry(QNameHelper.forLNS("maxInclusive", "http://www.w3.org/2001/XMLSchema"), SchemaType.FACET_MAX_INCLUSIVE), + new CodeForNameEntry(QNameHelper.forLNS("maxExclusive", "http://www.w3.org/2001/XMLSchema"), SchemaType.FACET_MAX_EXCLUSIVE), + new CodeForNameEntry(QNameHelper.forLNS("minInclusive", "http://www.w3.org/2001/XMLSchema"), SchemaType.FACET_MIN_INCLUSIVE), + new CodeForNameEntry(QNameHelper.forLNS("minExclusive", "http://www.w3.org/2001/XMLSchema"), SchemaType.FACET_MIN_EXCLUSIVE), + new CodeForNameEntry(QNameHelper.forLNS("totalDigits", "http://www.w3.org/2001/XMLSchema"), SchemaType.FACET_TOTAL_DIGITS), + new CodeForNameEntry(QNameHelper.forLNS("fractionDigits", "http://www.w3.org/2001/XMLSchema"), SchemaType.FACET_FRACTION_DIGITS), + }; + + private static final Map facetCodeMap = buildFacetCodeMap(); + + private static Map buildFacetCodeMap() + { + Map result = new HashMap(); + for (int i = 0; i < facetCodes.length; i++) + result.put(facetCodes[i].name, new Integer(facetCodes[i].code)); + return result; + } + + private static int translateFacetCode(QName name) + { + Integer result = ((Integer)facetCodeMap.get(name)); + if (result == null) + return -1; + return result.intValue(); + } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/StscState.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/StscState.java new file mode 100644 index 000000000..c03a094a8 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/StscState.java @@ -0,0 +1,1595 @@ +/* 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.XmlErrorCodes; +import org.apache.xmlbeans.impl.common.QNameHelper; +import org.apache.xmlbeans.impl.common.ResolverUtil; +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.SchemaGlobalElement; +import org.apache.xmlbeans.SchemaComponent; +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.SchemaGlobalAttribute; +import org.apache.xmlbeans.SchemaIdentityConstraint; +import org.apache.xmlbeans.SchemaAttributeGroup; +import org.apache.xmlbeans.SchemaModelGroup; +import org.apache.xmlbeans.SchemaTypeLoader; +import org.apache.xmlbeans.SystemProperties; +import org.apache.xmlbeans.XmlError; +import org.apache.xmlbeans.XmlBeans; +import org.apache.xmlbeans.XmlOptions; +import org.apache.xmlbeans.BindingConfig; +import org.apache.xmlbeans.impl.values.XmlStringImpl; +import org.apache.xmlbeans.impl.values.XmlValueOutOfRangeException; +import org.apache.xmlbeans.impl.util.HexBin; + +import java.util.*; +import java.net.URISyntaxException; +import java.net.URI; +import java.net.URL; +import java.io.File; + + +import javax.xml.namespace.QName; + +import org.apache.xmlbeans.impl.xb.xsdschema.SchemaDocument; +import org.xml.sax.EntityResolver; + +/** + * This class represents the state of the SchemaTypeSystemCompiler as it's + * going. + */ +public class StscState +{ + private String _givenStsName; + private Collection _errorListener; + private SchemaTypeSystemImpl _target; + private BindingConfig _config; + private Map _compatMap; + private boolean _doingDownloads; + private byte[] _digest = null; + private boolean _noDigest = false; + + // EXPERIMENTAL: recovery from compilation errors and partial type systems + private boolean _allowPartial = false; + private int _recoveredErrors = 0; + + private SchemaTypeLoader _importingLoader; + + private Map _containers = new LinkedHashMap(); + private SchemaDependencies _dependencies; + + private Map _redefinedGlobalTypes = new LinkedHashMap(); + private Map _redefinedModelGroups = new LinkedHashMap(); + private Map _redefinedAttributeGroups = new LinkedHashMap(); + + private Map _globalTypes = new LinkedHashMap(); + private Map _globalElements = new LinkedHashMap(); + private Map _globalAttributes = new LinkedHashMap(); + private Map _modelGroups = new LinkedHashMap(); + private Map _attributeGroups = new LinkedHashMap(); + private Map _documentTypes = new LinkedHashMap(); + private Map _attributeTypes = new LinkedHashMap(); + private Map _typesByClassname = new LinkedHashMap(); + private Map _misspelledNames = new HashMap(); + private Set _processingGroups = new LinkedHashSet(); + private Map _idConstraints = new LinkedHashMap(); + private Set _namespaces = new HashSet(); + private List _annotations = new ArrayList(); + private boolean _noUpa; + private boolean _noPvr; + private boolean _noAnn; + private boolean _mdefAll; + private Set _mdefNamespaces = buildDefaultMdefNamespaces(); + private EntityResolver _entityResolver; + private File _schemasDir; + + private static Set buildDefaultMdefNamespaces() + { + // namespaces which are known to appear in WSDLs redundantly + return new HashSet( + Arrays.asList( new String[] { + "http://www.openuri.org/2002/04/soap/conversation/", + })); + } + + /** + * Used to store the new target namespace for a chameleon + * included schema. + */ + public static final Object CHAMELEON_INCLUDE_URI = new Object(); + + /** + * Only constructed via StscState.start(). + */ + private StscState() + { + } + + /** + * Initializer for incremental compilation + */ + public void initFromTypeSystem(SchemaTypeSystemImpl system, Set newNamespaces) + { +// setGivenTypeSystemName(system.getName().substring(14)); + + SchemaContainer[] containers = system.containers(); + for (int i = 0; i < containers.length; i++) + { + if (!newNamespaces.contains(containers[i].getNamespace())) + { + // Copy data from the given container + addContainer(containers[i]); + } + } + } + + + /* CONTAINERS ================================================================*/ + + void addNewContainer(String namespace) + { + if (_containers.containsKey(namespace)) + return; + + SchemaContainer container = new SchemaContainer(namespace); + container.setTypeSystem(sts()); + addNamespace(namespace); + _containers.put(namespace, container); + } + + private void addContainer(SchemaContainer container) + { + _containers.put(container.getNamespace(), container); + List redefModelGroups = container.redefinedModelGroups(); + for (int i = 0; i < redefModelGroups.size(); i++) + { + QName name = ((SchemaModelGroup) redefModelGroups.get(i)).getName(); + _redefinedModelGroups.put(name, redefModelGroups.get(i)); + } + + List redefAttrGroups = container.redefinedAttributeGroups(); + for (int i = 0; i < redefAttrGroups.size(); i++) + { + QName name = ((SchemaAttributeGroup) redefAttrGroups.get(i)).getName(); + _redefinedAttributeGroups.put(name, redefAttrGroups.get(i)); + } + + List redefTypes = container.redefinedGlobalTypes(); + for (int i = 0; i < redefTypes.size(); i++) + { + QName name = ((SchemaType) redefTypes.get(i)).getName(); + _redefinedGlobalTypes.put(name, redefTypes.get(i)); + } + + List globalElems = container.globalElements(); + for (int i = 0; i < globalElems.size(); i++) + { + QName name = ((SchemaGlobalElement) globalElems.get(i)).getName(); + _globalElements.put(name, globalElems.get(i)); + } + + List globalAtts = container.globalAttributes(); + for (int i = 0; i < globalAtts.size(); i++) + { + QName name = ((SchemaGlobalAttribute) globalAtts.get(i)).getName(); + _globalAttributes.put(name, globalAtts.get(i)); + } + + List modelGroups = container.modelGroups(); + for (int i = 0; i < modelGroups.size(); i++) + { + QName name = ((SchemaModelGroup) modelGroups.get(i)).getName(); + _modelGroups.put(name, modelGroups.get(i)); + } + + List attrGroups = container.attributeGroups(); + for (int i = 0; i < attrGroups.size(); i++) + { + QName name = ((SchemaAttributeGroup) attrGroups.get(i)).getName(); + _attributeGroups.put(name, attrGroups.get(i)); + } + + List globalTypes = container.globalTypes(); + for (int i = 0; i < globalTypes.size(); i++) + { + SchemaType t = (SchemaType) globalTypes.get(i); + QName name = t.getName(); + _globalTypes.put(name, t); + if (t.getFullJavaName() != null) + addClassname(t.getFullJavaName(), t); + } + + List documentTypes = container.documentTypes(); + for (int i = 0; i < documentTypes.size(); i++) + { + SchemaType t = (SchemaType) documentTypes.get(i); + QName name = t.getProperties()[0].getName(); + _documentTypes.put(name, t); + if (t.getFullJavaName() != null) + addClassname(t.getFullJavaName(), t); + } + + List attributeTypes = container.attributeTypes(); + for (int i = 0; i < attributeTypes.size(); i++) + { + SchemaType t = (SchemaType) attributeTypes.get(i); + QName name = t.getProperties()[0].getName(); + _attributeTypes.put(name, t); + if (t.getFullJavaName() != null) + addClassname(t.getFullJavaName(), t); + } + + List identityConstraints = container.identityConstraints(); + for (int i = 0; i < identityConstraints.size(); i++) + { + QName name = ((SchemaIdentityConstraint) identityConstraints.get(i)).getName(); + _idConstraints.put(name, identityConstraints.get(i)); + } + + _annotations.addAll(container.annotations()); + _namespaces.add(container.getNamespace()); + container.unsetImmutable(); + } + + SchemaContainer getContainer(String namespace) + { + return (SchemaContainer) _containers.get(namespace); + } + + Map getContainerMap() + { + return Collections.unmodifiableMap(_containers); + } + + /* DEPENDENCIES ================================================================*/ + + void registerDependency(String sourceNs, String targetNs) + { + _dependencies.registerDependency(sourceNs, targetNs); + } + + void registerContribution(String ns, String fileUrl) + { + _dependencies.registerContribution(ns, fileUrl); + } + + SchemaDependencies getDependencies() + { + return _dependencies; + } + + void setDependencies(SchemaDependencies deps) + { + _dependencies = deps; + } + + boolean isFileProcessed(String url) + { + return _dependencies.isFileRepresented(url); + } + + + /** + * Initializer for schematypepath + */ + public void setImportingTypeLoader(SchemaTypeLoader loader) + { + _importingLoader = loader; + } + + /** + * Initializer for error handling. + */ + public void setErrorListener(Collection errorListener) + { _errorListener = errorListener; } + + /** + * Passes an error on to the current error listener. + * KHK: remove this + */ + public void error(String message, int code, XmlObject loc) + { addError(_errorListener, message, code, loc); } + + /** + * Passes an error on to the current error listener. + */ + public void error(String code, Object[] args, XmlObject loc) + { addError(_errorListener, code, args, loc); } + + /** + * Passes a recovered error on to the current error listener. + */ + public void recover(String code, Object[] args, XmlObject loc) + { addError(_errorListener, code, args, loc); _recoveredErrors++; } + + /** + * Passes an error on to the current error listener. + */ + public void warning(String message, int code, XmlObject loc) + { + addWarning(_errorListener, message, code, loc); + } + + /** + * Passes an error on to the current error listener. + */ + public void warning(String code, Object[] args, XmlObject loc) + { + // it's OK for XMLSchema.xsd itself to have reserved type names + if (code == XmlErrorCodes.RESERVED_TYPE_NAME && + loc.documentProperties().getSourceName() != null && + loc.documentProperties().getSourceName().indexOf("XMLSchema.xsd") > 0) + return; + + addWarning(_errorListener, code, args, loc); + } + + /** + * Passes a warning on to the current error listener. + */ + public void info(String message) + { addInfo(_errorListener, message); } + + /** + * Passes a warning on to the current error listener. + */ + public void info(String code, Object[] args) + { addInfo(_errorListener, code, args); } + + // KHK: remove this + public static void addError(Collection errorListener, String message, int code, XmlObject location) + { + XmlError err = + XmlError.forObject( + message, + XmlError.SEVERITY_ERROR, + location); + errorListener.add(err); + } + + public static void addError(Collection errorListener, String code, Object[] args, XmlObject location) + { + XmlError err = + XmlError.forObject( + code, + args, + XmlError.SEVERITY_ERROR, + location); + errorListener.add(err); + } + + public static void addError(Collection errorListener, String code, Object[] args, File location) + { + XmlError err = + XmlError.forLocation( + code, + args, + XmlError.SEVERITY_ERROR, + location.toURI().toString(), 0, 0, 0); + errorListener.add(err); + } + + public static void addError(Collection errorListener, String code, Object[] args, URL location) + { + XmlError err = + XmlError.forLocation( + code, + args, + XmlError.SEVERITY_ERROR, + location.toString(), 0, 0, 0); + errorListener.add(err); + } + + // KHK: remove this + public static void addWarning(Collection errorListener, String message, int code, XmlObject location) + { + XmlError err = + XmlError.forObject( + message, + XmlError.SEVERITY_WARNING, + location); + errorListener.add(err); + } + + public static void addWarning(Collection errorListener, String code, Object[] args, XmlObject location) + { + XmlError err = + XmlError.forObject( + code, + args, + XmlError.SEVERITY_WARNING, + location); + errorListener.add(err); + } + + public static void addInfo(Collection errorListener, String message) + { + XmlError err = XmlError.forMessage(message, XmlError.SEVERITY_INFO); + errorListener.add(err); + } + + public static void addInfo(Collection errorListener, String code, Object[] args) + { + XmlError err = XmlError.forMessage(code, args, XmlError.SEVERITY_INFO); + errorListener.add(err); + } + + public void setGivenTypeSystemName(String name) + { _givenStsName = name; } + + /** + * Initializer for references to the SchemaTypeLoader + */ + public void setTargetSchemaTypeSystem(SchemaTypeSystemImpl target) + { _target = target; } + + /** + * Accumulates a schema digest... + */ + public void addSchemaDigest(byte[] digest) + { + if (_noDigest) + return; + + if (digest == null) + { + _noDigest = true; + _digest = null; + return; + } + + if (_digest == null) + _digest = new byte[128/8]; // 128 bits. + int len = _digest.length; + if (digest.length < len) + len = digest.length; + for (int i = 0; i < len; i++) + _digest[i] ^= digest[i]; + } + + /** + * The SchemaTypeSystem which we're building types on behalf of. + */ + public SchemaTypeSystemImpl sts() + { + if (_target != null) + return _target; + + String name = _givenStsName; + if (name == null && _digest != null) + name = "s" + new String(HexBin.encode(_digest)); + + _target = new SchemaTypeSystemImpl(name); + return _target; + } + + /** + * True if the given URI is a local file + */ + public boolean shouldDownloadURI(String uriString) + { + if (_doingDownloads) + return true; + + if (uriString == null) + return false; + + try + { + URI uri = new URI(uriString); + if (uri.getScheme().equalsIgnoreCase("jar") || + uri.getScheme().equalsIgnoreCase("zip")) + { + // It may be local or not, depending on the embedded URI + String s = uri.getSchemeSpecificPart(); + int i = s.lastIndexOf('!'); + return shouldDownloadURI(i > 0 ? s.substring(0, i) : s); + } + return uri.getScheme().equalsIgnoreCase("file"); + } + catch (Exception e) + { + return false; + } + } + + /** + * Initializer for compatMap. + */ + public void setOptions(XmlOptions options) + { + if (options == null) + { + return; // defaults are all false. + } + + _allowPartial = options.hasOption("COMPILE_PARTIAL_TYPESYSTEM"); + + _compatMap = (Map)options.get(XmlOptions.COMPILE_SUBSTITUTE_NAMES); + _noUpa = options.hasOption(XmlOptions.COMPILE_NO_UPA_RULE) ? true : + !"true".equals(SystemProperties.getProperty("xmlbean.uniqueparticleattribution", "true")); + _noPvr = options.hasOption(XmlOptions.COMPILE_NO_PVR_RULE) ? true : + !"true".equals(SystemProperties.getProperty("xmlbean.particlerestriction", "true")); + _noAnn = options.hasOption(XmlOptions.COMPILE_NO_ANNOTATIONS) ? true : + !"true".equals(SystemProperties.getProperty("xmlbean.schemaannotations", "true")); + _doingDownloads = options.hasOption(XmlOptions.COMPILE_DOWNLOAD_URLS) ? true : + "true".equals(SystemProperties.getProperty("xmlbean.downloadurls", "false")); + _entityResolver = (EntityResolver)options.get(XmlOptions.ENTITY_RESOLVER); + + if (_entityResolver == null) + _entityResolver = ResolverUtil.getGlobalEntityResolver(); + + if (_entityResolver != null) + _doingDownloads = true; + + if (options.hasOption(XmlOptions.COMPILE_MDEF_NAMESPACES)) + { + _mdefNamespaces.addAll((Collection)options.get(XmlOptions.COMPILE_MDEF_NAMESPACES)); + + String local = "##local"; + String any = "##any"; + + if (_mdefNamespaces.contains(local)) + { + _mdefNamespaces.remove(local); + _mdefNamespaces.add(""); + } + if (_mdefNamespaces.contains(any)) + { + _mdefNamespaces.remove(any); + _mdefAll = true; + } + } + } + + /** + * May return null if there is no custom entity resolver. + */ + public EntityResolver getEntityResolver() + { + return _entityResolver; + } + + /** + * True if no unique particle attribution option is set + */ + public boolean noUpa() + { + return _noUpa; + } + + /** + * True if no particle valid (restriciton) option is set + */ + public boolean noPvr() + { + return _noPvr; + } + + /** + * True if annotations should be skipped + */ + public boolean noAnn() + { + return _noAnn; + } + + /** + * True if a partial SchemaTypeSystem should be produced + */ + // EXPERIMENTAL + public boolean allowPartial() + { + return _allowPartial; + } + + /** + * Get count of recovered errors. Not for public. + */ + // EXPERIMENTAL + public int getRecovered() + { + return _recoveredErrors; + } + + /** + * Intercepts XML names and translates them + * through the compat map, if any. + * + * Also looks for a default namespace for global definitions. + */ + private QName compatName(QName name, String chameleonNamespace) + { + // first check for a chameleonNamespace namespace + if (name.getNamespaceURI().length() == 0 && chameleonNamespace != null && chameleonNamespace.length() > 0) + name = new QName(chameleonNamespace, name.getLocalPart()); + + if (_compatMap == null) + return name; + + QName subst = (QName)_compatMap.get(name); + if (subst == null) + return name; + return subst; + } + + /** + * Initializer for the schema config object. + */ + public void setBindingConfig(BindingConfig config) + throws IllegalArgumentException + { + _config = config; + } + + public BindingConfig getBindingConfig() + throws IllegalArgumentException + { + return _config; + } + + /** + * Looks up package override for a namespace URI + */ + public String getPackageOverride(String namespace) + { + if (_config == null) + return null; + return _config.lookupPackageForNamespace(namespace); + } + + /** + * Looks up package override for a namespace URI + */ + public String getJavaPrefix(String namespace) + { + if (_config == null) + return null; + return _config.lookupPrefixForNamespace(namespace); + } + + /** + * Looks up package override for a namespace URI + */ + public String getJavaSuffix(String namespace) + { + if (_config == null) + return null; + return _config.lookupSuffixForNamespace(namespace); + } + + /** + * Looks up configured java name for the given qname. + */ + public String getJavaname(QName qname, int kind) + { + if (_config == null) + return null; + return _config.lookupJavanameForQName(qname, kind); + } + + /* SPELLINGS ======================================================*/ + + private static String crunchName(QName name) + { + // lowercase, and drop namespace. + return name.getLocalPart().toLowerCase(); + } + + void addSpelling(QName name, SchemaComponent comp) + { + _misspelledNames.put(crunchName(name), comp); + } + + SchemaComponent findSpelling(QName name) + { + return (SchemaComponent)_misspelledNames.get(crunchName(name)); + } + + /* NAMESPACES ======================================================*/ + + void addNamespace(String targetNamespace) + { + _namespaces.add(targetNamespace); + } + + String[] getNamespaces() + { + return (String[])_namespaces.toArray(new String[_namespaces.size()]); + } + + boolean linkerDefinesNamespace(String namespace) + { + return _importingLoader.isNamespaceDefined(namespace); + } + + /* TYPES ==========================================================*/ + + SchemaTypeImpl findGlobalType(QName name, String chameleonNamespace, String sourceNamespace) + { + name = compatName(name, chameleonNamespace); + SchemaTypeImpl result = (SchemaTypeImpl)_globalTypes.get(name); + boolean foundOnLoader = false; + if (result == null) + { + result = (SchemaTypeImpl)_importingLoader.findType(name); + foundOnLoader = result != null; + } + if (!foundOnLoader && sourceNamespace != null) + registerDependency(sourceNamespace, name.getNamespaceURI()); + return result; + } + + SchemaTypeImpl findRedefinedGlobalType(QName name, String chameleonNamespace, SchemaTypeImpl redefinedBy) + { + QName redefinedName = redefinedBy.getName(); + name = compatName(name, chameleonNamespace); + if (name.equals(redefinedName)) + { + return (SchemaTypeImpl)_redefinedGlobalTypes.get(redefinedBy); + // BUGBUG: should also link against _importingLoader.findRedefinedType + } + SchemaTypeImpl result = (SchemaTypeImpl)_globalTypes.get(name); + if (result == null) + result = (SchemaTypeImpl)_importingLoader.findType(name); + // no dependency is needed here, necause it's intra-namespace + return result; + } + + void addGlobalType(SchemaTypeImpl type, SchemaTypeImpl redefined) + { + if (type != null) + { + QName name = type.getName(); + SchemaContainer container = getContainer(name.getNamespaceURI()); + assert container != null && container == type.getContainer(); + + if (redefined != null) + { + if (_redefinedGlobalTypes.containsKey(redefined)) + { + if (!ignoreMdef(name)) { + if (_mdefAll) { + warning(XmlErrorCodes.SCHEMA_PROPERTIES$DUPLICATE, + new Object[] { "global type", QNameHelper.pretty(name), ((SchemaType) _redefinedGlobalTypes.get(redefined)).getSourceName() } , + type.getParseObject()); + } else { + error(XmlErrorCodes.SCHEMA_PROPERTIES$DUPLICATE, + new Object[] { "global type", QNameHelper.pretty(name), ((SchemaType) _redefinedGlobalTypes.get(redefined)).getSourceName() } , + type.getParseObject()); + } + } + } + else + { + _redefinedGlobalTypes.put(redefined, type); + container.addRedefinedType(type.getRef()); + } + } + else + { + if (_globalTypes.containsKey(name)) + { + if (!ignoreMdef(name)) { + if (_mdefAll) { + warning(XmlErrorCodes.SCHEMA_PROPERTIES$DUPLICATE, + new Object[] { "global type", QNameHelper.pretty(name), ((SchemaType) _globalTypes.get(name)).getSourceName() }, + type.getParseObject()); + } else { + error(XmlErrorCodes.SCHEMA_PROPERTIES$DUPLICATE, + new Object[] { "global type", QNameHelper.pretty(name), ((SchemaType) _globalTypes.get(name)).getSourceName() }, + type.getParseObject()); + } + } + } + else + { + _globalTypes.put(name, type); + container.addGlobalType(type.getRef()); + addSpelling(name, type); + } + } + } + } + + private boolean ignoreMdef(QName name) + { + return _mdefNamespaces.contains(name.getNamespaceURI()); + } + + SchemaType[] globalTypes() + { return (SchemaType[])_globalTypes.values().toArray(new SchemaType[_globalTypes.size()]); } + + SchemaType[] redefinedGlobalTypes() + { return (SchemaType[])_redefinedGlobalTypes.values().toArray(new SchemaType[_redefinedGlobalTypes.size()]); } + + /* DOCUMENT TYPES =================================================*/ + + SchemaTypeImpl findDocumentType(QName name, String chameleonNamespace, String sourceNamespace) + { + name = compatName(name, chameleonNamespace); + SchemaTypeImpl result = (SchemaTypeImpl)_documentTypes.get(name); + boolean foundOnLoader = false; + if (result == null) + { + result = (SchemaTypeImpl)_importingLoader.findDocumentType(name); + foundOnLoader = result != null; + } + if (!foundOnLoader && sourceNamespace != null) + registerDependency(sourceNamespace, name.getNamespaceURI()); + return result; + } + + void addDocumentType(SchemaTypeImpl type, QName name) + { + if (_documentTypes.containsKey(name)) + { + if (!ignoreMdef(name)) { + if (_mdefAll) { + warning(XmlErrorCodes.SCHEMA_PROPERTIES$DUPLICATE, + new Object[] { "global element", QNameHelper.pretty(name), ((SchemaComponent) _documentTypes.get(name)).getSourceName() }, + type.getParseObject()); + } else { + error(XmlErrorCodes.SCHEMA_PROPERTIES$DUPLICATE, + new Object[] { "global element", QNameHelper.pretty(name), ((SchemaComponent) _documentTypes.get(name)).getSourceName() }, + type.getParseObject()); + } + } + } + else + { + _documentTypes.put(name, type); + SchemaContainer container = getContainer(name.getNamespaceURI()); + assert container != null && container == type.getContainer(); + container.addDocumentType(type.getRef()); + } + } + + SchemaType[] documentTypes() + { return (SchemaType[])_documentTypes.values().toArray(new SchemaType[_documentTypes.size()]); } + + /* ATTRIBUTE TYPES =================================================*/ + + SchemaTypeImpl findAttributeType(QName name, String chameleonNamespace, String sourceNamespace) + { + name = compatName(name, chameleonNamespace); + SchemaTypeImpl result = (SchemaTypeImpl)_attributeTypes.get(name); + boolean foundOnLoader = false; + if (result == null) + { + result = (SchemaTypeImpl)_importingLoader.findAttributeType(name); + foundOnLoader = result != null; + } + if (!foundOnLoader && sourceNamespace != null) + registerDependency(sourceNamespace, name.getNamespaceURI()); + return result; + } + + void addAttributeType(SchemaTypeImpl type, QName name) + { + if (_attributeTypes.containsKey(name)) + { + if (!ignoreMdef(name)) { + if (_mdefAll) { + warning(XmlErrorCodes.SCHEMA_PROPERTIES$DUPLICATE, + new Object[] { "global attribute", QNameHelper.pretty(name), ((SchemaComponent) _attributeTypes.get(name)).getSourceName() }, + type.getParseObject()); + } else { + error(XmlErrorCodes.SCHEMA_PROPERTIES$DUPLICATE, + new Object[] { "global attribute", QNameHelper.pretty(name), ((SchemaComponent) _attributeTypes.get(name)).getSourceName() }, + type.getParseObject()); + } + } + } + else + { + _attributeTypes.put(name, type); + SchemaContainer container = getContainer(name.getNamespaceURI()); + assert container != null && container == type.getContainer(); + container.addAttributeType(type.getRef()); + } + } + + SchemaType[] attributeTypes() + { return (SchemaType[])_attributeTypes.values().toArray(new SchemaType[_attributeTypes.size()]); } + + /* ATTRIBUTES =====================================================*/ + + SchemaGlobalAttributeImpl findGlobalAttribute(QName name, String chameleonNamespace, String sourceNamespace) + { + name = compatName(name, chameleonNamespace); + SchemaGlobalAttributeImpl result = (SchemaGlobalAttributeImpl)_globalAttributes.get(name); + boolean foundOnLoader = false; + if (result == null) + { + result = (SchemaGlobalAttributeImpl)_importingLoader.findAttribute(name); + foundOnLoader = result != null; + } + if (!foundOnLoader && sourceNamespace != null) + registerDependency(sourceNamespace, name.getNamespaceURI()); + return result; + } + + void addGlobalAttribute(SchemaGlobalAttributeImpl attribute) + { + if (attribute != null) + { + QName name = attribute.getName(); + _globalAttributes.put(name, attribute); + addSpelling(name, attribute); + SchemaContainer container = getContainer(name.getNamespaceURI()); + assert container != null && container == attribute.getContainer(); + container.addGlobalAttribute(attribute.getRef()); + } + } + + SchemaGlobalAttribute[] globalAttributes() + { return (SchemaGlobalAttribute[])_globalAttributes.values().toArray(new SchemaGlobalAttribute[_globalAttributes.size()]); } + + /* ELEMENTS =======================================================*/ + + SchemaGlobalElementImpl findGlobalElement(QName name, String chameleonNamespace, String sourceNamespace) + { + name = compatName(name, chameleonNamespace); + SchemaGlobalElementImpl result = (SchemaGlobalElementImpl)_globalElements.get(name); + boolean foundOnLoader = false; + if (result == null) + { + result = (SchemaGlobalElementImpl)_importingLoader.findElement(name); + foundOnLoader = result != null; + } + if (!foundOnLoader && sourceNamespace != null) + registerDependency(sourceNamespace, name.getNamespaceURI()); + return result; + } + + void addGlobalElement(SchemaGlobalElementImpl element) + { + if (element != null) + { + QName name = element.getName(); + _globalElements.put(name, element); + SchemaContainer container = getContainer(name.getNamespaceURI()); + assert container != null && container == element.getContainer(); + container.addGlobalElement(element.getRef()); + addSpelling(name, element); + } + } + + SchemaGlobalElement[] globalElements() + { return (SchemaGlobalElement[])_globalElements.values().toArray(new SchemaGlobalElement[_globalElements.size()]); } + + /* ATTRIBUTE GROUPS ===============================================*/ + + SchemaAttributeGroupImpl findAttributeGroup(QName name, String chameleonNamespace, String sourceNamespace) + { + name = compatName(name, chameleonNamespace); + SchemaAttributeGroupImpl result = (SchemaAttributeGroupImpl)_attributeGroups.get(name); + boolean foundOnLoader = false; + if (result == null) + { + result = (SchemaAttributeGroupImpl)_importingLoader.findAttributeGroup(name); + foundOnLoader = result != null; + } + if (!foundOnLoader && sourceNamespace != null) + registerDependency(sourceNamespace, name.getNamespaceURI()); + return result; + } + + SchemaAttributeGroupImpl findRedefinedAttributeGroup(QName name, String chameleonNamespace, SchemaAttributeGroupImpl redefinedBy) + { + QName redefinitionFor = redefinedBy.getName(); + name = compatName(name, chameleonNamespace); + if (name.equals(redefinitionFor)) + { + return (SchemaAttributeGroupImpl)_redefinedAttributeGroups.get(redefinedBy); + // BUGBUG: should also link against _importingLoader.findRedefinedAttributeGroup + } + SchemaAttributeGroupImpl result = (SchemaAttributeGroupImpl)_attributeGroups.get(name); + if (result == null) + result = (SchemaAttributeGroupImpl)_importingLoader.findAttributeGroup(name); + return result; + } + + void addAttributeGroup(SchemaAttributeGroupImpl attributeGroup, SchemaAttributeGroupImpl redefined) + { + if (attributeGroup != null) + { + QName name = attributeGroup.getName(); + SchemaContainer container = getContainer(name.getNamespaceURI()); + assert container != null && container == attributeGroup.getContainer(); + if (redefined != null) + { + if (_redefinedAttributeGroups.containsKey(redefined)) + { + if (!ignoreMdef(name)) { + if (_mdefAll) { + warning(XmlErrorCodes.SCHEMA_PROPERTIES$DUPLICATE, + new Object[] { "attribute group", QNameHelper.pretty(name), ((SchemaComponent) _redefinedAttributeGroups.get(redefined)).getSourceName() }, + attributeGroup.getParseObject()); + } else { + error(XmlErrorCodes.SCHEMA_PROPERTIES$DUPLICATE, + new Object[] { "attribute group", QNameHelper.pretty(name), ((SchemaComponent) _redefinedAttributeGroups.get(redefined)).getSourceName() }, + attributeGroup.getParseObject()); + } + } + } + else + { + _redefinedAttributeGroups.put(redefined, attributeGroup); + container.addRedefinedAttributeGroup(attributeGroup.getRef()); + } + } + else + { + if (_attributeGroups.containsKey( name )) + { + if (!ignoreMdef(name)) { + if (_mdefAll) { + warning(XmlErrorCodes.SCHEMA_PROPERTIES$DUPLICATE, + new Object[] { "attribute group", QNameHelper.pretty(name), ((SchemaComponent) _attributeGroups.get(name)).getSourceName() }, + attributeGroup.getParseObject()); + } else { + error(XmlErrorCodes.SCHEMA_PROPERTIES$DUPLICATE, + new Object[] { "attribute group", QNameHelper.pretty(name), ((SchemaComponent) _attributeGroups.get(name)).getSourceName() }, + attributeGroup.getParseObject()); + } + } + } + else + { + _attributeGroups.put(attributeGroup.getName(), attributeGroup); + addSpelling(attributeGroup.getName(), attributeGroup); + container.addAttributeGroup(attributeGroup.getRef()); + } + } + } + } + + SchemaAttributeGroup[] attributeGroups() + { return (SchemaAttributeGroup[])_attributeGroups.values().toArray(new SchemaAttributeGroup[_attributeGroups.size()]); } + + SchemaAttributeGroup[] redefinedAttributeGroups() + { return (SchemaAttributeGroup[])_redefinedAttributeGroups.values().toArray(new SchemaAttributeGroup[_redefinedAttributeGroups.size()]); } + + /* MODEL GROUPS ===================================================*/ + + SchemaModelGroupImpl findModelGroup(QName name, String chameleonNamespace, String sourceNamespace) + { + name = compatName(name, chameleonNamespace); + SchemaModelGroupImpl result = (SchemaModelGroupImpl)_modelGroups.get(name); + boolean foundOnLoader = false; + if (result == null) + { + result = (SchemaModelGroupImpl)_importingLoader.findModelGroup(name); + foundOnLoader = result != null; + } + if (!foundOnLoader && sourceNamespace != null) + registerDependency(sourceNamespace, name.getNamespaceURI()); + return result; + } + + SchemaModelGroupImpl findRedefinedModelGroup(QName name, String chameleonNamespace, SchemaModelGroupImpl redefinedBy) + { + QName redefinitionFor = redefinedBy.getName(); + name = compatName(name, chameleonNamespace); + if (name.equals(redefinitionFor)) + { + return (SchemaModelGroupImpl)_redefinedModelGroups.get(redefinedBy); + // BUGBUG: should also link against _importingLoader.findRedefinedModelGroup + } + SchemaModelGroupImpl result = (SchemaModelGroupImpl)_modelGroups.get(name); + if (result == null) + result = (SchemaModelGroupImpl)_importingLoader.findModelGroup(name); + return result; + } + + void addModelGroup(SchemaModelGroupImpl modelGroup, SchemaModelGroupImpl redefined) + { + if (modelGroup != null) + { + QName name = modelGroup.getName(); + SchemaContainer container = getContainer(name.getNamespaceURI()); + assert container != null && container == modelGroup.getContainer(); + if (redefined != null) + { + if (_redefinedModelGroups.containsKey(redefined)) + { + if (!ignoreMdef(name)) { + if (_mdefAll) { + warning(XmlErrorCodes.SCHEMA_PROPERTIES$DUPLICATE, + new Object[] { "model group", QNameHelper.pretty(name), ((SchemaComponent) _redefinedModelGroups.get(redefined)).getSourceName() }, + modelGroup.getParseObject()); + } else { + error(XmlErrorCodes.SCHEMA_PROPERTIES$DUPLICATE, + new Object[] { "model group", QNameHelper.pretty(name), ((SchemaComponent) _redefinedModelGroups.get(redefined)).getSourceName() }, + modelGroup.getParseObject()); + } + } + } + else + { + _redefinedModelGroups.put(redefined, modelGroup); + container.addRedefinedModelGroup(modelGroup.getRef()); + } + } + else + { + if (_modelGroups.containsKey(name)) + { + if (!ignoreMdef(name)) { + if (_mdefAll) { + warning(XmlErrorCodes.SCHEMA_PROPERTIES$DUPLICATE, + new Object[] { "model group", QNameHelper.pretty(name), ((SchemaComponent) _modelGroups.get(name)).getSourceName() }, + modelGroup.getParseObject()); + } else { + error(XmlErrorCodes.SCHEMA_PROPERTIES$DUPLICATE, + new Object[] { "model group", QNameHelper.pretty(name), ((SchemaComponent) _modelGroups.get(name)).getSourceName() }, + modelGroup.getParseObject()); + } + } + } + else + { + _modelGroups.put(modelGroup.getName(), modelGroup); + addSpelling(modelGroup.getName(), modelGroup); + container.addModelGroup(modelGroup.getRef()); + } + } + } + } + + SchemaModelGroup[] modelGroups() + { return (SchemaModelGroup[])_modelGroups.values().toArray(new SchemaModelGroup[_modelGroups.size()]); } + + SchemaModelGroup[] redefinedModelGroups() + { return (SchemaModelGroup[])_redefinedModelGroups.values().toArray(new SchemaModelGroup[_redefinedModelGroups.size()]); } + + /* IDENTITY CONSTRAINTS ===========================================*/ + + SchemaIdentityConstraintImpl findIdConstraint(QName name, String chameleonNamespace, String sourceNamespace) + { + name = compatName(name, chameleonNamespace); + if (sourceNamespace != null) + registerDependency(sourceNamespace, name.getNamespaceURI()); + return (SchemaIdentityConstraintImpl)_idConstraints.get(name); + } + + void addIdConstraint(SchemaIdentityConstraintImpl idc) + { + if (idc != null) + { + QName name = idc.getName(); + SchemaContainer container = getContainer(name.getNamespaceURI()); + assert container != null && container == idc.getContainer(); + if (_idConstraints.containsKey(name)) + { + if (!ignoreMdef(name)) + warning(XmlErrorCodes.SCHEMA_PROPERTIES$DUPLICATE, + new Object[] { "identity constraint", QNameHelper.pretty(name), ((SchemaComponent) _idConstraints.get(name)).getSourceName() }, + idc.getParseObject()); + } + else + { + _idConstraints.put(name, idc); + addSpelling(idc.getName(), idc); + container.addIdentityConstraint(idc.getRef()); + } + } + } + + SchemaIdentityConstraintImpl[] idConstraints() + { return (SchemaIdentityConstraintImpl[])_idConstraints.values().toArray(new SchemaIdentityConstraintImpl[_idConstraints.size()]); } + + /* ANNOTATIONS ===========================================*/ + + void addAnnotation(SchemaAnnotationImpl ann, String targetNamespace) + { + if (ann != null) + { + SchemaContainer container = getContainer(targetNamespace); + assert container != null && container == ann.getContainer(); + _annotations.add(ann); + container.addAnnotation(ann); + } + } + + List annotations() + { return _annotations; } + + /* RECURSION AVOIDANCE ============================================*/ + boolean isProcessing(Object obj) + { + return _processingGroups.contains(obj); + } + + void startProcessing(Object obj) + { + assert(!_processingGroups.contains(obj)); + _processingGroups.add(obj); + } + + void finishProcessing(Object obj) + { + assert(_processingGroups.contains(obj)); + _processingGroups.remove(obj); + } + + Object[] getCurrentProcessing() + { + return _processingGroups.toArray(); + } + + /* JAVAIZATION ====================================================*/ + + Map typesByClassname() + { return Collections.unmodifiableMap(_typesByClassname); } + + void addClassname(String classname, SchemaType type) + { _typesByClassname.put(classname, type); } + + + + /** + * Stack management if (heaven help us) we ever need to do + * nested compilation of schema type system. + */ + private static final class StscStack + { + StscState current; + ArrayList stack = new ArrayList(); + final StscState push() + { + stack.add(current); + current = new StscState(); + return current; + } + final void pop() + { + current = (StscState)stack.get(stack.size() - 1); + stack.remove(stack.size() - 1); + } + } + + private static ThreadLocal tl_stscStack = new ThreadLocal(); + + public static StscState start() + { + StscStack stscStack = (StscStack) tl_stscStack.get(); + + if (stscStack==null) + { + stscStack = new StscStack(); + tl_stscStack.set(stscStack); + } + return stscStack.push(); + } + + public static StscState get() + { + return ((StscStack) tl_stscStack.get()).current; + } + + public static void end() + { + StscStack stscStack = (StscStack) tl_stscStack.get(); + stscStack.pop(); + if (stscStack.stack.size()==0) + tl_stscStack.set(null); // this is required to release all the references in this classloader + // which will enable class unloading and avoid OOM in PermGen + } + + private final static XmlValueRef XMLSTR_PRESERVE = buildString("preserve"); + private final static XmlValueRef XMLSTR_REPLACE = buildString("preserve"); + private final static XmlValueRef XMLSTR_COLLAPSE = buildString("preserve"); + + static final SchemaType[] EMPTY_ST_ARRAY = new SchemaType[0]; + static final SchemaType.Ref[] EMPTY_STREF_ARRAY = new SchemaType.Ref[0]; + + private final static XmlValueRef[] FACETS_NONE = new XmlValueRef[] + { null, null, null, null, null, null, null, null, null, + null, null, null }; + + private final static boolean[] FIXED_FACETS_NONE = new boolean[] + { false, false, false, false, false, false, false, false, false, + false, false, false }; + + private final static XmlValueRef[] FACETS_WS_COLLAPSE = new XmlValueRef[] + { null, null, null, null, null, null, null, null, null, + build_wsstring(SchemaType.WS_COLLAPSE), null, null }; + + private final static boolean[] FIXED_FACETS_WS = new boolean[] + { false, false, false, false, false, false, false, false, false, + true, false, false }; + + final static XmlValueRef[] FACETS_UNION = FACETS_NONE; + final static boolean[] FIXED_FACETS_UNION = FIXED_FACETS_NONE; + final static XmlValueRef[] FACETS_LIST = FACETS_WS_COLLAPSE; + final static boolean[] FIXED_FACETS_LIST = FIXED_FACETS_WS; + + static XmlValueRef build_wsstring(int wsr) + { + switch (wsr) + { + case SchemaType.WS_PRESERVE: + return XMLSTR_PRESERVE; + case SchemaType.WS_REPLACE: + return XMLSTR_REPLACE; + case SchemaType.WS_COLLAPSE: + return XMLSTR_COLLAPSE; + } + return null; + } + + static XmlValueRef buildString(String str) + { + if (str == null) + return null; + + try + { + XmlStringImpl i = new XmlStringImpl(); + i.set(str); + i.setImmutable(); + return new XmlValueRef(i); + } + catch (XmlValueOutOfRangeException e) + { + return null; + } + } + + public void notFoundError(QName itemName, int code, XmlObject loc, boolean recovered) + { + String expected; + String expectedName = QNameHelper.pretty(itemName); + String found = null; + String foundName = null; + String sourceName = null; + + if (recovered) + _recoveredErrors++; + + switch (code) + { + case SchemaType.TYPE: + expected = "type"; + break; + case SchemaType.ELEMENT: + expected = "element"; + break; + case SchemaType.ATTRIBUTE: + expected = "attribute"; + break; + case SchemaType.MODEL_GROUP: + expected = "model group"; + break; + case SchemaType.ATTRIBUTE_GROUP: + expected = "attribute group"; + break; + case SchemaType.IDENTITY_CONSTRAINT: + expected = "identity constraint"; + break; + default: + assert(false); + expected = "definition"; + break; + } + + SchemaComponent foundComponent = findSpelling(itemName); + QName name; + if (foundComponent != null) + { + name = foundComponent.getName(); + if (name != null) + { + switch (foundComponent.getComponentType()) + { + case SchemaComponent.TYPE: + found = "type"; + sourceName = ((SchemaType)foundComponent).getSourceName(); + break; + case SchemaComponent.ELEMENT: + found = "element"; + sourceName = ((SchemaGlobalElement)foundComponent).getSourceName(); + break; + case SchemaComponent.ATTRIBUTE: + found = "attribute"; + sourceName = ((SchemaGlobalAttribute)foundComponent).getSourceName(); + break; + case SchemaComponent.ATTRIBUTE_GROUP: + found = "attribute group"; + break; + case SchemaComponent.MODEL_GROUP: + found = "model group"; + break; + } + + if (sourceName != null) + { + sourceName = sourceName.substring(sourceName.lastIndexOf('/') + 1); + } + + if (!name.equals(itemName)) + { + foundName = QNameHelper.pretty(name); + } + } + } + + if (found == null) + { + // error with no help + error(XmlErrorCodes.SCHEMA_QNAME_RESOLVE, + new Object[] { expected, expectedName }, loc); + } + else { + // error with help + error(XmlErrorCodes.SCHEMA_QNAME_RESOLVE$HELP, + new Object[] { + expected, + expectedName, + found, + (foundName == null ? new Integer(0) : new Integer(1)), + foundName, + (sourceName == null ? new Integer(0) : new Integer(1)), + sourceName + }, + loc); + } + } + + + /** + * Produces the "sourceName" (to be used within the schema project + * source file copies) from the URI of the original source. + * + * Returns null if none. + */ + public String sourceNameForUri(String uri) + { + return (String)_sourceForUri.get(uri); + } + + /** + * Returns the whole sourceCopyMap, mapping URI's that have + * been read to "sourceName" local names that have been used + * to tag the types. + */ + public Map sourceCopyMap() + { + return Collections.unmodifiableMap(_sourceForUri); + } + + /** + * The base URI to use for nice filenames when saving sources. + */ + public void setBaseUri(URI uri) + { + _baseURI = uri; + } + + private final static String PROJECT_URL_PREFIX = "project://local"; + + public String relativize(String uri) + { + return relativize(uri, false); + } + + public String computeSavedFilename(String uri) + { + return relativize(uri, true); + } + + private String relativize(String uri, boolean forSavedFilename) + { + if (uri == null) + return null; + + // deal with things that do not look like absolute uris + if (uri.startsWith("/")) + { + uri = PROJECT_URL_PREFIX + uri.replace('\\', '/'); + } + else + { + // looks like a URL? + int colon = uri.indexOf(':'); + if (colon <= 1 || !uri.substring(0, colon).matches("^\\w+$")) + uri = PROJECT_URL_PREFIX + "/" + uri.replace('\\', '/'); + } + + // now relativize against that... + if (_baseURI != null) + { + try + { + URI relative = _baseURI.relativize(new URI(uri)); + if (!relative.isAbsolute()) + return relative.toString(); + else + uri = relative.toString(); + } + catch (URISyntaxException e) + { + } + } + + if (!forSavedFilename) + return uri; + + int lastslash = uri.lastIndexOf('/'); + String dir = QNameHelper.hexsafe(lastslash == -1 ? "" : uri.substring(0, lastslash)); + + int question = uri.indexOf('?', lastslash + 1); + if (question == -1) + return dir + "/" + uri.substring(lastslash + 1); + + String query = QNameHelper.hexsafe(question == -1 ? "" : uri.substring(question)); + + // if encoded query part is longer than 64 characters, just drop it + if (query.startsWith(QNameHelper.URI_SHA1_PREFIX)) + return dir + "/" + uri.substring(lastslash + 1, question); + else + return dir + "/" + uri.substring(lastslash + 1, question) + query; + } + + /** + * Notes another URI that has been consumed during compilation + * (this is the URI that is in the document .NAME property) + */ + public void addSourceUri(String uri, String nameToUse) + { + if (uri == null) + return; + + if (nameToUse == null) + nameToUse = computeSavedFilename(uri); + + _sourceForUri.put(uri, nameToUse); + } + + /** + * Returns the error listener being filled in during this compilation + */ + public Collection getErrorListener() + { + return _errorListener; + } + + /** + * Returns the schema type loader to use for processing s4s + */ + public SchemaTypeLoader getS4SLoader() + { + return _s4sloader; + } + + Map _sourceForUri = new HashMap(); + URI _baseURI = URI.create(PROJECT_URL_PREFIX + "/"); + SchemaTypeLoader _s4sloader = XmlBeans.typeLoaderForClassLoader(SchemaDocument.class.getClassLoader()); + + public File getSchemasDir() + { + return _schemasDir; + } + + public void setSchemasDir(File _schemasDir) + { + this._schemasDir = _schemasDir; + } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/StscTranslator.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/StscTranslator.java new file mode 100644 index 000000000..2e3fa3af8 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/StscTranslator.java @@ -0,0 +1,1781 @@ +/* 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.QNameSet; +import org.apache.xmlbeans.QNameSetBuilder; +import org.apache.xmlbeans.SchemaAttributeModel; +import org.apache.xmlbeans.SchemaBookmark; +import org.apache.xmlbeans.SchemaGlobalAttribute; +import org.apache.xmlbeans.SchemaGlobalElement; +import org.apache.xmlbeans.SchemaIdentityConstraint; +import org.apache.xmlbeans.SchemaLocalAttribute; +import org.apache.xmlbeans.SchemaParticle; +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.XmlAnySimpleType; +import org.apache.xmlbeans.XmlCursor; +import org.apache.xmlbeans.XmlErrorCodes; +import org.apache.xmlbeans.XmlNonNegativeInteger; +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.XmlPositiveInteger; +import org.apache.xmlbeans.impl.common.QNameHelper; +import org.apache.xmlbeans.impl.common.XMLChar; +import org.apache.xmlbeans.impl.common.XPath; +import org.apache.xmlbeans.impl.values.NamespaceContext; +import org.apache.xmlbeans.impl.values.XmlNonNegativeIntegerImpl; +import org.apache.xmlbeans.impl.values.XmlPositiveIntegerImpl; +import org.apache.xmlbeans.impl.values.XmlValueOutOfRangeException; +import org.apache.xmlbeans.impl.xb.xsdschema.Annotated; +import org.apache.xmlbeans.impl.xb.xsdschema.AnnotationDocument; +import org.apache.xmlbeans.impl.xb.xsdschema.Attribute; +import org.apache.xmlbeans.impl.xb.xsdschema.AttributeGroup; +import org.apache.xmlbeans.impl.xb.xsdschema.Element; +import org.apache.xmlbeans.impl.xb.xsdschema.FieldDocument; +import org.apache.xmlbeans.impl.xb.xsdschema.FormChoice; +import org.apache.xmlbeans.impl.xb.xsdschema.Keybase; +import org.apache.xmlbeans.impl.xb.xsdschema.KeyrefDocument; +import org.apache.xmlbeans.impl.xb.xsdschema.LocalElement; +import org.apache.xmlbeans.impl.xb.xsdschema.LocalSimpleType; +import org.apache.xmlbeans.impl.xb.xsdschema.NamedAttributeGroup; +import org.apache.xmlbeans.impl.xb.xsdschema.NamedGroup; +import org.apache.xmlbeans.impl.xb.xsdschema.RedefineDocument.Redefine; +import org.apache.xmlbeans.impl.xb.xsdschema.SchemaDocument.Schema; +import org.apache.xmlbeans.impl.xb.xsdschema.SimpleType; +import org.apache.xmlbeans.impl.xb.xsdschema.TopLevelAttribute; +import org.apache.xmlbeans.impl.xb.xsdschema.TopLevelComplexType; +import org.apache.xmlbeans.impl.xb.xsdschema.TopLevelElement; +import org.apache.xmlbeans.impl.xb.xsdschema.TopLevelSimpleType; +import org.apache.xmlbeans.soap.SOAPArrayType; + +import javax.xml.namespace.QName; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +public class StscTranslator +{ + private static final QName WSDL_ARRAYTYPE_NAME = + QNameHelper.forLNS("arrayType", "http://schemas.xmlsoap.org/wsdl/"); + private static final String FORM_QUALIFIED = "qualified"; + + public static void addAllDefinitions(StscImporter.SchemaToProcess[] schemasAndChameleons) + { + // Build all redefine objects + List redefinitions = new ArrayList(); + for (int i = 0; i < schemasAndChameleons.length; i++) + { + List redefines = schemasAndChameleons[i].getRedefines(); + if (redefines != null) + { + List redefineObjects = schemasAndChameleons[i].getRedefineObjects(); + Iterator it = redefines.iterator(); + Iterator ito = redefineObjects.iterator(); + for (; it.hasNext(); ) + { + assert ito.hasNext() : + "The array of redefines and redefine objects have to have the same length"; + redefinitions.add(new RedefinitionHolder( + (StscImporter.SchemaToProcess) it.next(), + (Redefine) ito.next())); + } + } + } + RedefinitionMaster globalRedefinitions = new RedefinitionMaster((RedefinitionHolder[]) + redefinitions.toArray(new RedefinitionHolder[redefinitions.size()])); + + StscState state = StscState.get(); + for (int j = 0; j < schemasAndChameleons.length; j++) + { + Schema schema = schemasAndChameleons[j].getSchema(); + String givenTargetNamespace = schemasAndChameleons[j].getChameleonNamespace(); + + // quick check for a few unsupported features + + if (schema.sizeOfNotationArray() > 0) + { + state.warning("Schema is not yet supported for this release.", XmlErrorCodes.UNSUPPORTED_FEATURE, schema.getNotationArray(0)); + } + + // figure namespace (taking into account chameleons) + String targetNamespace = schema.getTargetNamespace(); + boolean chameleon = false; + if (givenTargetNamespace != null && targetNamespace == null) + { + targetNamespace = givenTargetNamespace; + chameleon = true; + } + if (targetNamespace == null) + targetNamespace = ""; + + //SchemaContainer container = null; + if (targetNamespace.length() > 0 || !isEmptySchema(schema)) + { + state.registerContribution(targetNamespace, schema.documentProperties().getSourceName()); + state.addNewContainer(targetNamespace); + //container = state.getContainer(targetNamespace); + } + + List redefChain = new ArrayList(); + TopLevelComplexType[] complexTypes = schema.getComplexTypeArray(); + for (int i = 0; i < complexTypes.length; i++) + { + TopLevelComplexType type = complexTypes[i]; + TopLevelComplexType redef; + // 1. Traverse the list of redefining Schemas putting all redefinitions + // of this type in a List + RedefinitionHolder[] rhArray = globalRedefinitions.getComplexTypeRedefinitions( + type.getName(), schemasAndChameleons[j]); + for (int k = 0; k < rhArray.length; k++) + { + // In error cases, some redefinitions were nulled out in the list + // which is why we need to perform this check + if (rhArray[k] != null) + { + redef = rhArray[k].redefineComplexType(type.getName()); + assert redef != null; // This was already checked + redefChain.add(type); + type = redef; + } + } + + SchemaTypeImpl t = translateGlobalComplexType(type, targetNamespace, chameleon, redefChain.size() > 0); + state.addGlobalType(t, null); + SchemaTypeImpl r; + // 2. Traverse the List built in step 1 in reverse and add all the + // types in it to the list of redefined types + for (int k = redefChain.size() - 1; k >= 0; k--) + { + redef = (TopLevelComplexType) redefChain.remove(k); + r = translateGlobalComplexType(redef, targetNamespace, chameleon, k > 0); + state.addGlobalType(r, t); + t = r; + } + } + + TopLevelSimpleType[] simpleTypes = schema.getSimpleTypeArray(); + for (int i = 0; i < simpleTypes.length; i++) + { + TopLevelSimpleType type = simpleTypes[i]; + TopLevelSimpleType redef; + RedefinitionHolder[] rhArray = globalRedefinitions.getSimpleTypeRedefinitions( + type.getName(), schemasAndChameleons[j]); + for (int k = 0; k < rhArray.length; k++) + { + // In error cases, some redefinitions were nulled out in the list + // which is why we need to perform this check + if (rhArray[k] != null) + { + redef = rhArray[k].redefineSimpleType(type.getName()); + assert redef != null; // This was already checked + redefChain.add(type); + type = redef; + } + } + + SchemaTypeImpl t = translateGlobalSimpleType(type, targetNamespace, chameleon,redefChain.size() > 0); + state.addGlobalType(t, null); + SchemaTypeImpl r; + for (int k = redefChain.size()-1; k >= 0; k--) + { + redef = (TopLevelSimpleType) redefChain.remove(k); + r = translateGlobalSimpleType(redef, targetNamespace, chameleon, k > 0); + state.addGlobalType(r, t); + t = r; + } + } + + TopLevelElement[] elements = schema.getElementArray(); + for (int i = 0; i < elements.length; i++) + { + TopLevelElement element = elements[i]; + state.addDocumentType(translateDocumentType(element, targetNamespace, chameleon), QNameHelper.forLNS(element.getName(), targetNamespace)); + } + + TopLevelAttribute[] attributes = schema.getAttributeArray(); + for (int i = 0; i < attributes.length ; i++) + { + TopLevelAttribute attribute = attributes[i]; + state.addAttributeType(translateAttributeType(attribute, targetNamespace, chameleon), QNameHelper.forLNS(attribute.getName(), targetNamespace)); + } + + NamedGroup[] modelgroups = schema.getGroupArray(); + for (int i = 0; i < modelgroups.length; i++) + { + NamedGroup group = modelgroups[i]; + NamedGroup redef; + RedefinitionHolder[] rhArray = globalRedefinitions.getModelGroupRedefinitions( + group.getName(), schemasAndChameleons[j]); + for (int k = 0; k < rhArray.length; k++) + { + // In error cases, some redefinitions were nulled out in the list + // which is why we need to perform this check + if (rhArray[k] != null) + { + redef = rhArray[k].redefineModelGroup(group.getName()); + assert redef != null; // This was already checked + redefChain.add(group); + group = redef; + } + } + + SchemaModelGroupImpl g = translateModelGroup(group, targetNamespace, chameleon, redefChain.size() > 0); + state.addModelGroup(g, null); + SchemaModelGroupImpl r; + for (int k = redefChain.size()-1; k >= 0; k--) + { + redef = (NamedGroup) redefChain.remove(k); + r = translateModelGroup(redef, targetNamespace, chameleon, k > 0); + state.addModelGroup(r, g); + g = r; + } + } + + NamedAttributeGroup[] attrgroups = schema.getAttributeGroupArray(); + for (int i = 0; i < attrgroups.length; i++) + { + NamedAttributeGroup group = attrgroups[i]; + NamedAttributeGroup redef; + RedefinitionHolder[] rhArray = globalRedefinitions.getAttributeGroupRedefinitions( + group.getName(), schemasAndChameleons[j]); + for (int k = 0; k < rhArray.length; k++) + { + // In error cases, some redefinitions were nulled out in the list + // which is why we need to perform this check + if (rhArray[k] != null) + { + redef = rhArray[k].redefineAttributeGroup(group.getName()); + assert redef != null; // This was already checked + redefChain.add(group); + group = redef; + } + } + + SchemaAttributeGroupImpl g = translateAttributeGroup(group, targetNamespace, chameleon, redefChain.size() > 0); + state.addAttributeGroup(g, null); + SchemaAttributeGroupImpl r; + for (int k = redefChain.size()-1; k >= 0; k--) + { + redef = (NamedAttributeGroup) redefChain.remove(k); + r = translateAttributeGroup(redef, targetNamespace, chameleon, k > 0); + state.addAttributeGroup(r, g); + g = r; + } + } + + AnnotationDocument.Annotation[] annotations = schema.getAnnotationArray(); + for (int i = 0; i < annotations.length; i++) + state.addAnnotation(SchemaAnnotationImpl.getAnnotation(state.getContainer(targetNamespace), schema, annotations[i]), targetNamespace); + } + + for (int i = 0; i < redefinitions.size(); i++) + ((RedefinitionHolder) redefinitions.get(i)).complainAboutMissingDefinitions(); + } + + private static class RedefinitionHolder + { + // record redefinitions + private Map stRedefinitions = Collections.EMPTY_MAP; + private Map ctRedefinitions = Collections.EMPTY_MAP; + private Map agRedefinitions = Collections.EMPTY_MAP; + private Map mgRedefinitions = Collections.EMPTY_MAP; + private String schemaLocation = ""; + private StscImporter.SchemaToProcess schemaRedefined; + + // first build set of redefined components + RedefinitionHolder(StscImporter.SchemaToProcess schemaToProcess, Redefine redefine) + { + schemaRedefined = schemaToProcess; + if (redefine != null) + { + StscState state = StscState.get(); + + stRedefinitions = new HashMap(); + ctRedefinitions = new HashMap(); + agRedefinitions = new HashMap(); + mgRedefinitions = new HashMap(); + if (redefine.getSchemaLocation() != null) + schemaLocation = redefine.getSchemaLocation(); + + TopLevelComplexType[] complexTypes = redefine.getComplexTypeArray(); + for (int i = 0; i < complexTypes.length; i++) + { + if (complexTypes[i].getName() != null) + { + // KHK: which rule? sch-props-correct.2? + if (ctRedefinitions.containsKey(complexTypes[i].getName())) + state.error("Duplicate type redefinition: " + complexTypes[i].getName(), XmlErrorCodes.DUPLICATE_GLOBAL_TYPE, null); + else + ctRedefinitions.put(complexTypes[i].getName(), complexTypes[i]); + } + } + + TopLevelSimpleType[] simpleTypes = redefine.getSimpleTypeArray(); + for (int i = 0; i < simpleTypes.length; i++) + { + if (simpleTypes[i].getName() != null) + { + if (stRedefinitions.containsKey(simpleTypes[i].getName())) + state.error("Duplicate type redefinition: " + simpleTypes[i].getName(), XmlErrorCodes.DUPLICATE_GLOBAL_TYPE, null); + else + stRedefinitions.put(simpleTypes[i].getName(), simpleTypes[i]); + } + } + + NamedGroup[] modelgroups = redefine.getGroupArray(); + for (int i = 0; i < modelgroups.length; i++) + { + if (modelgroups[i].getName() != null) + { + if (mgRedefinitions.containsKey(modelgroups[i].getName())) + state.error("Duplicate type redefinition: " + modelgroups[i].getName(), XmlErrorCodes.DUPLICATE_GLOBAL_TYPE, null); + else + mgRedefinitions.put(modelgroups[i].getName(), modelgroups[i]); + } + } + + NamedAttributeGroup[] attrgroups = redefine.getAttributeGroupArray(); + for (int i = 0; i < attrgroups.length; i++) + { + if (attrgroups[i].getName() != null) + { + if (agRedefinitions.containsKey(attrgroups[i].getName())) + state.error("Duplicate type redefinition: " + attrgroups[i].getName(), XmlErrorCodes.DUPLICATE_GLOBAL_TYPE, null); + else + agRedefinitions.put(attrgroups[i].getName(), attrgroups[i]); + } + } + } + } + + public TopLevelSimpleType redefineSimpleType(String name) + { + if (name == null || !stRedefinitions.containsKey(name)) + return null; + return (TopLevelSimpleType)stRedefinitions.remove(name); + } + + public TopLevelComplexType redefineComplexType(String name) + { + if (name == null || !ctRedefinitions.containsKey(name)) + return null; + return (TopLevelComplexType)ctRedefinitions.remove(name); + } + + public NamedGroup redefineModelGroup(String name) + { + if (name == null || !mgRedefinitions.containsKey(name)) + return null; + return (NamedGroup)mgRedefinitions.remove(name); + } + + public NamedAttributeGroup redefineAttributeGroup(String name) + { + if (name == null || !agRedefinitions.containsKey(name)) + return null; + return (NamedAttributeGroup)agRedefinitions.remove(name); + } + + public void complainAboutMissingDefinitions() + { + if (stRedefinitions.isEmpty() && ctRedefinitions.isEmpty() && + agRedefinitions.isEmpty() && mgRedefinitions.isEmpty()) + return; + + StscState state = StscState.get(); + + for (Iterator i = stRedefinitions.keySet().iterator(); i.hasNext(); ) + { + String name = (String)i.next(); + state.error("Redefined simple type " + name + " not found in " + schemaLocation, XmlErrorCodes.GENERIC_ERROR, (XmlObject)stRedefinitions.get(name)); + } + + for (Iterator i = ctRedefinitions.keySet().iterator(); i.hasNext(); ) + { + String name = (String)i.next(); + state.error("Redefined complex type " + name + " not found in " + schemaLocation, XmlErrorCodes.GENERIC_ERROR, (XmlObject)ctRedefinitions.get(name)); + } + + for (Iterator i = agRedefinitions.keySet().iterator(); i.hasNext(); ) + { + String name = (String)i.next(); + state.error("Redefined attribute group " + name + " not found in " + schemaLocation, XmlErrorCodes.GENERIC_ERROR, (XmlObject)agRedefinitions.get(name)); + } + + for (Iterator i = mgRedefinitions.keySet().iterator(); i.hasNext(); ) + { + String name = (String)i.next(); + state.error("Redefined model group " + name + " not found in " + schemaLocation, XmlErrorCodes.GENERIC_ERROR, (XmlObject)mgRedefinitions.get(name)); + } + } + } + + /** + * This is used to aggregate all redefinitions for a specific component name. + * The idea is to record the list of <redefine%gt; sections that could + * potentially redefine this component. When the list of actual redefinitions + * is requested, the potential redefinitions are first filtered based on + * accessibilty of the schema currently being processed from the redefining Schemas + * and then topologically sorted based on the inclusion relationship to + * ensure that redefinitions are applied in the right order. + */ + private static class RedefinitionMaster + { + // record redefinitions + private Map stRedefinitions = Collections.EMPTY_MAP; + private Map ctRedefinitions = Collections.EMPTY_MAP; + private Map agRedefinitions = Collections.EMPTY_MAP; + private Map mgRedefinitions = Collections.EMPTY_MAP; + private static final RedefinitionHolder[] EMPTY_REDEFINTION_HOLDER_ARRAY = + new RedefinitionHolder[0]; + + RedefinitionMaster(RedefinitionHolder[] redefHolders) + { + if (redefHolders.length > 0) + { + stRedefinitions = new HashMap(); + ctRedefinitions = new HashMap(); + agRedefinitions = new HashMap(); + mgRedefinitions = new HashMap(); + + for (int i = 0; i < redefHolders.length; i++) + { + RedefinitionHolder redefHolder = redefHolders[i]; + for (Iterator it = redefHolder.stRedefinitions.keySet().iterator(); it.hasNext();) + { + Object key = it.next(); + List redefinedIn = (List) stRedefinitions.get(key); + if (redefinedIn == null) + { + redefinedIn = new ArrayList(); + stRedefinitions.put(key, redefinedIn); + } + redefinedIn.add(redefHolders[i]); + } + for (Iterator it = redefHolder.ctRedefinitions.keySet().iterator(); it.hasNext();) + { + Object key = it.next(); + List redefinedIn = (List) ctRedefinitions.get(key); + if (redefinedIn == null) + { + redefinedIn = new ArrayList(); + ctRedefinitions.put(key, redefinedIn); + } + redefinedIn.add(redefHolders[i]); + } + for (Iterator it = redefHolder.agRedefinitions.keySet().iterator(); it.hasNext();) + { + Object key = it.next(); + List redefinedIn = (List) agRedefinitions.get(key); + if (redefinedIn == null) + { + redefinedIn = new ArrayList(); + agRedefinitions.put(key, redefinedIn); + } + redefinedIn.add(redefHolders[i]); + } + for (Iterator it = redefHolder.mgRedefinitions.keySet().iterator(); it.hasNext();) + { + Object key = it.next(); + List redefinedIn = (List) mgRedefinitions.get(key); + if (redefinedIn == null) + { + redefinedIn = new ArrayList(); + mgRedefinitions.put(key, redefinedIn); + } + redefinedIn.add(redefHolders[i]); + } + } + } + } + + RedefinitionHolder[] getSimpleTypeRedefinitions(String name, + StscImporter.SchemaToProcess schema) + { + List redefines = (List) stRedefinitions.get(name); + if (redefines == null) + return EMPTY_REDEFINTION_HOLDER_ARRAY; + return doTopologicalSort(redefines, schema, name, SIMPLE_TYPE); + } + + RedefinitionHolder[] getComplexTypeRedefinitions(String name, + StscImporter.SchemaToProcess schema) + { + List redefines = (List) ctRedefinitions.get(name); + if (redefines == null) + return EMPTY_REDEFINTION_HOLDER_ARRAY; + return doTopologicalSort(redefines, schema, name, COMPLEX_TYPE); + } + + RedefinitionHolder[] getAttributeGroupRedefinitions(String name, + StscImporter.SchemaToProcess schema) + { + List redefines = (List) agRedefinitions.get(name); + if (redefines == null) + return EMPTY_REDEFINTION_HOLDER_ARRAY; + return doTopologicalSort(redefines, schema, name, ATTRIBUTE_GROUP); + } + + RedefinitionHolder[] getModelGroupRedefinitions(String name, + StscImporter.SchemaToProcess schema) + { + List redefines = (List) mgRedefinitions.get(name); + if (redefines == null) + return EMPTY_REDEFINTION_HOLDER_ARRAY; + return doTopologicalSort(redefines, schema, name, MODEL_GROUP); + } + + private final static short SIMPLE_TYPE = 1; + private final static short COMPLEX_TYPE = 2; + private final static short MODEL_GROUP = 3; + private final static short ATTRIBUTE_GROUP = 4; + + private RedefinitionHolder[] doTopologicalSort(List genericRedefines, + StscImporter.SchemaToProcess schema, String name, short componentType) + { + // We have a list of files that redefine this name + // Filter out the ones that don't redefine this file in particular + RedefinitionHolder[] specificRedefines = new RedefinitionHolder[genericRedefines.size()]; + int n = 0; + for (int i = 0; i < genericRedefines.size(); i++) + { + RedefinitionHolder h = (RedefinitionHolder) genericRedefines.get(i); + if (h.schemaRedefined == schema || + h.schemaRedefined.indirectIncludes(schema)) + specificRedefines[n++] = h; + } + // Now we have the list of files that specifically redefine the + // name in the file that we are looking for + // Sort this list into topological order to get the right order + // and figure out if there are multiple redefinitions involved + RedefinitionHolder[] sortedRedefines = new RedefinitionHolder[n]; + int[] numberOfIncludes = new int[n]; + // Just count the number of inclusions for each redefinition + for (int i = 0; i < n-1; i++) + { + RedefinitionHolder current = specificRedefines[i]; + for (int j = i + 1; j < n; j++) + { + if (current.schemaRedefined.indirectIncludes(specificRedefines[j].schemaRedefined)) + numberOfIncludes[i]++; + if (specificRedefines[j].schemaRedefined.indirectIncludes(current.schemaRedefined)) + numberOfIncludes[j]++; + } + } + // Eliminate members one by one, according to the number of schemas + // that they include, to complete the sort + int position = 0; + boolean errorReported = false; + while (position < n) + { + int index = -1; + for (int i = 0; i < numberOfIncludes.length; i++) + if (numberOfIncludes[i] == 0) + { + if (index < 0) + index = i; + } + if (index < 0) + { + // Error! Circular redefinition + if (!errorReported) + { + StringBuffer fileNameList = new StringBuffer(); + XmlObject location = null; + for (int i = 0; i < n; i++) + if (specificRedefines[i] != null) + { + fileNameList.append(specificRedefines[i].schemaLocation). + append(',').append(' '); + if (location == null) + location = locationFromRedefinitionAndCode( + specificRedefines[i], name, componentType); + } + StscState.get().error("Detected circular redefinition of " + + componentNameFromCode(componentType) + " \"" + name + + "\"; Files involved: " + fileNameList.toString(), + XmlErrorCodes.GENERIC_ERROR, location); + errorReported = true; + } + int min = n; + for (int i = 0; i < n; i++) + if (numberOfIncludes[i] > 0 && numberOfIncludes[i] < min) + { + min = numberOfIncludes[i]; + index = i; + } + numberOfIncludes[index]--; + } + else + { + assert specificRedefines[index] != null; + sortedRedefines[position++] = specificRedefines[index]; + for (int i = 0; i < n; i++) + if (specificRedefines[i] != null && + specificRedefines[i].schemaRedefined. + indirectIncludes(specificRedefines[index]. + schemaRedefined)) + numberOfIncludes[i]--; + specificRedefines[index] = null; + numberOfIncludes[index]--; + } + } + // Nice. We now have all the redefinitions of this name in the list + // Each one has to transitively redefine the one before, otherwise + // it means we are attepting two different redefinitions for the same + // component + for (int i = 1; i < n; i++) + { + // Find the previous index with non-null Schema + // Since i is never 0, such index always exists + int j; + for (j = i-1; j >= 0; j--) + if (sortedRedefines[j] != null) + break; + + if (!sortedRedefines[i].schemaRedefined.indirectIncludes( + sortedRedefines[j].schemaRedefined)) + { + StscState.get().error("Detected multiple redefinitions of " + + componentNameFromCode(componentType) + + " \"" + name + "\"; Files involved: " + + sortedRedefines[j].schemaRedefined.getSourceName() + ", " + + sortedRedefines[i].schemaRedefined.getSourceName(), + XmlErrorCodes.DUPLICATE_GLOBAL_TYPE, + locationFromRedefinitionAndCode(sortedRedefines[i], name, componentType)); + // Ignore this redefinition + switch (componentType) + { + case SIMPLE_TYPE: + sortedRedefines[i].redefineSimpleType(name); break; + case COMPLEX_TYPE: + sortedRedefines[i].redefineComplexType(name); break; + case ATTRIBUTE_GROUP: + sortedRedefines[i].redefineAttributeGroup(name); break; + case MODEL_GROUP: + sortedRedefines[i].redefineModelGroup(name); break; + } + sortedRedefines[i] = null; + } + } + + return sortedRedefines; + } + + private String componentNameFromCode(short code) + { + String componentName; + switch (code) + { + case SIMPLE_TYPE: componentName = "simple type"; break; + case COMPLEX_TYPE: componentName = "complex type"; break; + case MODEL_GROUP: componentName = "model group"; break; + case ATTRIBUTE_GROUP: componentName = "attribute group"; break; + default: componentName = ""; + } + return componentName; + } + + private XmlObject locationFromRedefinitionAndCode(RedefinitionHolder redefinition, + String name, short code) + { + XmlObject location; + switch (code) + { + case SIMPLE_TYPE: + location = (XmlObject) redefinition.stRedefinitions.get(name); + break; + case COMPLEX_TYPE: + location = (XmlObject) redefinition.ctRedefinitions.get(name); + break; + case MODEL_GROUP: + location = (XmlObject) redefinition.mgRedefinitions.get(name); + break; + case ATTRIBUTE_GROUP: + location = (XmlObject) redefinition.agRedefinitions.get(name); + break; + default: + location = null; + } + return location; + } + } + + private static String findFilename(XmlObject xobj) + { + return StscState.get().sourceNameForUri(xobj.documentProperties().getSourceName()); + } + + private static SchemaTypeImpl translateDocumentType ( TopLevelElement xsdType, String targetNamespace, boolean chameleon ) + { + SchemaTypeImpl sType = new SchemaTypeImpl( StscState.get().getContainer(targetNamespace) ); + + sType.setDocumentType(true); + sType.setParseContext( xsdType, targetNamespace, chameleon, null, null, false); + sType.setFilename( findFilename( xsdType ) ); + + return sType; + } + + private static SchemaTypeImpl translateAttributeType ( TopLevelAttribute xsdType, String targetNamespace, boolean chameleon ) + { + SchemaTypeImpl sType = new SchemaTypeImpl( StscState.get().getContainer(targetNamespace) ); + + sType.setAttributeType(true); + sType.setParseContext( xsdType, targetNamespace, chameleon, null, null, false); + sType.setFilename( findFilename( xsdType ) ); + + return sType; + } + + private static SchemaTypeImpl translateGlobalComplexType(TopLevelComplexType xsdType, String targetNamespace, boolean chameleon, boolean redefinition) + { + StscState state = StscState.get(); + + String localname = xsdType.getName(); + if (localname == null) + { + state.error(XmlErrorCodes.MISSING_NAME, new Object[] { "global type" }, xsdType); + // recovery: ignore unnamed types. + return null; + } + if (!XMLChar.isValidNCName(localname)) + { + state.error(XmlErrorCodes.INVALID_VALUE, new Object[] { localname, "name" }, xsdType.xgetName()); + // recovery: let the name go through anyway. + } + + QName name = QNameHelper.forLNS(localname, targetNamespace); + + if (isReservedTypeName(name)) + { + state.warning(XmlErrorCodes.RESERVED_TYPE_NAME, new Object[] { QNameHelper.pretty(name) }, xsdType); + return null; + } + // System.err.println("Recording type " + QNameHelper.pretty(name)); + + SchemaTypeImpl sType = new SchemaTypeImpl(state.getContainer(targetNamespace)); + sType.setParseContext(xsdType, targetNamespace, chameleon, null, null, redefinition); + sType.setFilename(findFilename(xsdType)); + sType.setName(QNameHelper.forLNS(localname, targetNamespace)); + sType.setAnnotation(SchemaAnnotationImpl.getAnnotation(state.getContainer(targetNamespace), xsdType)); + sType.setUserData(getUserData(xsdType)); + return sType; + } + + private static SchemaTypeImpl translateGlobalSimpleType(TopLevelSimpleType xsdType, String targetNamespace, boolean chameleon, boolean redefinition) + { + StscState state = StscState.get(); + + String localname = xsdType.getName(); + if (localname == null) + { + state.error(XmlErrorCodes.MISSING_NAME, new Object[] { "global type" }, xsdType); + // recovery: ignore unnamed types. + return null; + } + if (!XMLChar.isValidNCName(localname)) + { + state.error(XmlErrorCodes.INVALID_VALUE, new Object[] { localname, "name" }, xsdType.xgetName()); + // recovery: let the name go through anyway. + } + + QName name = QNameHelper.forLNS(localname, targetNamespace); + + if (isReservedTypeName(name)) + { + state.warning(XmlErrorCodes.RESERVED_TYPE_NAME, new Object[] { QNameHelper.pretty(name) }, xsdType); + return null; + } + // System.err.println("Recording type " + QNameHelper.pretty(name)); + + SchemaTypeImpl sType = new SchemaTypeImpl(state.getContainer(targetNamespace)); + sType.setSimpleType(true); + sType.setParseContext(xsdType, targetNamespace, chameleon, null, null, redefinition); + sType.setFilename(findFilename(xsdType)); + sType.setName(name); + sType.setAnnotation(SchemaAnnotationImpl.getAnnotation(state.getContainer(targetNamespace), xsdType)); + sType.setUserData(getUserData(xsdType)); + return sType; + } + + /*package*/ static SchemaTypeImpl translateAnonymousSimpleType(SimpleType typedef, + String targetNamespace, boolean chameleon, String elemFormDefault, + String attFormDefault, List anonymousTypes, SchemaType outerType) + { + StscState state = StscState.get(); + SchemaTypeImpl sType = new SchemaTypeImpl(state.getContainer(targetNamespace)); + sType.setSimpleType(true); + sType.setParseContext(typedef, targetNamespace, chameleon, + elemFormDefault, attFormDefault, false); + sType.setOuterSchemaTypeRef(outerType.getRef()); + sType.setAnnotation(SchemaAnnotationImpl.getAnnotation(state.getContainer(targetNamespace), typedef)); + sType.setUserData(getUserData(typedef)); + anonymousTypes.add(sType); + return sType; + } + + static FormChoice findElementFormDefault(XmlObject obj) + { + XmlCursor cur = obj.newCursor(); + while (cur.getObject().schemaType() != Schema.type) + if (!cur.toParent()) + return null; + return ((Schema)cur.getObject()).xgetElementFormDefault(); + } + + public static boolean uriMatch(String s1, String s2) + { + if (s1 == null) + return s2 == null || s2.equals(""); + if (s2 == null) + return s1.equals(""); + return s1.equals(s2); + } + + public static void copyGlobalElementToLocalElement(SchemaGlobalElement referenced, SchemaLocalElementImpl target ) + { + + target.setNameAndTypeRef(referenced.getName(), referenced.getType().getRef()); + target.setNillable(referenced.isNillable()); + target.setDefault(referenced.getDefaultText(), referenced.isFixed(), ((SchemaGlobalElementImpl)referenced).getParseObject()); + target.setIdentityConstraints(((SchemaLocalElementImpl)referenced).getIdentityConstraintRefs()); + target.setBlock(referenced.blockExtension(), referenced.blockRestriction(), referenced.blockSubstitution()); + target.setAbstract(referenced.isAbstract()); + target.setTransitionRules(((SchemaParticle)referenced).acceptedStartNames(), + ((SchemaParticle)referenced).isSkippable()); + target.setAnnotation(referenced.getAnnotation()); + } + + public static void copyGlobalAttributeToLocalAttribute(SchemaGlobalAttributeImpl referenced, SchemaLocalAttributeImpl target ) + { + target.init( + referenced.getName(), referenced.getTypeRef(), referenced.getUse(), + referenced.getDefaultText(), + referenced.getParseObject(), referenced._defaultValue, + referenced.isFixed(), + referenced.getWSDLArrayType(), + referenced.getAnnotation(), null); + } + + /** + * Translates a local or global schema element. + */ + // check rule 3.3.3 + // http://www.w3c.org/TR/#section-Constraints-on-XML-Representations-of-Element-Declarations + public static SchemaLocalElementImpl translateElement( + Element xsdElt, String targetNamespace, boolean chameleon, + String elemFormDefault, String attFormDefault, + List anonymousTypes, SchemaType outerType) + { + StscState state = StscState.get(); + + SchemaTypeImpl sgHead = null; + + // translate sg head + if (xsdElt.isSetSubstitutionGroup()) + { + sgHead = state.findDocumentType(xsdElt.getSubstitutionGroup(), + ((SchemaTypeImpl)outerType).getChameleonNamespace(), targetNamespace); + + if (sgHead != null) + StscResolver.resolveType(sgHead); + } + + String name = xsdElt.getName(); + QName ref = xsdElt.getRef(); + + + if (ref != null && name != null) + { + // if (name.equals(ref.getLocalPart()) && uriMatch(targetNamespace, ref.getNamespaceURI())) + // state.warning("Element " + name + " specifies both a ref and a name", XmlErrorCodes.ELEMENT_EXTRA_REF, xsdElt.xgetRef()); + // else + state.error(XmlErrorCodes.SCHEMA_ELEM$REF_OR_NAME_HAS_BOTH, new Object[] { name }, xsdElt.xgetRef()); + // ignore name + name = null; + } + if (ref == null && name == null) + { + state.error(XmlErrorCodes.SCHEMA_ELEM$REF_OR_NAME_HAS_NEITHER, null, xsdElt); + // recovery: ignore this element + return null; + } + if (name != null && !XMLChar.isValidNCName(name)) + { + state.error(XmlErrorCodes.INVALID_VALUE, new Object[] { name, "name" }, xsdElt.xgetName()); + // recovery: let the name go through anyway. + } + + if (ref != null) + { + if (xsdElt.getType() != null) + { + state.error(XmlErrorCodes.SCHEMA_ELEM$REF_FEATURES, new Object[] { "type" }, xsdElt.xgetType()); + // recovery: let the name go through anyway. + } + + if (xsdElt.getSimpleType() != null) + { + state.error(XmlErrorCodes.SCHEMA_ELEM$REF_FEATURES, new Object[] { "" }, xsdElt.getSimpleType()); + // recovery: let the name go through anyway. + } + + if (xsdElt.getComplexType() != null) + { + state.error(XmlErrorCodes.SCHEMA_ELEM$REF_FEATURES, new Object[] { "" }, xsdElt.getComplexType()); + // recovery: let the name go through anyway. + } + + if (xsdElt.getForm() != null) + { + state.error(XmlErrorCodes.SCHEMA_ELEM$REF_FEATURES, new Object[] { "form" }, xsdElt.xgetForm()); + // recovery: let the name go through anyway. + } + + if (xsdElt.sizeOfKeyArray() > 0) + { + state.warning(XmlErrorCodes.SCHEMA_ELEM$REF_FEATURES, new Object[] { "" }, xsdElt); + // recovery: ignore + } + + if (xsdElt.sizeOfKeyrefArray() > 0) + { + state.warning(XmlErrorCodes.SCHEMA_ELEM$REF_FEATURES, new Object[] { "" }, xsdElt); + // recovery: ignore + } + + if (xsdElt.sizeOfUniqueArray() > 0) + { + state.warning(XmlErrorCodes.SCHEMA_ELEM$REF_FEATURES, new Object[] { "" }, xsdElt); + // recovery: ignore + } + + if (xsdElt.isSetDefault()) + { + state.warning(XmlErrorCodes.SCHEMA_ELEM$REF_FEATURES, new Object[] { "default" }, xsdElt.xgetDefault()); + // recovery: ignore + } + + if (xsdElt.isSetFixed()) + { + state.warning(XmlErrorCodes.SCHEMA_ELEM$REF_FEATURES, new Object[] { "fixed" }, xsdElt.xgetFixed()); + // recovery: ignore + } + + if (xsdElt.isSetBlock()) + { + state.warning(XmlErrorCodes.SCHEMA_ELEM$REF_FEATURES, new Object[] { "block" }, xsdElt.xgetBlock()); + // recovery: ignore + } + + if (xsdElt.isSetNillable()) + { + state.warning(XmlErrorCodes.SCHEMA_ELEM$REF_FEATURES, new Object[] { "nillable" }, xsdElt.xgetNillable()); + // recovery: ignore + } + + assert(xsdElt instanceof LocalElement); + SchemaGlobalElement referenced = state.findGlobalElement(ref, chameleon ? targetNamespace : null, targetNamespace); + if (referenced == null) + { + state.notFoundError(ref, SchemaType.ELEMENT, xsdElt.xgetRef(), true); + // recovery: ignore this element + return null; + } + SchemaLocalElementImpl target = new SchemaLocalElementImpl(); + target.setParticleType(SchemaParticle.ELEMENT); + target.setUserData(getUserData(xsdElt)); + copyGlobalElementToLocalElement( referenced, target ); + return target; + } + + QName qname; + SchemaLocalElementImpl impl; + SchemaType sType = null; + + if (xsdElt instanceof LocalElement) + { + impl = new SchemaLocalElementImpl(); + boolean qualified = false; // default + FormChoice form = xsdElt.xgetForm(); + if (form != null) + qualified = form.getStringValue().equals(FORM_QUALIFIED); + else if (elemFormDefault != null) + qualified = elemFormDefault.equals(FORM_QUALIFIED); + else + { + form = findElementFormDefault(xsdElt); + qualified = form != null && form.getStringValue().equals(FORM_QUALIFIED); + } + + qname = qualified ? QNameHelper.forLNS(name, targetNamespace) : QNameHelper.forLN(name); + } + else + { + SchemaGlobalElementImpl gelt = new SchemaGlobalElementImpl(state.getContainer(targetNamespace)); + impl = gelt; + + // Set subst group head + if (sgHead != null) + { + SchemaGlobalElementImpl head = state.findGlobalElement(xsdElt.getSubstitutionGroup(), chameleon ? targetNamespace : null, targetNamespace); + if (head != null) + gelt.setSubstitutionGroup(head.getRef()); + } + + // Set subst group members + qname = QNameHelper.forLNS(name, targetNamespace); + SchemaTypeImpl docType = (SchemaTypeImpl)outerType; + + QName[] sgMembers = docType.getSubstitutionGroupMembers(); + QNameSetBuilder transitionRules = new QNameSetBuilder(); + transitionRules.add(qname); + + for (int i = 0 ; i < sgMembers.length ; i++) + { + gelt.addSubstitutionGroupMember(sgMembers[i]); + transitionRules.add(sgMembers[i]); + } + + impl.setTransitionRules(QNameSet.forSpecification(transitionRules), false); + impl.setTransitionNotes(QNameSet.EMPTY, true); + + boolean finalExt = false; + boolean finalRest = false; + Object ds = xsdElt.getFinal(); + if (ds != null) + { + if (ds instanceof String && ds.equals("#all")) + { + // #ALL value + finalExt = finalRest = true; + } + else if (ds instanceof List) + { + if (((List)ds).contains("extension")) + finalExt = true; + if (((List)ds).contains("restriction")) + finalRest = true; + } + } + + gelt.setFinal(finalExt, finalRest); + gelt.setAbstract(xsdElt.getAbstract()); + gelt.setFilename(findFilename(xsdElt)); + gelt.setParseContext(xsdElt, targetNamespace, chameleon); + } + + SchemaAnnotationImpl ann = SchemaAnnotationImpl.getAnnotation(state.getContainer(targetNamespace), xsdElt); + impl.setAnnotation(ann); + impl.setUserData(getUserData(xsdElt)); + if (xsdElt.getType() != null) + { + sType = state.findGlobalType(xsdElt.getType(), chameleon ? targetNamespace : null, targetNamespace ); + if (sType == null) + state.notFoundError(xsdElt.getType(), SchemaType.TYPE, xsdElt.xgetType(), true); + } + + boolean simpleTypedef = false; + Annotated typedef = xsdElt.getComplexType(); + if (typedef == null) + { + typedef = xsdElt.getSimpleType(); + simpleTypedef = true; + } + + if ((sType != null) && typedef != null) + { + state.error(XmlErrorCodes.SCHEMA_ELEM$TYPE_ATTR_OR_NESTED_TYPE, null, typedef); + typedef = null; + } + + if (typedef != null) + { + Object[] grps = state.getCurrentProcessing(); + QName[] context = new QName[grps.length]; + for (int i = 0; i < context.length; i++) + if (grps[i] instanceof SchemaModelGroupImpl) + context[i] = ((SchemaModelGroupImpl ) grps[i]).getName(); + SchemaType repeat = checkRecursiveGroupReference(context, qname, (SchemaTypeImpl)outerType); + if (repeat != null) + sType = repeat; + else + { + SchemaTypeImpl sTypeImpl = new SchemaTypeImpl(state.getContainer(targetNamespace)); + sType = sTypeImpl; + sTypeImpl.setContainerField(impl); + sTypeImpl.setOuterSchemaTypeRef(outerType == null ? null : outerType.getRef()); + sTypeImpl.setGroupReferenceContext(context); + // leave the anonymous type unresolved: it will be resolved later. + anonymousTypes.add(sType); + sTypeImpl.setSimpleType(simpleTypedef); + sTypeImpl.setParseContext(typedef, targetNamespace, chameleon, + elemFormDefault, attFormDefault, false); + sTypeImpl.setAnnotation(SchemaAnnotationImpl.getAnnotation(state.getContainer(targetNamespace), typedef)); + sTypeImpl.setUserData(getUserData(typedef)); + } + } + + if (sType == null) + { + // type may inherit from substitution group head + if (sgHead != null) + { + SchemaGlobalElement head = state.findGlobalElement(xsdElt.getSubstitutionGroup(), chameleon ? targetNamespace : null, targetNamespace); + + // Bug - Do I need to copy the type if it's anonymous? + // If element does not exist, error has already been reported + if (head != null) + sType = head.getType(); + } + + } + + + + if (sType == null) + sType = BuiltinSchemaTypeSystem.ST_ANY_TYPE; + + SOAPArrayType wat = null; + XmlCursor c = xsdElt.newCursor(); + String arrayType = c.getAttributeText(WSDL_ARRAYTYPE_NAME); + c.dispose(); + if (arrayType != null) + { + try + { + wat = new SOAPArrayType(arrayType, new NamespaceContext(xsdElt)); + } + catch (XmlValueOutOfRangeException e) + { + state.error(XmlErrorCodes.SOAPARRAY, new Object[] {arrayType}, xsdElt); + } + } + impl.setWsdlArrayType(wat); + + boolean isFixed = xsdElt.isSetFixed(); + if (xsdElt.isSetDefault() && isFixed) + { + state.error(XmlErrorCodes.SCHEMA_ELEM$DEFAULT_OR_FIXED, null, xsdElt.xgetFixed()); + // recovery: ignore fixed + isFixed = false; + } + impl.setParticleType(SchemaParticle.ELEMENT); + impl.setNameAndTypeRef(qname, sType.getRef()); + impl.setNillable(xsdElt.getNillable()); + impl.setDefault(isFixed ? xsdElt.getFixed() : xsdElt.getDefault(), isFixed, xsdElt); + + Object block = xsdElt.getBlock(); + boolean blockExt = false; + boolean blockRest = false; + boolean blockSubst = false; + + if (block != null) + { + if (block instanceof String && block.equals("#all")) + { + // #ALL value + blockExt = blockRest = blockSubst = true; + } + else if (block instanceof List) + { + if (((List)block).contains("extension")) + blockExt = true; + if (((List)block).contains("restriction")) + blockRest = true; + if (((List)block).contains("substitution")) + blockSubst = true; + } + } + + impl.setBlock(blockExt, blockRest, blockSubst); + + boolean constraintFailed = false; + + // Translate Identity constraints + + int length = xsdElt.sizeOfKeyArray() + xsdElt.sizeOfKeyrefArray() + xsdElt.sizeOfUniqueArray(); + SchemaIdentityConstraintImpl[] constraints = new SchemaIdentityConstraintImpl[length]; + int cur = 0; + + // Handle key constraints + Keybase[] keys = xsdElt.getKeyArray(); + for (int i = 0 ; i < keys.length ; i++, cur++) { + constraints[cur] = translateIdentityConstraint(keys[i], targetNamespace, chameleon); + if (constraints[cur] != null) + constraints[cur].setConstraintCategory(SchemaIdentityConstraint.CC_KEY); + else + constraintFailed = true; + } + + // Handle unique constraints + Keybase[] uc = xsdElt.getUniqueArray(); + for (int i = 0 ; i < uc.length ; i++, cur++) { + constraints[cur] = translateIdentityConstraint(uc[i], targetNamespace, chameleon); + if (constraints[cur] != null) + constraints[cur].setConstraintCategory(SchemaIdentityConstraint.CC_UNIQUE); + else + constraintFailed = true; + } + + // Handle keyref constraints + KeyrefDocument.Keyref[] krs = xsdElt.getKeyrefArray(); + for (int i = 0 ; i < krs.length ; i++, cur++) { + constraints[cur] = translateIdentityConstraint(krs[i], targetNamespace, chameleon); + if (constraints[cur] != null) + constraints[cur].setConstraintCategory(SchemaIdentityConstraint.CC_KEYREF); + else + constraintFailed = true; + } + + if (!constraintFailed) + { + SchemaIdentityConstraint.Ref[] refs = new SchemaIdentityConstraint.Ref[length]; + for (int i = 0 ; i < refs.length ; i++) + refs[i] = constraints[i].getRef(); + + impl.setIdentityConstraints(refs); + } + + return impl; + } + + /** + * We need to do this because of the following kind of Schemas: + * + * + * + * + * + * + * + * + * + * (see JIRA bug XMLBEANS-35) + * Even though this should not be allowed because it produces an infinite + * number of anonymous types and local elements nested within each other, + * the de facto consensus among Schema processors is that this should be + * valid, therefore we have to detect this situation and "patch up" the + * Schema object model so that instead of creating a new anonymous type, + * we refer to the one that was already created earlier. + * In order to accomplish that, we store inside every anonymous type the + * list of groups that were dereferenced at the moment the type was created + * and if the same pattern is about to repeat, it means that we are in a + * case similar to the above. + */ + private static SchemaType checkRecursiveGroupReference(QName[] context, QName containingElement, SchemaTypeImpl outerType) + { + if (context.length < 1) + return null; + SchemaTypeImpl type = outerType; + + while (type != null) + { + if (type.getName() != null || type.isDocumentType()) + return null; // not anonymous + if (containingElement.equals(type.getContainerField().getName())) + { + QName[] outerContext = type.getGroupReferenceContext(); + if (outerContext != null && outerContext.length == context.length) + { + // Smells like trouble + boolean equal = true; + for (int i = 0; i < context.length; i++) + if (!(context[i] == null && outerContext[i] == null || + context[i] != null && context[i].equals(outerContext[i]))) + { + equal = false; + break; + } + if (equal) + return type; + } + } + type = (SchemaTypeImpl) type.getOuterType(); + } + return null; + } + + private static String removeWhitespace(String xpath) + { + StringBuffer sb = new StringBuffer(); + for (int i = 0; i < xpath.length(); i++) + { + char ch = xpath.charAt(i); + if (XMLChar.isSpace(ch)) + continue; + sb.append(ch); + } + return sb.toString(); + } + + public static final org.apache.xmlbeans.impl.regex.RegularExpression XPATH_REGEXP = new org.apache.xmlbeans.impl.regex.RegularExpression("(\\.//)?((((child::)?((\\i\\c*:)?(\\i\\c*|\\*)))|\\.)/)*((((child::)?((\\i\\c*:)?(\\i\\c*|\\*)))|\\.)|((attribute::|@)((\\i\\c*:)?(\\i\\c*|\\*))))(\\|(\\.//)?((((child::)?((\\i\\c*:)?(\\i\\c*|\\*)))|\\.)/)*((((child::)?((\\i\\c*:)?(\\i\\c*|\\*)))|\\.)|((attribute::|@)((\\i\\c*:)?(\\i\\c*|\\*)))))*", "X"); + + private static boolean checkXPathSyntax(String xpath) + { + if (xpath == null) + return false; + + // strip whitespace from xpath + xpath = removeWhitespace(xpath); + + // apply regexp + synchronized (XPATH_REGEXP) + { + return (XPATH_REGEXP.matches(xpath)); + } + } + + private static SchemaIdentityConstraintImpl translateIdentityConstraint(Keybase parseIC, + String targetNamespace, boolean chameleon) + { + StscState state = StscState.get(); + + // first do some checking + String selector = parseIC.getSelector() == null ? null : parseIC.getSelector().getXpath(); + if (!checkXPathSyntax(selector)) + { + state.error(XmlErrorCodes.SELECTOR_XPATH, new Object[] { selector }, parseIC.getSelector().xgetXpath()); + return null; + } + + FieldDocument.Field[] fieldElts = parseIC.getFieldArray(); + for (int j = 0; j < fieldElts.length; j++) + { + if (!checkXPathSyntax(fieldElts[j].getXpath())) + { + state.error(XmlErrorCodes.FIELDS_XPATH, new Object[] { fieldElts[j].getXpath() }, fieldElts[j].xgetXpath()); + return null; + } + } + + // then translate. + SchemaIdentityConstraintImpl ic = new SchemaIdentityConstraintImpl(state.getContainer(targetNamespace)); + ic.setName(QNameHelper.forLNS(parseIC.getName(), targetNamespace)); + ic.setSelector(parseIC.getSelector().getXpath()); + ic.setParseContext(parseIC, targetNamespace, chameleon); + SchemaAnnotationImpl ann = SchemaAnnotationImpl.getAnnotation(state.getContainer(targetNamespace), parseIC); + ic.setAnnotation(ann); + ic.setUserData(getUserData(parseIC)); + + // Set the ns map + XmlCursor c = parseIC.newCursor(); + Map nsMap = new HashMap(); + + c.getAllNamespaces(nsMap); + nsMap.remove(""); // Remove the default mapping. This cannot be used by the xpath expressions. + ic.setNSMap(nsMap); + c.dispose(); + + String[] fields = new String[fieldElts.length]; + for (int j = 0 ; j < fields.length ; j++) + fields[j] = fieldElts[j].getXpath(); + ic.setFields(fields); + + try { + ic.buildPaths(); + } + catch (XPath.XPathCompileException e) { + state.error(XmlErrorCodes.INVALID_XPATH, new Object[] { e.getMessage() }, parseIC); + return null; + } + + state.addIdConstraint(ic); + ic.setFilename(findFilename(parseIC)); + + return state.findIdConstraint(ic.getName(), targetNamespace, null); + + } + + public static SchemaModelGroupImpl translateModelGroup(NamedGroup namedGroup, String targetNamespace, boolean chameleon, boolean redefinition) + { + String name = namedGroup.getName(); + if (name == null) + { + StscState.get().error(XmlErrorCodes.MISSING_NAME, new Object[] { "model group" }, namedGroup); + return null; + } + SchemaContainer c = StscState.get().getContainer(targetNamespace); + SchemaModelGroupImpl result = new SchemaModelGroupImpl(c); + SchemaAnnotationImpl ann = SchemaAnnotationImpl.getAnnotation(c, namedGroup); + FormChoice elemFormDefault = findElementFormDefault(namedGroup); + FormChoice attFormDefault = findAttributeFormDefault(namedGroup); + result.init(QNameHelper.forLNS(name, targetNamespace), targetNamespace, chameleon, + elemFormDefault == null ? null : elemFormDefault.getStringValue(), + attFormDefault == null ? null : attFormDefault.getStringValue(), + redefinition, namedGroup, ann, getUserData(namedGroup)); + result.setFilename(findFilename(namedGroup)); + return result; + } + + public static SchemaAttributeGroupImpl translateAttributeGroup(AttributeGroup attrGroup, String targetNamespace, boolean chameleon, boolean redefinition) + { + String name = attrGroup.getName(); + if (name == null) + { + StscState.get().error(XmlErrorCodes.MISSING_NAME, new Object[] { "attribute group" }, attrGroup); + return null; + } + SchemaContainer c = StscState.get().getContainer(targetNamespace); + SchemaAttributeGroupImpl result = new SchemaAttributeGroupImpl(c); + SchemaAnnotationImpl ann = SchemaAnnotationImpl.getAnnotation(c, attrGroup); + FormChoice formDefault = findAttributeFormDefault(attrGroup); + result.init(QNameHelper.forLNS(name, targetNamespace), targetNamespace, chameleon, + formDefault == null ? null : formDefault.getStringValue(), + redefinition, attrGroup, ann, getUserData(attrGroup)); + result.setFilename(findFilename(attrGroup)); + return result; + } + + static FormChoice findAttributeFormDefault(XmlObject obj) + { + XmlCursor cur = obj.newCursor(); + while (cur.getObject().schemaType() != Schema.type) + if (!cur.toParent()) + return null; + return ((Schema)cur.getObject()).xgetAttributeFormDefault(); + } + + static SchemaLocalAttributeImpl translateAttribute( + Attribute xsdAttr, String targetNamespace, String formDefault, boolean chameleon, + List anonymousTypes, SchemaType outerType, SchemaAttributeModel baseModel, + boolean local) + { + StscState state = StscState.get(); + + String name = xsdAttr.getName(); + QName ref = xsdAttr.getRef(); + + if (ref != null && name != null) + { + if (name.equals(ref.getLocalPart()) && uriMatch(targetNamespace, ref.getNamespaceURI())) + state.warning(XmlErrorCodes.SCHEMA_ATTR$REF_OR_NAME_HAS_BOTH, new Object[] { name }, xsdAttr.xgetRef()); + else + state.error(XmlErrorCodes.SCHEMA_ATTR$REF_OR_NAME_HAS_BOTH, new Object[] { name }, xsdAttr.xgetRef()); + // ignore name + name = null; + } + if (ref == null && name == null) + { + state.error(XmlErrorCodes.SCHEMA_ATTR$REF_OR_NAME_HAS_NEITHER, null, xsdAttr); + // recovery: ignore this element + return null; + } + if (name != null && !XMLChar.isValidNCName(name)) + { + state.error(XmlErrorCodes.INVALID_VALUE, new Object[] { name, "name" }, xsdAttr.xgetName()); + // recovery: let the name go through anyway. + } + + boolean isFixed = false; + String deftext = null; + String fmrfixedtext = null; + QName qname; + SchemaLocalAttributeImpl sAttr; + SchemaType sType = null; + int use = SchemaLocalAttribute.OPTIONAL; + + if (local) + sAttr = new SchemaLocalAttributeImpl(); + else + { + sAttr = new SchemaGlobalAttributeImpl(state.get().getContainer(targetNamespace)); + ((SchemaGlobalAttributeImpl)sAttr).setParseContext(xsdAttr, targetNamespace, chameleon); + } + + if (ref != null) + { + if (xsdAttr.getType() != null) + { + state.error(XmlErrorCodes.SCHEMA_ATTR$REF_FEATURES, new Object[] { "type" }, xsdAttr.xgetType()); + // recovery: ignore type, simpleType + } + + if (xsdAttr.getSimpleType() != null) + { + state.error(XmlErrorCodes.SCHEMA_ATTR$REF_FEATURES, new Object[] { "" }, xsdAttr.getSimpleType()); + // recovery: ignore type, simpleType + } + + if (xsdAttr.getForm() != null) + { + state.error(XmlErrorCodes.SCHEMA_ATTR$REF_FEATURES, new Object[] { "form" }, xsdAttr.xgetForm()); + // recovery: ignore form + } + + SchemaGlobalAttribute referenced = state.findGlobalAttribute(ref, chameleon ? targetNamespace : null, targetNamespace); + if (referenced == null) + { + state.notFoundError(ref, SchemaType.ATTRIBUTE, xsdAttr.xgetRef(), true); + // recovery: ignore this element + return null; + } + + qname = ref; + use = referenced.getUse(); + sType = referenced.getType(); + deftext = referenced.getDefaultText(); + if (deftext != null) + { + isFixed = referenced.isFixed(); + if (isFixed) + fmrfixedtext = deftext; + } + } + else + { + if (local) + { + boolean qualified = false; // default + FormChoice form = xsdAttr.xgetForm(); + if (form != null) + qualified = form.getStringValue().equals(FORM_QUALIFIED); + else if (formDefault != null) + qualified = formDefault.equals(FORM_QUALIFIED); + else + { + form = findAttributeFormDefault(xsdAttr); + qualified = form != null && form.getStringValue().equals(FORM_QUALIFIED); + } + + qname = qualified ? QNameHelper.forLNS(name, targetNamespace) : QNameHelper.forLN(name); + } + else + { + qname = QNameHelper.forLNS(name, targetNamespace); + } + + if (xsdAttr.getType() != null) + { + sType = state.findGlobalType(xsdAttr.getType(), chameleon ? targetNamespace : null, targetNamespace ); + if (sType == null) + state.notFoundError(xsdAttr.getType(), SchemaType.TYPE, xsdAttr.xgetType(), true); + } + + if (qname.getNamespaceURI().equals("http://www.w3.org/2001/XMLSchema-instance")) + { + state.error(XmlErrorCodes.NO_XSI, new Object[] { "http://www.w3.org/2001/XMLSchema-instance" }, xsdAttr.xgetName()); + } + + if (qname.getNamespaceURI().length() == 0 && qname.getLocalPart().equals("xmlns")) + { + state.error(XmlErrorCodes.NO_XMLNS, null, xsdAttr.xgetName()); + } + + LocalSimpleType typedef = xsdAttr.getSimpleType(); + + if ((sType != null) && typedef != null) + { + state.error(XmlErrorCodes.SCHEMA_ATTR$TYPE_ATTR_OR_NESTED_TYPE, null, typedef); + typedef = null; + } + + if (typedef != null) + { + SchemaTypeImpl sTypeImpl = new SchemaTypeImpl(state.getContainer(targetNamespace)); + sType = sTypeImpl; + sTypeImpl.setContainerField(sAttr); + sTypeImpl.setOuterSchemaTypeRef(outerType == null ? null : outerType.getRef()); + // leave the anonymous type unresolved: it will be resolved later. + anonymousTypes.add(sType); + sTypeImpl.setSimpleType(true); + sTypeImpl.setParseContext(typedef, targetNamespace, chameleon, null, null, false); + sTypeImpl.setAnnotation(SchemaAnnotationImpl.getAnnotation(state.getContainer(targetNamespace), typedef)); + sTypeImpl.setUserData(getUserData(typedef)); + } + + if (sType == null && baseModel != null && baseModel.getAttribute(qname) != null) + sType = baseModel.getAttribute(qname).getType(); + } + + if (sType == null) + sType = BuiltinSchemaTypeSystem.ST_ANY_SIMPLE; + + if (!sType.isSimpleType()) + { + // KHK: which rule? could use #a-simple_type_definition + state.error("Attributes must have a simple type (not complex).", XmlErrorCodes.INVALID_SCHEMA, xsdAttr); + // recovery: switch to the any-type + sType = BuiltinSchemaTypeSystem.ST_ANY_SIMPLE; + } + + if (xsdAttr.isSetUse()) + { + use = translateUseCode(xsdAttr.xgetUse()); + + // ignore referenced default if no longer optional + if (use != SchemaLocalAttribute.OPTIONAL && !isFixed) + deftext = null; + } + + if (xsdAttr.isSetDefault() || xsdAttr.isSetFixed()) + { + if (isFixed && !xsdAttr.isSetFixed()) + state.error("A use of a fixed attribute definition must also be fixed", XmlErrorCodes.REDUNDANT_DEFAULT_FIXED, xsdAttr.xgetFixed()); + + isFixed = xsdAttr.isSetFixed(); + + if (xsdAttr.isSetDefault() && isFixed) + { + state.error(XmlErrorCodes.SCHEMA_ATTR$DEFAULT_OR_FIXED, null, xsdAttr.xgetFixed()); + // recovery: ignore fixed + isFixed = false; + } + deftext = isFixed ? xsdAttr.getFixed() : xsdAttr.getDefault(); + // BUGBUG(radup) this is not good, since they should be compared by value + // in StscChecker; but there we don't have yet access to the referred attr + if (fmrfixedtext != null && !fmrfixedtext.equals(deftext)) + { + state.error(XmlErrorCodes.SCHEMA_ATTR$FIXED_NOT_MATCH, null, xsdAttr.xgetFixed()); + // recovery: reset fixed to the original value + deftext = fmrfixedtext; + } + } + + if (!local) + { + ((SchemaGlobalAttributeImpl)sAttr).setFilename(findFilename(xsdAttr)); + } + + SOAPArrayType wat = null; + XmlCursor c = xsdAttr.newCursor(); + String arrayType = c.getAttributeText(WSDL_ARRAYTYPE_NAME); + c.dispose(); + if (arrayType != null) + { + try + { + wat = new SOAPArrayType(arrayType, new NamespaceContext(xsdAttr)); + } + catch (XmlValueOutOfRangeException e) + { + state.error(XmlErrorCodes.SOAPARRAY, new Object[] {arrayType}, xsdAttr); + } + } + + SchemaAnnotationImpl ann = SchemaAnnotationImpl.getAnnotation(state.getContainer(targetNamespace), xsdAttr); + sAttr.init( + qname, + sType.getRef(), + use, + deftext, xsdAttr, null, isFixed, + wat, ann, getUserData(xsdAttr)); + + return sAttr; + } + + static int translateUseCode(Attribute.Use attruse) + { + if (attruse == null) + return SchemaLocalAttribute.OPTIONAL; + + String val = attruse.getStringValue(); + if (val.equals("optional")) + return SchemaLocalAttribute.OPTIONAL; + if (val.equals("required")) + return SchemaLocalAttribute.REQUIRED; + if (val.equals("prohibited")) + return SchemaLocalAttribute.PROHIBITED; + return SchemaLocalAttribute.OPTIONAL; + } + + static BigInteger buildBigInt(XmlAnySimpleType value) + { + if (value == null) + return null; + String text = value.getStringValue(); + BigInteger bigInt; + try + { + bigInt = new BigInteger(text); + } + catch (NumberFormatException e) + { + StscState.get().error(XmlErrorCodes.INVALID_VALUE_DETAIL, new Object[] { text, "nonNegativeInteger", e.getMessage() }, value); + return null; + } + + if (bigInt.signum() < 0) + { + StscState.get().error(XmlErrorCodes.INVALID_VALUE, new Object[] { text, "nonNegativeInteger" }, value); + return null; + } + + return bigInt; + } + + + static XmlNonNegativeInteger buildNnInteger(XmlAnySimpleType value) + { + BigInteger bigInt = buildBigInt(value); + try + { + XmlNonNegativeIntegerImpl i = new XmlNonNegativeIntegerImpl(); + i.set(bigInt); + i.setImmutable(); + return i; + } + catch (XmlValueOutOfRangeException e) + { + StscState.get().error("Internal error processing number", XmlErrorCodes.MALFORMED_NUMBER, value); + return null; + } + } + + static XmlPositiveInteger buildPosInteger(XmlAnySimpleType value) + { + BigInteger bigInt = buildBigInt(value); + try + { + XmlPositiveIntegerImpl i = new XmlPositiveIntegerImpl(); + i.set(bigInt); + i.setImmutable(); + return i; + } + catch (XmlValueOutOfRangeException e) + { + StscState.get().error("Internal error processing number", XmlErrorCodes.MALFORMED_NUMBER, value); + return null; + } + } + + + private static Object getUserData(XmlObject pos) + { + XmlCursor.XmlBookmark b = pos.newCursor().getBookmark(SchemaBookmark.class); + if (b != null && b instanceof SchemaBookmark) + return ((SchemaBookmark) b).getValue(); + else + return null; + } + + private static boolean isEmptySchema(Schema schema) + { + XmlCursor cursor = schema.newCursor(); + boolean result = !cursor.toFirstChild(); + cursor.dispose(); + return result; + } + + private static boolean isReservedTypeName(QName name) + { + return (BuiltinSchemaTypeSystem.get().findType(name) != null); + } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/XQuerySchemaTypeSystem.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/XQuerySchemaTypeSystem.java new file mode 100644 index 000000000..41aed8d25 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/XQuerySchemaTypeSystem.java @@ -0,0 +1,1139 @@ +/* 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 java.io.File; +import java.io.InputStream; +import java.math.BigInteger; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import javax.xml.namespace.QName; + +import org.apache.xmlbeans.Filer; +import org.apache.xmlbeans.QNameSet; +import org.apache.xmlbeans.SchemaAnnotation; +import org.apache.xmlbeans.SchemaAttributeGroup; +import org.apache.xmlbeans.SchemaAttributeModel; +import org.apache.xmlbeans.SchemaComponent; +import org.apache.xmlbeans.SchemaGlobalAttribute; +import org.apache.xmlbeans.SchemaGlobalElement; +import org.apache.xmlbeans.SchemaIdentityConstraint; +import org.apache.xmlbeans.SchemaModelGroup; +import org.apache.xmlbeans.SchemaParticle; +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.SchemaTypeSystem; +import org.apache.xmlbeans.impl.common.QNameHelper; +import org.apache.xmlbeans.impl.values.XmlIntegerImpl; +import org.apache.xmlbeans.impl.values.XmlStringImpl; +import org.apache.xmlbeans.impl.values.XmlValueOutOfRangeException; + +/** + * Same as {@link BuiltinSchemaTypeSystem} but adds three extra types + * (dayTimeDuration, yearMonthDuration and anyAtomicType) + * and makes all the primitives extend anyAtomicType. + * + * @author Radu Preotiuc + * + */ +public class XQuerySchemaTypeSystem extends SchemaTypeLoaderBase implements + SchemaTypeSystem +{ + // The global builtin type system + public static SchemaTypeSystem get() + { return _global; } + + // Extra constants; since the extra types are going to be part of XMLSchema 1.1 + // we will want to eventually move these to SchemaType + public static final int BTC_FIRST_XQUERY = 52; + public static final int BTC_ANY_ATOMIC = 52; + public static final int BTC_DAY_TIME_DURATION = 53; + public static final int BTC_YEAR_MONTH_DURATION = 54; + public static final int BTC_LAST_XQUERY = 54; + + // some constants that need to be initialized early + private static final SchemaType[] EMPTY_SCHEMATYPE_ARRAY = new SchemaType[0]; + private static final SchemaType.Ref[] EMPTY_SCHEMATYPEREF_ARRAY = new SchemaType.Ref[0]; + private static final SchemaGlobalElement[] EMPTY_SCHEMAELEMENT_ARRAY = new SchemaGlobalElement[0]; + private static final SchemaGlobalAttribute[] EMPTY_SCHEMAATTRIBUTE_ARRAY = new SchemaGlobalAttribute[0]; + private static final SchemaModelGroup[] EMPTY_SCHEMAMODELGROUP_ARRAY = new SchemaModelGroup[0]; + private static final SchemaAttributeGroup[] EMPTY_SCHEMAATTRIBUTEGROUP_ARRAY = new SchemaAttributeGroup[0]; + private static final SchemaAnnotation[] EMPTY_SCHEMAANNOTATION_ARRAY = new SchemaAnnotation[0]; + + private static XQuerySchemaTypeSystem _global = new XQuerySchemaTypeSystem(); + + // UR types + public static final SchemaTypeImpl ST_ANY_TYPE = _global.getBuiltinType(SchemaType.BTC_ANY_TYPE); + public static final SchemaTypeImpl ST_ANY_SIMPLE = _global.getBuiltinType(SchemaType.BTC_ANY_SIMPLE); + public static final SchemaTypeImpl ST_ANY_ATOMIC = _global.getBuiltinType(BTC_ANY_ATOMIC); + + // primitives + public static final SchemaTypeImpl ST_BOOLEAN = _global.getBuiltinType(SchemaType.BTC_BOOLEAN); + public static final SchemaTypeImpl ST_BASE_64_BINARY = _global.getBuiltinType(SchemaType.BTC_BASE_64_BINARY); + public static final SchemaTypeImpl ST_HEX_BINARY = _global.getBuiltinType(SchemaType.BTC_HEX_BINARY); + public static final SchemaTypeImpl ST_ANY_URI = _global.getBuiltinType(SchemaType.BTC_ANY_URI); + public static final SchemaTypeImpl ST_QNAME = _global.getBuiltinType(SchemaType.BTC_QNAME); + public static final SchemaTypeImpl ST_NOTATION = _global.getBuiltinType(SchemaType.BTC_NOTATION); + public static final SchemaTypeImpl ST_FLOAT = _global.getBuiltinType(SchemaType.BTC_FLOAT); + public static final SchemaTypeImpl ST_DOUBLE = _global.getBuiltinType(SchemaType.BTC_DOUBLE); + public static final SchemaTypeImpl ST_DECIMAL = _global.getBuiltinType(SchemaType.BTC_DECIMAL); + public static final SchemaTypeImpl ST_STRING = _global.getBuiltinType(SchemaType.BTC_STRING); + + public static final SchemaTypeImpl ST_DURATION = _global.getBuiltinType(SchemaType.BTC_DURATION); + public static final SchemaTypeImpl ST_DATE_TIME = _global.getBuiltinType(SchemaType.BTC_DATE_TIME); + public static final SchemaTypeImpl ST_TIME = _global.getBuiltinType(SchemaType.BTC_TIME); + public static final SchemaTypeImpl ST_DATE = _global.getBuiltinType(SchemaType.BTC_DATE); + public static final SchemaTypeImpl ST_G_YEAR_MONTH = _global.getBuiltinType(SchemaType.BTC_G_YEAR_MONTH); + public static final SchemaTypeImpl ST_G_YEAR = _global.getBuiltinType(SchemaType.BTC_G_YEAR); + public static final SchemaTypeImpl ST_G_MONTH_DAY = _global.getBuiltinType(SchemaType.BTC_G_MONTH_DAY); + public static final SchemaTypeImpl ST_G_DAY = _global.getBuiltinType(SchemaType.BTC_G_DAY); + public static final SchemaTypeImpl ST_G_MONTH = _global.getBuiltinType(SchemaType.BTC_G_MONTH); + + // derived numerics + public static final SchemaTypeImpl ST_INTEGER = _global.getBuiltinType(SchemaType.BTC_INTEGER); + public static final SchemaTypeImpl ST_LONG = _global.getBuiltinType(SchemaType.BTC_LONG); + public static final SchemaTypeImpl ST_INT = _global.getBuiltinType(SchemaType.BTC_INT); + public static final SchemaTypeImpl ST_SHORT = _global.getBuiltinType(SchemaType.BTC_SHORT); + public static final SchemaTypeImpl ST_BYTE = _global.getBuiltinType(SchemaType.BTC_BYTE); + public static final SchemaTypeImpl ST_NON_POSITIVE_INTEGER = _global.getBuiltinType(SchemaType.BTC_NON_POSITIVE_INTEGER); + public static final SchemaTypeImpl ST_NEGATIVE_INTEGER = _global.getBuiltinType(SchemaType.BTC_NEGATIVE_INTEGER); + public static final SchemaTypeImpl ST_NON_NEGATIVE_INTEGER = _global.getBuiltinType(SchemaType.BTC_NON_NEGATIVE_INTEGER); + public static final SchemaTypeImpl ST_POSITIVE_INTEGER = _global.getBuiltinType(SchemaType.BTC_POSITIVE_INTEGER); + public static final SchemaTypeImpl ST_UNSIGNED_LONG = _global.getBuiltinType(SchemaType.BTC_UNSIGNED_LONG); + public static final SchemaTypeImpl ST_UNSIGNED_INT = _global.getBuiltinType(SchemaType.BTC_UNSIGNED_INT); + public static final SchemaTypeImpl ST_UNSIGNED_SHORT = _global.getBuiltinType(SchemaType.BTC_UNSIGNED_SHORT); + public static final SchemaTypeImpl ST_UNSIGNED_BYTE = _global.getBuiltinType(SchemaType.BTC_UNSIGNED_BYTE); + + // derived strings + public static final SchemaTypeImpl ST_NORMALIZED_STRING = _global.getBuiltinType(SchemaType.BTC_NORMALIZED_STRING); + public static final SchemaTypeImpl ST_TOKEN = _global.getBuiltinType(SchemaType.BTC_TOKEN); + public static final SchemaTypeImpl ST_NAME = _global.getBuiltinType(SchemaType.BTC_NAME); + public static final SchemaTypeImpl ST_NCNAME = _global.getBuiltinType(SchemaType.BTC_NCNAME); + public static final SchemaTypeImpl ST_LANGUAGE = _global.getBuiltinType(SchemaType.BTC_LANGUAGE); + public static final SchemaTypeImpl ST_ID = _global.getBuiltinType(SchemaType.BTC_ID); + public static final SchemaTypeImpl ST_IDREF = _global.getBuiltinType(SchemaType.BTC_IDREF); + public static final SchemaTypeImpl ST_IDREFS = _global.getBuiltinType(SchemaType.BTC_IDREFS); + public static final SchemaTypeImpl ST_ENTITY = _global.getBuiltinType(SchemaType.BTC_ENTITY); + public static final SchemaTypeImpl ST_ENTITIES = _global.getBuiltinType(SchemaType.BTC_ENTITIES); + public static final SchemaTypeImpl ST_NMTOKEN = _global.getBuiltinType(SchemaType.BTC_NMTOKEN); + public static final SchemaTypeImpl ST_NMTOKENS = _global.getBuiltinType(SchemaType.BTC_NMTOKENS); + + // derived durations + public static final SchemaTypeImpl ST_DAY_TIME_DURATION = _global.getBuiltinType(BTC_DAY_TIME_DURATION); + public static final SchemaTypeImpl ST_YEAR_MONTH_DURATION = _global.getBuiltinType(BTC_YEAR_MONTH_DURATION); + + // the no-type + public static final SchemaTypeImpl ST_NO_TYPE = _global.getBuiltinType(SchemaType.BTC_NOT_BUILTIN); + + private final static XmlValueRef XMLSTR_PRESERVE = buildString("preserve"); + private final static XmlValueRef XMLSTR_REPLACE = buildString("preserve"); + private final static XmlValueRef XMLSTR_COLLAPSE = buildString("preserve"); + + private final static XmlValueRef[] FACETS_NONE = new XmlValueRef[] + { null, null, null, null, null, null, null, null, null, + null, null, null }; + + private final static boolean[] FIXED_FACETS_NONE = new boolean[] + { false, false, false, false, false, false, false, false, false, + false, false, false }; + + private final static XmlValueRef[] FACETS_WS_COLLAPSE = new XmlValueRef[] + { null, null, null, null, null, null, null, null, null, + build_wsstring(SchemaType.WS_COLLAPSE), null, null }; + + private final static XmlValueRef[] FACETS_WS_REPLACE = new XmlValueRef[] + { null, null, null, null, null, null, null, null, null, + build_wsstring(SchemaType.WS_REPLACE), null, null }; + + private final static XmlValueRef[] FACETS_WS_PRESERVE = new XmlValueRef[] + { null, null, null, null, null, null, null, null, null, + build_wsstring(SchemaType.WS_PRESERVE), null, null }; + + private final static XmlValueRef[] FACETS_INTEGER = new XmlValueRef[] + { null, null, null, null, null, null, null, null, buildNnInteger(BigInteger.ZERO), + build_wsstring(SchemaType.WS_COLLAPSE), null, null }; + + private final static XmlValueRef[] FACETS_LONG = new XmlValueRef[] + { null, null, null, null, buildInteger(BigInteger.valueOf(Long.MIN_VALUE)), buildInteger(BigInteger.valueOf(Long.MAX_VALUE)), null, null, buildNnInteger(BigInteger.ZERO), + build_wsstring(SchemaType.WS_COLLAPSE), null, null }; + + private final static XmlValueRef[] FACETS_INT = new XmlValueRef[] + { null, null, null, null, buildInteger(BigInteger.valueOf(Integer.MIN_VALUE)), buildInteger(BigInteger.valueOf(Integer.MAX_VALUE)), null, null, buildNnInteger(BigInteger.ZERO), + build_wsstring(SchemaType.WS_COLLAPSE), null, null }; + + private final static XmlValueRef[] FACETS_SHORT = new XmlValueRef[] + { null, null, null, null, buildInteger(BigInteger.valueOf(Short.MIN_VALUE)), buildInteger(BigInteger.valueOf(Short.MAX_VALUE)), null, null, buildNnInteger(BigInteger.ZERO), + build_wsstring(SchemaType.WS_COLLAPSE), null, null }; + + private final static XmlValueRef[] FACETS_BYTE = new XmlValueRef[] + { null, null, null, null, buildInteger(BigInteger.valueOf(Byte.MIN_VALUE)), buildInteger(BigInteger.valueOf(Byte.MAX_VALUE)), null, null, buildNnInteger(BigInteger.ZERO), + build_wsstring(SchemaType.WS_COLLAPSE), null, null }; + + private final static XmlValueRef[] FACETS_NONNEGATIVE = new XmlValueRef[] + { null, null, null, null, buildInteger(BigInteger.ZERO), null, null, null, buildNnInteger(BigInteger.ZERO), + build_wsstring(SchemaType.WS_COLLAPSE), null, null }; + + private final static XmlValueRef[] FACETS_POSITIVE = new XmlValueRef[] + { null, null, null, null, buildInteger(BigInteger.ONE), null, null, null, buildNnInteger(BigInteger.ZERO), + build_wsstring(SchemaType.WS_COLLAPSE), null, null }; + + private final static XmlValueRef[] FACETS_NONPOSITIVE = new XmlValueRef[] + { null, null, null, null, null, buildInteger(BigInteger.ZERO), null, null, buildNnInteger(BigInteger.ZERO), + build_wsstring(SchemaType.WS_COLLAPSE), null, null }; + + private final static XmlValueRef[] FACETS_NEGATIVE = new XmlValueRef[] + { null, null, null, null, null, buildInteger(BigInteger.ONE.negate()), null, null, buildNnInteger(BigInteger.ZERO), + build_wsstring(SchemaType.WS_COLLAPSE), null, null }; + + private final static XmlValueRef[] FACETS_UNSIGNED_LONG = new XmlValueRef[] + { null, null, null, null, buildInteger(BigInteger.ZERO), buildInteger(new BigInteger("18446744073709551615")), null, null, buildNnInteger(BigInteger.ZERO), + build_wsstring(SchemaType.WS_COLLAPSE), null, null }; + + private final static XmlValueRef[] FACETS_UNSIGNED_INT = new XmlValueRef[] + { null, null, null, null, buildInteger(BigInteger.ZERO), buildInteger(BigInteger.valueOf(4294967295L)), null, null, buildNnInteger(BigInteger.ZERO), + build_wsstring(SchemaType.WS_COLLAPSE), null, null }; + + private final static XmlValueRef[] FACETS_UNSIGNED_SHORT = new XmlValueRef[] + { null, null, null, null, buildInteger(BigInteger.ZERO), buildInteger(BigInteger.valueOf(65535)), null, null, buildNnInteger(BigInteger.ZERO), + build_wsstring(SchemaType.WS_COLLAPSE), null, null }; + + private final static XmlValueRef[] FACETS_UNSIGNED_BYTE = new XmlValueRef[] + { null, null, null, null, buildInteger(BigInteger.ZERO), buildInteger(BigInteger.valueOf(255)), null, null, buildNnInteger(BigInteger.ZERO), + build_wsstring(SchemaType.WS_COLLAPSE), null, null }; + + private final static XmlValueRef[] FACETS_BUILTIN_LIST = new XmlValueRef[] + { null, buildNnInteger(BigInteger.ONE), null, null, null, null, null, null, null, + build_wsstring(SchemaType.WS_COLLAPSE), null, null }; + + private final static boolean[] FIXED_FACETS_WS = new boolean[] + { false, false, false, false, false, false, false, false, false, + true, false, false }; + + private final static boolean[] FIXED_FACETS_INTEGER = new boolean[] + { false, false, false, false, false, false, false, false, true, + true, false, false }; + + final static XmlValueRef[] FACETS_UNION = FACETS_NONE; + final static boolean[] FIXED_FACETS_UNION = FIXED_FACETS_NONE; + + final static XmlValueRef[] FACETS_LIST = FACETS_WS_COLLAPSE; + final static boolean[] FIXED_FACETS_LIST = FIXED_FACETS_WS; + + + /* + * LAST Static initializer + */ + static { + for (int i = SchemaType.BTC_NOT_BUILTIN; i <= SchemaType.BTC_LAST_BUILTIN; i++) + { + _global.fillInType(i); + } + for (int i = BTC_FIRST_XQUERY; i <= BTC_LAST_XQUERY; i++) + { + _global.fillInType(i); + } + } + + private Map _typeMap = new HashMap(); + private SchemaTypeImpl[] _typeArray = new SchemaTypeImpl[SchemaType.BTC_LAST_BUILTIN + 1 + + BTC_LAST_XQUERY - BTC_FIRST_XQUERY + 1]; + private Map _handlesToObjects = new HashMap(); + private Map _objectsToHandles = new HashMap(); + private Map _typesByClassname = new HashMap(); + private SchemaContainer _container = new SchemaContainer("http://www.w3.org/2001/XMLSchema"); + + private SchemaTypeImpl getBuiltinType(int btc) + { + return _typeArray[arrayIndexForBtc(btc)]; + } + + private XQuerySchemaTypeSystem() + { + _container.setTypeSystem(this); + // UR types + setupType(SchemaType.BTC_ANY_TYPE, "anyType", "org.apache.xmlbeans.XmlObject"); + setupType(SchemaType.BTC_ANY_SIMPLE, "anySimpleType", "org.apache.xmlbeans.XmlAnySimpleType"); + setupType(BTC_ANY_ATOMIC, "anyAtomicType", null); + + // primitives + setupType(SchemaType.BTC_BOOLEAN, "boolean", "org.apache.xmlbeans.XmlBoolean"); + setupType(SchemaType.BTC_BASE_64_BINARY, "base64Binary", "org.apache.xmlbeans.XmlBase64Binary"); + setupType(SchemaType.BTC_HEX_BINARY, "hexBinary", "org.apache.xmlbeans.XmlHexBinary"); + setupType(SchemaType.BTC_ANY_URI, "anyURI", "org.apache.xmlbeans.XmlAnyURI"); + setupType(SchemaType.BTC_QNAME, "QName", "org.apache.xmlbeans.XmlQName"); + setupType(SchemaType.BTC_NOTATION, "NOTATION", "org.apache.xmlbeans.XmlNOTATION"); + setupType(SchemaType.BTC_FLOAT, "float", "org.apache.xmlbeans.XmlFloat"); + setupType(SchemaType.BTC_DOUBLE, "double", "org.apache.xmlbeans.XmlDouble"); + setupType(SchemaType.BTC_DECIMAL, "decimal", "org.apache.xmlbeans.XmlDecimal"); + setupType(SchemaType.BTC_STRING, "string", "org.apache.xmlbeans.XmlString"); + + setupType(SchemaType.BTC_DURATION, "duration", "org.apache.xmlbeans.XmlDuration"); + setupType(SchemaType.BTC_DATE_TIME, "dateTime", "org.apache.xmlbeans.XmlDateTime"); + setupType(SchemaType.BTC_TIME, "time", "org.apache.xmlbeans.XmlTime"); + setupType(SchemaType.BTC_DATE, "date", "org.apache.xmlbeans.XmlDate"); + setupType(SchemaType.BTC_G_YEAR_MONTH, "gYearMonth", "org.apache.xmlbeans.XmlGYearMonth"); + setupType(SchemaType.BTC_G_YEAR, "gYear", "org.apache.xmlbeans.XmlGYear"); + setupType(SchemaType.BTC_G_MONTH_DAY, "gMonthDay", "org.apache.xmlbeans.XmlGMonthDay"); + setupType(SchemaType.BTC_G_DAY, "gDay", "org.apache.xmlbeans.XmlGDay"); + setupType(SchemaType.BTC_G_MONTH, "gMonth", "org.apache.xmlbeans.XmlGMonth"); + + // derived numerics + setupType(SchemaType.BTC_INTEGER, "integer", "org.apache.xmlbeans.XmlInteger"); + setupType(SchemaType.BTC_LONG, "long", "org.apache.xmlbeans.XmlLong"); + setupType(SchemaType.BTC_INT, "int", "org.apache.xmlbeans.XmlInt"); + setupType(SchemaType.BTC_SHORT, "short", "org.apache.xmlbeans.XmlShort"); + setupType(SchemaType.BTC_BYTE, "byte", "org.apache.xmlbeans.XmlByte"); + setupType(SchemaType.BTC_NON_POSITIVE_INTEGER, "nonPositiveInteger", "org.apache.xmlbeans.XmlNonPositiveInteger"); + setupType(SchemaType.BTC_NEGATIVE_INTEGER, "negativeInteger", "org.apache.xmlbeans.XmlNegativeInteger"); + setupType(SchemaType.BTC_NON_NEGATIVE_INTEGER, "nonNegativeInteger", "org.apache.xmlbeans.XmlNonNegativeInteger"); + setupType(SchemaType.BTC_POSITIVE_INTEGER, "positiveInteger", "org.apache.xmlbeans.XmlPositiveInteger"); + setupType(SchemaType.BTC_UNSIGNED_LONG, "unsignedLong", "org.apache.xmlbeans.XmlUnsignedLong"); + setupType(SchemaType.BTC_UNSIGNED_INT, "unsignedInt", "org.apache.xmlbeans.XmlUnsignedInt"); + setupType(SchemaType.BTC_UNSIGNED_SHORT, "unsignedShort", "org.apache.xmlbeans.XmlUnsignedShort"); + setupType(SchemaType.BTC_UNSIGNED_BYTE, "unsignedByte", "org.apache.xmlbeans.XmlUnsignedByte"); + + // derived strings + setupType(SchemaType.BTC_NORMALIZED_STRING, "normalizedString", "org.apache.xmlbeans.XmlNormalizedString"); + setupType(SchemaType.BTC_TOKEN, "token", "org.apache.xmlbeans.XmlToken"); + setupType(SchemaType.BTC_NAME, "Name", "org.apache.xmlbeans.XmlName"); + setupType(SchemaType.BTC_NCNAME, "NCName", "org.apache.xmlbeans.XmlNCName"); + setupType(SchemaType.BTC_LANGUAGE, "language", "org.apache.xmlbeans.XmlLanguage"); + setupType(SchemaType.BTC_ID, "ID", "org.apache.xmlbeans.XmlID"); + setupType(SchemaType.BTC_IDREF, "IDREF", "org.apache.xmlbeans.XmlIDREF"); + setupType(SchemaType.BTC_IDREFS, "IDREFS", "org.apache.xmlbeans.XmlIDREFS"); + setupType(SchemaType.BTC_ENTITY, "ENTITY", "org.apache.xmlbeans.XmlENTITY"); + setupType(SchemaType.BTC_ENTITIES, "ENTITIES", "org.apache.xmlbeans.XmlENTITIES"); + setupType(SchemaType.BTC_NMTOKEN, "NMTOKEN", "org.apache.xmlbeans.XmlNMTOKEN"); + setupType(SchemaType.BTC_NMTOKENS, "NMTOKENS", "org.apache.xmlbeans.XmlNMTOKENS"); + + // derived durations + setupType(BTC_DAY_TIME_DURATION, "dayTimeDuration", null); + setupType(BTC_YEAR_MONTH_DURATION, "yearMonthDuration", null); + + // the no-type + setupType(SchemaType.BTC_NOT_BUILTIN, null, null); + _container.setImmutable(); + } + + + /** + * Returns the name of this loader. + */ + public String getName() + { + return "xquery.typesystem.builtin"; + } + + public boolean isNamespaceDefined(String namespace) + { + return namespace.equals("http://www.w3.org/2001/XMLSchema"); + } + + public SchemaType findType(QName name) + { + return (SchemaType)_typeMap.get(name); + } + + + public SchemaType findDocumentType(QName name) + { + return null; + } + + public SchemaType findAttributeType(QName name) + { + return null; + } + + public SchemaGlobalElement findElement(QName name) + { + return null; + } + + public SchemaGlobalAttribute findAttribute(QName name) + { + return null; + } + + public SchemaType.Ref findTypeRef(QName name) + { + SchemaType type = findType(name); + return (type == null ? null : type.getRef()); + } + + public SchemaType.Ref findDocumentTypeRef(QName name) + { + return null; + } + + public SchemaType.Ref findAttributeTypeRef(QName name) + { + return null; + } + + public SchemaGlobalElement.Ref findElementRef(QName name) + { + return null; + } + + public SchemaGlobalAttribute.Ref findAttributeRef(QName name) + { + return null; + } + + public SchemaModelGroup.Ref findModelGroupRef(QName name) + { + return null; + } + + public SchemaAttributeGroup.Ref findAttributeGroupRef(QName name) + { + return null; + } + + public SchemaIdentityConstraint.Ref findIdentityConstraintRef(QName name) + { + return null; + } + + public SchemaType typeForClassname(String classname) + { + return (SchemaType)_typesByClassname.get(classname); + } + + public InputStream getSourceAsStream(String sourceName) + { + return null; // builtin schema type system has no source. + } + + /** + * Returns the global types defined in this loader. + */ + public SchemaType[] globalTypes() + { + SchemaType[] result = new SchemaType[_typeArray.length - 1]; + System.arraycopy(_typeArray, 1, result, 0, result.length); + return result; + } + + /** + * Returns the document types defined in this loader. + */ + public SchemaType[] documentTypes() + { + return EMPTY_SCHEMATYPE_ARRAY; + } + + /** + * Returns the attribute types defined in this loader. + */ + public SchemaType[] attributeTypes() + { + return EMPTY_SCHEMATYPE_ARRAY; + } + + /** + * Returns the global elements defined in this loader. + */ + public SchemaGlobalElement[] globalElements() + { + return EMPTY_SCHEMAELEMENT_ARRAY; + } + + /** + * Returns the global attributes defined in this loader. + */ + public SchemaGlobalAttribute[] globalAttributes() + { + return EMPTY_SCHEMAATTRIBUTE_ARRAY; + } + + /** + * Returns the model groups defined in this loader. + */ + public SchemaModelGroup[] modelGroups() + { + return EMPTY_SCHEMAMODELGROUP_ARRAY; + } + + /** + * Returns the attribute groups defined in this loader. + */ + public SchemaAttributeGroup[] attributeGroups() + { + return EMPTY_SCHEMAATTRIBUTEGROUP_ARRAY; + } + + /* + * Returns the top-level annotations. + */ + public SchemaAnnotation[] annotations() + { + return EMPTY_SCHEMAANNOTATION_ARRAY; + } + + /** + * Returns the handle for the given type within this loader. + */ + public String handleForType(SchemaType type) + { + return (String)_objectsToHandles.get(type); + } + + /** + * Returns the classloader used by this loader for resolving types. + */ + public ClassLoader getClassLoader() + { + return BuiltinSchemaTypeSystem.class.getClassLoader(); + } + + /** + * Saves this type to a directory. + */ + public void saveToDirectory(File classDir) + { + throw new UnsupportedOperationException("The builtin schema type system cannot be saved."); + } + + /** + * Saves this type system using a Filer + */ + public void save(Filer filer) + { + throw new UnsupportedOperationException("The builtin schema type system cannot be saved."); + } + + private int arrayIndexForBtc(int btc) + { + return btc > SchemaType.BTC_LAST_BUILTIN ? + btc - BTC_FIRST_XQUERY + SchemaType.BTC_LAST_BUILTIN + 1 : btc; + } + + private static XmlValueRef build_wsstring(int wsr) + { + switch (wsr) + { + case SchemaType.WS_PRESERVE: + return XMLSTR_PRESERVE; + case SchemaType.WS_REPLACE: + return XMLSTR_REPLACE; + case SchemaType.WS_COLLAPSE: + return XMLSTR_COLLAPSE; + } + return null; + } + + private static XmlValueRef buildNnInteger(BigInteger bigInt) + { + if (bigInt == null) + return null; + if (bigInt.signum() < 0) + return null; + try + { + XmlIntegerImpl i = new XmlIntegerImpl(); + i.setBigIntegerValue(bigInt); + i.setImmutable(); + return new XmlValueRef(i); + } + catch (XmlValueOutOfRangeException e) + { + return null; + } + } + + private static XmlValueRef buildInteger(BigInteger bigInt) + { + if (bigInt == null) + return null; + try + { + XmlIntegerImpl i = new XmlIntegerImpl(); + i.setBigIntegerValue(bigInt); + i.setImmutable(); + return new XmlValueRef(i); + } + catch (XmlValueOutOfRangeException e) + { + return null; + } + } + + private static XmlValueRef buildString(String str) + { + if (str == null) + return null; + + try + { + XmlStringImpl i = new XmlStringImpl(); + i.setStringValue(str); + i.setImmutable(); + return new XmlValueRef(i); + } + catch (XmlValueOutOfRangeException e) + { + return null; + } + } + + private void setupType(int btc, String localname, String classname) + { + SchemaTypeImpl result = new SchemaTypeImpl(_container, true); + _container.addGlobalType(result.getRef()); + QName name = localname == null ? null : QNameHelper.forLNS(localname, "http://www.w3.org/2001/XMLSchema"); + String handle = "_BI_" + (localname == null ? "NO_TYPE" : localname); + result.setName(name); + result.setBuiltinTypeCode(btc); + if (classname != null) + result.setFullJavaName(classname); + + _typeArray[arrayIndexForBtc(btc)] = result; + _typeMap.put(name, result); + _handlesToObjects.put(handle, result); + _objectsToHandles.put(result, handle); + if (classname != null) + _typesByClassname.put(classname, result); + } + + public void resolve() + { + // we're born resolved and don't need to do anything. + } + + public SchemaType typeForHandle(String handle) + { + return (SchemaType)_handlesToObjects.get(handle); + } + + public SchemaComponent resolveHandle(String handle) + { + return (SchemaComponent)_handlesToObjects.get(handle); + } + + /** + * Links a type. + */ + public void fillInType(int btc) + { + SchemaTypeImpl result = getBuiltinType(btc); + SchemaType base; + SchemaType item = null; + int variety = SchemaType.ATOMIC; + int derivationType = SchemaType.DT_RESTRICTION; + + switch (btc) + { + case SchemaType.BTC_NOT_BUILTIN: + variety = SchemaType.NOT_SIMPLE; + base = ST_ANY_TYPE; + break; + + case SchemaType.BTC_ANY_TYPE: + variety = SchemaType.NOT_SIMPLE; + base = null; + derivationType = SchemaType.DT_RESTRICTION; + break; + + default: + assert(false); + + case SchemaType.BTC_ANY_SIMPLE: + base = ST_ANY_TYPE; break; + + case BTC_ANY_ATOMIC: + base = ST_ANY_SIMPLE; + + case SchemaType.BTC_BOOLEAN: + case SchemaType.BTC_BASE_64_BINARY: + case SchemaType.BTC_HEX_BINARY: + case SchemaType.BTC_ANY_URI: + case SchemaType.BTC_QNAME: + case SchemaType.BTC_NOTATION: + case SchemaType.BTC_FLOAT: + case SchemaType.BTC_DOUBLE: + case SchemaType.BTC_DECIMAL: + 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: + base = ST_ANY_ATOMIC; break; + + // derived numerics + case SchemaType.BTC_INTEGER: + base = ST_DECIMAL; break; + + case SchemaType.BTC_LONG: + base = ST_INTEGER; break; + + case SchemaType.BTC_INT: + base = ST_LONG; break; + + case SchemaType.BTC_SHORT: + base = ST_INT; break; + + case SchemaType.BTC_BYTE: + base = ST_SHORT; break; + + case SchemaType.BTC_NON_POSITIVE_INTEGER: + base = ST_INTEGER; break; + + case SchemaType.BTC_NEGATIVE_INTEGER: + base = ST_NON_POSITIVE_INTEGER; break; + + case SchemaType.BTC_NON_NEGATIVE_INTEGER: + base = ST_INTEGER; break; + + case SchemaType.BTC_POSITIVE_INTEGER: + base = ST_NON_NEGATIVE_INTEGER; break; + + case SchemaType.BTC_UNSIGNED_LONG: + base = ST_NON_NEGATIVE_INTEGER; break; + + case SchemaType.BTC_UNSIGNED_INT: + base = ST_UNSIGNED_LONG; break; + + case SchemaType.BTC_UNSIGNED_SHORT: + base = ST_UNSIGNED_INT; break; + + case SchemaType.BTC_UNSIGNED_BYTE: + base = ST_UNSIGNED_SHORT; break; + + // derived strings + case SchemaType.BTC_NORMALIZED_STRING: + base = ST_STRING; break; + + case SchemaType.BTC_TOKEN: + base = ST_NORMALIZED_STRING; break; + + case SchemaType.BTC_NAME: + base = ST_TOKEN; break; + + case SchemaType.BTC_NCNAME: + base = ST_NAME; break; + + case SchemaType.BTC_ID: + case SchemaType.BTC_IDREF: + case SchemaType.BTC_ENTITY: + base = ST_NCNAME; break; + + case SchemaType.BTC_LANGUAGE: + case SchemaType.BTC_NMTOKEN: + base = ST_TOKEN; break; + + case SchemaType.BTC_IDREFS: + case SchemaType.BTC_ENTITIES: + case SchemaType.BTC_NMTOKENS: + variety = SchemaType.LIST; + base = ST_ANY_SIMPLE; + if (btc == SchemaType.BTC_IDREFS) + item = ST_IDREF; + else if (btc == SchemaType.BTC_ENTITIES) + item = ST_ENTITY; + else + item = ST_NMTOKEN; + break; + + // derived durations + case BTC_DAY_TIME_DURATION: + case BTC_YEAR_MONTH_DURATION: + base = ST_DURATION; + break; + + } + + result.setDerivationType(derivationType); + result.setSimpleTypeVariety(variety); + if (variety != SchemaType.NOT_SIMPLE) + { + result.setSimpleType(true); + } + else + { + assert (btc == SchemaType.BTC_ANY_TYPE || btc == SchemaType.BTC_NOT_BUILTIN); + } + result.setBaseTypeRef(base == null ? null : base.getRef()); + result.setBaseDepth(base == null ? 0 : ((SchemaTypeImpl)base).getBaseDepth() + 1); + result.setListItemTypeRef(item == null ? null : item.getRef()); + if (btc >= SchemaType.BTC_FIRST_PRIMITIVE && btc <= SchemaType.BTC_LAST_PRIMITIVE || + btc == BTC_ANY_ATOMIC) + result.setPrimitiveTypeRef(result.getRef()); + else if (variety == SchemaType.ATOMIC) + { + if (base == null) + throw new IllegalStateException("Base was null for " + btc); + if (base.getPrimitiveType() == null) + throw new IllegalStateException("Base.gpt was null for " + btc); + result.setPrimitiveTypeRef(base.getPrimitiveType().getRef()); + } + + XmlValueRef[] facets; + boolean[] fixedf; + int wsr = SchemaType.WS_COLLAPSE; + int decimalSize = SchemaType.NOT_DECIMAL; + + // now set up facets + switch (btc) + { + default: + assert(false); + + case SchemaType.BTC_ANY_TYPE: + case SchemaType.BTC_ANY_SIMPLE: + case SchemaType.BTC_NOT_BUILTIN: + case BTC_ANY_ATOMIC: + facets = FACETS_NONE; + fixedf = FIXED_FACETS_NONE; + wsr = SchemaType.WS_UNSPECIFIED; + break; + + case SchemaType.BTC_STRING: + facets = FACETS_WS_PRESERVE; + fixedf = FIXED_FACETS_NONE; + wsr = SchemaType.WS_PRESERVE; + break; + + case SchemaType.BTC_BOOLEAN: + case SchemaType.BTC_BASE_64_BINARY: + case SchemaType.BTC_HEX_BINARY: + case SchemaType.BTC_ANY_URI: + case SchemaType.BTC_QNAME: + case SchemaType.BTC_FLOAT: + case SchemaType.BTC_DOUBLE: + case SchemaType.BTC_NOTATION: + 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: + facets = FACETS_WS_COLLAPSE; + fixedf = FIXED_FACETS_WS; + break; + + case SchemaType.BTC_DECIMAL: + facets = FACETS_WS_COLLAPSE; + fixedf = FIXED_FACETS_WS; + decimalSize = SchemaType.SIZE_BIG_DECIMAL; + break; + + // derived numerics + case SchemaType.BTC_INTEGER: + facets = FACETS_INTEGER; + fixedf = FIXED_FACETS_INTEGER; + decimalSize = SchemaType.SIZE_BIG_INTEGER; + break; + + case SchemaType.BTC_LONG: + facets = FACETS_LONG; + fixedf = FIXED_FACETS_INTEGER; + decimalSize = SchemaType.SIZE_LONG; + break; + + case SchemaType.BTC_INT: + facets = FACETS_INT; + fixedf = FIXED_FACETS_INTEGER; + decimalSize = SchemaType.SIZE_INT; + break; + + case SchemaType.BTC_SHORT: + facets = FACETS_SHORT; + fixedf = FIXED_FACETS_INTEGER; + decimalSize = SchemaType.SIZE_SHORT; + break; + + case SchemaType.BTC_BYTE: + facets = FACETS_BYTE; + fixedf = FIXED_FACETS_INTEGER; + decimalSize = SchemaType.SIZE_BYTE; + break; + + case SchemaType.BTC_NON_POSITIVE_INTEGER: + facets = FACETS_NONPOSITIVE; + fixedf = FIXED_FACETS_INTEGER; + decimalSize = SchemaType.SIZE_BIG_INTEGER; + break; + + case SchemaType.BTC_NEGATIVE_INTEGER: + facets = FACETS_NEGATIVE; + fixedf = FIXED_FACETS_INTEGER; + decimalSize = SchemaType.SIZE_BIG_INTEGER; + break; + + case SchemaType.BTC_NON_NEGATIVE_INTEGER: + facets = FACETS_NONNEGATIVE; + fixedf = FIXED_FACETS_INTEGER; + decimalSize = SchemaType.SIZE_BIG_INTEGER; + break; + + case SchemaType.BTC_POSITIVE_INTEGER: + facets = FACETS_POSITIVE; + fixedf = FIXED_FACETS_INTEGER; + decimalSize = SchemaType.SIZE_BIG_INTEGER; + break; + + case SchemaType.BTC_UNSIGNED_LONG: + facets = FACETS_UNSIGNED_LONG; + fixedf = FIXED_FACETS_INTEGER; + decimalSize = SchemaType.SIZE_BIG_INTEGER; + break; + + case SchemaType.BTC_UNSIGNED_INT: + facets = FACETS_UNSIGNED_INT; + fixedf = FIXED_FACETS_INTEGER; + decimalSize = SchemaType.SIZE_LONG; + break; + + case SchemaType.BTC_UNSIGNED_SHORT: + facets = FACETS_UNSIGNED_SHORT; + fixedf = FIXED_FACETS_INTEGER; + decimalSize = SchemaType.SIZE_INT; + break; + + case SchemaType.BTC_UNSIGNED_BYTE: + facets = FACETS_UNSIGNED_BYTE; + fixedf = FIXED_FACETS_INTEGER; + decimalSize = SchemaType.SIZE_SHORT; + break; + + + // derived strings + case SchemaType.BTC_NORMALIZED_STRING: + facets = FACETS_WS_REPLACE; + fixedf = FIXED_FACETS_NONE; + wsr = SchemaType.WS_REPLACE; + break; + + case SchemaType.BTC_TOKEN: + case SchemaType.BTC_NAME: + case SchemaType.BTC_NCNAME: + case SchemaType.BTC_LANGUAGE: + case SchemaType.BTC_ID: + case SchemaType.BTC_IDREF: + case SchemaType.BTC_IDREFS: + case SchemaType.BTC_ENTITY: + case SchemaType.BTC_NMTOKEN: + facets = FACETS_WS_COLLAPSE; + fixedf = FIXED_FACETS_NONE; + wsr = SchemaType.WS_COLLAPSE; + break; + + case SchemaType.BTC_ENTITIES: + case SchemaType.BTC_NMTOKENS: + facets = FACETS_BUILTIN_LIST; + fixedf = FIXED_FACETS_NONE; + wsr = SchemaType.WS_UNSPECIFIED; + break; + + case BTC_DAY_TIME_DURATION: + case BTC_YEAR_MONTH_DURATION: + facets = FACETS_WS_COLLAPSE; + fixedf = FIXED_FACETS_WS; + wsr = SchemaType.WS_COLLAPSE; + break; + + } + + // fundamental facets + int ordered = SchemaType.UNORDERED; + boolean isNumeric = false; + boolean isFinite = false; + boolean isBounded = false; + + switch (btc) + { + default: + assert(false); + + case SchemaType.BTC_ANY_TYPE: + case SchemaType.BTC_NOT_BUILTIN: + case SchemaType.BTC_ANY_SIMPLE: + case BTC_ANY_ATOMIC: + case SchemaType.BTC_STRING: + case SchemaType.BTC_BASE_64_BINARY: + case SchemaType.BTC_HEX_BINARY: + case SchemaType.BTC_ANY_URI: + case SchemaType.BTC_QNAME: + case SchemaType.BTC_NOTATION: + case SchemaType.BTC_NORMALIZED_STRING: + case SchemaType.BTC_TOKEN: + case SchemaType.BTC_NAME: + case SchemaType.BTC_NCNAME: + case SchemaType.BTC_LANGUAGE: + case SchemaType.BTC_ID: + case SchemaType.BTC_IDREF: + case SchemaType.BTC_IDREFS: + case SchemaType.BTC_ENTITY: + case SchemaType.BTC_NMTOKEN: + case SchemaType.BTC_ENTITIES: + case SchemaType.BTC_NMTOKENS: + break; + + case SchemaType.BTC_BOOLEAN: + isFinite = true; + break; + + + case SchemaType.BTC_FLOAT: + case SchemaType.BTC_DOUBLE: + case SchemaType.BTC_DECIMAL: + case SchemaType.BTC_INTEGER: + isNumeric = true; + ordered = SchemaType.TOTAL_ORDER; + break; + + 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 BTC_DAY_TIME_DURATION: + case BTC_YEAR_MONTH_DURATION: + ordered = SchemaType.PARTIAL_ORDER; + break; + + case SchemaType.BTC_LONG: + case SchemaType.BTC_INT: + case SchemaType.BTC_SHORT: + case SchemaType.BTC_BYTE: + case SchemaType.BTC_NON_POSITIVE_INTEGER: + case SchemaType.BTC_NEGATIVE_INTEGER: + case SchemaType.BTC_NON_NEGATIVE_INTEGER: + case SchemaType.BTC_POSITIVE_INTEGER: + case SchemaType.BTC_UNSIGNED_LONG: + case SchemaType.BTC_UNSIGNED_INT: + case SchemaType.BTC_UNSIGNED_SHORT: + case SchemaType.BTC_UNSIGNED_BYTE: + isNumeric = true; + ordered = SchemaType.TOTAL_ORDER; + isFinite = true; + isBounded = true; + break; + } + + result.setBasicFacets(facets, fixedf); + result.setWhiteSpaceRule(wsr); + result.setOrdered(ordered); + result.setBounded(isBounded); + result.setNumeric(isNumeric); + result.setFinite(isFinite); + result.setDecimalSize(decimalSize); + result.setAnonymousTypeRefs(EMPTY_SCHEMATYPEREF_ARRAY); + + String pattern = null; + boolean hasPattern = false; + + switch (btc) + { + case SchemaType.BTC_LANGUAGE: + pattern = "[a-zA-Z]{1,8}(-[a-zA-Z0-9]{1,8})*"; // we used to have ([a-zA-Z]{2}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*", but s4s uses the more lenient pattern to the left. + hasPattern = true; + break; + case SchemaType.BTC_NMTOKEN: + pattern = "\\c+"; + hasPattern = true; + break; + case SchemaType.BTC_NAME: + pattern = "\\i\\c*"; + hasPattern = true; + break; + case SchemaType.BTC_NCNAME: + pattern = "[\\i-[:]][\\c-[:]]*"; + hasPattern = true; + break; + case BTC_DAY_TIME_DURATION: + pattern = "[^YM]*[DT].*"; + hasPattern = true; + break; + case BTC_YEAR_MONTH_DURATION: + pattern = "[^DT]*"; + hasPattern = true; + break; + + // These types inherit their patterns + case SchemaType.BTC_ID: + case SchemaType.BTC_IDREF: + case SchemaType.BTC_ENTITY: + hasPattern = true; + break; + } + + if (pattern != null) + { + org.apache.xmlbeans.impl.regex.RegularExpression p = null; + try { p = org.apache.xmlbeans.impl.regex.SchemaRegularExpression.forPattern(pattern); } + catch (org.apache.xmlbeans.impl.regex.ParseException e) { assert false; } + result.setPatterns(new org.apache.xmlbeans.impl.regex.RegularExpression[] {p}); + } + result.setPatternFacet(hasPattern); + + + + // ANY_TYPE has to be able to act like a complex type + if (btc == SchemaType.BTC_ANY_TYPE) + { + SchemaParticleImpl contentModel = new SchemaParticleImpl(); + contentModel.setParticleType(SchemaParticle.WILDCARD); + contentModel.setWildcardSet(QNameSet.ALL); + contentModel.setWildcardProcess(SchemaParticle.LAX); + contentModel.setMinOccurs(BigInteger.ZERO); + contentModel.setMaxOccurs(null); + contentModel.setTransitionRules(QNameSet.ALL, true); + contentModel.setTransitionNotes(QNameSet.ALL, true); + + SchemaAttributeModelImpl attrModel = new SchemaAttributeModelImpl(); + attrModel.setWildcardProcess(SchemaAttributeModel.LAX); + attrModel.setWildcardSet(QNameSet.ALL); + + result.setComplexTypeVariety(SchemaType.MIXED_CONTENT); + result.setContentModel(contentModel, attrModel, Collections.EMPTY_MAP, Collections.EMPTY_MAP, false); + result.setAnonymousTypeRefs(EMPTY_SCHEMATYPEREF_ARRAY); + result.setWildcardSummary(QNameSet.ALL, true, QNameSet.ALL, true); + } + else if (btc == SchemaType.BTC_NOT_BUILTIN) + { + // so does the no_type : it permits no contents (and even empty contents is invalid, but that's special-cased) + SchemaParticleImpl contentModel = null; // empty + SchemaAttributeModelImpl attrModel = new SchemaAttributeModelImpl(); // empty + result.setComplexTypeVariety(SchemaType.EMPTY_CONTENT); + result.setContentModel(contentModel, attrModel, Collections.EMPTY_MAP, Collections.EMPTY_MAP, false); + result.setAnonymousTypeRefs(EMPTY_SCHEMATYPEREF_ARRAY); + result.setWildcardSummary(QNameSet.EMPTY, false, QNameSet.EMPTY, false); + } + + result.setOrderSensitive(false); + } + + public static SchemaType getNoType() + { + return ST_NO_TYPE; + } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/XmlValueRef.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/XmlValueRef.java new file mode 100644 index 000000000..4bda5024f --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/schema/XmlValueRef.java @@ -0,0 +1,67 @@ +/* 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.XmlObject; +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.XmlAnySimpleType; + +import java.util.ArrayList; +import java.util.List; +import java.util.Iterator; + +public class XmlValueRef +{ + XmlAnySimpleType _obj; + SchemaType.Ref _typeref; + Object _initVal; + + public XmlValueRef(XmlAnySimpleType xobj) + { + if (xobj == null) + throw new IllegalArgumentException(); + _obj = xobj; + } + + XmlValueRef(SchemaType.Ref typeref, Object initVal) + { + if (typeref == null) + throw new IllegalArgumentException(); + _typeref = typeref; + _initVal = initVal; + } + + synchronized XmlAnySimpleType get() + { + if (_obj == null) + { + SchemaType type = _typeref.get(); + if (type.getSimpleVariety() != SchemaType.LIST) + _obj = type.newValue(_initVal); + else + { + List actualVals = new ArrayList(); + for (Iterator i = ((List)_initVal).iterator(); i.hasNext(); ) + { + XmlValueRef ref = (XmlValueRef)i.next(); + actualVals.add(ref.get()); + } + _obj = type.newValue(actualVals); + } + } + return _obj; + } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/util/Base64.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/util/Base64.java new file mode 100644 index 000000000..a12b02a0e --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/util/Base64.java @@ -0,0 +1,361 @@ +/* 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.util; + +import java.io.UnsupportedEncodingException; +/** + * This class provides encode/decode for RFC 2045 Base64 as + * defined by RFC 2045, N. Freed and N. Borenstein. + * RFC 2045: Multipurpose Internet Mail Extensions (MIME) + * Part One: Format of Internet Message Bodies. Reference + * 1996 Available at: http://www.ietf.org/rfc/rfc2045.txt + * This class is used by XML Schema binary format validation + * + * This implementation does not encode/decode streaming + * data. You need the data that you will encode/decode + * already on a byte arrray. + * + * @author Jeffrey Rodriguez + * @author Sandy Gao + * @version $Id$ + */ +public final class Base64 { + + static private final int BASELENGTH = 255; + static private final int LOOKUPLENGTH = 64; + static private final int TWENTYFOURBITGROUP = 24; + static private final int EIGHTBIT = 8; + static private final int SIXTEENBIT = 16; + //static private final int SIXBIT = 6; + static private final int FOURBYTE = 4; + static private final int SIGN = -128; + static private final byte PAD = ( byte ) '='; + static private final boolean fDebug = false; + static private byte [] base64Alphabet = new byte[BASELENGTH]; + static private byte [] lookUpBase64Alphabet = new byte[LOOKUPLENGTH]; + + static { + + for (int i = 0; i= 'A'; i--) { + base64Alphabet[i] = (byte) (i-'A'); + } + for (int i = 'z'; i>= 'a'; i--) { + base64Alphabet[i] = (byte) ( i-'a' + 26); + } + + for (int i = '9'; i >= '0'; i--) { + base64Alphabet[i] = (byte) (i-'0' + 52); + } + + base64Alphabet['+'] = 62; + base64Alphabet['/'] = 63; + + for (int i = 0; i<=25; i++) + lookUpBase64Alphabet[i] = (byte) ('A'+i ); + + for (int i = 26, j = 0; i<=51; i++, j++) + lookUpBase64Alphabet[i] = (byte) ('a'+ j ); + + for (int i = 52, j = 0; i<=61; i++, j++) + lookUpBase64Alphabet[i] = (byte) ('0' + j ); + lookUpBase64Alphabet[62] = (byte) '+'; + lookUpBase64Alphabet[63] = (byte) '/'; + + } + + protected static boolean isWhiteSpace(byte octect) { + return (octect == 0x20 || octect == 0xd || octect == 0xa || octect == 0x9); + } + + protected static boolean isPad(byte octect) { + return (octect == PAD); + } + + protected static boolean isData(byte octect) { + return (base64Alphabet[octect] != -1); + } + + protected static boolean isBase64(byte octect) { + return (isWhiteSpace(octect) || isPad(octect) || isData(octect)); + } + + /** + * Encodes hex octects into Base64 + * + * @param binaryData Array containing binaryData + * @return Encoded Base64 array + */ + public static byte[] encode(byte[] binaryData) { + + if (binaryData == null) + return null; + + int lengthDataBits = binaryData.length*EIGHTBIT; + int fewerThan24bits = lengthDataBits%TWENTYFOURBITGROUP; + int numberTriplets = lengthDataBits/TWENTYFOURBITGROUP; + byte encodedData[] = null; + + if (fewerThan24bits != 0) //data not divisible by 24 bit + encodedData = new byte[ (numberTriplets + 1 )*4 ]; + else // 16 or 8 bit + encodedData = new byte[ numberTriplets*4 ]; + + byte k=0, l=0, b1=0,b2=0,b3=0; + + int encodedIndex = 0; + int dataIndex = 0; + int i = 0; + if (fDebug) { + System.out.println("number of triplets = " + numberTriplets ); + } + for (i = 0; i>4 ) ; + decodedData[encodedIndex++] = (byte)(((b2 & 0xf)<<4 ) |( (b3>>2) & 0xf) ); + decodedData[encodedIndex++] = (byte)( b3<<6 | b4 ); + } + + if (!isData( (d1 = base64Data[dataIndex++]) ) || + !isData( (d2 = base64Data[dataIndex++]) )) { + return null;//if found "no data" just return null + } + + b1 = base64Alphabet[d1]; + b2 = base64Alphabet[d2]; + + d3 = base64Data[dataIndex++]; + d4 = base64Data[dataIndex++]; + if (!isData( (d3 ) ) || + !isData( (d4 ) )) {//Check if they are PAD characters + if (isPad( d3 ) && isPad( d4)) { //Two PAD e.g. 3c[Pad][Pad] + if ((b2 & 0xf) != 0)//last 4 bits should be zero + return null; + byte[] tmp = new byte[ i*3 + 1 ]; + System.arraycopy( decodedData, 0, tmp, 0, i*3 ); + tmp[encodedIndex] = (byte)( b1 <<2 | b2>>4 ) ; + return tmp; + } else if (!isPad( d3) && isPad(d4)) { //One PAD e.g. 3cQ[Pad] + b3 = base64Alphabet[ d3 ]; + if ((b3 & 0x3 ) != 0)//last 2 bits should be zero + return null; + byte[] tmp = new byte[ i*3 + 2 ]; + System.arraycopy( decodedData, 0, tmp, 0, i*3 ); + tmp[encodedIndex++] = (byte)( b1 <<2 | b2>>4 ); + tmp[encodedIndex] = (byte)(((b2 & 0xf)<<4 ) |( (b3>>2) & 0xf) ); + return tmp; + } else { + return null;//an error like "3c[Pad]r", "3cdX", "3cXd", "3cXX" where X is non data + } + } else { //No PAD e.g 3cQl + b3 = base64Alphabet[ d3 ]; + b4 = base64Alphabet[ d4 ]; + decodedData[encodedIndex++] = (byte)( b1 <<2 | b2>>4 ) ; + decodedData[encodedIndex++] = (byte)(((b2 & 0xf)<<4 ) |( (b3>>2) & 0xf) ); + decodedData[encodedIndex++] = (byte)( b3<<6 | b4 ); + + } + + return decodedData; + } + +// /** +// * Decodes Base64 data into octects +// * +// * @param base64Data String containing Base64 data +// * @return string containing decoded data. +// */ +// public static String decode(String base64Data) { +// if (base64Data == null) +// return null; +// +// byte[] decoded = null; +// try { +// decoded = decode(base64Data.getBytes("utf-8")); +// } +// catch(UnsupportedEncodingException e) { +// } +// finally { +// return decoded == null ? null : new String(decoded); +// } +// } +// +// /** +// * Encodes octects (using utf-8) into Base64 data +// * +// * @param binaryData String containing Hex data +// * @return string containing decoded data. +// */ +// public static String encode(String binaryData) { +// if (binaryData == null) +// return null; +// +// byte[] encoded = null; +// try { +// encoded = encode(binaryData.getBytes("utf-8")); +// } +// catch(UnsupportedEncodingException e) {} +// finally { +// return encoded == null ? null : new String(encoded); +// } +// } + + /** + * remove WhiteSpace from MIME containing encoded Base64 data. + * + * @param data the byte array of base64 data (with WS) + * @return the byte array of base64 data (without WS) + */ + protected static byte[] removeWhiteSpace(byte[] data) { + if (data == null) + return null; + + // count characters that's not whitespace + int newSize = 0; + int len = data.length; + for (int i = 0; i < len; i++) { + if (!isWhiteSpace(data[i])) + newSize++; + } + + // if no whitespace, just return the input array + if (newSize == len) + return data; + + // create the array to return + byte[] newArray = new byte[newSize]; + + int j = 0; + for (int i = 0; i < len; i++) { + if (!isWhiteSpace(data[i])) + newArray[j++] = data[i]; + } + return newArray; + } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/util/Diff.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/util/Diff.java new file mode 100644 index 000000000..1ad7b03a3 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/util/Diff.java @@ -0,0 +1,55 @@ +/* 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.util; + +import java.io.IOException; +import java.io.LineNumberReader; +import java.io.Reader; +import java.util.List; + +/** + * This needs to be here so that it can be accessed by FilerImpl + */ +public class Diff +{ + public static void readersAsText(Reader r1, String name1, Reader r2, String name2, + List diffs) + throws IOException + { + LineNumberReader reader1 = new LineNumberReader(r1); + LineNumberReader reader2 = new LineNumberReader(r2); + String line1 = reader1.readLine(); + String line2 = reader2.readLine(); + while (line1 != null && line2 != null) + { + if (!line1.equals(line2)) + { + diffs.add("File \"" + name1 + "\" and file \"" + + name2 + "\" differ at line " + reader1.getLineNumber() + + ":" + "\n" + line1 + "\n========\n" + line2); + break; + } + line1 = reader1.readLine(); + line2 = reader2.readLine(); + } + if (line1 == null && line2 != null) + diffs.add("File \"" + name2 + "\" has extra lines at line " + + reader2.getLineNumber() + ":\n" + line2); + if (line1 != null && line2 == null) + diffs.add("File \"" + name1 + "\" has extra lines at line " + + reader1.getLineNumber() + ":\n" + line1); + } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/util/FilerImpl.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/util/FilerImpl.java new file mode 100755 index 000000000..2a077830c --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/util/FilerImpl.java @@ -0,0 +1,231 @@ +/* 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.util; + +import org.apache.xmlbeans.Filer; + +import java.io.IOException; +import java.io.File; +import java.io.Writer; +import java.io.FileReader; +import java.io.FileOutputStream; +import java.io.FileWriter; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.StringReader; +import java.io.StringWriter; +import java.nio.charset.Charset; +import java.nio.charset.CharsetEncoder; +import java.nio.charset.CodingErrorAction; +import java.util.Set; +import java.util.HashSet; +import java.util.List; +import java.util.ArrayList; + +import repackage.Repackager; + +/** + * This implementation of Filer writes to disk. + */ +public class FilerImpl implements Filer +{ + private File classdir; + private File srcdir; + private Repackager repackager; + private boolean verbose; + private List sourceFiles; + private boolean incrSrcGen; + private Set seenTypes; + private static final Charset CHARSET; + + static + { + Charset temp = null; + try + { + temp = Charset.forName(System.getProperty("file.encoding")); + } + catch (Exception e) {} + CHARSET = temp; + } + + public FilerImpl(File classdir, File srcdir, Repackager repackager, boolean verbose, boolean incrSrcGen) + { + this.classdir = classdir; + this.srcdir = srcdir; + this.repackager = repackager; + this.verbose = verbose; + this.sourceFiles = (sourceFiles != null ? sourceFiles : new ArrayList()); + this.incrSrcGen = incrSrcGen; + if (this.incrSrcGen) + seenTypes = new HashSet(); + } + + /** + * Creates a new schema binary file (.xsb) and returns a stream for writing to it. + * + * @param typename fully qualified type name + * @return a stream to write the type to + * @throws java.io.IOException + */ + public OutputStream createBinaryFile(String typename) throws IOException + { + if (verbose) + System.err.println("created binary: " + typename); + // KHK: for now the typename will already be a relative filename for the binary + //String filename = typename.replace('.', File.separatorChar) + ".xsb"; + File source = new File(classdir, typename); + source.getParentFile().mkdirs(); + + return new FileOutputStream( source ); + } + + /** + * Creates a new binding source file (.java) and returns a writer for it. + * + * @param typename fully qualified type name + * @return a stream to write the type to + * @throws java.io.IOException + */ + public Writer createSourceFile(String typename) throws IOException + { + if (incrSrcGen) + seenTypes.add(typename); + + if (typename.indexOf('$') > 0) + { + typename = + typename.substring( 0, typename.lastIndexOf( '.' ) ) + "." + + typename.substring( typename.indexOf( '$' ) + 1 ); + } + + String filename = typename.replace('.', File.separatorChar) + ".java"; + + File sourcefile = new File(srcdir, filename); + sourcefile.getParentFile().mkdirs(); + if (verbose) + System.err.println("created source: " + sourcefile.getAbsolutePath()); + + sourceFiles.add(sourcefile); + + if (incrSrcGen && sourcefile.exists()) + { + // Generate the file in a buffer and then compare it to the + // file already on disk + return new IncrFileWriter(sourcefile, repackager); + } + else + { + return repackager == null ? + (Writer) writerForFile( sourcefile ) : + (Writer) new RepackagingWriter( sourcefile, repackager ); + } + } + + public List getSourceFiles() + { + return new ArrayList(sourceFiles); + } + + public Repackager getRepackager() + { + return repackager; + } + + private static final Writer writerForFile(File f) throws IOException + { + if (CHARSET == null) + return new FileWriter(f); + + FileOutputStream fileStream = new FileOutputStream(f); + CharsetEncoder ce = CHARSET.newEncoder(); + ce.onUnmappableCharacter(CodingErrorAction.REPORT); + return new OutputStreamWriter(fileStream, ce); + } + + static class IncrFileWriter extends StringWriter + { + private File _file; + private Repackager _repackager; + + public IncrFileWriter(File file, Repackager repackager) + { + _file = file; + _repackager = repackager; + } + + public void close() throws IOException + { + super.close(); + + // This is where all the real work happens + StringBuffer sb = _repackager != null ? + _repackager.repackage(getBuffer()) : + getBuffer(); + String str = sb.toString(); + List diffs = new ArrayList(); + StringReader sReader = new StringReader(str); + FileReader fReader = new FileReader(_file); + + try + { + Diff.readersAsText(sReader, "", + fReader, _file.getName(), diffs); + } + finally + { + sReader.close(); + fReader.close(); + } + + if (diffs.size() > 0) + { + // Diffs encountered, replace the file on disk with text from + // the buffer + Writer fw = writerForFile(_file); + try + { fw.write(str); } + finally + { fw.close(); } + } + else + ; // If no diffs, don't do anything + } + } + + static class RepackagingWriter extends StringWriter + { + public RepackagingWriter ( File file, Repackager repackager ) + { + _file = file; + _repackager = repackager; + } + + public void close ( ) throws IOException + { + super.close(); + + Writer fw = writerForFile( _file ); + try + { fw.write( _repackager.repackage( getBuffer() ).toString() ); } + finally + { fw.close(); } + } + + private File _file; + private Repackager _repackager; + } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/util/HexBin.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/util/HexBin.java new file mode 100644 index 000000000..bd72bd862 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/util/HexBin.java @@ -0,0 +1,155 @@ +/* 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.util; + +import java.io.UnsupportedEncodingException; +/** + * format validation + * + * This class encodes/decodes hexadecimal data + * @author Jeffrey Rodriguez + * @version $Id$ + */ +public final class HexBin { + static private final int BASELENGTH = 255; + static private final int LOOKUPLENGTH = 16; + static private byte [] hexNumberTable = new byte[BASELENGTH]; + static private byte [] lookUpHexAlphabet = new byte[LOOKUPLENGTH]; + + + static { + for (int i = 0; i= '0'; i--) { + hexNumberTable[i] = (byte) (i-'0'); + } + for ( int i = 'F'; i>= 'A'; i--) { + hexNumberTable[i] = (byte) ( i-'A' + 10 ); + } + for ( int i = 'f'; i>= 'a'; i--) { + hexNumberTable[i] = (byte) ( i-'a' + 10 ); + } + + for(int i = 0; i<10; i++ ) + lookUpHexAlphabet[i] = (byte) ('0'+i ); + for(int i = 10; i<=15; i++ ) + lookUpHexAlphabet[i] = (byte) ('A'+i -10); + } + + /** + * byte to be tested if it is Base64 alphabet + * + * @param octect + * @return + */ + static boolean isHex(byte octect) { + return (hexNumberTable[octect] != -1); + } + + /** + * Converts bytes to a hex string + */ + static public String bytesToString(byte[] binaryData) + { + if (binaryData == null) + return null; + return new String(encode(binaryData)); + } + + /** + * Converts a hex string to a byte array. + */ + static public byte[] stringToBytes(String hexEncoded) + { + return decode(hexEncoded.getBytes()); + } + + /** + * array of byte to encode + * + * @param binaryData + * @return return encode binary array + */ + static public byte[] encode(byte[] binaryData) { + if (binaryData == null) + return null; + int lengthData = binaryData.length; + int lengthEncode = lengthData * 2; + byte[] encodedData = new byte[lengthEncode]; + for( int i = 0; i> 4) & 0xf]; + encodedData[i*2+1] = lookUpHexAlphabet[ binaryData[i] & 0xf]; + } + return encodedData; + } + + static public byte[] decode(byte[] binaryData) { + if (binaryData == null) + return null; + int lengthData = binaryData.length; + if (lengthData % 2 != 0) + return null; + + int lengthDecode = lengthData / 2; + byte[] decodedData = new byte[lengthDecode]; + for( int i = 0; i 0) { + char ch = cs.charAt(cs.length() - 1); + if (ch == 'f' || ch == 'F') { + if (cs.charAt(cs.length() - 2) != 'N') + throw new NumberFormatException("Invalid char '" + ch + "' in float."); + } + } + return Float.parseFloat(v); + } + catch (NumberFormatException e) { + if (v.equals(POS_INF_LEX)) return Float.POSITIVE_INFINITY; + if (v.equals(NEG_INF_LEX)) return Float.NEGATIVE_INFINITY; + if (v.equals(NAN_LEX)) return Float.NaN; + + throw e; + } + } + + public static float lexFloat(CharSequence cs, Collection errors) + { + try { + return lexFloat(cs); + } + catch (NumberFormatException e) { + String msg = "invalid float: " + cs; + errors.add(XmlError.forMessage(msg)); + + return Float.NaN; + } + } + + public static String printFloat(float value) + { + if (value == Float.POSITIVE_INFINITY) + return POS_INF_LEX; + else if (value == Float.NEGATIVE_INFINITY) + return NEG_INF_LEX; + else if (Float.isNaN(value)) + return NAN_LEX; + else + return Float.toString(value); + } + + + // ======================== double ======================== + public static double lexDouble(CharSequence cs) + throws NumberFormatException + { + final String v = cs.toString(); + + try { + //current jdk impl of parseDouble calls trim() on the string. + //Any other space is illegal anyway, whether there are one or more spaces. + //so no need to do a collapse pass through the string. + if (cs.length() > 0) { + char ch = cs.charAt(cs.length() - 1); + if (ch == 'd' || ch == 'D') + throw new NumberFormatException("Invalid char '" + ch + "' in double."); + } + return Double.parseDouble(v); + } + catch (NumberFormatException e) { + if (v.equals(POS_INF_LEX)) return Double.POSITIVE_INFINITY; + if (v.equals(NEG_INF_LEX)) return Double.NEGATIVE_INFINITY; + if (v.equals(NAN_LEX)) return Double.NaN; + + throw e; + } + } + + public static double lexDouble(CharSequence cs, Collection errors) + { + try { + return lexDouble(cs); + } + catch (NumberFormatException e) { + String msg = "invalid double: " + cs; + errors.add(XmlError.forMessage(msg)); + + return Double.NaN; + } + } + + public static String printDouble(double value) + { + if (value == Double.POSITIVE_INFINITY) + return POS_INF_LEX; + else if (value == Double.NEGATIVE_INFINITY) + return NEG_INF_LEX; + else if (Double.isNaN(value)) + return NAN_LEX; + else + return Double.toString(value); + } + + + // ======================== decimal ======================== + public static BigDecimal lexDecimal(CharSequence cs) + throws NumberFormatException + { + final String v = cs.toString(); + + //TODO: review this + //NOTE: we trim unneeded zeros from the string because + //java.math.BigDecimal considers them significant for its + //equals() method, but the xml value + //space does not consider them significant. + //See http://www.w3.org/2001/05/xmlschema-errata#e2-44 + return new BigDecimal(trimTrailingZeros(v)); + } + + public static BigDecimal lexDecimal(CharSequence cs, Collection errors) + { + try { + return lexDecimal(cs); + } + catch (NumberFormatException e) { + String msg = "invalid long: " + cs; + errors.add(XmlError.forMessage(msg)); + return DECIMAL__ZERO; + } + } + + private static final char[] CH_ZEROS = new char[] {'0', '0', '0', '0', '0', '0', '0', '0', + '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0'}; + + public static String printDecimal(BigDecimal value) + { + // We can't simply use value.toString() here, because in JDK1.5 that returns an + // exponent String and exponents are not allowed in XMLSchema decimal values + // The following code comes from Apache Harmony + String intStr = value.unscaledValue().toString(); + int scale = value.scale(); + if ((scale == 0) || ((value.longValue() == 0) && (scale < 0))) + return intStr; + + int begin = (value.signum() < 0) ? 1 : 0; + int delta = scale; + // We take space for all digits, plus a possible decimal point, plus 'scale' + StringBuffer result = new StringBuffer(intStr.length() + 1 + Math.abs(scale)); + + if (begin == 1) + { + // If the number is negative, we insert a '-' character at front + result.append('-'); + } + if (scale > 0) + { + delta -= (intStr.length() - begin); + if (delta >= 0) + { + result.append("0."); //$NON-NLS-1$ + // To append zeros after the decimal point + for (; delta > CH_ZEROS.length; delta -= CH_ZEROS.length) + result.append(CH_ZEROS); + result.append(CH_ZEROS, 0, delta); + result.append(intStr.substring(begin)); + } + else + { + delta = begin - delta; + result.append(intStr.substring(begin, delta)); + result.append('.'); + result.append(intStr.substring(delta)); + } + } + else + {// (scale <= 0) + result.append(intStr.substring(begin)); + // To append trailing zeros + for (; delta < -CH_ZEROS.length; delta += CH_ZEROS.length) + result.append(CH_ZEROS); + result.append(CH_ZEROS, 0, -delta); + } + return result.toString(); + } + + // ======================== integer ======================== + public static BigInteger lexInteger(CharSequence cs) + throws NumberFormatException + { + if (cs.length() > 1) { + if (cs.charAt(0) == '+' && cs.charAt(1) == '-') + throw new NumberFormatException("Illegal char sequence '+-'"); + } + final String v = cs.toString(); + + //TODO: consider special casing zero and one to return static values + //from BigInteger to avoid object creation. + return new BigInteger(trimInitialPlus(v)); + } + + public static BigInteger lexInteger(CharSequence cs, Collection errors) + { + try { + return lexInteger(cs); + } + catch (NumberFormatException e) { + String msg = "invalid long: " + cs; + errors.add(XmlError.forMessage(msg)); + return BigInteger.ZERO; + } + } + + public static String printInteger(BigInteger value) + { + return value.toString(); + } + + // ======================== long ======================== + public static long lexLong(CharSequence cs) + throws NumberFormatException + { + final String v = cs.toString(); + return Long.parseLong(trimInitialPlus(v)); + } + + public static long lexLong(CharSequence cs, Collection errors) + { + try { + return lexLong(cs); + } + catch (NumberFormatException e) { + String msg = "invalid long: " + cs; + errors.add(XmlError.forMessage(msg)); + return 0L; + } + } + + public static String printLong(long value) + { + return Long.toString(value); + } + + + // ======================== short ======================== + public static short lexShort(CharSequence cs) + throws NumberFormatException + { + return parseShort(cs); + } + + public static short lexShort(CharSequence cs, Collection errors) + { + try { + return lexShort(cs); + } + catch (NumberFormatException e) { + String msg = "invalid short: " + cs; + errors.add(XmlError.forMessage(msg)); + return 0; + } + } + + public static String printShort(short value) + { + return Short.toString(value); + } + + + // ======================== int ======================== + public static int lexInt(CharSequence cs) + throws NumberFormatException + { + return parseInt(cs); + } + + public static int lexInt(CharSequence cs, Collection errors) + { + try { + return lexInt(cs); + } + catch (NumberFormatException e) { + String msg = "invalid int:" + cs; + errors.add(XmlError.forMessage(msg)); + return 0; + } + } + + public static String printInt(int value) + { + return Integer.toString(value); + } + + + // ======================== byte ======================== + public static byte lexByte(CharSequence cs) + throws NumberFormatException + { + return parseByte(cs); + } + + public static byte lexByte(CharSequence cs, Collection errors) + { + try { + return lexByte(cs); + } + catch (NumberFormatException e) { + String msg = "invalid byte: " + cs; + errors.add(XmlError.forMessage(msg)); + return 0; + } + } + + public static String printByte(byte value) + { + return Byte.toString(value); + } + + + // ======================== boolean ======================== + public static boolean lexBoolean(CharSequence v) + { + switch (v.length()) { + case 1: // "0" or "1" + final char c = v.charAt(0); + if ('0' == c) return false; + if ('1' == c) return true; + break; + case 4: //"true" + if ('t' == v.charAt(0) && + 'r' == v.charAt(1) && + 'u' == v.charAt(2) && + 'e' == v.charAt(3)) { + return true; + } + break; + case 5: //"false" + if ('f' == v.charAt(0) && + 'a' == v.charAt(1) && + 'l' == v.charAt(2) && + 's' == v.charAt(3) && + 'e' == v.charAt(4)) { + return false; + } + break; + } + + //reaching here means an invalid boolean lexical + String msg = "invalid boolean: " + v; + throw new InvalidLexicalValueException(msg); + } + + public static boolean lexBoolean(CharSequence value, Collection errors) + { + try { + return lexBoolean(value); + } + catch (InvalidLexicalValueException e) { + errors.add(XmlError.forMessage(e.getMessage())); + return false; + } + } + + public static String printBoolean(boolean value) + { + return (value ? "true" : "false"); + } + + + // ======================== string ======================== + public static String lexString(CharSequence cs, Collection errors) + { + final String v = cs.toString(); + + return v; + } + + + public static String lexString(CharSequence lexical_value) + { + return lexical_value.toString(); + } + + public static String printString(String value) + { + return value; + } + + + // ======================== QName ======================== + public static QName lexQName(CharSequence charSeq, NamespaceContext nscontext) + { + String prefix, localname; + + int firstcolon; + boolean hasFirstCollon = false; + for (firstcolon = 0; firstcolon < charSeq.length(); firstcolon++) + if (charSeq.charAt(firstcolon) == NAMESPACE_SEP) { + hasFirstCollon = true; + break; + } + + if (hasFirstCollon) { + prefix = charSeq.subSequence(0, firstcolon).toString(); + localname = charSeq.subSequence(firstcolon + 1, charSeq.length()).toString(); + if (firstcolon == 0) { + throw new InvalidLexicalValueException("invalid xsd:QName '" + charSeq.toString() + "'"); + } + } else { + prefix = EMPTY_PREFIX; + localname = charSeq.toString(); + } + + String uri = nscontext.getNamespaceURI(prefix); + + if (uri == null) { + if (prefix != null && prefix.length() > 0) + throw new InvalidLexicalValueException("Can't resolve prefix: " + prefix); + + uri = ""; + } + + return new QName(uri, localname); + } + + public static QName lexQName(String xsd_qname, Collection errors, + NamespaceContext nscontext) + { + try { + return lexQName(xsd_qname, nscontext); + } + catch (InvalidLexicalValueException e) { + errors.add(XmlError.forMessage(e.getMessage())); + final int idx = xsd_qname.indexOf(NAMESPACE_SEP); + return new QName(null, xsd_qname.substring(idx)); + } + } + + public static String printQName(QName qname, NamespaceContext nsContext, + Collection errors) + { + final String uri = qname.getNamespaceURI(); + assert uri != null; //qname is not allowed to have null uri values + final String prefix; + if (uri.length() > 0) { + prefix = nsContext.getPrefix(uri); + if (prefix == null) { + String msg = "NamespaceContext does not provide" + + " prefix for namespaceURI " + uri; + errors.add(XmlError.forMessage(msg)); + } + } else { + prefix = null; + } + return getQNameString(uri, qname.getLocalPart(), prefix); + + } + + public static String getQNameString(String uri, + String localpart, + String prefix) + { + if (prefix != null && + uri != null && + uri.length() > 0 && + prefix.length() > 0) { + return (prefix + NAMESPACE_SEP + localpart); + } else { + return localpart; + } + } + + // ======================== GDate ======================== + public static GDate lexGDate(CharSequence charSeq) + { + return new GDate(charSeq); + } + + public static GDate lexGDate(String xsd_gdate, Collection errors) + { + try { + return lexGDate(xsd_gdate); + } + catch (IllegalArgumentException e) { + errors.add(XmlError.forMessage(e.getMessage())); + return new GDateBuilder().toGDate(); + } + } + + public static String printGDate(GDate gdate, Collection errors) + { + return gdate.toString(); + } + + + // ======================== dateTime ======================== + public static XmlCalendar lexDateTime(CharSequence v) + { + GDateSpecification value = getGDateValue(v, SchemaType.BTC_DATE_TIME); + return value.getCalendar(); + } + + + public static String printDateTime(Calendar c) + { + return printDateTime(c, SchemaType.BTC_DATE_TIME); + } + + public static String printTime(Calendar c) + { + return printDateTime(c, SchemaType.BTC_TIME); + } + + public static String printDate(Calendar c) + { + return printDateTime(c, SchemaType.BTC_DATE); + } + + public static String printDate(Date d) + { + GDateSpecification value = getGDateValue(d, SchemaType.BTC_DATE); + return value.toString(); + } + + public static String printDateTime(Calendar c, int type_code) + { + GDateSpecification value = getGDateValue(c, type_code); + return value.toString(); + } + + public static String printDateTime(Date c) + { + GDateSpecification value = getGDateValue(c, SchemaType.BTC_DATE_TIME); + return value.toString(); + } + + + // ======================== hexBinary ======================== + public static CharSequence printHexBinary(byte[] val) + { + return HexBin.bytesToString(val); + } + + public static byte[] lexHexBinary(CharSequence lexical_value) + { + byte[] buf = HexBin.decode(lexical_value.toString().getBytes()); + if (buf != null) + return buf; + else + throw new InvalidLexicalValueException("invalid hexBinary value"); + } + + + // ======================== base64binary ======================== + public static CharSequence printBase64Binary(byte[] val) + { + final byte[] bytes = Base64.encode(val); + return new String(bytes); + } + + public static byte[] lexBase64Binary(CharSequence lexical_value) + { + byte[] buf = Base64.decode(lexical_value.toString().getBytes()); + if (buf != null) + return buf; + else + throw new InvalidLexicalValueException("invalid base64Binary value"); + } + + + // date utils + public static GDateSpecification getGDateValue(Date d, + int builtin_type_code) + { + GDateBuilder gDateBuilder = new GDateBuilder(d); + gDateBuilder.setBuiltinTypeCode(builtin_type_code); + GDate value = gDateBuilder.toGDate(); + return value; + } + + + public static GDateSpecification getGDateValue(Calendar c, + int builtin_type_code) + { + GDateBuilder gDateBuilder = new GDateBuilder(c); + gDateBuilder.setBuiltinTypeCode(builtin_type_code); + GDate value = gDateBuilder.toGDate(); + return value; + } + + public static GDateSpecification getGDateValue(CharSequence v, + int builtin_type_code) + { + GDateBuilder gDateBuilder = new GDateBuilder(v); + gDateBuilder.setBuiltinTypeCode(builtin_type_code); + GDate value = gDateBuilder.toGDate(); + return value; + } + + private static String trimInitialPlus(String xml) + { + if (xml.length() > 0 && xml.charAt(0) == '+') { + return xml.substring(1); + } else { + return xml; + } + } + + private static String trimTrailingZeros(String xsd_decimal) + { + final int last_char_idx = xsd_decimal.length() - 1; + if (xsd_decimal.charAt(last_char_idx) == '0') + { + final int last_point = xsd_decimal.lastIndexOf('.'); + if (last_point >= 0) { + //find last trailing zero + for (int idx = last_char_idx; idx > last_point; idx--) { + if (xsd_decimal.charAt(idx) != '0') { + return xsd_decimal.substring(0, idx + 1); + } + } + //reaching here means the string matched xxx.0* + return xsd_decimal.substring(0, last_point); + } + } + return xsd_decimal; + } + + private static int parseInt(CharSequence cs) + { + return parseIntXsdNumber(cs, Integer.MIN_VALUE, Integer.MAX_VALUE); + } + + private static short parseShort(CharSequence cs) + { + return (short)parseIntXsdNumber(cs, Short.MIN_VALUE, Short.MAX_VALUE); + } + + private static byte parseByte(CharSequence cs) + { + return (byte)parseIntXsdNumber(cs, Byte.MIN_VALUE, Byte.MAX_VALUE); + } + + private static int parseIntXsdNumber(CharSequence ch, int min_value, int max_value) + { + // int parser on a CharSequence + int length = ch.length(); + if (length < 1) + throw new NumberFormatException("For input string: \"" + ch.toString() + "\""); + + int sign = 1; + int result = 0; + int start = 0; + int limit; + int limit2; + + char c = ch.charAt(0); + if (c == '-') { + start++; + limit = (min_value / 10); + limit2 = -(min_value % 10); + } else if (c == '+') { + start++; + sign = -1; + limit = -(max_value / 10); + limit2 = (max_value % 10); + } else { + sign = -1; + limit = -(max_value / 10); + limit2 = (max_value % 10); + } + + for (int i = 0; i < length - start; i++) { + c = ch.charAt(i + start); + int v = Character.digit(c, 10); + + if (v < 0) + throw new NumberFormatException("For input string: \"" + ch.toString() + "\""); + + if (result < limit || (result==limit && v > limit2)) + throw new NumberFormatException("For input string: \"" + ch.toString() + "\""); + + result = result * 10 - v; + } + + return sign * result; + } + + // ======================== anyURI ======================== + public static CharSequence printAnyURI(CharSequence val) + { + return val; + } + + /** + * Checkes the regular expression of URI, defined by RFC2369 http://www.ietf.org/rfc/rfc2396.txt Appendix B. + * Note: The whitespace normalization rule collapse must be applied priot to calling this method. + * @param lexical_value the lexical value + * @return same input value if input value is in the lexical space + * @throws InvalidLexicalValueException + */ + public static CharSequence lexAnyURI(CharSequence lexical_value) + { + /* // Reg exp from RFC2396, but it's too forgiving for XQTS + Pattern p = Pattern.compile("^([^:/?#]+:)?(//[^/?#]*)?([^?#]*)(\\?[^#]*)?(#.*)?"); + Matcher m = p.matcher(lexical_value); + if ( !m.matches() ) + throw new InvalidLexicalValueException("invalid anyURI value"); + else + { + for ( int i = 0; i<= m.groupCount(); i++ ) + { + System.out.print(" " + i + ": " + m.group(i)); + } + System.out.println(""); + return lexical_value; + } */ + + // Per XMLSchema spec allow spaces inside URIs + StringBuffer s = new StringBuffer(lexical_value.toString()); + for (int ic = 0; ic= 0) + { + s.replace(i, i + 1, URI_CHARS_REPLACED_WITH[ic]); + i += 3; + } + } + + try + { + URI.create(s.toString()); + } + catch (IllegalArgumentException e) + { + throw new InvalidLexicalValueException("invalid anyURI value: " + lexical_value, e); + } + + return lexical_value; + } +} \ No newline at end of file diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/validator/ValidatingInfoXMLStreamReader.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/validator/ValidatingInfoXMLStreamReader.java new file mode 100644 index 000000000..4c1a35d0a --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/validator/ValidatingInfoXMLStreamReader.java @@ -0,0 +1,179 @@ +/* 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.validator; + +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.SchemaLocalElement; +import org.apache.xmlbeans.SchemaParticle; +import org.apache.xmlbeans.SchemaLocalAttribute; +import org.apache.xmlbeans.SchemaAttributeModel; +import org.apache.xmlbeans.GDate; +import org.apache.xmlbeans.GDuration; + +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.events.XMLEvent; +import javax.xml.namespace.QName; +import java.math.BigDecimal; +import java.util.List; + +/** + * Extension of {@link ValidatingXMLStreamReader} to provide Post Schema Validation Info + * over an XMLStreamReader. + * + * @author Cezar Andrei (cezar.andrei at bea.com) + * Date: Aug 17, 2004 + */ +public class ValidatingInfoXMLStreamReader + extends ValidatingXMLStreamReader + implements XMLStreamReader +{ + public ValidatingInfoXMLStreamReader() + { + super(); + } + + private int _attCount = -1; + private int _attIndex = 0; + + public int nextWithAttributes() + throws XMLStreamException + { + if (_attIndex < _attCount) + { + validate_attribute(_attIndex); + _attIndex ++; + return XMLEvent.ATTRIBUTE; + } + else + return next(); + } + + protected void validate_attributes(int attCount) + { + _attCount = attCount; + _attIndex = 0; + } + + + /** + * @return Returns the SchemaType of the current element. + * This can be different than getCurrentElement().getType() if xsi:type attribute is used. + * Null is returned if no schema type is available. + * For attribute types use {@link #getCurrentAttribute()}.getType(). + * Warning: the returned SchemaType can be an {@link org.apache.xmlbeans.XmlBeans#NO_TYPE}, + * see {@link org.apache.xmlbeans.SchemaType#isNoType}. Or can be the parent type, for unrecognized elements + * that are part of wildcards. + */ + public SchemaType getCurrentElementSchemaType() + { + return _validator==null ? null : _validator.getCurrentElementSchemaType(); + } + + /** + * @return Returns the curent local element, null if one is not available, see {@link #getCurrentWildcardElement()}. + */ + public SchemaLocalElement getCurrentElement ( ) + { + return _validator==null ? null : _validator.getCurrentElement(); + } + + /** + * @return Returns the current particle, if this is a wildcard particle + * {@link org.apache.xmlbeans.SchemaParticle#WILDCARD} method {@link #getCurrentElement()} + * might return null if wildcard's processContents is skip or lax. + */ + public SchemaParticle getCurrentWildcardElement() + { + return _validator==null ? null : _validator.getCurrentWildcardElement(); + } + + /** + * @return Returns the curent local attribute, global attribute if the current attribute is part of an + * attribute wildcard, or null if none is available. + */ + public SchemaLocalAttribute getCurrentAttribute() + { + return _validator==null ? null : _validator.getCurrentAttribute(); + } + + /** + * @return Returns the attribute model for attributes if available, else null is returned. + */ + public SchemaAttributeModel getCurrentWildcardAttribute() + { + return _validator==null ? null : _validator.getCurrentWildcardAttribute(); + } + + public String getStringValue() + { + return _validator==null ? null : _validator.getStringValue(); + } + + public BigDecimal getDecimalValue() + { + return _validator==null ? null : _validator.getDecimalValue(); + } + + public boolean getBooleanValue() + { + return _validator==null ? false : _validator.getBooleanValue(); + } + + public float getFloatValue() + { + return _validator==null ? 0 : _validator.getFloatValue(); + } + + public double getDoubleValue() + { + return _validator==null ? 0 : _validator.getDoubleValue(); + } + + public QName getQNameValue() + { + return _validator==null ? null : _validator.getQNameValue(); + } + + public GDate getGDateValue() + { + return _validator==null ? null : _validator.getGDateValue(); + } + + public GDuration getGDurationValue() + { + return _validator==null ? null : _validator.getGDurationValue(); + } + + public byte[] getByteArrayValue() + { + return _validator==null ? null : _validator.getByteArrayValue(); + } + + public List getListValue() + { + return _validator==null ? null : _validator.getListValue(); + } + + public List getListTypes() + { + return _validator==null ? null : _validator.getListTypes(); + } + + public SchemaType getUnionType() + { + return _validator==null ? null : _validator.getUnionType(); + } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/validator/ValidatingXMLInputStream.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/validator/ValidatingXMLInputStream.java new file mode 100644 index 000000000..cc01bf22e --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/validator/ValidatingXMLInputStream.java @@ -0,0 +1,389 @@ +/* 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.validator; + +import org.apache.xmlbeans.impl.common.XMLNameHelper; +import org.apache.xmlbeans.impl.common.GenericXmlInputStream; +import org.apache.xmlbeans.impl.common.ValidatorListener.Event; +import org.apache.xmlbeans.impl.common.ValidatorListener; +import org.apache.xmlbeans.impl.common.XmlWhitespace; +import org.apache.xmlbeans.impl.schema.BuiltinSchemaTypeSystem; +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.SchemaTypeLoader; +import org.apache.xmlbeans.XmlCursor; +import org.apache.xmlbeans.XmlError; +import org.apache.xmlbeans.XmlOptions; +import org.apache.xmlbeans.XMLStreamValidationException; +import java.util.Map; +import java.util.AbstractCollection; +import java.util.Iterator; +import java.util.Collections; + +import org.apache.xmlbeans.xml.stream.Attribute; +import org.apache.xmlbeans.xml.stream.AttributeIterator; +import org.apache.xmlbeans.xml.stream.CharacterData; +import org.apache.xmlbeans.xml.stream.StartElement; +import org.apache.xmlbeans.xml.stream.XMLEvent; +import org.apache.xmlbeans.xml.stream.XMLInputStream; +import org.apache.xmlbeans.xml.stream.XMLName; +import org.apache.xmlbeans.xml.stream.XMLStreamException; +import javax.xml.namespace.QName; + +/** + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ +public final class ValidatingXMLInputStream + extends GenericXmlInputStream implements Event +{ + public ValidatingXMLInputStream ( + XMLInputStream xis, + SchemaTypeLoader typeLoader, SchemaType sType, XmlOptions options ) + throws XMLStreamException + { + _source = xis; + + // Figure out the root type + + options = XmlOptions.maskNull( options ); + + SchemaType type = (SchemaType) options.get( XmlOptions.DOCUMENT_TYPE ); + + if (type == null) + type = sType; + + if (type == null) + { + type = BuiltinSchemaTypeSystem.ST_ANY_TYPE; + + xis = xis.getSubStream(); + + if (xis.skip( XMLEvent.START_ELEMENT )) + { + SchemaType docType = + typeLoader.findDocumentType( + XMLNameHelper.getQName( xis.next().getName() ) ); + + if (docType != null) + type = docType; + } + + xis.close(); + } + + // Create the validator + + _validator = + new Validator( + type, null, typeLoader, options, new ExceptionXmlErrorListener() ); + + nextEvent( ValidatorListener.BEGIN ); + } + + // TODO - this is the quick and dirty impl of streaming validation, + // may objects are created (like strings) which can be optimized + + protected XMLEvent nextEvent ( ) throws XMLStreamException + { + XMLEvent e = _source.next(); + + if (e == null) + { + if (!_finished) + { + flushText(); + nextEvent( ValidatorListener.END ); + _finished = true; + } + } + else + { + switch ( e.getType() ) + { + case XMLEvent.CHARACTER_DATA : + case XMLEvent.SPACE : + { + CharacterData cd = (CharacterData) e; + + if (cd.hasContent()) + _text.append( cd.getContent() ); + + break; + } + case XMLEvent.START_ELEMENT : + { + StartElement se = (StartElement) e; + + flushText(); + + // Used for prefix to namespace mapping + _startElement = se; + + // Prepare the xsi:* values + + AttributeIterator attrs = se.getAttributes(); + + while ( attrs.hasNext() ) + { + Attribute attr = attrs.next(); + + XMLName attrName = attr.getName(); + + if ("http://www.w3.org/2001/XMLSchema-instance".equals( + attrName.getNamespaceUri() )) + { + String local = attrName.getLocalName(); + + if (local.equals( "type" )) + _xsiType = attr.getValue(); + else if (local.equals( "nil" )) + _xsiNil = attr.getValue(); + else if (local.equals( "schemaLocation" )) + _xsiLoc = attr.getValue(); + else if (local.equals( "noNamespaceSchemaLocation" )) + _xsiNoLoc = attr.getValue(); + } + } + + // Emit the START + + // TODO - should delay the aquisition of the name + _name = e.getName(); + + nextEvent( ValidatorListener.BEGIN ); + + // Emit the attrs + + attrs = se.getAttributes(); + + while ( attrs.hasNext() ) + { + Attribute attr = attrs.next(); + + XMLName attrName = attr.getName(); + + if ("http://www.w3.org/2001/XMLSchema-instance".equals( + attrName.getNamespaceUri() )) + { + String local = attrName.getLocalName(); + + if (local.equals( "type" )) + continue; + else if (local.equals( "nil" )) + continue; + else if (local.equals( "schemaLocation" )) + continue; + else if (local.equals( "noNamespaceSchemaLocation" )) + continue; + } + + // TODO - God, this is lame :-) + + _text.append( attr.getValue() ); + _name = attr.getName(); + + nextEvent( ValidatorListener.ATTR ); + } + + clearText(); + + _startElement = null; + + break; + } + + case XMLEvent.END_ELEMENT : + { + flushText(); + + nextEvent( ValidatorListener.END ); + + break; + } + } + } + + return e; + } + + private void clearText ( ) + { + _text.delete( 0, _text.length() ); + } + + private void flushText ( ) throws XMLStreamException + { + if (_text.length() > 0) + { + nextEvent( ValidatorListener.TEXT ); + clearText(); + } + } + + public String getNamespaceForPrefix ( String prefix ) + { + if (_startElement == null) + return null; + + Map map = _startElement.getNamespaceMap(); + + if (map == null) + return null; + + return (String) map.get( prefix ); + } + + public XmlCursor getLocationAsCursor ( ) + { + return null; + } + + public javax.xml.stream.Location getLocation() + { + try + { + final org.apache.xmlbeans.xml.stream.Location xeLoc = _source.peek().getLocation(); + + if (xeLoc==null) + return null; + + javax.xml.stream.Location loc = new javax.xml.stream.Location() + { + public int getLineNumber() + { return xeLoc.getLineNumber(); } + + public int getColumnNumber() + { return xeLoc.getColumnNumber(); } + + public int getCharacterOffset() + { return -1;} + + public String getPublicId() + { return xeLoc.getPublicId(); } + + public String getSystemId() + { return xeLoc.getSystemId(); } + }; + + return loc; + } + catch (XMLStreamException e) + { + return null; + } + } + + public String getXsiType ( ) + { + return _xsiType; + } + + public String getXsiNil ( ) + { + return _xsiNil; + } + + public String getXsiLoc ( ) + { + return _xsiLoc; + } + + public String getXsiNoLoc ( ) + { + return _xsiNoLoc; + } + + public QName getName ( ) + { + return XMLNameHelper.getQName( _name ); + } + + public String getText ( ) + { + return _text.toString(); + } + + public String getText ( int wsr ) + { + return XmlWhitespace.collapse( _text.toString(), wsr ); + } + + public boolean textIsWhitespace ( ) + { + for ( int i = 0 ; i < _text.length() ; i++ ) + { + switch ( _text.charAt( i ) ) + { + case ' ': + case '\n': + case '\r': + case '\t': + break; + + default : + return false; + } + } + + return true; + } + + private final class ExceptionXmlErrorListener extends AbstractCollection + { + public boolean add(Object o) + { + assert ValidatingXMLInputStream.this._exception == null; + + ValidatingXMLInputStream.this._exception = + new XMLStreamValidationException( (XmlError)o ); + + return false; + } + + public Iterator iterator() + { + return Collections.EMPTY_LIST.iterator(); + } + + public int size() + { + return 0; + } + } + + private void nextEvent ( int kind ) + throws XMLStreamException + { + assert _exception == null; + + _validator.nextEvent( kind, this ); + + if (_exception != null) + throw _exception; + } + + private XMLStreamValidationException _exception; + + private XMLInputStream _source; + private Validator _validator; + private StringBuffer _text = new StringBuffer(); + private boolean _finished; + private String _xsiType; + private String _xsiNil; + private String _xsiLoc; + private String _xsiNoLoc; + private XMLName _name; + private StartElement _startElement; +} \ No newline at end of file diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/validator/ValidatingXMLStreamReader.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/validator/ValidatingXMLStreamReader.java new file mode 100644 index 000000000..99c856384 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/validator/ValidatingXMLStreamReader.java @@ -0,0 +1,939 @@ +/* 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.validator; + +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.SchemaTypeLoader; +import org.apache.xmlbeans.XmlCursor; +import org.apache.xmlbeans.XmlError; +import org.apache.xmlbeans.XmlOptions; +import org.apache.xmlbeans.impl.common.ValidatorListener; +import org.apache.xmlbeans.impl.common.XmlWhitespace; +import org.apache.xmlbeans.impl.common.QNameHelper; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.Location; +import javax.xml.stream.events.XMLEvent; +import javax.xml.stream.util.StreamReaderDelegate; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +/** + * This class is a wrapper over a generic XMLStreamReader that provides validation. + * There are 3 cases: + *
    1) the XMLStreamReader represents a document, it contains only one element document + * - in this case the user schema type should be null or it should be a document SchemaType + *
    2) the XMLStreamReader represents an xml-fragment (content only) - must have at least one user type or xsi:type + *
    a) it has an xsi:type - if user schema type is available it has to be a base type of xsi:type + *
    b) it doesn't have xsi:type - user must provide a schema type + * otherwise will error and will not do validation + *
    3) the XMLStreamReader represents a global attribute - i.e. user schema type is null and only one attribute + *
    + * + * @author Cezar Andrei (cezar.andrei at bea.com) + * Date: Feb 13, 2004 + */ +public class ValidatingXMLStreamReader + extends StreamReaderDelegate + implements XMLStreamReader +{ + public static final String OPTION_ATTTRIBUTE_VALIDATION_COMPAT_MODE = "OPTION_ATTTRIBUTE_VALIDATION_COMPAT_MODE"; + + private static final String URI_XSI = "http://www.w3.org/2001/XMLSchema-instance"; + private static final QName XSI_TYPE = new QName(URI_XSI, "type"); + private static final QName XSI_NIL = new QName(URI_XSI, "nil"); + private static final QName XSI_SL = new QName(URI_XSI, "schemaLocation"); + private static final QName XSI_NSL = new QName(URI_XSI, "noNamespaceSchemaLocation"); + + private SchemaType _contentType; + private SchemaTypeLoader _stl; + private XmlOptions _options; + private Collection _errorListener; + protected Validator _validator; + private final ElementEventImpl _elemEvent; + private final AttributeEventImpl _attEvent; + private final SimpleEventImpl _simpleEvent; + private PackTextXmlStreamReader _packTextXmlStreamReader; + + private int _state; + private final int STATE_FIRSTEVENT = 0; + private final int STATE_VALIDATING = 1; + private final int STATE_ATTBUFFERING = 2; + private final int STATE_ERROR = 3; + + private List _attNamesList; + private List _attValuesList; + private SchemaType _xsiType; + + private int _depth; + + /** + * Default constructor. Use init(...) to set the params. + * See {@link #init} + */ + public ValidatingXMLStreamReader() + { + super(); + _elemEvent = new ElementEventImpl(); + _attEvent = new AttributeEventImpl(); + _simpleEvent = new SimpleEventImpl(); + _packTextXmlStreamReader = new PackTextXmlStreamReader(); + } + + /** + * Used in case of reusing the same ValidatinXMLStreamReader object + * @param xsr The stream to be validated + * @param startWithCurrentEvent Validation will start if true with the current event or if false with the next event in the stream + * @param contentType The schemaType of the content. This can be null for document and global Att validation + * @param stl SchemaTypeLoader context of validation + * @param options Validator options + * @param errorListener Errors and warnings listener + */ + public void init(XMLStreamReader xsr, boolean startWithCurrentEvent, SchemaType contentType, + SchemaTypeLoader stl, XmlOptions options, Collection errorListener) + { + _packTextXmlStreamReader.init(xsr); + +// setParent(xsr); + setParent(_packTextXmlStreamReader); + _contentType = contentType; + _stl = stl; + _options = options; + _errorListener = errorListener; +// _elemEvent.setXMLStreamReader(xsr); +// _attEvent.setXMLStreamReader(xsr); +// _simpleEvent.setXMLStreamReader(xsr); + _elemEvent.setXMLStreamReader(_packTextXmlStreamReader); + _attEvent.setXMLStreamReader(_packTextXmlStreamReader); + _simpleEvent.setXMLStreamReader(_packTextXmlStreamReader); + _validator = null; + _state = STATE_FIRSTEVENT; + if (_attNamesList!=null) + { + _attNamesList.clear(); + _attValuesList.clear(); + } + _xsiType = null; + _depth = 0; + + if (startWithCurrentEvent) + { + int evType = getEventType(); + validate_event(evType); + } + } + + private static class PackTextXmlStreamReader + extends StreamReaderDelegate + implements XMLStreamReader + { + private boolean _hasBufferedText; + private StringBuffer _buffer = new StringBuffer(); + private int _textEventType; + + void init(XMLStreamReader xmlstream) + { + setParent(xmlstream); + _hasBufferedText = false; + _buffer.delete(0, _buffer.length()); + } + + public int next() + throws XMLStreamException + { + if (_hasBufferedText) + { + clearBuffer(); + return super.getEventType(); + } + + int evType = super.next(); + + if (evType == XMLEvent.CHARACTERS || evType == XMLEvent.CDATA || evType == XMLEvent.SPACE) + { + _textEventType = evType; + bufferText(); + } + + return evType; + } + + private void clearBuffer() + { + _buffer.delete(0, _buffer.length()); + _hasBufferedText = false; + } + + private void bufferText() + throws XMLStreamException + { + if (super.hasText()) + _buffer.append( super.getText()); + + _hasBufferedText = true; + + while (hasNext()) + { + int evType = super.next(); + + switch (evType) + { + case XMLEvent.CHARACTERS: + case XMLEvent.CDATA: + case XMLEvent.SPACE: + if (super.hasText()) + _buffer.append(super.getText()); + + case XMLEvent.COMMENT: + //ignore + continue; + default: + return; + } + } + } + + public String getText() + { + assert _hasBufferedText; + return _buffer.toString(); + } + + public int getTextLength() + { + assert _hasBufferedText; + return _buffer.length(); + } + + public int getTextStart() + { + assert _hasBufferedText; + return 0; + } + + public char[] getTextCharacters() + { + assert _hasBufferedText; + return _buffer.toString().toCharArray(); + } + + public int getTextCharacters(int sourceStart, char[] target, int targetStart, int length) + { + assert _hasBufferedText; + _buffer.getChars(sourceStart, sourceStart + length, target, targetStart); + return length; + } + + public boolean isWhiteSpace() + { + assert _hasBufferedText; + return XmlWhitespace.isAllSpace(_buffer); + } + + public boolean hasText() + { + if (_hasBufferedText) + return true; + else + return super.hasText(); + } + + public int getEventType() + { + if (_hasBufferedText) + return _textEventType; + else + return super.getEventType(); + } + } + + private static class ElementEventImpl + implements ValidatorListener.Event + { + private static final int BUF_LENGTH = 1024; + private char[] _buf = new char[BUF_LENGTH]; + private int _length; + private boolean _supportForGetTextCharacters = true; + + private XMLStreamReader _xmlStream; + + private void setXMLStreamReader(XMLStreamReader xsr) + { + _xmlStream = xsr; + } + + // can return null, used only to locate errors + public XmlCursor getLocationAsCursor() + { + return null; + } + + public javax.xml.stream.Location getLocation() + { + return _xmlStream.getLocation(); + } + + // fill up chars with the xsi:type attribute value if there is one othervise return false + public String getXsiType() // BEGIN xsi:type + { + return _xmlStream.getAttributeValue(URI_XSI, "type"); + } + + // fill up chars with xsi:nill attribute value if any + public String getXsiNil() // BEGIN xsi:nil + { + return _xmlStream.getAttributeValue(URI_XSI, "nil"); + } + + // not used curently + public String getXsiLoc() // BEGIN xsi:schemaLocation + { + return _xmlStream.getAttributeValue(URI_XSI, "schemaLocation"); + } + + // not used curently + public String getXsiNoLoc() // BEGIN xsi:noNamespaceSchemaLocation + { + return _xmlStream.getAttributeValue(URI_XSI, "noNamespaceSchemaLocation"); + } + + // On START and ATTR + public QName getName() + { + // avoid construction of a new QName object after the bug in getName() is fixed. + if (_xmlStream.hasName()) + return new QName(_xmlStream.getNamespaceURI(), _xmlStream.getLocalName()); + else + return null; + } + + // On TEXT and ATTR + public String getText() + { + _length = 0; + addTextToBuffer(); + return new String( _buf, 0, _length ); +// return _xmlStream.getText(); + } + + public String getText(int wsr) + { + return XmlWhitespace.collapse( _xmlStream.getText(), wsr ); + } + + public boolean textIsWhitespace() + { + return _xmlStream.isWhiteSpace(); + } + + public String getNamespaceForPrefix(String prefix) + { + return _xmlStream.getNamespaceURI(prefix); + } + + private void addTextToBuffer() + { + int textLength = _xmlStream.getTextLength(); + ensureBufferLength(textLength); + + if (_supportForGetTextCharacters) + try + { + _length = _xmlStream.getTextCharacters(0, _buf, _length, textLength); + } + catch(Exception e) + { + _supportForGetTextCharacters = false; + } + + if(!_supportForGetTextCharacters) + { + System.arraycopy(_xmlStream.getTextCharacters(), _xmlStream.getTextStart(), _buf, _length, textLength); + _length = _length + textLength; + } + } + + private void ensureBufferLength(int lengthToAdd) + { + if (_length + lengthToAdd>_buf.length) + { + char[] newBuf = new char[_length + lengthToAdd]; + if (_length>0) + System.arraycopy(_buf, 0, newBuf, 0, _length); + _buf = newBuf; + } + } + } + + private static final class AttributeEventImpl + implements ValidatorListener.Event + { + private int _attIndex; + private XMLStreamReader _xmlStream; + + private void setXMLStreamReader(XMLStreamReader xsr) + { + _xmlStream = xsr; + } + + // can return null, used only to locate errors + public XmlCursor getLocationAsCursor() + { + return null; + } + + public javax.xml.stream.Location getLocation() + { + return _xmlStream.getLocation(); + } + + // fill up chars with the xsi:type attribute value if there is one othervise return false + public String getXsiType() // BEGIN xsi:type + { + throw new IllegalStateException(); + } + + // fill up chars with xsi:nill attribute value if any + public String getXsiNil() // BEGIN xsi:nil + { + throw new IllegalStateException(); + } + + // not used curently + public String getXsiLoc() // BEGIN xsi:schemaLocation + { + throw new IllegalStateException(); + } + + // not used curently + public String getXsiNoLoc() // BEGIN xsi:noNamespaceSchemaLocation + { + throw new IllegalStateException(); + } + + // On START and ATTR + public QName getName() + { + assert _xmlStream.isStartElement() : "Not on Start Element."; + String uri = _xmlStream.getAttributeNamespace(_attIndex); + QName qn = new QName(uri==null ? "" : uri, _xmlStream.getAttributeLocalName(_attIndex)); + //System.out.println(" Att QName: " + qn); + return qn; + } + + // On TEXT and ATTR + public String getText() + { + assert _xmlStream.isStartElement() : "Not on Start Element."; + return _xmlStream.getAttributeValue(_attIndex); + } + + public String getText(int wsr) + { + assert _xmlStream.isStartElement() : "Not on Start Element."; + return XmlWhitespace.collapse( _xmlStream.getAttributeValue(_attIndex), wsr ); + } + + public boolean textIsWhitespace() + { + throw new IllegalStateException(); + } + + public String getNamespaceForPrefix(String prefix) + { + assert _xmlStream.isStartElement() : "Not on Start Element."; + return _xmlStream.getNamespaceURI(prefix); + } + + private void setAttributeIndex(int attIndex) + { + _attIndex = attIndex; + } + } + + /** + * This is used as implementation of Event for validating global attributes + * and for pushing the buffered attributes + */ + private static final class SimpleEventImpl + implements ValidatorListener.Event + { + private String _text; + private QName _qname; + private XMLStreamReader _xmlStream; + + private void setXMLStreamReader(XMLStreamReader xsr) + { + _xmlStream = xsr; + } + + // should return null, getLocation will be used, used only to locate errors + public XmlCursor getLocationAsCursor() + { return null; } + + public javax.xml.stream.Location getLocation() + { + return _xmlStream.getLocation(); + } + + // fill up chars with the xsi:type attribute value if there is one othervise return false + public String getXsiType() // BEGIN xsi:type + { return null; } + + // fill up chars with xsi:nill attribute value if any + public String getXsiNil() // BEGIN xsi:nil + { return null; } + + // not used curently + public String getXsiLoc() // BEGIN xsi:schemaLocation + { return null; } + + // not used curently + public String getXsiNoLoc() // BEGIN xsi:noNamespaceSchemaLocation + { return null; } + + // On START and ATTR + public QName getName() + { return _qname; } + + // On TEXT and ATTR + public String getText() + { + return _text; + } + + public String getText(int wsr) + { + return XmlWhitespace.collapse( _text, wsr ); + } + + public boolean textIsWhitespace() + { return false; } + + public String getNamespaceForPrefix(String prefix) + { + return _xmlStream.getNamespaceURI(prefix); + } + } + + /* public methods in XMLStreamReader */ + + public Object getProperty(String s) throws IllegalArgumentException + { + return super.getProperty(s); + } + + public int next() throws XMLStreamException + { + int evType = super.next(); + //debugEvent(evType); + + validate_event(evType); + + return evType; + } + + private void validate_event(int evType) + { + if (_state==STATE_ERROR) + return; + + if (_depth<0) + throw new IllegalArgumentException("ValidatingXMLStreamReader cannot go further than the subtree is was initialized on."); + + switch(evType) + { + case XMLEvent.START_ELEMENT: + _depth++; + if (_state == STATE_ATTBUFFERING) + pushBufferedAttributes(); + + if (_validator==null) + { + // avoid construction of a new QName object after the bug in getName() is fixed. + QName qname = new QName(getNamespaceURI(), getLocalName()); + + if (_contentType==null) + _contentType = typeForGlobalElement(qname); + + if (_state==STATE_ERROR) + break; + + initValidator(_contentType); + _validator.nextEvent(Validator.BEGIN, _elemEvent); + } + + _validator.nextEvent(Validator.BEGIN, _elemEvent); + + int attCount = getAttributeCount(); + validate_attributes(attCount); + + break; + + case XMLEvent.ATTRIBUTE: + if (getAttributeCount()==0) + break; + + if (_state == STATE_FIRSTEVENT || _state == STATE_ATTBUFFERING) + { + // buffer all Attributes + for (int i=0; i 1 than the validator will add an error + } + else + { + addError("No content type provided for validation of a content model."); + _state = STATE_ERROR; + return; + } + } + + // here validationType is the right type, start pushing all acumulated attributes + initValidator(validationType); + _validator.nextEvent(Validator.BEGIN, _simpleEvent); + + // validate attributes from _attNamesList + validate_attributes(_attNamesList.size()); + _attNamesList = null; + _attValuesList = null; + + _state = STATE_VALIDATING; + } + + private boolean isSpecialAttribute(QName qn) + { + if (qn.getNamespaceURI().equals(URI_XSI)) + return qn.getLocalPart().equals(XSI_TYPE.getLocalPart()) || + qn.getLocalPart().equals(XSI_NIL.getLocalPart()) || + qn.getLocalPart().equals(XSI_SL.getLocalPart()) || + qn.getLocalPart().equals(XSI_NSL.getLocalPart()); + + return false; + } + + /** + * Initializes the validator for the given schemaType + * @param schemaType + */ + private void initValidator(SchemaType schemaType) + { + assert schemaType!=null; + + _validator = new Validator(schemaType, null, _stl, _options, _errorListener); + } + + private SchemaType typeForGlobalElement(QName qname) + { + assert qname!=null; + + SchemaType docType = _stl.findDocumentType(qname); + + if (docType==null) + { + addError("Schema document type not found for element '" + qname + "'."); + _state = STATE_ERROR; + } + return docType; + } + + private void addError(String msg) + { + String source = null; + Location location = getLocation(); + + if (location != null) + { + source = location.getPublicId(); + if (source==null) + source = location.getSystemId(); + + _errorListener.add(XmlError.forLocation(msg, source, location)); + } + else + _errorListener.add(XmlError.forMessage(msg)); + } + + protected void validate_attributes(int attCount) + { + for(int i=0; i 0) + { + switch ( kind ) + { + case END : _eatContent--; break; + case BEGIN : _eatContent++; break; + } + } + else + { + assert + kind == BEGIN || kind == ATTR || + kind == END || kind == TEXT || kind == ENDATTRS; + + switch ( kind ) + { + case BEGIN : beginEvent( event ); break; + case ATTR : attrEvent( event ); break; + case ENDATTRS : endAttrsEvent( event ); break; + case TEXT : textEvent( event ); break; + case END : endEvent( event ); break; + } + } + } + + private void beginEvent ( Event event ) + { + _localElement = null; + _wildcardElement = null; + State state = topState(); + + SchemaType elementType = null; + SchemaField elementField = null; + + if (state == null) + { + elementType = _rootType; + elementField = _rootField; + } + else + { + + QName name = event.getName(); + + assert name != null; + + state._isEmpty = false; + + if (state._isNil) + { + emitFieldError(event, XmlErrorCodes.ELEM_LOCALLY_VALID$NIL_WITH_CONTENT, + null, state._field.getName(), state._type, null, + XmlValidationError.NIL_ELEMENT, state._type); + + _eatContent = 1; + return; + } + + if (!state._isNil && state._field != null && state._field.isFixed()) + { + emitFieldError(event, XmlErrorCodes.ELEM_LOCALLY_VALID$FIXED_WITH_CONTENT, + new Object[] { QNameHelper.pretty(state._field.getName()) }, + state._field.getName(), state._type, null, + XmlValidationError.ELEMENT_NOT_ALLOWED, state._type); + } + + if (!state.visit( name )) + { + findDetailedErrorBegin(event ,state , name); + + _eatContent = 1; + + return; + } + + SchemaParticle currentParticle = state.currentParticle(); + _wildcardElement = currentParticle; + + if (currentParticle.getParticleType() == SchemaParticle.WILDCARD) + { + //_wildcardElement = currentParticle; + QNameSet elemWildcardSet = currentParticle.getWildcardSet(); + + if (!elemWildcardSet.contains( name )) + { + // Additional processing may be needed to generate more + // descriptive messages + // KHK: cvc-complex-type.2.4? cvc-particle.1.3? cvc-wildcard-namespace ? + emitFieldError(event, XmlErrorCodes.PARTICLE_VALID$NOT_WILDCARD_VALID, + new Object[] { QNameHelper.pretty(name) }, + name, null, null, + XmlValidationError.ELEMENT_NOT_ALLOWED, state._type); + + _eatContent = 1; + + return; + } + + int wildcardProcess = currentParticle.getWildcardProcess(); + + if (wildcardProcess == SchemaParticle.SKIP || + wildcardProcess == SchemaParticle.LAX && _treatLaxAsSkip) + { + _eatContent = 1; + return; + } + + _localElement = _globalTypes.findElement( name ); + elementField = _localElement; + + if (elementField == null) + { + if (wildcardProcess == SchemaParticle.STRICT) + { + // KHK: cvc-complex-type.2.4c? cvc-assess-elt.1.1.1.3.2? + emitFieldError( event, XmlErrorCodes.ASSESS_ELEM_SCHEMA_VALID$NOT_RESOLVED, + new Object[] { QNameHelper.pretty(name) }, + name, state._type, null, + XmlValidationError.ELEMENT_NOT_ALLOWED, state._type); + } + + _eatContent = 1; + + return; + } + } + else + { + assert currentParticle.getParticleType() == SchemaParticle.ELEMENT; + + // If the current element particle name does not match the name + // of the event, then the current element is a substitute for + // the current particle. Replace the field with the global + // element for the replacement + + if (! currentParticle.getName().equals(name)) + { + if (((SchemaLocalElement)currentParticle).blockSubstitution()) + { + emitFieldError( event, XmlErrorCodes.PARTICLE_VALID$BLOCK_SUBSTITUTION, + new Object[] { QNameHelper.pretty(name) }, + name, state._type, null, + XmlValidationError.ELEMENT_NOT_ALLOWED, state._type); + + _eatContent = 1; + return; + } + + SchemaGlobalElement newField = _globalTypes.findElement(name); + + assert newField != null; + + if (newField != null) + { + elementField = newField; + _localElement = newField; + } + } + else + { + elementField = (SchemaField) currentParticle; + } + } + + elementType = elementField.getType(); + } + + assert elementType != null; + + // + // the no-type is always invalid (even if there is an xsi:type) + // + + if (elementType.isNoType()) + { + emitFieldError( event, XmlErrorCodes.ELEM_LOCALLY_VALID$NO_TYPE, + null, event.getName(), null, null, + XmlValidationError.ELEMENT_TYPE_INVALID, null); + + _eatContent = 1; + } + + // + // See if the element has an xsi:type on it + // + + SchemaType xsiType = null; + + String value = event.getXsiType(); + + if (value != null) + { + // Turn off the listener so a public error message + // does not get generated, but I can see if there was + // an error through the error state + + int originalErrorState = _errorState; + + _suspendErrors++; + + try + { + _vc._event = null; + + xsiType = _globalTypes.findType( XmlQNameImpl.validateLexical( value, _vc, event ) ); + } + catch ( Throwable t ) + { + _errorState++; + } + finally + { + _suspendErrors--; + } + + if (originalErrorState != _errorState) + { + // not sure how to extract this one + emitFieldError( event, XmlErrorCodes.ELEM_LOCALLY_VALID$XSI_TYPE_INVALID_QNAME, + new Object[] { value }, event.getName(), xsiType, null, + XmlValidationError.ELEMENT_TYPE_INVALID, state._type); + + _eatContent = 1; + + return; + } + else if (xsiType == null) + { + // NOT SURE errorAttributes._expectedSchemaType = xsiType; + emitFieldError( event, XmlErrorCodes.ELEM_LOCALLY_VALID$XSI_TYPE_NOT_FOUND, + new Object[] { value }, event.getName(), null, null, + XmlValidationError.ELEMENT_TYPE_INVALID, null); + + _eatContent = 1; + + return; + } + } + + if (xsiType != null && !xsiType.equals(elementType)) + { + if (!elementType.isAssignableFrom(xsiType)) + { + emitFieldError( event, XmlErrorCodes.ELEM_LOCALLY_VALID$XSI_TYPE_NOT_DERIVED, + new Object[] { xsiType, elementType }, event.getName(), elementType, null, + XmlValidationError.ELEMENT_TYPE_INVALID, (state == null ? null : state._type)); + + _eatContent = 1; + + return; + } + + if (elementType.blockExtension()) + { + for ( SchemaType t = xsiType ; ! t.equals( elementType ) ; + t = t.getBaseType() ) + { + if (t.getDerivationType() == SchemaType.DT_EXTENSION) + { + emitFieldError( event, XmlErrorCodes.ELEM_LOCALLY_VALID$XSI_TYPE_BLOCK_EXTENSION, + new Object[] { xsiType, elementType }, event.getName(), elementType, null, + XmlValidationError.ELEMENT_TYPE_INVALID, (state == null ? null : state._type)); + + _eatContent = 1; + + return; + } + } + } + + if (elementType.blockRestriction()) + { + for ( SchemaType t = xsiType ; ! t.equals( elementType ) ; + t = t.getBaseType() ) + { + if (t.getDerivationType() == SchemaType.DT_RESTRICTION) + { + emitFieldError( event, XmlErrorCodes.ELEM_LOCALLY_VALID$XSI_TYPE_BLOCK_RESTRICTION, + new Object[] { xsiType, elementType }, event.getName(), elementType, null, + XmlValidationError.ELEMENT_TYPE_INVALID, (state == null ? null : state._type)); + + _eatContent = 1; + + return; + } + } + } + + if (elementField instanceof SchemaLocalElement) + { + SchemaLocalElement sle = (SchemaLocalElement)elementField; + _localElement = sle; + + if (sle.blockExtension() || sle.blockRestriction()) + { + for ( SchemaType t = xsiType ; ! t.equals( elementType ) ; + t = t.getBaseType() ) + { + if ((t.getDerivationType() == SchemaType.DT_RESTRICTION && sle.blockRestriction()) || + (t.getDerivationType() == SchemaType.DT_EXTENSION && sle.blockExtension())) + { + //need to find a way to get the right type + emitFieldError( event, XmlErrorCodes.ELEM_LOCALLY_VALID$XSI_TYPE_PROHIBITED_SUBST, + new Object[] { xsiType, QNameHelper.pretty(sle.getName()) }, + sle.getName(), null, null, XmlValidationError.ELEMENT_TYPE_INVALID, null); + + _eatContent = 1; + + return; + } + } + } + } + + elementType = xsiType; + } + + if (elementField instanceof SchemaLocalElement) + { + SchemaLocalElement sle = (SchemaLocalElement)elementField; + _localElement = sle; + + if (sle.isAbstract()) + { + //todo (dutta) need to find a way to get the right type + emitError(event, XmlErrorCodes.ELEM_LOCALLY_VALID$ABSTRACT, + new Object[] { QNameHelper.pretty(sle.getName()) }, + sle.getName(), null, null, XmlValidationError.ELEMENT_TYPE_INVALID, null); + + _eatContent = 1; + return; + } + } + + if (elementType != null && elementType.isAbstract()) + { + emitError(event, XmlErrorCodes.ELEM_LOCALLY_VALID$ABSTRACT, + new Object[] { elementType }, + event.getName(), elementType, null, XmlValidationError.ELEMENT_TYPE_INVALID, (state == null ? null : state._type)); + + _eatContent = 1; + + return; + } + + boolean isNil = false; + boolean hasNil = false; + + String nilValue = event.getXsiNil(); + + if (nilValue != null) + { + _vc._event = event; + isNil = JavaBooleanHolder.validateLexical(nilValue, _vc); + hasNil = true; + } + + // note in schema spec 3.3.4, you're not even allowed to say xsi:nil="false" if you're not nillable! + if (hasNil && (elementField == null || !elementField.isNillable())) + { + emitFieldError( event, XmlErrorCodes.ELEM_LOCALLY_VALID$NOT_NILLABLE, null, + elementField == null ? null : elementField.getName(), elementType, null, + XmlValidationError.ELEMENT_TYPE_INVALID, (state == null ? null : state._type)); + + _eatContent = 1; + return; + } + + if (isNil && elementField != null && elementField.isFixed()) + { + emitFieldError( event, XmlErrorCodes.ELEM_LOCALLY_VALID$NIL_WITH_FIXED, null, + elementField == null ? null : elementField.getName(), elementType, null, + XmlValidationError.ELEMENT_TYPE_INVALID, (state == null ? null : state._type)); + } + + newState( elementType, elementField, isNil ); + + // Dispatch this element event to any identity constraints + // As well as adding any new identity constraints that exist + + _constraintEngine.element( + event, + elementType, + elementField instanceof SchemaLocalElement + ? ((SchemaLocalElement) elementField).getIdentityConstraints() + : null ); + } + + private void attrEvent ( Event event ) + { + QName attrName = event.getName(); + + State state = topState(); + + if (state._attrs == null) + state._attrs = new HashSet(); + + if (state._attrs.contains( attrName )) + { + emitFieldError( event, XmlErrorCodes.XML_DUPLICATE_ATTRIBUTE, + new Object[] { QNameHelper.pretty( attrName ) }, + attrName, null, null, XmlValidationError.INCORRECT_ATTRIBUTE, state._type ); + + return; + } + + state._attrs.add( attrName ); + + if (!state._canHaveAttrs) + { + emitFieldError( event, XmlErrorCodes.ELEM_COMPLEX_TYPE_LOCALLY_VALID$NO_WILDCARD, + new Object[] {QNameHelper.pretty( attrName )}, attrName, null, null, + XmlValidationError.INCORRECT_ATTRIBUTE, state._type); + return; + } + + SchemaLocalAttribute attrSchema = + state._attrModel == null + ? null + : state._attrModel.getAttribute( attrName ); + + if (attrSchema != null) + { + _localAttribute = attrSchema; + + if (attrSchema.getUse() == SchemaLocalAttribute.PROHIBITED) + { + emitFieldError( event, XmlErrorCodes.ELEM_COMPLEX_TYPE_LOCALLY_VALID$PROHIBITED_ATTRIBUTE, + new Object[] { QNameHelper.pretty( attrName ) } , + attrName, null, null, XmlValidationError.INCORRECT_ATTRIBUTE, state._type ); + + return; + } + + String value = + validateSimpleType( + attrSchema.getType(), attrSchema, event, false, false ); + + _constraintEngine.attr( event, attrName, attrSchema.getType(), value ); + + return; + } + + int wildcardProcess = state._attrModel.getWildcardProcess(); + + _wildcardAttribute = state._attrModel; + + if (wildcardProcess == SchemaAttributeModel.NONE) + { + // todo (dutta) need additional logic to determine the expectedSchemaType + emitFieldError( event, XmlErrorCodes.ELEM_COMPLEX_TYPE_LOCALLY_VALID$NO_WILDCARD, + new Object[] { QNameHelper.pretty( attrName ) }, + attrName, null, null, XmlValidationError.INCORRECT_ATTRIBUTE, state._type); + + return; + } + + QNameSet attrWildcardSet = state._attrModel.getWildcardSet(); + + if (!attrWildcardSet.contains( attrName )) + { + // todo (dutta) need additional logic to determine the expectedSchemaType + emitFieldError( event, XmlErrorCodes.ELEM_COMPLEX_TYPE_LOCALLY_VALID$NOT_WILDCARD_VALID, + new Object[] { QNameHelper.pretty( attrName ) }, + attrName, null, null, XmlValidationError.INCORRECT_ATTRIBUTE, state._type); + + return; + } + + if (wildcardProcess == SchemaAttributeModel.SKIP || + wildcardProcess == SchemaAttributeModel.LAX && _treatLaxAsSkip) + return; + + attrSchema = _globalTypes.findAttribute( attrName ); + _localAttribute = attrSchema; + + if (attrSchema == null) + { + if (wildcardProcess == SchemaAttributeModel.LAX) + return; + + assert wildcardProcess == SchemaAttributeModel.STRICT; + + // KHK: cvc-assess-attr.1.2 ? + // todo (dutta) need additional logic to determine the expectedSchemaType + emitFieldError( event, XmlErrorCodes.ASSESS_ATTR_SCHEMA_VALID$NOT_RESOLVED, + new Object[] { QNameHelper.pretty( attrName ) }, + attrName, null, null, XmlValidationError.INCORRECT_ATTRIBUTE, state._type); + + return; + } + + String value = + validateSimpleType( + attrSchema.getType(), attrSchema, event, false, false ); + + _constraintEngine.attr( event, attrName, attrSchema.getType(), value ); + } + + private void endAttrsEvent ( Event event ) + { + State state = topState(); + + if (state._attrModel != null) + { + SchemaLocalAttribute[] attrs = state._attrModel.getAttributes(); + + for ( int i = 0 ; i < attrs.length ; i++ ) + { + SchemaLocalAttribute sla = attrs[ i ]; + + if (state._attrs == null || + !state._attrs.contains( sla.getName() )) + { + if (sla.getUse() == SchemaLocalAttribute.REQUIRED) + { + // KHK: cvc-complex-type.4 + emitFieldError( event, XmlErrorCodes.ELEM_COMPLEX_TYPE_LOCALLY_VALID$MISSING_REQUIRED_ATTRIBUTE, + new Object[] { QNameHelper.pretty(sla.getName()) }, + sla.getName(), null, null, XmlValidationError.INCORRECT_ATTRIBUTE, state._type); + } + else if (sla.isDefault() || sla.isFixed()) + { + _constraintEngine.attr(event, sla.getName(), sla.getType(), sla.getDefaultText()); + + // We don't need to validate attribute defaults because this is done at compiletime. + /* + String value = sla.getDefaultText(); + SchemaType type = sla.getType(); + + if (XmlQName.type.isAssignableFrom(type)) + { + emitFieldError( + event, + "Default QName values are unsupported for attribute: " + + QNameHelper.pretty(sla.getName()), + XmlError.SEVERITY_INFO); + } + + else + { + validateSimpleType( + type, sla.getDefaultText(), event ); + + _constraintEngine.attr( event, type, value ); + } + */ + } + } + } + } + } + + private void endEvent ( Event event ) + { + _localElement = null; + _wildcardElement = null; + State state = topState(); + + if (!state._isNil) + { + if (!state.end()) + { + findDetailedErrorEnd(event,state); + } + + // This end event has no text, use this fact to pass no text to + // handleText + + if (state._isEmpty) + handleText( event, true, state._field ); + } + + popState( event ); + + _constraintEngine.endElement( event ); + } + + private void textEvent ( Event event ) + { + State state = topState(); + + if (state._isNil) + { + emitFieldError( event, XmlErrorCodes.ELEM_LOCALLY_VALID$NIL_WITH_CONTENT, null, + state._field.getName(), state._type, null, + XmlValidationError.NIL_ELEMENT, state._type ); + } + else + handleText( event, false, state._field ); + + state._isEmpty = false; + } + + + private void handleText ( + Event event, boolean emptyContent, SchemaField field ) + { + State state = topState(); + + if (!state._sawText) + { + if (state._hasSimpleContent) + { + String value = + validateSimpleType( + state._type, field, event, emptyContent, true ); + + _constraintEngine.text( event, state._type, value, false ); + } + else if (state._canHaveMixedContent) + { + // handles cvc-elt.5.2.2.2.1, checking mixed content against fixed. + // if we see a
    c, we validate against + // the first 'a' text and we check the content of mixedType to + // be empty in beginElem(). we don't care about checking against + // the 'c' text since there will already be an error for + String value = + validateSimpleType( + XmlString.type, field, event, emptyContent, true ); + + _constraintEngine.text( event, XmlString.type, value, false ); + } + else if (emptyContent) + { + _constraintEngine.text( event, state._type, null, true ); + } + else + _constraintEngine.text( event, state._type, "", false); + } + + if (!emptyContent && !state._canHaveMixedContent && + !event.textIsWhitespace() && !state._hasSimpleContent) + { + if (field instanceof SchemaLocalElement) + { + SchemaLocalElement e = (SchemaLocalElement)field; + + assert state._type.getContentType() == SchemaType.EMPTY_CONTENT || + state._type.getContentType() == SchemaType.ELEMENT_CONTENT; + + // KHK: cvc-complex-type.2.1 or .2.3 + String errorCode = (state._type.getContentType() == SchemaType.EMPTY_CONTENT ? + XmlErrorCodes.ELEM_COMPLEX_TYPE_LOCALLY_VALID$EMPTY_WITH_CONTENT : + XmlErrorCodes.ELEM_COMPLEX_TYPE_LOCALLY_VALID$ELEMENT_ONLY_WITH_TEXT); + + emitError(event, errorCode,new Object[] {QNameHelper.pretty(e.getName())}, + e.getName(), field.getType(), null, + XmlValidationError.ELEMENT_TYPE_INVALID, null); + } + else + { + // KHK: cvc-complex-type.2.1 or .2.3 + // todo (dutta) offendingQName = not sure how to get this(event.getName()??); + emitError(event, "Can't have mixed content", event.getName(), + state._type, null, XmlValidationError.ELEMENT_TYPE_INVALID, null); + } + } + + if (!emptyContent) + state._sawText = true; + } + + private void findDetailedErrorBegin(Event event, State state, QName qName) + { + ArrayList expectedNames = new ArrayList(); + ArrayList optionalNames = new ArrayList(); + + SchemaProperty[] eltProperties = state._type.getElementProperties(); + for (int ii = 0; ii < eltProperties.length; ii++) + { + //Get the element from the schema + SchemaProperty sProp = eltProperties[ii]; + + // test if the element is valid + if (state.test(sProp.getName())) + { + if (0 == BigInteger.ZERO.compareTo(sProp.getMinOccurs())) + optionalNames.add(sProp.getName()); + else + expectedNames.add(sProp.getName()); + } + } + + List names = (expectedNames.size() > 0 ? expectedNames : optionalNames); + + if (names.size() > 0) + { + StringBuffer buf = new StringBuffer(); + for (Iterator iter = names.iterator(); iter.hasNext();) + { + QName qname = (QName) iter.next(); + buf.append(QNameHelper.pretty(qname)); + if (iter.hasNext()) + buf.append(" "); + } + + emitFieldError( event, XmlErrorCodes.ELEM_COMPLEX_TYPE_LOCALLY_VALID$EXPECTED_DIFFERENT_ELEMENT, + new Object[] { new Integer(names.size()), buf.toString(), QNameHelper.pretty(qName) }, + qName, null, names, XmlValidationError.INCORRECT_ELEMENT, state._type); + } + else + { + emitFieldError( event, XmlErrorCodes.ELEM_COMPLEX_TYPE_LOCALLY_VALID$ELEMENT_NOT_ALLOWED, + new Object[] { QNameHelper.pretty(qName) }, + qName, null, null, XmlValidationError.INCORRECT_ELEMENT, state._type); + } + } + + private void findDetailedErrorEnd(Event event, State state) + { + SchemaProperty[] eltProperties = state._type.getElementProperties(); + + ArrayList expectedNames = new ArrayList(); + ArrayList optionalNames = new ArrayList(); + + for (int ii = 0; ii < eltProperties.length; ii++) + { + //Get the element from the schema + SchemaProperty sProp = eltProperties[ii]; + + // test if the element is valid + if (state.test(sProp.getName())) + { + if (0 == BigInteger.ZERO.compareTo(sProp.getMinOccurs())) + optionalNames.add(sProp.getName()); + else + expectedNames.add(sProp.getName()); + } + } + + List names = (expectedNames.size() > 0 ? expectedNames : optionalNames); + + if (names.size() > 0) + { + StringBuffer buf = new StringBuffer(); + for (Iterator iter = names.iterator(); iter.hasNext();) + { + QName qname = (QName) iter.next(); + buf.append(QNameHelper.pretty(qname)); + if (iter.hasNext()) + buf.append(" "); + } + + emitFieldError( event, XmlErrorCodes.ELEM_COMPLEX_TYPE_LOCALLY_VALID$MISSING_ELEMENT, + new Object[] { new Integer(names.size()), buf.toString() }, + null, null, names, XmlValidationError.INCORRECT_ELEMENT, state._type); + } + else + { + emitFieldError( event, XmlErrorCodes.ELEM_COMPLEX_TYPE_LOCALLY_VALID$EXPECTED_ELEMENT, + null, null, null, null, XmlValidationError.ELEMENT_NOT_ALLOWED, state._type); + } + } + + + private final class State + { + boolean visit ( QName name ) + { + return _canHaveElements && _visitor.visit( name ); + } + + boolean test( QName name ) + { + return _canHaveElements && _visitor.testValid( name ); + } + + boolean end ( ) + { + return !_canHaveElements || _visitor.visit( null ); + } + + SchemaParticle currentParticle ( ) + { + assert _visitor != null; + return _visitor.currentParticle(); + } + + SchemaType _type; + SchemaField _field; + + boolean _canHaveAttrs; + boolean _canHaveMixedContent; + boolean _hasSimpleContent; + + boolean _sawText; + boolean _isEmpty; + boolean _isNil; + + SchemaTypeVisitorImpl _visitor; + boolean _canHaveElements; + + SchemaAttributeModel _attrModel; + + HashSet _attrs; + + State _next; + } + + private boolean derivedFromInteger( SchemaType type ) + { + int btc = type.getBuiltinTypeCode(); + + while (btc == SchemaType.BTC_NOT_BUILTIN) + { + type = type.getBaseType(); + btc = type.getBuiltinTypeCode(); + } + // This depends on the ordering of the constant values, which is not ideal but is easier + return btc >= SchemaType.BTC_INTEGER && btc <= SchemaType.BTC_UNSIGNED_BYTE; + } + + private void newState ( SchemaType type, SchemaField field, boolean isNil ) + { + State state = new State(); + + state._type = type; + state._field = field; + state._isEmpty = true; + state._isNil = isNil; + + if (type.isSimpleType()) + { + state._hasSimpleContent = true; + } + else + { + state._canHaveAttrs = true; + state._attrModel = type.getAttributeModel(); + + switch ( type.getContentType() ) + { + case SchemaType.EMPTY_CONTENT : + break; + + case SchemaType.SIMPLE_CONTENT : + state._hasSimpleContent = true; + break; + + case SchemaType.MIXED_CONTENT : + state._canHaveMixedContent = true; + // Fall through + + case SchemaType.ELEMENT_CONTENT : + + SchemaParticle particle = type.getContentModel(); + + state._canHaveElements = particle != null; + + if (state._canHaveElements) + state._visitor = initVisitor( particle ); + + break; + + default : + throw new RuntimeException( "Unexpected content type" ); + } + } + + pushState( state ); + } + + private void popState ( Event e ) + { + if (_stateStack._visitor != null) + { + poolVisitor( _stateStack._visitor ); + _stateStack._visitor = null; + } + + _stateStack = _stateStack._next; + } + + private void pushState ( State state ) + { + state._next = _stateStack; + _stateStack = state; + } + + private LinkedList _visitorPool = new LinkedList(); + + private void poolVisitor( SchemaTypeVisitorImpl visitor ) + { + _visitorPool.add( visitor ); + } + + private SchemaTypeVisitorImpl initVisitor( SchemaParticle particle ) + { + if (_visitorPool.isEmpty()) + return new SchemaTypeVisitorImpl( particle ); + + SchemaTypeVisitorImpl result = + (SchemaTypeVisitorImpl) _visitorPool.removeLast(); + + result.init( particle ); + + return result; + } + + private State topState ( ) + { + return _stateStack; + } + + // + // Simple Type Validation + // + // emptyContent means that you can't use the event to get text: there is + // no text, but you can use the event to do prefix resolution (in the case + // where the default is a qname) + // + + private String validateSimpleType ( + SchemaType type, SchemaField field, Event event, + boolean emptyContent, boolean canApplyDefault ) + { + if (!type.isSimpleType() && + type.getContentType() != SchemaType.SIMPLE_CONTENT) + { + assert false; + // throw new RuntimeException( "Not a simple type" ); + return null; // should never happen + } + + // + // the no-type is always invalid + // + + if (type.isNoType()) + { + emitError(event, (field.isAttribute() ? XmlErrorCodes.ATTR_LOCALLY_VALID$NO_TYPE : XmlErrorCodes.ELEM_LOCALLY_VALID$NO_TYPE), + null, field.getName(), type, null, XmlValidationError.ELEMENT_TYPE_INVALID, null); + + return null; + } + + // Get the value as a string (as normalized by the white space rule + // TODO - will want to optimize this later + + String value = ""; + + if (!emptyContent) + { + int wsr = type.getWhiteSpaceRule(); + value = wsr == SchemaType.WS_PRESERVE ? event.getText() : event.getText( wsr ); + } + + // See if I can apply a default/fixed value + + if (value.length() == 0 && canApplyDefault && field != null && + (field.isDefault() || field.isFixed())) + { + if (XmlQName.type.isAssignableFrom(type)) + { + // TODO: will be fixed in XmlSchema 1.1 + emitError( event, "Default QName values are unsupported for " + + QNameHelper.readable(type) + " - ignoring.", null, null, + XmlError.SEVERITY_INFO, field.getName(), null, type, null, + XmlValidationError.ELEMENT_TYPE_INVALID, null); + + return null; + } + + String defaultValue = + XmlWhitespace.collapse( + field.getDefaultText(), type.getWhiteSpaceRule() ); + +// BUGBUG - should validate defaultValue at compile time + // KHK: cvc-elt.5.1.2 ? + return + validateSimpleType( type, defaultValue, event ) + ? defaultValue + : null; + } + + // KHK: cvc-elt.5.2.1 ? + if (!validateSimpleType( type, value, event )) + return null; + + if (field != null && field.isFixed()) + { +// TODO - fixed value should have been cooked at compile time + String fixedValue = + XmlWhitespace.collapse( + field.getDefaultText(), type.getWhiteSpaceRule() ); + + if (!validateSimpleType( type, fixedValue, event )) + return null; + + XmlObject val = type.newValue( value ); + XmlObject def = type.newValue( fixedValue ); + + if (!val.valueEquals( def )) + { + // TODO (dutta) - make this more verbose + if (field.isAttribute()) + { + // KHK: check for is cvc-complex-type.3.1 or cvc-au + emitError(event, XmlErrorCodes.ATTR_LOCALLY_VALID$FIXED, + new Object[] { value, fixedValue, QNameHelper.pretty(event.getName()) }, + null, field.getType(), null, XmlValidationError.ELEMENT_TYPE_INVALID, null); + } + else + { + String errorCode = null; + + // see rule 5 of cvc-elt: Element Locally Valid (Element) + if (field.getType().getContentType() == SchemaType.MIXED_CONTENT) + errorCode = XmlErrorCodes.ELEM_LOCALLY_VALID$FIXED_VALID_MIXED_CONTENT; + else if (type.isSimpleType()) + errorCode = XmlErrorCodes.ELEM_LOCALLY_VALID$FIXED_VALID_SIMPLE_TYPE; + else + assert false : "Element with fixed may not be EMPTY or ELEMENT_ONLY"; + + emitError(event, errorCode, + new Object[] { value, fixedValue }, + field.getName(), field.getType(), null, XmlValidationError.ELEMENT_TYPE_INVALID, null); + } + + return null; + } + } + + return value; + } + + private boolean validateSimpleType ( + SchemaType type, String value, Event event ) + { + if (!type.isSimpleType() && + type.getContentType() != SchemaType.SIMPLE_CONTENT) + { + assert false; + throw new RuntimeException( "Not a simple type" ); + } + + int retState = _errorState; + + switch ( type.getSimpleVariety() ) + { + case SchemaType.ATOMIC : validateAtomicType( type, value, event );break; + case SchemaType.UNION : validateUnionType( type, value, event );break; + case SchemaType.LIST : validateListType( type, value, event );break; + + default : throw new RuntimeException( "Unexpected simple variety" ); + } + + return retState == _errorState; + } + + private void validateAtomicType ( + SchemaType type, String value, Event event ) + { + // Now we should have only an atomic type to validate + + assert type.getSimpleVariety() == SchemaType.ATOMIC; + + // Record the current error state to see if any new errors are made + int errorState = _errorState; + _vc._event = event; + + switch ( type.getPrimitiveType().getBuiltinTypeCode() ) + { + case SchemaType.BTC_ANY_SIMPLE : + { + // Always valid! + _stringValue = value; + break; + } + case SchemaType.BTC_STRING : + { + JavaStringEnumerationHolderEx.validateLexical( value, type, _vc ); + _stringValue = value; + break; + } + case SchemaType.BTC_DECIMAL : + { + JavaDecimalHolderEx.validateLexical( value, type, _vc ); + + // An additional rule states that if the type is xs:integer or derived from it, + // then the decimal dot is not allowed. + // verify that values extending xsd:integer don't have a decimal point + if ( derivedFromInteger( type ) && value.lastIndexOf('.') >= 0 ) + { + _vc.invalid(XmlErrorCodes.INTEGER, new Object[] { value }); + } + + if (errorState == _errorState) + { + _decimalValue = new BigDecimal( value ); + JavaDecimalHolderEx.validateValue( _decimalValue, type, _vc ); + } + + break; + } + case SchemaType.BTC_BOOLEAN : + { + _booleanValue = JavaBooleanHolderEx.validateLexical( value, type, _vc ); + break; + } + case SchemaType.BTC_FLOAT : + { + float f = + JavaFloatHolderEx.validateLexical( value, type, _vc ); + + if (errorState == _errorState) + JavaFloatHolderEx.validateValue( f, type, _vc ); + + _floatValue = f; + break; + } + case SchemaType.BTC_DOUBLE : + { + double d = + JavaDoubleHolderEx.validateLexical( value, type, _vc ); + + if (errorState == _errorState) + JavaDoubleHolderEx.validateValue( d, type, _vc ); + + _doubleValue = d; + break; + } + case SchemaType.BTC_QNAME : + { + QName n = + JavaQNameHolderEx.validateLexical( + value, type, _vc, event ); + + if (errorState == _errorState) + JavaQNameHolderEx.validateValue( n, type, _vc ); + + _qnameValue = n; + break; + } + case SchemaType.BTC_ANY_URI : + { + JavaUriHolderEx.validateLexical( value, type, _vc ); + // Do strict validation + if (_strict) + { + try + { + XsTypeConverter.lexAnyURI( value ); + } + catch (InvalidLexicalValueException ilve) + { + _vc.invalid(XmlErrorCodes.ANYURI, new Object[] { value }); + } + } + _stringValue = value; + break; + } + case SchemaType.BTC_G_MONTH : + { + // In the case of gMonth, there is some strict mode validation to do + if (_strict && value.length() == 6 && + value.charAt( 4 ) == '-' && value.charAt( 5 ) == '-') + _vc.invalid(XmlErrorCodes.DATE, new Object[] { value }); + // Fall through + } + 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 : + { + GDate d = XmlDateImpl.validateLexical( value, type, _vc ); + + if (d != null) + XmlDateImpl.validateValue( d, type, _vc ); + + _gdateValue = d; + break; + } + case SchemaType.BTC_DURATION : + { + GDuration d = XmlDurationImpl.validateLexical( value, type, _vc ); + + if (d != null) + XmlDurationImpl.validateValue( d, type, _vc ); + + _gdurationValue = d; + break; + } + case SchemaType.BTC_BASE_64_BINARY : + { + byte[] v = + JavaBase64HolderEx.validateLexical( value, type, _vc ); + + if (v != null) + JavaBase64HolderEx.validateValue( v, type, _vc ); + + _byteArrayValue = v; + break; + } + case SchemaType.BTC_HEX_BINARY : + { + byte[] v = + JavaHexBinaryHolderEx.validateLexical( value, type, _vc ); + + if (v != null) + JavaHexBinaryHolderEx.validateValue( v, type, _vc ); + + _byteArrayValue = v; + break; + } + case SchemaType.BTC_NOTATION : + { + QName n = + JavaNotationHolderEx.validateLexical( + value, type, _vc, event ); + + if (errorState == _errorState) + JavaNotationHolderEx.validateValue( n, type, _vc ); + + _qnameValue = n; + break; + } + + default : + throw new RuntimeException( "Unexpected primitive type code" ); + } + } + + private void validateListType ( + SchemaType type, String value, Event event ) + { + int errorState = _errorState; + + if (!type.matchPatternFacet( value )) + { + emitError(event, XmlErrorCodes.DATATYPE_VALID$PATTERN_VALID, + new Object[] { "list", value, QNameHelper.readable(type) }, + null, type, null, XmlValidationError.LIST_INVALID, null); + } + + String[] items = XmlListImpl.split_list(value); + + int i; + XmlObject o; + + if ((o = type.getFacet( SchemaType.FACET_LENGTH )) != null) + { + if ((i = ((SimpleValue)o).getIntValue()) != items.length) + { + //offending Qname not valid + emitError(event, XmlErrorCodes.DATATYPE_LENGTH_VALID$LIST_LENGTH, + new Object[] { value, new Integer(items.length), new Integer(i), QNameHelper.readable(type) }, + null, type, null, XmlValidationError.LIST_INVALID, null); + } + } + + if ((o = type.getFacet( SchemaType.FACET_MIN_LENGTH )) != null) + { + if ((i = ((SimpleValue)o).getIntValue()) > items.length) + { + //offending Qname not valid + emitError(event, XmlErrorCodes.DATATYPE_LENGTH_VALID$LIST_LENGTH, + new Object[] { value, new Integer(items.length), new Integer(i), QNameHelper.readable(type) }, + null, type, null, XmlValidationError.LIST_INVALID, null); + } + } + + if ((o = type.getFacet( SchemaType.FACET_MAX_LENGTH )) != null) + { + if ((i = ((SimpleValue)o).getIntValue()) < items.length) + { + //offending Qname not valid + emitError(event, XmlErrorCodes.DATATYPE_LENGTH_VALID$LIST_LENGTH, + new Object[] { value, new Integer(items.length), new Integer(i), QNameHelper.readable(type) }, + null, type, null, XmlValidationError.LIST_INVALID, null); + } + } + + SchemaType itemType = type.getListItemType(); + _listValue = new ArrayList(); + _listTypes = new ArrayList(); + + for ( i = 0 ; i < items.length ; i++ ) + { + validateSimpleType( + itemType, items[i], event ); + addToList(itemType); + } + + // If no errors up to this point, then I can create an + // XmlList from this value and campare it again enums. + + if (errorState == _errorState) + { + if (type.getEnumerationValues() != null) + { + // Lists which contain QNames will need a resolver + + NamespaceContext.push( + new NamespaceContext( event ) ); + + try + { + XmlObject listValue = ( (SchemaTypeImpl) type).newValidatingValue( value ); + } + catch (XmlValueOutOfRangeException e) + { + //offending Qname not valid ?? + emitError(event, XmlErrorCodes.DATATYPE_ENUM_VALID, + new Object[] { "list", value, QNameHelper.readable(type) }, + null, type, null, XmlValidationError.LIST_INVALID, null); + } + finally + { + NamespaceContext.pop(); + } + } + } + } + + private void validateUnionType ( + SchemaType type, String value, Event event ) + { + // TODO - if xsi:type is specified on a union, it selects + // that union member type + + if (!type.matchPatternFacet( value )) + { + //offending Qname not valid ?? + emitError(event, XmlErrorCodes.DATATYPE_VALID$PATTERN_VALID, + new Object[] { "union", value, QNameHelper.readable(type) }, + null, type, null, XmlValidationError.UNION_INVALID, null); + } + + int currentWsr = SchemaType.WS_PRESERVE; + String currentValue = value; + + SchemaType[] types = type.getUnionMemberTypes(); + + int originalState = _errorState; + + int i; + for ( i = 0 ; i < types.length ; i++ ) + { + int memberWsr = types[ i ].getWhiteSpaceRule(); + + if (memberWsr == SchemaType.WS_UNSPECIFIED) + memberWsr = SchemaType.WS_PRESERVE; + + if (memberWsr != currentWsr) + { + currentWsr = memberWsr; + currentValue = XmlWhitespace.collapse( value, currentWsr ); + } + + int originalErrorState = _errorState; + + _suspendErrors++; + + try + { + validateSimpleType( types[ i ], currentValue, event ); + } + finally + { + _suspendErrors--; + } + + if (originalErrorState == _errorState) + { + _unionType = types[i]; + break; + } + } + + _errorState = originalState; + + if (i >= types.length) + { + //offending Qname not valid ?? + emitError(event, XmlErrorCodes.DATATYPE_VALID$UNION, + new Object[] { value, QNameHelper.readable(type) }, + null, type, null, XmlValidationError.UNION_INVALID, null); + } + else + { + XmlObject[] unionEnumvals = type.getEnumerationValues(); + + if (unionEnumvals != null) + { + // Unions which contain QNames will need a resolver + + NamespaceContext.push( new NamespaceContext( event ) ); + + try + { + XmlObject unionValue = type.newValue( value ); + + for ( i = 0 ; i < unionEnumvals.length ; i++ ) + { + if (unionValue.valueEquals( unionEnumvals[ i ] )) + break; + } + + if (i >= unionEnumvals.length) + { + //offending Qname not valid ?? + emitError(event, XmlErrorCodes.DATATYPE_ENUM_VALID, + new Object[] { "union", value, QNameHelper.readable(type) }, + null, type, null, XmlValidationError.UNION_INVALID, null); + } + } + catch (XmlValueOutOfRangeException e) + { + // actually, the current union code always ends up here when invalid + + //offending Qname not valid ?? + emitError(event, XmlErrorCodes.DATATYPE_ENUM_VALID, + new Object[] { "union", value, QNameHelper.readable(type) }, + null, type, null, XmlValidationError.UNION_INVALID, null); + } + finally + { + NamespaceContext.pop(); + } + } + } + } + + private void addToList(SchemaType type) + { + if (type.getSimpleVariety() != SchemaType.ATOMIC && + type.getSimpleVariety() != SchemaType.UNION) + return; + + if (type.getUnionMemberTypes().length>0 && getUnionType()!=null) + { + type = getUnionType(); + _unionType = null; + } + + _listTypes.add(type); + + if (type.getPrimitiveType() == null) + { + // instance has an error for this value so there is no primitive type. + // an error should already have been produced. + _listValue.add(null); + return; + } + + switch ( type.getPrimitiveType().getBuiltinTypeCode() ) + { + case SchemaType.BTC_ANY_SIMPLE : + { + _listValue.add(_stringValue); + break; + } + case SchemaType.BTC_STRING : + { + _listValue.add(_stringValue); + _stringValue = null; + break; + } + case SchemaType.BTC_DECIMAL : + { + _listValue.add( _decimalValue ); + _decimalValue = null; + break; + } + case SchemaType.BTC_BOOLEAN : + { + _listValue.add(_booleanValue ? Boolean.TRUE : Boolean.FALSE); + _booleanValue = false; + break; + } + case SchemaType.BTC_FLOAT : + { + _listValue.add(new Float(_floatValue)); + _floatValue = 0; + break; + } + case SchemaType.BTC_DOUBLE : + { + _listValue.add(new Double(_doubleValue)); + _doubleValue = 0; + break; + } + case SchemaType.BTC_QNAME : + { + _listValue.add(_qnameValue); + _qnameValue = null; + break; + } + case SchemaType.BTC_ANY_URI : + { + _listTypes.add(_stringValue); + break; + } + 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 : + { + _listValue.add(_gdateValue); + _gdateValue = null; + break; + } + case SchemaType.BTC_DURATION : + { + _listValue.add(_gdurationValue); + _gdurationValue = null; + break; + } + case SchemaType.BTC_BASE_64_BINARY : + { + _listValue.add(_byteArrayValue); + _byteArrayValue = null; + break; + } + case SchemaType.BTC_HEX_BINARY : + { + _listValue.add(_byteArrayValue); + _byteArrayValue = null; + break; + } + case SchemaType.BTC_NOTATION : + { + _listValue.add(_qnameValue); + _qnameValue = null; + break; + } + + default : + throw new RuntimeException( "Unexpected primitive type code" ); + } + } + + // + // Members of the validator class + // + + private boolean _invalid; + private SchemaType _rootType; + private SchemaField _rootField; + private SchemaTypeLoader _globalTypes; + private State _stateStack; + private int _errorState; + private Collection _errorListener; + private boolean _treatLaxAsSkip; + private boolean _strict; + private ValidatorVC _vc; + private int _suspendErrors; + private IdentityConstraint _constraintEngine; + private int _eatContent; + + private SchemaLocalElement _localElement; + private SchemaParticle _wildcardElement; + private SchemaLocalAttribute _localAttribute; + private SchemaAttributeModel _wildcardAttribute; + private SchemaType _unionType; + + // Strongly typed values + private String _stringValue; + private BigDecimal _decimalValue; + private boolean _booleanValue; + private float _floatValue; + private double _doubleValue; + private QName _qnameValue; + private GDate _gdateValue; + private GDuration _gdurationValue; + private byte[] _byteArrayValue; + private List _listValue; + private List _listTypes; + + private void resetValues() + { + _localAttribute = null; + _wildcardAttribute = null; + _stringValue = null; + _decimalValue = null; + _booleanValue = false; + _floatValue = 0; + _doubleValue = 0; + _qnameValue = null; + _gdateValue = null; + _gdurationValue = null; + _byteArrayValue = null; + _listValue = null; + _listTypes = null; + _unionType = null; + _localAttribute = null; + } + + /** + * @return Returns the SchemaType of the current element. + * This can be different than getCurrentElement().getType() if xsi:type attribute is used. + * Null is returned if no schema type is available. + * For attribute types use {@link #getCurrentAttribute()}.getType(). + * Warning: the returned SchemaType can be an {@link org.apache.xmlbeans.XmlBeans#NO_TYPE}, + * see {@link SchemaType#isNoType}. Or can be the parent type, for unrecognized elements + * that are part of wildcards. + */ + public SchemaType getCurrentElementSchemaType ( ) + { + State state = topState(); + if (state!=null) + return state._type; + + return null; + } + + /** + * @return Returns the curent local element, null if one is not available, see {@link #getCurrentWildcardElement()}. + */ + public SchemaLocalElement getCurrentElement ( ) + { + if (_localElement != null) + return _localElement; + + // it means the element is to be skiped and it doesn't have a known SchemaLocalElement + + if (_eatContent > 0) + return null; + + //try getting it from the stack (this should happen after END) + + if (_stateStack != null && _stateStack._field instanceof SchemaLocalElement) + return (SchemaLocalElement) _stateStack._field; + + return null; + } + + /** + * @return Returns the current particle, if this is a wildcard particle {@link SchemaParticle#WILDCARD} + * method {@link #getCurrentElement()} might return null if wildcard's processContents is skip or lax. + */ + public SchemaParticle getCurrentWildcardElement() + { + return _wildcardElement; + } + + /** + * @return Returns the curent local attribute, global attribute if the current attribute is part of an + * attribute wildcard, or null if none is available. + */ + public SchemaLocalAttribute getCurrentAttribute() + { + return _localAttribute; + } + + /** + * @return Returns the attribute model for attributes if available, else null is returned. + */ + public SchemaAttributeModel getCurrentWildcardAttribute() + { + return _wildcardAttribute; + } + + public String getStringValue() + { + return _stringValue; + } + + public BigDecimal getDecimalValue() + { + return _decimalValue; + } + + public boolean getBooleanValue() + { + return _booleanValue; + } + + public float getFloatValue() + { + return _floatValue; + } + + public double getDoubleValue() + { + return _doubleValue; + } + + public QName getQNameValue() + { + return _qnameValue; + } + + public GDate getGDateValue() + { + return _gdateValue; + } + + public GDuration getGDurationValue() + { + return _gdurationValue; + } + + public byte[] getByteArrayValue() + { + return _byteArrayValue; + } + + public List getListValue() + { + return _listValue; + } + + public List getListTypes() + { + return _listTypes; + } + + public SchemaType getUnionType() + { + return _unionType; + } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/validator/ValidatorUtil.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/validator/ValidatorUtil.java new file mode 100644 index 000000000..dedd37339 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/validator/ValidatorUtil.java @@ -0,0 +1,142 @@ +/* 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.validator; + +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.XmlCursor; +import org.apache.xmlbeans.impl.common.PrefixResolver; +import org.apache.xmlbeans.impl.common.ValidatorListener; +import org.apache.xmlbeans.impl.common.XmlWhitespace; + +import javax.xml.namespace.QName; +import java.util.Collection; + +/** + * Author: Cezar Andrei (cezar.andrei at bea.com) + * Date: Feb 5, 2004 + */ +public class ValidatorUtil +{ + private static class EventImpl implements ValidatorListener.Event + { + PrefixResolver _prefixResolver; + String _text; + + EventImpl(PrefixResolver prefixResolver, String text) + { + _prefixResolver = prefixResolver; + _text = text; + } + + // can return null, used only to locate errors + public XmlCursor getLocationAsCursor() + { + return null; + } + + public javax.xml.stream.Location getLocation() + { + return null; + } + + // fill up chars with the xsi:type attribute value if there is one othervise return false + public String getXsiType() // BEGIN xsi:type + { + return null; + } + + // fill up chars with xsi:nill attribute value if any + public String getXsiNil() // BEGIN xsi:nil + { + return null; + } + + public String getXsiLoc() // BEGIN xsi:schemaLocation + { + return null; + } + + public String getXsiNoLoc() // BEGIN xsi:noNamespaceSchemaLocation + { + return null; + } + + // On START and ATTR + public QName getName() + { + return null; + } + + // On TEXT and ATTR + public String getText() + { + return _text; + } + + public String getText(int wsr) + { + return XmlWhitespace.collapse( _text, wsr ); + } + + public boolean textIsWhitespace() + { + return false; + } + + public String getNamespaceForPrefix(String prefix) + { + return _prefixResolver.getNamespaceForPrefix(prefix); + } + } + + public static boolean validateSimpleType ( + SchemaType type, String value, Collection errors, PrefixResolver prefixResolver ) + { + if (!type.isSimpleType() && type.getContentType() != SchemaType.SIMPLE_CONTENT) + { + assert false; + throw new RuntimeException( "Not a simple type" ); + } + + Validator validator = + new Validator( + type, null, type.getTypeSystem(), null, errors); + + //make only one event at the beginning and than reuse it + EventImpl ev = new EventImpl(prefixResolver, value); + + validator.nextEvent(ValidatorListener.BEGIN, ev); + + validator.nextEvent(ValidatorListener.TEXT, ev); + + validator.nextEvent(ValidatorListener.END, ev); + + return validator.isValid(); + } + +// public static void main(String[] args) +// { +// String value; +// value = " +1.2323 "; +// System.out.println("float " + validateSimpleType(XmlFloat.type, value, null , null)); +// value = " +234 "; +// System.out.println("posInt " + validateSimpleType(XmlPositiveInteger.type, value, null , null)); +// value = "2001-01-01"; +// System.out.println("IntOrDateUnion " + validateSimpleType(DocDocument.Doc.IntOrDateUnion.type, value, null , null)); +// value = "232321"; +// System.out.println("IntOrDateUnion " + validateSimpleType(DocDocument.Doc.IntOrDateUnion.type, value, null , null)); +// } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaBase64Holder.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaBase64Holder.java new file mode 100644 index 000000000..afa165f97 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaBase64Holder.java @@ -0,0 +1,153 @@ +/* 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.values; + +import org.apache.xmlbeans.impl.schema.BuiltinSchemaTypeSystem; + +import org.apache.xmlbeans.impl.util.Base64; +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.XmlErrorCodes; +import org.apache.xmlbeans.XmlBase64Binary; +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.impl.common.ValidationContext; +import org.apache.xmlbeans.impl.common.QNameHelper; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.Arrays; +import java.io.UnsupportedEncodingException; + +public abstract class JavaBase64Holder extends XmlObjectBase +{ + public SchemaType schemaType() + { return BuiltinSchemaTypeSystem.ST_BASE_64_BINARY; } + + protected byte[] _value; + + // SIMPLE VALUE ACCESSORS BELOW ------------------------------------------- + + // gets raw text value + protected String compute_text(NamespaceManager nsm) + { + return new String(Base64.encode(_value)); + } + protected void set_text(String s) + { + _hashcached = false; + if (_validateOnSet()) + _value = validateLexical(s, schemaType(), _voorVc); + else + _value = lex(s, _voorVc); + } + protected void set_nil() + { + _hashcached = false; + _value = null; + } + + public static byte[] lex(String v, ValidationContext c) + { + byte[] vBytes = null; + try + { + vBytes = v.getBytes("UTF-8"); + } + catch(UnsupportedEncodingException uee) + { + // should never happen - UTF-8 is always supported + } + final byte[] bytes = Base64.decode(vBytes); + + if (bytes == null) + { + // TODO - get a decent error with line numbers and such here + c.invalid(XmlErrorCodes.BASE64BINARY, new Object[] { "not encoded properly" }); + } + + return bytes; + } + + public static byte[] validateLexical(String v, SchemaType sType, ValidationContext context) + { + final byte[] bytes = lex(v, context); + if (bytes == null) return null; + + if (!sType.matchPatternFacet(v)) + { + context.invalid(XmlErrorCodes.DATATYPE_VALID$PATTERN_VALID$NO_VALUE, + new Object[] { "base 64", QNameHelper.readable(sType) }); + return null; + } + + return bytes; + } + + public byte[] getByteArrayValue() + { + check_dated(); + if (_value == null) + return null; + + byte[] result = new byte[_value.length]; + System.arraycopy(_value, 0, result, 0, _value.length); + return result; + } + + // setters + protected void set_ByteArray(byte[] ba) + { + _hashcached = false; + _value = new byte[ba.length]; + System.arraycopy(ba, 0, _value, 0, ba.length); + } + + // comparators + protected boolean equal_to(XmlObject i) + { + byte[] ival = ((XmlBase64Binary) i).getByteArrayValue(); + return Arrays.equals(_value, ival); + } + + //because computing hashcode is expensive we'll cache it + protected boolean _hashcached = false; + protected int hashcode = 0; + protected static MessageDigest md5; + static + { + try + { + md5 = MessageDigest.getInstance("MD5"); + } + catch( NoSuchAlgorithmException e ) + { + throw new IllegalStateException("Cannot find MD5 hash Algorithm"); + } + } + + protected int value_hash_code() + { + if( _hashcached ) + return hashcode; + + _hashcached = true; + + if( _value == null ) + return hashcode = 0; + + byte[] res = md5.digest(_value); + return hashcode = res[0]<<24 + res[1]<<16 + res[2]<<8 + res[3]; + } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaBase64HolderEx.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaBase64HolderEx.java new file mode 100644 index 000000000..52d4f7292 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaBase64HolderEx.java @@ -0,0 +1,125 @@ +/* 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.values; + +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.XmlErrorCodes; +import org.apache.xmlbeans.impl.common.ValidationContext; +import org.apache.xmlbeans.impl.common.QNameHelper; + +public abstract class JavaBase64HolderEx extends JavaBase64Holder +{ + private SchemaType _schemaType; + + public SchemaType schemaType() + { return _schemaType; } + + public JavaBase64HolderEx(SchemaType type, boolean complex) + { _schemaType = type; initComplexType(complex, false); } + + protected int get_wscanon_rule() + { + return schemaType().getWhiteSpaceRule(); + } + + protected void set_text(String s) + { + final byte[] v; + + if (_validateOnSet()) + v = validateLexical(s, schemaType(), _voorVc); + else + v = lex(s, _voorVc); + + if (v != null && _validateOnSet()) + validateValue(v, schemaType(), XmlObjectBase._voorVc); + + super.set_ByteArray(v); + } + + // setters + protected void set_ByteArray(byte[] v) + { + if (_validateOnSet()) + validateValue(v, schemaType(), _voorVc); + + super.set_ByteArray(v); + } + + public static void validateValue(byte[] v, SchemaType sType, ValidationContext context) + { + int i; + XmlObject o; + + if ((o = sType.getFacet(SchemaType.FACET_LENGTH)) != null) + { + if ((i = ((XmlObjectBase)o).bigIntegerValue().intValue()) != v.length) + { + context.invalid(XmlErrorCodes.DATATYPE_LENGTH_VALID$BINARY, + new Object[] { "base64Binary", new Integer(v.length), new Integer(i), QNameHelper.readable(sType) } ); + } + } + + if ((o = sType.getFacet( SchemaType.FACET_MIN_LENGTH )) != null) + { + if ((i = ((XmlObjectBase)o).bigIntegerValue().intValue()) > v.length) + { + context.invalid(XmlErrorCodes.DATATYPE_MIN_LENGTH_VALID$BINARY, + new Object[] { "base64Binary", new Integer(v.length), new Integer(i), QNameHelper.readable(sType) } ); + } + } + + if ((o = sType.getFacet( SchemaType.FACET_MAX_LENGTH )) != null) + { + if ((i = ((XmlObjectBase)o).bigIntegerValue().intValue()) < v.length) + { + context.invalid(XmlErrorCodes.DATATYPE_MAX_LENGTH_VALID$BINARY, + new Object[] { "base64Binary", new Integer(v.length), new Integer(i), QNameHelper.readable(sType) } ); + } + } + + XmlObject[] vals = sType.getEnumerationValues(); + + if (vals != null) + { + enumLoop: for ( i = 0 ; i < vals.length ; i++ ) + { + byte[] enumBytes = ((XmlObjectBase)vals[i]).byteArrayValue(); + + if (enumBytes.length != v.length) + continue; + + for ( int j = 0 ; j < enumBytes.length ; j++ ) + if (enumBytes[j] != v[j]) + continue enumLoop; + + break; + } + + if (i >= vals.length) + context.invalid(XmlErrorCodes.DATATYPE_ENUM_VALID$NO_VALUE, + new Object[] { "base64Binary", QNameHelper.readable(sType) }); + } + } + + protected void validate_simpleval(String lexical, ValidationContext ctx) + { + validateLexical(lexical, schemaType(), ctx); + validateValue(byteArrayValue(), schemaType(), ctx); + } + +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaBooleanHolder.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaBooleanHolder.java new file mode 100644 index 000000000..a3b538154 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaBooleanHolder.java @@ -0,0 +1,81 @@ +/* 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.values; + +import org.apache.xmlbeans.impl.schema.BuiltinSchemaTypeSystem; +import org.apache.xmlbeans.XmlErrorCodes; +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.XmlBoolean; +import org.apache.xmlbeans.impl.common.ValidationContext; + +public abstract class JavaBooleanHolder extends XmlObjectBase +{ + public SchemaType schemaType() + { return BuiltinSchemaTypeSystem.ST_BOOLEAN; } + + private boolean _value; + + // SIMPLE VALUE ACCESSORS BELOW ------------------------------------------- + + // gets raw text value + protected String compute_text(NamespaceManager nsm) { return _value ? "true" : "false"; } + protected void set_text(String s) + { + _value = validateLexical(s, _voorVc); + } + public static boolean validateLexical(String v, ValidationContext context) + { + if (v.equals("true") || v.equals("1")) + return true; + + if (v.equals("false") || v.equals("0")) + return false; + + context.invalid(XmlErrorCodes.BOOLEAN, new Object[]{ v }); + + return false; + } + protected void set_nil() + { + _value = false; + } + // numerics: fractional + public boolean getBooleanValue() { check_dated(); return _value; } + + // setters + protected void set_boolean(boolean f) + { + _value = f; + } + + // comparators + protected int compare_to(XmlObject i) + { + // no ordering defined between true and false + return _value == ((XmlBoolean)i).getBooleanValue() ? 0 : 2; + } + + protected boolean equal_to(XmlObject i) + { + return _value == ((XmlBoolean)i).getBooleanValue(); + } + + protected int value_hash_code() + { + return _value ? 957379554 : 676335975; + } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaBooleanHolderEx.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaBooleanHolderEx.java new file mode 100644 index 000000000..1cf9f7a0e --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaBooleanHolderEx.java @@ -0,0 +1,61 @@ +/* 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.values; + +import org.apache.xmlbeans.XmlErrorCodes; +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.impl.common.ValidationContext; +import org.apache.xmlbeans.impl.common.QNameHelper; + + + +public abstract class JavaBooleanHolderEx extends JavaBooleanHolder +{ + private SchemaType _schemaType; + + public SchemaType schemaType() + { return _schemaType; } + + public static boolean validateLexical(String v, SchemaType sType, ValidationContext context) + { + boolean b = JavaBooleanHolder.validateLexical(v, context); + validatePattern(v, sType, context); + return b; + } + + public static void validatePattern(String v, SchemaType sType, ValidationContext context) + { + // the only new facet that can apply to booleans is pattern! + if (!sType.matchPatternFacet(v)) + context.invalid(XmlErrorCodes.DATATYPE_VALID$PATTERN_VALID, + new Object[] { "boolean", v, QNameHelper.readable(sType) }); + } + + public JavaBooleanHolderEx(SchemaType type, boolean complex) + { _schemaType = type; initComplexType(complex, false); } + + protected void set_text(String s) + { + if (_validateOnSet()) + validatePattern(s, _schemaType, _voorVc); + super.set_text(s); + } + + protected void validate_simpleval(String lexical, ValidationContext ctx) + { + validateLexical(lexical, schemaType(), ctx); + } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaDecimalHolder.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaDecimalHolder.java new file mode 100644 index 000000000..4687e8432 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaDecimalHolder.java @@ -0,0 +1,177 @@ +/* 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.values; + +import java.math.BigDecimal; +import java.math.BigInteger; + +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.XmlErrorCodes; +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.impl.common.ValidationContext; +import org.apache.xmlbeans.impl.schema.BuiltinSchemaTypeSystem; +import org.apache.xmlbeans.impl.util.XsTypeConverter; + +public class JavaDecimalHolder extends XmlObjectBase +{ + public SchemaType schemaType() + { return BuiltinSchemaTypeSystem.ST_DECIMAL; } + + private BigDecimal _value; + + // SIMPLE VALUE ACCESSORS BELOW ------------------------------------------- + + // sets/gets raw text value + protected String compute_text(NamespaceManager nsm) { return XsTypeConverter.printDecimal(_value); } + protected void set_text(String s) + { + if (_validateOnSet()) + validateLexical(s, _voorVc); + + try { + set_BigDecimal(new BigDecimal(s)); + } + catch (NumberFormatException e) + { + _voorVc.invalid(XmlErrorCodes.DECIMAL, new Object[] { s }); + } + } + protected void set_nil() + { + _value = null; + } + + /** + * Performs lexical validation only. + */ + + public static void validateLexical(String v, ValidationContext context) + { + // TODO - will want to validate Chars with built in white space handling + // However, this fcn sometimes takes a value with wsr applied + // already + int l = v.length(); + int i = 0; + + if (i < l) + { + int ch = v.charAt(i); + + if (ch == '+' || ch == '-') + i++; + } + + boolean sawDot = false; + boolean sawDigit = false; + + for ( ; i < l ; i++ ) + { + int ch = v.charAt(i); + + if (ch == '.') + { + if (sawDot) + { + context.invalid(XmlErrorCodes.DECIMAL, + new Object[] { "saw '.' more than once: " + v }); + return; + } + + sawDot = true; + } + else if (ch >= '0' && ch <= '9') + { + sawDigit = true; + } + else + { + // TODO - may need to escape error char + context.invalid(XmlErrorCodes.DECIMAL, + new Object[] { "unexpected char '" + ch + "'" }); + return; + } + } + + if (!sawDigit) + { + context.invalid(XmlErrorCodes.DECIMAL, + new Object[] { "expected at least one digit" }); + return; + } + } + + // numerics: fractional + public BigDecimal getBigDecimalValue() { check_dated(); return _value; } + + // setters + protected void set_BigDecimal(BigDecimal v) { _value = v; } + + // comparators + protected int compare_to(XmlObject decimal) + { + return _value.compareTo(((XmlObjectBase)decimal).bigDecimalValue()); + } + protected boolean equal_to(XmlObject decimal) + { + return (_value.compareTo(((XmlObjectBase)decimal).bigDecimalValue())) == 0; + } + + static private BigInteger _maxlong = BigInteger.valueOf(Long.MAX_VALUE); + static private BigInteger _minlong = BigInteger.valueOf(Long.MIN_VALUE); + + /** + * Note, this is carefully aligned with hash codes for all xsd:decimal + * primitives. + */ + protected int value_hash_code() + { + if (_value.scale() > 0) + { + if (_value.setScale(0, BigDecimal.ROUND_DOWN).compareTo(_value) != 0) + return decimalHashCode(); + } + + BigInteger intval = _value.toBigInteger(); + + if (intval.compareTo(_maxlong) > 0 || + intval.compareTo(_minlong) < 0) + return intval.hashCode(); + + long longval = intval.longValue(); + + return (int)((longval >> 32) * 19 + longval); + } + + /** + * This method will has BigDecimals with the same arithmetic value to + * the same hash code (eg, 2.3 & 2.30 will have the same hash.) + * This differs from BigDecimal.hashCode() + */ + protected int decimalHashCode() { + assert _value.scale() > 0; + + // Get decimal value as string, and strip off zeroes on the right + String strValue = _value.toString(); + int i; + for (i = strValue.length() - 1 ; i >= 0 ; i --) + if (strValue.charAt(i) != '0') break; + + assert strValue.indexOf('.') < i; + + // Return the canonicalized string hashcode + return strValue.substring(0, i + 1).hashCode(); + } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaDecimalHolderEx.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaDecimalHolderEx.java new file mode 100644 index 000000000..a57ed56c5 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaDecimalHolderEx.java @@ -0,0 +1,215 @@ +/* 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.values; + +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.XmlErrorCodes; +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.impl.common.ValidationContext; +import org.apache.xmlbeans.impl.common.QNameHelper; + + +import java.math.BigDecimal; + +public abstract class JavaDecimalHolderEx extends JavaDecimalHolder +{ + private SchemaType _schemaType; + + public SchemaType schemaType() + { return _schemaType; } + + public JavaDecimalHolderEx(SchemaType type, boolean complex) + { _schemaType = type; initComplexType(complex, false); } + + protected void set_text(String s) + { + if (_validateOnSet()) + validateLexical(s, _schemaType, _voorVc); + + BigDecimal v = null; + try { + v = new BigDecimal(s); + } + catch (NumberFormatException e) + { + _voorVc.invalid(XmlErrorCodes.DECIMAL, new Object[] { s }); + } + + if (_validateOnSet()) + validateValue(v, _schemaType, _voorVc); + + super.set_BigDecimal(v); + } + + protected void set_BigDecimal(BigDecimal v) + { + if (_validateOnSet()) + validateValue(v, _schemaType, _voorVc); + super.set_BigDecimal(v); + } + + public static void validateLexical(String v, SchemaType sType, ValidationContext context) + { + JavaDecimalHolder.validateLexical(v, context); + + // check pattern + if (sType.hasPatternFacet()) + { + if (!sType.matchPatternFacet(v)) + { + // TODO - describe string and pattern here in error + context.invalid(XmlErrorCodes.DATATYPE_VALID$PATTERN_VALID, + new Object[] { "decimal", v, QNameHelper.readable(sType) }); + } + } + } + + /** + * Performs facet validation only. + */ + + public static void validateValue(BigDecimal v, SchemaType sType, ValidationContext context) + { + // fractional digits + XmlObject fd = sType.getFacet(SchemaType.FACET_FRACTION_DIGITS); + if (fd != null) + { + int scale = ((XmlObjectBase)fd).getBigIntegerValue().intValue(); + try + { + // used only for side-effect - this does not change v despite + // the name of the method + v.setScale(scale); + } + catch(ArithmeticException e) + { + // ArithmeticException will be thrown if cannot represent as an Integer + // with this scale - i.e. would need a fraction which would correspond + // to digits beyond the allowed number + context.invalid(XmlErrorCodes.DATATYPE_FRACTION_DIGITS_VALID, + new Object[] { new Integer(v.scale()), v.toString(), new Integer(scale), QNameHelper.readable(sType) }); + return; + } + } + + // total digits + XmlObject td = sType.getFacet(SchemaType.FACET_TOTAL_DIGITS); + if (td != null) + { + String temp = v.unscaledValue().toString(); + int tdf = ((XmlObjectBase)td).getBigIntegerValue().intValue(); + int origLen = temp.length(); + int len = origLen; + if (origLen > 0) + { + // don't count leading minus + if (temp.charAt(0) == '-') + { + len -= 1; + } + + // don't count trailing zeros if we can absorb them into scale + int insignificantTrailingZeros = 0; + int vScale = v.scale(); + for(int j = origLen-1; + temp.charAt(j) == '0' && j > 0 && insignificantTrailingZeros < vScale; + j--) + { + insignificantTrailingZeros++; + } + + len -= insignificantTrailingZeros; + } + + if (len > tdf) + { + context.invalid(XmlErrorCodes.DATATYPE_TOTAL_DIGITS_VALID, + new Object[] { new Integer(len), v.toString(), new Integer(tdf), QNameHelper.readable(sType) }); + return; + } + } + + // min ex + XmlObject mine = sType.getFacet(SchemaType.FACET_MIN_EXCLUSIVE); + if (mine != null) + { + BigDecimal m = ((XmlObjectBase)mine).getBigDecimalValue(); + if (v.compareTo(m) <= 0) + { + context.invalid(XmlErrorCodes.DATATYPE_MIN_EXCLUSIVE_VALID, + new Object[] { "decimal", v, m, QNameHelper.readable(sType) }); + return; + } + } + + // min in + XmlObject mini = sType.getFacet(SchemaType.FACET_MIN_INCLUSIVE); + if (mini != null) + { + BigDecimal m = ((XmlObjectBase)mini).getBigDecimalValue(); + if (v.compareTo(m) < 0) + { + context.invalid(XmlErrorCodes.DATATYPE_MIN_INCLUSIVE_VALID, + new Object[] { "decimal", v, m, QNameHelper.readable(sType) }); + return; + } + } + + // max in + XmlObject maxi = sType.getFacet(SchemaType.FACET_MAX_INCLUSIVE); + if (maxi != null) + { + BigDecimal m = ((XmlObjectBase)maxi).getBigDecimalValue(); + if (v.compareTo(m) > 0) + { + context.invalid(XmlErrorCodes.DATATYPE_MAX_INCLUSIVE_VALID, + new Object[] { "decimal", v, m, QNameHelper.readable(sType) }); + return; + } + } + + // max ex + XmlObject maxe = sType.getFacet(SchemaType.FACET_MAX_EXCLUSIVE); + if (maxe != null) + { + BigDecimal m = ((XmlObjectBase)maxe).getBigDecimalValue(); + if (v.compareTo(m) >= 0) + { + context.invalid(XmlErrorCodes.DATATYPE_MAX_EXCLUSIVE_VALID, + new Object[] { "decimal", v, m, QNameHelper.readable(sType) }); + return; + } + } + + // enumeration + XmlObject[] vals = sType.getEnumerationValues(); + if (vals != null) + { + for (int i = 0; i < vals.length; i++) + if (v.equals(((XmlObjectBase)vals[i]).getBigDecimalValue())) + return; + context.invalid(XmlErrorCodes.DATATYPE_ENUM_VALID, + new Object[] { "decimal", v, QNameHelper.readable(sType) }); + } + } + + protected void validate_simpleval(String lexical, ValidationContext ctx) + { + validateLexical(lexical, schemaType(), ctx); + validateValue(getBigDecimalValue(), schemaType(), ctx); + } + +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaDoubleHolder.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaDoubleHolder.java new file mode 100644 index 000000000..bed9552e6 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaDoubleHolder.java @@ -0,0 +1,111 @@ +/* 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.values; + +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.XmlErrorCodes; +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.impl.schema.BuiltinSchemaTypeSystem; +import org.apache.xmlbeans.impl.common.ValidationContext; +import org.apache.xmlbeans.impl.util.XsTypeConverter; + +import java.math.BigDecimal; +import java.math.BigInteger; + +public abstract class JavaDoubleHolder extends XmlObjectBase +{ + public SchemaType schemaType() + { return BuiltinSchemaTypeSystem.ST_DOUBLE; } + + double _value; + + // SIMPLE VALUE ACCESSORS BELOW ------------------------------------------- + + // gets/sets raw text value + protected String compute_text(NamespaceManager nsm) { return serialize(_value); } + + public static String serialize(double d) + { + if (d == Double.POSITIVE_INFINITY) + return "INF"; + else if (d == Double.NEGATIVE_INFINITY) + return "-INF"; + else if (d == Double.NaN) + return "NaN"; + else + return Double.toString(d); + } + protected void set_text(String s) + { + set_double(validateLexical(s,_voorVc)); + } + public static double validateLexical(String v, ValidationContext context) + { + try + { + return XsTypeConverter.lexDouble(v); + } + catch(NumberFormatException e) + { + context.invalid(XmlErrorCodes.DOUBLE, new Object[]{v}); + + return Double.NaN; + } + } + protected void set_nil() + { + _value = 0.0; + } + + // numerics: fractional + public BigDecimal getBigDecimalValue() { check_dated(); return new BigDecimal(_value); } + public double getDoubleValue() { check_dated(); return _value; } + public float getFloatValue() { check_dated(); return (float)_value; } + + // setters + protected void set_double(double v) { _value = v; } + protected void set_float(float v) { set_double((double)v); } + protected void set_long(long v) { set_double((double)v); } + protected void set_BigDecimal(BigDecimal v) { set_double(v.doubleValue()); } + protected void set_BigInteger(BigInteger v) { set_double(v.doubleValue()); } + + // comparators + protected int compare_to(XmlObject d) + { + return compare(_value,((XmlObjectBase)d).doubleValue()); + } + static int compare(double thisValue, double thatValue) + { + if (thisValue < thatValue) return -1; + if (thisValue > thatValue) return 1; + + long thisBits = Double.doubleToLongBits(thisValue); + long thatBits = Double.doubleToLongBits(thatValue); + + return thisBits == thatBits ? 0 : thisBits < thatBits ? -1 : 1; + } + + protected boolean equal_to(XmlObject d) + { + return compare(_value, ((XmlObjectBase)d).doubleValue()) == 0; + } + + protected int value_hash_code() + { + long v = Double.doubleToLongBits(_value); + return (int)((v >> 32) * 19 + v); + } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaDoubleHolderEx.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaDoubleHolderEx.java new file mode 100644 index 000000000..cda2984a3 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaDoubleHolderEx.java @@ -0,0 +1,111 @@ +/* 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.values; + +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.XmlErrorCodes; +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.impl.common.ValidationContext; +import org.apache.xmlbeans.impl.common.QNameHelper; + + + +public abstract class JavaDoubleHolderEx extends JavaDoubleHolder +{ + public JavaDoubleHolderEx(SchemaType type, boolean complex) + { _schemaType = type; initComplexType(complex, false); } + + private SchemaType _schemaType; + + public SchemaType schemaType() + { return _schemaType; } + + protected void set_double(double v) + { + if (_validateOnSet()) + validateValue(v, _schemaType, _voorVc); + super.set_double(v); + } + + public static double validateLexical(String v, SchemaType sType, ValidationContext context) + { + double d = JavaDoubleHolder.validateLexical(v, context); + + if (!sType.matchPatternFacet(v)) + context.invalid(XmlErrorCodes.DATATYPE_VALID$PATTERN_VALID, + new Object[] { "double", v, QNameHelper.readable(sType) }); + + return d; + } + + public static void validateValue(double v, SchemaType sType, ValidationContext context) + { + XmlObject x; + double d; + + if ((x = sType.getFacet(SchemaType.FACET_MIN_EXCLUSIVE)) != null) + { + if (compare(v, d = ((XmlObjectBase)x).doubleValue()) <= 0) + { + context.invalid(XmlErrorCodes.DATATYPE_MIN_EXCLUSIVE_VALID, + new Object[] { "double", new Double(v), new Double(d), QNameHelper.readable(sType) }); + } + } + + if ((x = sType.getFacet(SchemaType.FACET_MIN_INCLUSIVE)) != null) + { + if (compare(v, d = ((XmlObjectBase)x).doubleValue()) < 0) + { + context.invalid(XmlErrorCodes.DATATYPE_MIN_INCLUSIVE_VALID, + new Object[] { "double", new Double(v), new Double(d), QNameHelper.readable(sType) }); + } + } + + if ((x = sType.getFacet(SchemaType.FACET_MAX_INCLUSIVE)) != null) + { + if (compare(v, d = ((XmlObjectBase)x).doubleValue()) > 0) + { + context.invalid(XmlErrorCodes.DATATYPE_MAX_INCLUSIVE_VALID, + new Object[] { "double", new Double(v), new Double(d), QNameHelper.readable(sType) }); + } + } + + if ((x = sType.getFacet(SchemaType.FACET_MAX_EXCLUSIVE)) != null) + { + if (compare(v, d = ((XmlObjectBase)x).doubleValue()) >= 0) + { + context.invalid(XmlErrorCodes.DATATYPE_MAX_EXCLUSIVE_VALID, + new Object[] { "double", new Double(v), new Double(d), QNameHelper.readable(sType) }); + } + } + + XmlObject[] vals = sType.getEnumerationValues(); + if (vals != null) + { + for (int i = 0; i < vals.length; i++) + if (compare(v, ((XmlObjectBase)vals[i]).doubleValue()) == 0) + return; + context.invalid(XmlErrorCodes.DATATYPE_ENUM_VALID, + new Object[] { "double", new Double(v), QNameHelper.readable(sType) }); + } + } + + protected void validate_simpleval(String lexical, ValidationContext ctx) + { + validateLexical(lexical, schemaType(), ctx); + validateValue(doubleValue(), schemaType(), ctx); + } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaFloatHolder.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaFloatHolder.java new file mode 100644 index 000000000..dad176d94 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaFloatHolder.java @@ -0,0 +1,112 @@ +/* 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.values; + +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.XmlErrorCodes; +import org.apache.xmlbeans.impl.schema.BuiltinSchemaTypeSystem; +import org.apache.xmlbeans.impl.common.ValidationContext; +import org.apache.xmlbeans.impl.util.XsTypeConverter; + +import java.math.BigDecimal; +import java.math.BigInteger; + +public abstract class JavaFloatHolder extends XmlObjectBase +{ + public SchemaType schemaType() + { return BuiltinSchemaTypeSystem.ST_FLOAT; } + + private float _value; + + // SIMPLE VALUE ACCESSORS BELOW ------------------------------------------- + + // gets+sets raw text value + protected String compute_text(NamespaceManager nsm) { + return serialize(_value); + } + + public static String serialize(float f) + { + if (f == Float.POSITIVE_INFINITY) + return "INF"; + else if (f == Float.NEGATIVE_INFINITY) + return "-INF"; + else if (f == Float.NaN) + return "NaN"; + else + return Float.toString(f); + } + protected void set_text(String s) + { + set_float(validateLexical(s,_voorVc)); + } + public static float validateLexical(String v, ValidationContext context) + { + try + { + return XsTypeConverter.lexFloat(v); + } + catch(NumberFormatException e) + { + context.invalid(XmlErrorCodes.FLOAT, new Object[]{v}); + + return Float.NaN; + } + } + protected void set_nil() + { + _value = 0.0f; + } + // numerics: fractional + public BigDecimal getBigDecimalValue() { check_dated(); return new BigDecimal(_value); } + public double getDoubleValue() { check_dated(); return _value; } + public float getFloatValue() { check_dated(); return _value; } + + // setters + protected void set_double(double v) { set_float((float)v); } + protected void set_float(float v) { _value = v; } + protected void set_long(long v) { set_float((float)v); } + protected void set_BigDecimal(BigDecimal v) { set_float(v.floatValue()); } + protected void set_BigInteger(BigInteger v) { set_float(v.floatValue()); } + + // comparators + protected int compare_to(XmlObject f) + { + return compare(_value,((XmlObjectBase)f).floatValue()); + } + + static int compare(float thisValue, float thatValue) + { + if (thisValue < thatValue) return -1; + if (thisValue > thatValue) return 1; + + int thisBits = Float.floatToIntBits(thisValue); + int thatBits = Float.floatToIntBits(thatValue); + + return thisBits == thatBits ? 0 : thisBits < thatBits ? -1 : 1; + } + + protected boolean equal_to(XmlObject f) + { + return compare(_value, ((XmlObjectBase)f).floatValue()) == 0; + } + + protected int value_hash_code() + { + return Float.floatToIntBits(_value); + } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaFloatHolderEx.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaFloatHolderEx.java new file mode 100644 index 000000000..c47d34d0a --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaFloatHolderEx.java @@ -0,0 +1,112 @@ +/* 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.values; + +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.XmlErrorCodes; +import org.apache.xmlbeans.impl.common.ValidationContext; +import org.apache.xmlbeans.impl.common.QNameHelper; + + + +public abstract class JavaFloatHolderEx extends JavaFloatHolder +{ + public JavaFloatHolderEx(SchemaType type, boolean complex) + { _schemaType = type; initComplexType(complex, false); } + + private SchemaType _schemaType; + + public SchemaType schemaType() + { return _schemaType; } + + protected void set_float(float v) + { + if (_validateOnSet()) + validateValue(v, _schemaType, _voorVc); + super.set_float(v); + } + + public static float validateLexical(String v, SchemaType sType, ValidationContext context) + { + float f = JavaFloatHolder.validateLexical(v, context); + + if (!sType.matchPatternFacet(v)) + context.invalid(XmlErrorCodes.DATATYPE_VALID$PATTERN_VALID, + new Object[] { "float", v, QNameHelper.readable(sType) }); + + return f; + } + + public static void validateValue(float v, SchemaType sType, ValidationContext context) + { + XmlObject x; + float f; + + if ((x = sType.getFacet(SchemaType.FACET_MIN_EXCLUSIVE)) != null) + { + if (compare(v, f = ((XmlObjectBase)x).floatValue()) <= 0) + { + context.invalid(XmlErrorCodes.DATATYPE_MIN_EXCLUSIVE_VALID, + new Object[] { "float", new Float(v), new Float(f), QNameHelper.readable(sType) }); + } + } + + if ((x = sType.getFacet(SchemaType.FACET_MIN_INCLUSIVE)) != null) + { + if (compare(v, f = ((XmlObjectBase)x).floatValue()) < 0) + { + context.invalid(XmlErrorCodes.DATATYPE_MIN_INCLUSIVE_VALID, + new Object[] { "float", new Float(v), new Float(f), QNameHelper.readable(sType) }); + } + } + + if ((x = sType.getFacet(SchemaType.FACET_MAX_INCLUSIVE)) != null) + { + if (compare(v, f = ((XmlObjectBase)x).floatValue()) > 0) + { + context.invalid(XmlErrorCodes.DATATYPE_MAX_INCLUSIVE_VALID, + new Object[] { "float", new Float(v), new Float(f), QNameHelper.readable(sType) }); + } + } + + if ((x = sType.getFacet(SchemaType.FACET_MAX_EXCLUSIVE)) != null) + { + if (compare(v, f = ((XmlObjectBase)x).floatValue()) >= 0) + { + context.invalid(XmlErrorCodes.DATATYPE_MAX_EXCLUSIVE_VALID, + new Object[] { "float", new Float(v), new Float(f), QNameHelper.readable(sType) }); + } + } + + XmlObject[] vals = sType.getEnumerationValues(); + if (vals != null) + { + for (int i = 0; i < vals.length; i++) + if (compare(v, ((XmlObjectBase)vals[i]).floatValue()) == 0) + return; + context.invalid(XmlErrorCodes.DATATYPE_ENUM_VALID, + new Object[] { "float", new Float(v), QNameHelper.readable(sType) }); + } + } + + protected void validate_simpleval(String lexical, ValidationContext ctx) + { + validateLexical(lexical, schemaType(), ctx); + validateValue(floatValue(), schemaType(), ctx); + } + +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaGDateHolderEx.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaGDateHolderEx.java new file mode 100644 index 000000000..36d0f2576 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaGDateHolderEx.java @@ -0,0 +1,319 @@ +/* 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.values; + +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.XmlErrorCodes; +import org.apache.xmlbeans.GDate; +import org.apache.xmlbeans.GDateSpecification; +import org.apache.xmlbeans.GDateBuilder; +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.impl.common.ValidationContext; +import org.apache.xmlbeans.impl.common.QNameHelper; + +import java.util.Date; +import java.util.Calendar; + +public abstract class JavaGDateHolderEx extends XmlObjectBase +{ + public JavaGDateHolderEx(SchemaType type, boolean complex) + { + _schemaType = type; + initComplexType(complex, false); + } + + public SchemaType schemaType() + { return _schemaType; } + + private SchemaType _schemaType; + private GDate _value; + + // SIMPLE VALUE ACCESSORS BELOW ------------------------------------------- + + // sets/gets raw text value + protected String compute_text(NamespaceManager nsm) + { return _value == null ? "" : _value.toString(); } + + protected void set_text(String s) + { + GDate newVal; + if (_validateOnSet()) + newVal = validateLexical(s, _schemaType, _voorVc); + else + newVal = lex(s, _schemaType, _voorVc); + + if (_validateOnSet() && newVal != null) + validateValue(newVal, _schemaType, _voorVc); + + _value = newVal; + } + + public static GDate lex(String v, SchemaType sType, ValidationContext context) + { + GDate date = null; + + try + { + date = new GDate(v); + } + catch (Exception e) + { + context.invalid(XmlErrorCodes.DATE, new Object[] { v }); + } + + if (date != null) + { + if (date.getBuiltinTypeCode() != sType.getPrimitiveType().getBuiltinTypeCode()) + { + context.invalid(XmlErrorCodes.DATE, new Object[] { "wrong type: " + v }); + date = null; + } + else if (!date.isValid()) + { + context.invalid(XmlErrorCodes.DATE, new Object[] { v }); + date = null; + } + } + + return date; + } + + public static GDate validateLexical(String v, SchemaType sType, ValidationContext context) + { + + GDate date = lex(v, sType, context); + + if (date != null && sType.hasPatternFacet()) + if (!sType.matchPatternFacet(v)) + context.invalid(XmlErrorCodes.DATATYPE_VALID$PATTERN_VALID, + new Object[] { "date", v, QNameHelper.readable(sType) }); + + return date; + } + + public static void validateValue(GDateSpecification v, SchemaType sType, ValidationContext context) + { + XmlObject x; + GDate g; + + if (v.getBuiltinTypeCode() != sType.getPrimitiveType().getBuiltinTypeCode()) + context.invalid(XmlErrorCodes.DATE, new Object[] { "Date (" + v + ") does not have the set of fields required for " + QNameHelper.readable(sType) }); + + if ((x = sType.getFacet(SchemaType.FACET_MIN_EXCLUSIVE)) != null) + if (v.compareToGDate(g = ((XmlObjectBase)x).gDateValue()) <= 0) + context.invalid(XmlErrorCodes.DATATYPE_MIN_EXCLUSIVE_VALID, + new Object[] { "date", v, g, QNameHelper.readable(sType) }); + + if ((x = sType.getFacet(SchemaType.FACET_MIN_INCLUSIVE)) != null) + if (v.compareToGDate(g = ((XmlObjectBase)x).gDateValue()) < 0) + context.invalid(XmlErrorCodes.DATATYPE_MIN_INCLUSIVE_VALID, + new Object[] { "date", v, g, QNameHelper.readable(sType) }); + + if ((x = sType.getFacet(SchemaType.FACET_MAX_EXCLUSIVE)) != null) + if (v.compareToGDate(g = ((XmlObjectBase)x).gDateValue()) >= 0) + context.invalid(XmlErrorCodes.DATATYPE_MAX_EXCLUSIVE_VALID, + new Object[] { "date", v, g, QNameHelper.readable(sType) }); + + if ((x = sType.getFacet(SchemaType.FACET_MAX_INCLUSIVE)) != null) + if (v.compareToGDate(g = ((XmlObjectBase)x).gDateValue()) > 0) + context.invalid(XmlErrorCodes.DATATYPE_MAX_INCLUSIVE_VALID, + new Object[] { "date", v, g, QNameHelper.readable(sType) }); + + XmlObject[] vals = sType.getEnumerationValues(); + if (vals != null) + { + for (int i = 0; i < vals.length; i++) + if (v.compareToGDate(((XmlObjectBase)vals[i]).gDateValue()) == 0) + return; + context.invalid(XmlErrorCodes.DATATYPE_ENUM_VALID, + new Object[] { "date", v, QNameHelper.readable(sType) }); + } + } + + protected void set_nil() + { + _value = null; + } + + // numerics: gYear, gMonth, gDay accept an integer + public int getIntValue() + { + int code = schemaType().getPrimitiveType().getBuiltinTypeCode(); + + if (code != SchemaType.BTC_G_DAY && + code != SchemaType.BTC_G_MONTH && + code != SchemaType.BTC_G_YEAR) + throw new XmlValueOutOfRangeException(); + + check_dated(); + + if (_value == null) + return 0; + + switch (code) + { + case SchemaType.BTC_G_DAY: + return _value.getDay(); + case SchemaType.BTC_G_MONTH: + return _value.getMonth(); + case SchemaType.BTC_G_YEAR: + return _value.getYear(); + default: + assert(false); + throw new IllegalStateException(); + } + } + + public GDate getGDateValue() + { + check_dated(); + + if (_value == null) + return null; + + return _value; + } + + public Calendar getCalendarValue() + { + check_dated(); + + if (_value == null) + return null; + + return _value.getCalendar(); + } + + public Date getDateValue() + { + check_dated(); + + if (_value == null) + return null; + + return _value.getDate(); + } + + // setters + protected void set_int(int v) + { + int code = schemaType().getPrimitiveType().getBuiltinTypeCode(); + + if (code != SchemaType.BTC_G_DAY && + code != SchemaType.BTC_G_MONTH && + code != SchemaType.BTC_G_YEAR) + throw new XmlValueOutOfRangeException(); + + GDateBuilder value = new GDateBuilder(); + + switch (code) + { + case SchemaType.BTC_G_DAY: + value.setDay(v); break; + case SchemaType.BTC_G_MONTH: + value.setMonth(v); break; + case SchemaType.BTC_G_YEAR: + value.setYear(v); break; + } + + if (_validateOnSet()) + validateValue(value, _schemaType, _voorVc); + + _value = value.toGDate(); + } + + protected void set_GDate(GDateSpecification v) + { + int code = schemaType().getPrimitiveType().getBuiltinTypeCode(); + + GDate candidate; + + if (v.isImmutable() && (v instanceof GDate) && v.getBuiltinTypeCode() == code) + candidate = (GDate)v; + else + { + // truncate extra fields from the date if necessary. + if (v.getBuiltinTypeCode() != code) + { + GDateBuilder gDateBuilder = new GDateBuilder(v); + gDateBuilder.setBuiltinTypeCode(code); + v = gDateBuilder; + } + candidate = new GDate(v); + } + + if (_validateOnSet()) + validateValue(candidate, _schemaType, _voorVc); + + _value = candidate; + } + + protected void set_Calendar(Calendar c) + { + int code = schemaType().getPrimitiveType().getBuiltinTypeCode(); + + GDateBuilder gDateBuilder = new GDateBuilder(c); + gDateBuilder.setBuiltinTypeCode(code); + GDate value = gDateBuilder.toGDate(); + + if (_validateOnSet()) + validateValue(value, _schemaType, _voorVc); + + _value = value; + } + + protected void set_Date(Date v) + { + int code = schemaType().getPrimitiveType().getBuiltinTypeCode(); + + if (code != SchemaType.BTC_DATE && code != SchemaType.BTC_DATE_TIME || + v == null) + throw new XmlValueOutOfRangeException(); + + GDateBuilder gDateBuilder = new GDateBuilder(v); + gDateBuilder.setBuiltinTypeCode(code); + GDate value = gDateBuilder.toGDate(); + + if (_validateOnSet()) + validateValue(value, _schemaType, _voorVc); + + _value = value; + } + + + // comparators + protected int compare_to(XmlObject obj) + { + return _value.compareToGDate(((XmlObjectBase)obj).gDateValue()); + } + + protected boolean equal_to(XmlObject obj) + { + return _value.equals(((XmlObjectBase)obj).gDateValue()); + } + + protected int value_hash_code() + { + return _value.hashCode(); + } + + protected void validate_simpleval(String lexical, ValidationContext ctx) + { + validateLexical(lexical, schemaType(), ctx); + validateValue(gDateValue(), schemaType(), ctx); + } + +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaGDurationHolderEx.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaGDurationHolderEx.java new file mode 100644 index 000000000..cd002c57a --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaGDurationHolderEx.java @@ -0,0 +1,160 @@ +/* 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.values; + +import org.apache.xmlbeans.GDuration; +import org.apache.xmlbeans.GDurationSpecification; +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.impl.common.ValidationContext; +import org.apache.xmlbeans.impl.common.QNameHelper; +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.XmlErrorCodes; + +public abstract class JavaGDurationHolderEx extends XmlObjectBase +{ + public JavaGDurationHolderEx(SchemaType type, boolean complex) + { _schemaType = type; initComplexType(complex, false); } + + GDuration _value; + private SchemaType _schemaType; + + public SchemaType schemaType() { return _schemaType; } + + protected void set_text(String s) + { + GDuration newVal; + if (_validateOnSet()) + newVal = validateLexical(s, _schemaType, _voorVc); + else + newVal = lex(s, _voorVc); + + if (_validateOnSet() && newVal != null) + validateValue(newVal, _schemaType, _voorVc); + + _value = newVal; + } + + protected void set_GDuration(GDurationSpecification v) + { + if (_validateOnSet()) + validateValue(v, _schemaType, _voorVc); + + if (v.isImmutable() && (v instanceof GDuration)) + _value = (GDuration)v; + else + _value = new GDuration(v); + } + + protected String compute_text(NamespaceManager nsm) + { return _value == null ? "" : _value.toString(); } + + protected void set_nil() + { + _value = null; + } + + public GDuration getGDurationValue() + { + check_dated(); + + return _value == null ? null : _value; + } + + public static GDuration lex(String v, ValidationContext context) + { + GDuration duration = null; + + try + { + duration = new GDuration(v); + } + catch (Exception e) + { + context.invalid(XmlErrorCodes.DURATION, new Object[] { v }); + } + + return duration; + } + + public static GDuration validateLexical(String v, SchemaType sType, ValidationContext context) + { + GDuration duration = lex(v, context); + + if (duration != null && sType.hasPatternFacet()) + if (!sType.matchPatternFacet(v)) + context.invalid(XmlErrorCodes.DATATYPE_VALID$PATTERN_VALID, + new Object[] { "duration", v, QNameHelper.readable(sType) }); + + return duration; + } + + public static void validateValue(GDurationSpecification v, SchemaType sType, ValidationContext context) + { + XmlObject x; + GDuration g; + + if ((x = sType.getFacet(SchemaType.FACET_MIN_EXCLUSIVE)) != null) + if (v.compareToGDuration(g = ((XmlObjectBase)x).gDurationValue()) <= 0) + context.invalid(XmlErrorCodes.DATATYPE_MIN_EXCLUSIVE_VALID, + new Object[] { "duration", v, g, QNameHelper.readable(sType) }); + + if ((x = sType.getFacet(SchemaType.FACET_MIN_INCLUSIVE)) != null) + if (v.compareToGDuration(g = ((XmlObjectBase)x).gDurationValue()) < 0) + context.invalid(XmlErrorCodes.DATATYPE_MIN_INCLUSIVE_VALID, + new Object[] { "duration", v, g, QNameHelper.readable(sType) }); + + if ((x = sType.getFacet(SchemaType.FACET_MAX_EXCLUSIVE)) != null) + if (v.compareToGDuration(g = ((XmlObjectBase)x).gDurationValue()) >= 0) + context.invalid(XmlErrorCodes.DATATYPE_MAX_EXCLUSIVE_VALID, + new Object[] { "duration", v, g, QNameHelper.readable(sType) }); + + if ((x = sType.getFacet(SchemaType.FACET_MAX_INCLUSIVE)) != null) + if (v.compareToGDuration(g = ((XmlObjectBase)x).gDurationValue()) > 0) + context.invalid(XmlErrorCodes.DATATYPE_MAX_INCLUSIVE_VALID, + new Object[] { "duration", v, g, QNameHelper.readable(sType) }); + + XmlObject[] vals = sType.getEnumerationValues(); + if (vals != null) + { + for (int i = 0; i < vals.length; i++) + if (v.compareToGDuration(((XmlObjectBase)vals[i]).gDurationValue()) == 0) + return; + context.invalid(XmlErrorCodes.DATATYPE_ENUM_VALID, + new Object[] { "duration", v, QNameHelper.readable(sType) }); + } + } + + protected int compare_to(XmlObject d) + { + return _value.compareToGDuration(((XmlObjectBase) d).gDurationValue()); + } + + protected boolean equal_to(XmlObject d) + { + return _value.equals(((XmlObjectBase) d).gDurationValue()); + } + + protected int value_hash_code() + { + return _value.hashCode(); + } + + protected void validate_simpleval(String lexical, ValidationContext ctx) + { + validateLexical(lexical, schemaType(), ctx); + validateValue(gDurationValue(), schemaType(), ctx); + } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaHexBinaryHolder.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaHexBinaryHolder.java new file mode 100644 index 000000000..a0c026d51 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaHexBinaryHolder.java @@ -0,0 +1,155 @@ +/* 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.values; + +import org.apache.xmlbeans.impl.schema.BuiltinSchemaTypeSystem; + +import org.apache.xmlbeans.impl.util.HexBin; +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.XmlErrorCodes; +import org.apache.xmlbeans.XmlHexBinary; +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.impl.common.ValidationContext; +import org.apache.xmlbeans.impl.common.QNameHelper; + +import java.security.NoSuchAlgorithmException; +import java.security.MessageDigest; +import java.util.Arrays; +import java.io.UnsupportedEncodingException; + +public abstract class JavaHexBinaryHolder extends XmlObjectBase +{ + public SchemaType schemaType() + { return BuiltinSchemaTypeSystem.ST_HEX_BINARY; } + + protected byte[] _value; + + // SIMPLE VALUE ACCESSORS BELOW ------------------------------------------- + + // gets raw text value + protected String compute_text(NamespaceManager nsm) + { + return new String(HexBin.encode(_value)); + } + protected void set_text(String s) + { + _hashcached = false; + if (_validateOnSet()) + _value = validateLexical(s, schemaType(), _voorVc); + else + _value = lex(s, _voorVc); + } + protected void set_nil() + { + _hashcached = false; + _value = null; + } + + public static byte[] lex(String v, ValidationContext context) + { + byte[] vBytes = null; + try + { + vBytes = v.getBytes("UTF-8"); + } + catch(UnsupportedEncodingException uee) + { + // should never happen - UTF-8 is always supported + } + byte[] bytes = HexBin.decode(vBytes); + + if (bytes == null) + { + // TODO - get a decent error with line numbers and such here + context.invalid(XmlErrorCodes.HEXBINARY, new Object[] { "not encoded properly" }); + } + + return bytes; + } + + public static byte[] validateLexical(String v, SchemaType sType, ValidationContext context) + { + byte[] bytes = lex(v, context); + + if (bytes == null) + return null; + + if (!sType.matchPatternFacet(v)) + { + context.invalid( "Hex encoded data does not match pattern for " + QNameHelper.readable(sType)); + return null; + } + + return bytes; + } + + public byte[] getByteArrayValue() + { + check_dated(); + if (_value == null) + return null; + + byte[] result = new byte[_value.length]; + System.arraycopy(_value, 0, result, 0, _value.length); + return result; + } + + // setters + protected void set_ByteArray(byte[] ba) + { + _hashcached = false; + _value = new byte[ba.length]; + System.arraycopy(ba, 0, _value, 0, ba.length); + } + + // comparators + protected boolean equal_to(XmlObject i) + { + byte[] ival = ((XmlHexBinary) i).getByteArrayValue(); + return Arrays.equals(_value, ival); + } + + //because computing hashcode is expensive we'll cache it + protected boolean _hashcached = false; + protected int hashcode = 0; + protected static MessageDigest md5; + static + { + try + { + md5 = MessageDigest.getInstance("MD5"); + } + catch( NoSuchAlgorithmException e ) + { + throw new IllegalStateException("Cannot find MD5 hash Algorithm"); + } + } + + protected int value_hash_code() + { + if( _hashcached ) + return hashcode; + + _hashcached = true; + + if( _value == null ) + return hashcode = 0; + + byte[] res = md5.digest(_value); + return hashcode = res[0]<<24 + res[1]<<16 + res[2]<<8 + res[3]; + } + +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaHexBinaryHolderEx.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaHexBinaryHolderEx.java new file mode 100644 index 000000000..de94381f8 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaHexBinaryHolderEx.java @@ -0,0 +1,128 @@ +/* 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.values; + +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.XmlErrorCodes; +import org.apache.xmlbeans.impl.common.QNameHelper; +import org.apache.xmlbeans.impl.common.ValidationContext; + + +public abstract class JavaHexBinaryHolderEx extends JavaHexBinaryHolder +{ + private SchemaType _schemaType; + + + public SchemaType schemaType() + { return _schemaType; } + + public JavaHexBinaryHolderEx(SchemaType type, boolean complex) + { _schemaType = type; initComplexType(complex, false); } + + protected int get_wscanon_rule() + { + return schemaType().getWhiteSpaceRule(); + } + + protected void set_text(String s) + { + byte[] v; + + if (_validateOnSet()) + v = validateLexical(s, schemaType(), _voorVc); + else + v = lex(s, _voorVc); + + if (_validateOnSet() && v != null) + validateValue(v, schemaType(), XmlObjectBase._voorVc); + + super.set_ByteArray(v); + + _value = v; + } + + // setters + protected void set_ByteArray(byte[] v) + { + if (_validateOnSet()) + validateValue(v, schemaType(), _voorVc); + + super.set_ByteArray(v); + } + + public static void validateValue(byte[] v, SchemaType sType, ValidationContext context) + { + int i; + XmlObject o; + + if ((o = sType.getFacet(SchemaType.FACET_LENGTH)) != null) + { + if ((i = ((XmlObjectBase)o).bigIntegerValue().intValue()) != v.length) + { + context.invalid(XmlErrorCodes.DATATYPE_LENGTH_VALID$BINARY, + new Object[] { "hexBinary", new Integer(v.length), new Integer(i), QNameHelper.readable(sType) } ); + } + } + + if ((o = sType.getFacet( SchemaType.FACET_MIN_LENGTH )) != null) + { + if ((i = ((XmlObjectBase)o).bigIntegerValue().intValue()) > v.length) + { + context.invalid(XmlErrorCodes.DATATYPE_MIN_LENGTH_VALID$BINARY, + new Object[] { "hexBinary", new Integer(v.length), new Integer(i), QNameHelper.readable(sType) } ); + } + } + + if ((o = sType.getFacet( SchemaType.FACET_MAX_LENGTH )) != null) + { + if ((i = ((XmlObjectBase)o).bigIntegerValue().intValue()) < v.length) + { + context.invalid(XmlErrorCodes.DATATYPE_MAX_LENGTH_VALID$BINARY, + new Object[] { "hexBinary", new Integer(v.length), new Integer(i), QNameHelper.readable(sType) } ); + } + } + + XmlObject[] vals = sType.getEnumerationValues(); + + if (vals != null) + { + enumLoop: for ( i = 0 ; i < vals.length ; i++ ) + { + byte[] enumBytes = ((XmlObjectBase)vals[i]).byteArrayValue(); + + if (enumBytes.length != v.length) + continue; + + for ( int j = 0 ; j < enumBytes.length ; j++ ) + if (enumBytes[j] != v[j]) + continue enumLoop; + + break; + } + + if (i >= vals.length) + context.invalid(XmlErrorCodes.DATATYPE_ENUM_VALID$NO_VALUE, + new Object[] { "hexBinary", QNameHelper.readable(sType) }); + } + } + + protected void validate_simpleval(String lexical, ValidationContext ctx) + { + validateLexical(lexical, schemaType(), ctx); + validateValue(byteArrayValue(), schemaType(), ctx); + } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaIntHolder.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaIntHolder.java new file mode 100644 index 000000000..6651b7039 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaIntHolder.java @@ -0,0 +1,103 @@ +/* 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.values; + +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.XmlErrorCodes; +import org.apache.xmlbeans.SimpleValue; + +import java.math.BigDecimal; +import java.math.BigInteger; + +import org.apache.xmlbeans.impl.schema.BuiltinSchemaTypeSystem; +import org.apache.xmlbeans.impl.util.XsTypeConverter; + +public abstract class JavaIntHolder extends XmlObjectBase +{ + public SchemaType schemaType() + { return BuiltinSchemaTypeSystem.ST_INT; } + + private int _value; + + // SIMPLE VALUE ACCESSORS BELOW ------------------------------------------- + + // gets raw text value + public String compute_text(NamespaceManager nsm) { return Long.toString(_value); } + protected void set_text(String s) + { + try { set_int(XsTypeConverter.lexInt(s)); } + catch (Exception e) { throw new XmlValueOutOfRangeException(XmlErrorCodes.INT, new Object[] { s }); } + } + protected void set_nil() + { + _value = 0; + } + // numerics: fractional + public BigDecimal getBigDecimalValue() { check_dated(); return new BigDecimal((double) _value); } + public BigInteger getBigIntegerValue() { check_dated(); return BigInteger.valueOf(_value); } + public long getLongValue() { check_dated(); return _value; } + public int getIntValue() { check_dated(); return _value; } + + static final BigInteger _max = BigInteger.valueOf(Integer.MAX_VALUE); + static final BigInteger _min = BigInteger.valueOf(Integer.MIN_VALUE); + + // setters + protected void set_BigDecimal(BigDecimal v) { set_BigInteger(v.toBigInteger()); } + protected void set_BigInteger(BigInteger v) + { + if (v.compareTo(_max) > 0 || v.compareTo(_min) < 0) + throw new XmlValueOutOfRangeException(); + set_int(v.intValue()); + } + protected void set_long(long l) + { + if (l > Integer.MAX_VALUE || l < Integer.MIN_VALUE) + throw new XmlValueOutOfRangeException(); + set_int((int)l); + } + protected void set_int(int i) + { + _value = i; + } + + // comparators + protected int compare_to(XmlObject i) + { + if (((SimpleValue)i).instanceType().getDecimalSize() > SchemaType.SIZE_INT) + return -i.compareTo(this); + + return _value == ((XmlObjectBase)i).intValue() ? 0 : + _value < ((XmlObjectBase)i).intValue() ? -1 : 1; + } + + protected boolean equal_to(XmlObject i) + { + if (((SimpleValue)i).instanceType().getDecimalSize() > SchemaType.SIZE_INT) + return i.valueEquals(this); + + return _value == ((XmlObjectBase)i).intValue(); + } + + /** + * Note, this is carefully aligned with hash codes for all xsd:decimal + * primitives. + */ + protected int value_hash_code() + { + return _value; + } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaIntHolderEx.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaIntHolderEx.java new file mode 100644 index 000000000..d9faf73ae --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaIntHolderEx.java @@ -0,0 +1,183 @@ +/* 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.values; + +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.XmlErrorCodes; +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.impl.common.ValidationContext; +import org.apache.xmlbeans.impl.common.QNameHelper; +import org.apache.xmlbeans.impl.util.XsTypeConverter; + +public abstract class JavaIntHolderEx extends JavaIntHolder +{ + public JavaIntHolderEx(SchemaType type, boolean complex) + { _schemaType = type; initComplexType(complex, false); } + + private SchemaType _schemaType; + + + public SchemaType schemaType() + { return _schemaType; } + + protected void set_text(String s) + { + int v; + + try { v = XsTypeConverter.lexInt(s); } + catch (Exception e) { throw new XmlValueOutOfRangeException(); } + + if (_validateOnSet()) + { + validateValue(v, _schemaType, _voorVc); + validateLexical(s, _schemaType, _voorVc); + } + + super.set_int(v); + } + + protected void set_int(int v) + { + if (_validateOnSet()) + validateValue(v, _schemaType, _voorVc); + + super.set_int(v); + } + + public static void validateLexical(String v, SchemaType sType, ValidationContext context) + { + JavaDecimalHolder.validateLexical(v, context); + + // check pattern + if (sType.hasPatternFacet()) + { + if (!sType.matchPatternFacet(v)) + { + context.invalid(XmlErrorCodes.DATATYPE_VALID$PATTERN_VALID, + new Object[] { "int", v, QNameHelper.readable(sType) }); + } + } + } + + private static void validateValue(int v, SchemaType sType, ValidationContext context) + { + // total digits + XmlObject td = sType.getFacet(SchemaType.FACET_TOTAL_DIGITS); + if (td != null) + { + String temp = Integer.toString(v); + int len = temp.length(); + if (len > 0 && temp.charAt(0) == '-') + len -= 1; + int m = getIntValue(td); + if (len > m) + { + context.invalid(XmlErrorCodes.DATATYPE_TOTAL_DIGITS_VALID, + new Object[] { new Integer(len), temp, new Integer(getIntValue(td)), QNameHelper.readable(sType) }); + return; + } + } + + // min ex + XmlObject mine = sType.getFacet(SchemaType.FACET_MIN_EXCLUSIVE); + if (mine != null) + { + int m = getIntValue(mine); + if (!(v > m)) + { + context.invalid(XmlErrorCodes.DATATYPE_MIN_EXCLUSIVE_VALID, + new Object[] { "int", new Integer(v), new Integer(m), QNameHelper.readable(sType) }); + return; + } + } + + // min in + XmlObject mini = sType.getFacet(SchemaType.FACET_MIN_INCLUSIVE); + if (mini != null) + { + int m = getIntValue(mini); + if (!(v >= m)) + { + context.invalid(XmlErrorCodes.DATATYPE_MIN_INCLUSIVE_VALID, + new Object[] { "int", new Integer(v), new Integer(m), QNameHelper.readable(sType) }); + return; + } + } + + // max in + XmlObject maxi = sType.getFacet(SchemaType.FACET_MAX_INCLUSIVE); + if (maxi != null) + { + int m = getIntValue(maxi); + if (!(v <= m)) + { + context.invalid(XmlErrorCodes.DATATYPE_MAX_EXCLUSIVE_VALID, + new Object[] { "int", new Integer(v), new Integer(m), QNameHelper.readable(sType) }); + return; + } + } + + // max ex + XmlObject maxe = sType.getFacet(SchemaType.FACET_MAX_EXCLUSIVE); + if (maxe != null) + { + int m = getIntValue(maxe); + if (!(v < m)) + { + context.invalid(XmlErrorCodes.DATATYPE_MAX_EXCLUSIVE_VALID, + new Object[] { "int", new Integer(v), new Integer(m), QNameHelper.readable(sType) }); + return; + } + } + + // enumeration + XmlObject[] vals = sType.getEnumerationValues(); + if (vals != null) + { + for (int i = 0; i < vals.length; i++) + { + if (v == getIntValue(vals[i])) + return; + } + context.invalid(XmlErrorCodes.DATATYPE_ENUM_VALID, + new Object[] { "int", new Integer(v), QNameHelper.readable(sType) }); + } + } + + private static int getIntValue(XmlObject o) { + SchemaType s = o.schemaType(); + switch (s.getDecimalSize()) + { + case SchemaType.SIZE_BIG_DECIMAL: + return ((XmlObjectBase)o).getBigDecimalValue().intValue(); + case SchemaType.SIZE_BIG_INTEGER: + return ((XmlObjectBase)o).getBigIntegerValue().intValue(); + case SchemaType.SIZE_LONG: + return (int)((XmlObjectBase)o).getLongValue(); + default: + return ((XmlObjectBase)o).getIntValue(); + } + + } + + protected void validate_simpleval(String lexical, ValidationContext ctx) + { + validateLexical(lexical, schemaType(), ctx); + validateValue(getIntValue(), schemaType(), ctx); + } + +} + diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaIntegerHolder.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaIntegerHolder.java new file mode 100644 index 000000000..172f8a13d --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaIntegerHolder.java @@ -0,0 +1,98 @@ +/* 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.values; + +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.XmlErrorCodes; +import org.apache.xmlbeans.SimpleValue; +import org.apache.xmlbeans.impl.common.ValidationContext; + +import java.math.BigDecimal; +import java.math.BigInteger; + +import org.apache.xmlbeans.impl.schema.BuiltinSchemaTypeSystem; + +public abstract class JavaIntegerHolder extends XmlObjectBase +{ + public SchemaType schemaType() + { return BuiltinSchemaTypeSystem.ST_INTEGER; } + + private BigInteger _value; + + // SIMPLE VALUE ACCESSORS BELOW ------------------------------------------- + + // gets/sets raw text value + protected String compute_text(NamespaceManager nsm) { return _value.toString(); } + protected void set_text(String s) + { + set_BigInteger(lex(s, _voorVc)); + } + public static BigInteger lex(String s, ValidationContext vc) + { + if (s.length() > 0 && s.charAt( 0 ) == '+' ) + s = s.substring(1); + + try { return new BigInteger(s); } + catch (Exception e) { vc.invalid(XmlErrorCodes.INTEGER, new Object[] { s }); return null; } + } + protected void set_nil() + { + _value = null; + } + // numerics: fractional + public BigDecimal getBigDecimalValue() { check_dated(); return _value == null ? null : new BigDecimal(_value); } + public BigInteger getBigIntegerValue() { check_dated(); return _value; } + + // setters + protected void set_BigDecimal(BigDecimal v) { _value = v.toBigInteger(); } + protected void set_BigInteger(BigInteger v) { _value = v; } + + // comparators + protected int compare_to(XmlObject i) + { + if (((SimpleValue)i).instanceType().getDecimalSize() > SchemaType.SIZE_BIG_INTEGER) + return -i.compareTo(this); + + return _value.compareTo(((XmlObjectBase)i).bigIntegerValue()); + } + + protected boolean equal_to(XmlObject i) + { + if (((SimpleValue)i).instanceType().getDecimalSize() > SchemaType.SIZE_BIG_INTEGER) + return i.valueEquals(this); + + return _value.equals(((XmlObjectBase)i).bigIntegerValue()); + } + + static private BigInteger _maxlong = BigInteger.valueOf(Long.MAX_VALUE); + static private BigInteger _minlong = BigInteger.valueOf(Long.MIN_VALUE); + + /** + * Note, this is carefully aligned with hash codes for all xsd:decimal + * primitives. + */ + protected int value_hash_code() + { + if (_value.compareTo(_maxlong) > 0 || + _value.compareTo(_minlong) < 0) + return _value.hashCode(); + + long longval = _value.longValue(); + + return (int)((longval >> 32) * 19 + longval); + } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaIntegerHolderEx.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaIntegerHolderEx.java new file mode 100644 index 000000000..cdee3ae80 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaIntegerHolderEx.java @@ -0,0 +1,181 @@ +/* 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.values; + +import java.math.BigInteger; + +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.XmlErrorCodes; +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.XmlPositiveInteger; +import org.apache.xmlbeans.impl.common.ValidationContext; +import org.apache.xmlbeans.impl.common.QNameHelper; + +public class JavaIntegerHolderEx extends JavaIntegerHolder +{ + public JavaIntegerHolderEx(SchemaType type, boolean complex) + { _schemaType = type; initComplexType(complex, false); } + + private SchemaType _schemaType; + + + public SchemaType schemaType() + { return _schemaType; } + + protected void set_text(String s) + { + BigInteger v = lex(s, _voorVc); + + if (_validateOnSet()) + validateValue(v, _schemaType, _voorVc); + + if (_validateOnSet()) + validateLexical(s, _schemaType, _voorVc); + + super.set_BigInteger(v); + } + + protected void set_BigInteger(BigInteger v) + { + if (_validateOnSet()) + validateValue(v, _schemaType, _voorVc); + + super.set_BigInteger(v); + } + + public static void validateLexical(String v, SchemaType sType, ValidationContext context) + { + JavaDecimalHolder.validateLexical(v, context); + if ( v.lastIndexOf('.')>=0 ) + context.invalid(XmlErrorCodes.INTEGER, + new Object[] { v }); + + // check pattern + if (sType.hasPatternFacet()) + { + if (!sType.matchPatternFacet(v)) + { + context.invalid(XmlErrorCodes.DATATYPE_VALID$PATTERN_VALID, + new Object[] { "integer", v, QNameHelper.readable(sType) }); + } + } + } + + private static void validateValue(BigInteger v, SchemaType sType, ValidationContext context) + { + // total digits + XmlPositiveInteger td = (XmlPositiveInteger)sType.getFacet(SchemaType.FACET_TOTAL_DIGITS); + if (td != null) + { + String temp = v.toString(); + int len = temp.length(); + if (len > 0 && temp.charAt(0) == '-') + len -= 1; + if (len > td.getBigIntegerValue().intValue()) + { + context.invalid(XmlErrorCodes.DATATYPE_TOTAL_DIGITS_VALID, + new Object[] { new Integer(len), temp, new Integer(td.getBigIntegerValue().intValue()), QNameHelper.readable(sType) }); + return; + } + } + + // min ex + XmlObject mine = sType.getFacet(SchemaType.FACET_MIN_EXCLUSIVE); + if (mine != null) + { + BigInteger m = getBigIntegerValue(mine); + if (!(v.compareTo(m) > 0)) + { + context.invalid(XmlErrorCodes.DATATYPE_MIN_EXCLUSIVE_VALID, + new Object[] { "integer", v, m, QNameHelper.readable(sType) }); + return; + } + } + + // min in + XmlObject mini = sType.getFacet(SchemaType.FACET_MIN_INCLUSIVE); + if (mini != null) + { + BigInteger m = getBigIntegerValue(mini); + if (!(v.compareTo(m) >= 0)) + { + context.invalid(XmlErrorCodes.DATATYPE_MIN_INCLUSIVE_VALID, + new Object[] { "integer", v, m, QNameHelper.readable(sType) }); + return; + } + } + + // max in + XmlObject maxi = sType.getFacet(SchemaType.FACET_MAX_INCLUSIVE); + if (maxi != null) + { + BigInteger m = getBigIntegerValue(maxi); + if (!(v.compareTo(m) <= 0)) + { + context.invalid(XmlErrorCodes.DATATYPE_MAX_INCLUSIVE_VALID, + new Object[] { "integer", v, m, QNameHelper.readable(sType) }); + return; + } + } + + // max ex + XmlObject maxe = sType.getFacet(SchemaType.FACET_MAX_EXCLUSIVE); + if (maxe != null) + { + BigInteger m = getBigIntegerValue(maxe); + if (!(v.compareTo(m) < 0)) + { + context.invalid(XmlErrorCodes.DATATYPE_MAX_EXCLUSIVE_VALID, + new Object[] { "integer", v, m, QNameHelper.readable(sType) }); + return; + } + } + + // enumeration + XmlObject[] vals = sType.getEnumerationValues(); + if (vals != null) + { + for (int i = 0; i < vals.length; i++) + { + if (v.equals(getBigIntegerValue(vals[i]))) + return; + } + context.invalid(XmlErrorCodes.DATATYPE_ENUM_VALID, + new Object[] { "integer", v, QNameHelper.readable(sType) }); + } + } + + private static BigInteger getBigIntegerValue(XmlObject o) + { + SchemaType s = o.schemaType(); + switch (s.getDecimalSize()) + { + case SchemaType.SIZE_BIG_DECIMAL: + return ((XmlObjectBase)o).bigDecimalValue().toBigInteger(); + case SchemaType.SIZE_BIG_INTEGER: + return ((XmlObjectBase)o).bigIntegerValue(); + default: + throw new IllegalStateException("Bad facet type for Big Int: " + s); + } + } + + protected void validate_simpleval(String lexical, ValidationContext ctx) + { + validateLexical(lexical, schemaType(), ctx); + validateValue(getBigIntegerValue(), schemaType(), ctx); + } + +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaLongHolder.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaLongHolder.java new file mode 100644 index 000000000..296c5ee49 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaLongHolder.java @@ -0,0 +1,95 @@ +/* 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.values; + +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.XmlErrorCodes; +import org.apache.xmlbeans.SimpleValue; + +import java.math.BigInteger; +import java.math.BigDecimal; + +import org.apache.xmlbeans.impl.schema.BuiltinSchemaTypeSystem; +import org.apache.xmlbeans.impl.util.XsTypeConverter; + +public abstract class JavaLongHolder extends XmlObjectBase +{ + public SchemaType schemaType() + { return BuiltinSchemaTypeSystem.ST_LONG; } + + private long _value; + + // SIMPLE VALUE ACCESSORS BELOW ------------------------------------------- + + // gets raw text value + protected String compute_text(NamespaceManager nsm) { return Long.toString(_value); } + protected void set_text(String s) + { + try { set_long(XsTypeConverter.lexLong(s)); } + catch (Exception e) { throw new XmlValueOutOfRangeException(XmlErrorCodes.LONG, new Object[] { s }); } + } + protected void set_nil() + { + _value = 0L; + } + + // numerics: fractional + public BigDecimal getBigDecimalValue() { check_dated(); return BigDecimal.valueOf(_value); } + public BigInteger getBigIntegerValue() { check_dated(); return BigInteger.valueOf(_value); } + public long getLongValue() { check_dated(); return _value; } + + private static final BigInteger _max = BigInteger.valueOf(Long.MAX_VALUE); + private static final BigInteger _min = BigInteger.valueOf(Long.MIN_VALUE); + + // setters + protected void set_BigDecimal(BigDecimal v) { set_BigInteger(v.toBigInteger()); } + protected void set_BigInteger(BigInteger v) + { + if (v.compareTo(_max) > 0 || v.compareTo(_min) < 0) + throw new XmlValueOutOfRangeException(); + _value = v.longValue(); + } + protected void set_long(long l) { _value = l; } + + // comparators + protected int compare_to(XmlObject l) + { + if (((SimpleValue)l).instanceType().getDecimalSize() > SchemaType.SIZE_LONG) + return -l.compareTo(this); + + return _value == ((XmlObjectBase)l).longValue() ? 0 : + _value < ((XmlObjectBase)l).longValue() ? -1 : 1; + } + + protected boolean equal_to(XmlObject l) + { + if (((SimpleValue)l).instanceType().getDecimalSize() > SchemaType.SIZE_LONG) + return l.valueEquals(this); + + return _value == ((XmlObjectBase)l).longValue(); + } + + /** + * Note, this is carefully aligned with hash codes for all xsd:decimal + * primitives. + */ + protected int value_hash_code() + { + return (int)((_value >> 32) * 19 + _value); + } + +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaLongHolderEx.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaLongHolderEx.java new file mode 100644 index 000000000..57db2a528 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaLongHolderEx.java @@ -0,0 +1,181 @@ +/* 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.values; + +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.XmlErrorCodes; +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.impl.common.ValidationContext; +import org.apache.xmlbeans.impl.common.QNameHelper; +import org.apache.xmlbeans.impl.util.XsTypeConverter; + +public abstract class JavaLongHolderEx extends JavaLongHolder +{ + public JavaLongHolderEx(SchemaType type, boolean complex) + { _schemaType = type; initComplexType(complex, false); } + + private SchemaType _schemaType; + + + public SchemaType schemaType() + { return _schemaType; } + + protected void set_text(String s) + { + long v; + + try { v = XsTypeConverter.lexLong(s); } + catch (Exception e) { throw new XmlValueOutOfRangeException(); } + + if (_validateOnSet()) + { + validateValue(v, _schemaType, _voorVc); + validateLexical(s, _schemaType, _voorVc); + } + + super.set_long(v); + } + + protected void set_long(long v) + { + if (_validateOnSet()) + validateValue(v, _schemaType, _voorVc); + + super.set_long(v); + } + + public static void validateLexical(String v, SchemaType sType, ValidationContext context) + { + JavaDecimalHolder.validateLexical(v, context); + + // check pattern + if (sType.hasPatternFacet()) + { + if (!sType.matchPatternFacet(v)) + { + context.invalid(XmlErrorCodes.DATATYPE_VALID$PATTERN_VALID, + new Object[] { "long", v, QNameHelper.readable(sType) }); + } + } + } + + private static void validateValue(long v, SchemaType sType, ValidationContext context) + { + // total digits + XmlObject td = sType.getFacet(SchemaType.FACET_TOTAL_DIGITS); + if (td != null) + { + long m = getLongValue(td); + String temp = Long.toString(v); + int len = temp.length(); + if (len > 0 && temp.charAt(0) == '-') + len -= 1; + if (len > m) + { + context.invalid(XmlErrorCodes.DATATYPE_TOTAL_DIGITS_VALID, + new Object[] { new Integer(len), temp, new Long(m), QNameHelper.readable(sType) }); + return; + } + } + + // min ex + XmlObject mine = sType.getFacet(SchemaType.FACET_MIN_EXCLUSIVE); + if (mine != null) + { + long m = getLongValue(mine); + if (!(v > m)) + { + context.invalid(XmlErrorCodes.DATATYPE_MIN_EXCLUSIVE_VALID, + new Object[] { "long", new Long(v), new Long(m), QNameHelper.readable(sType) }); + return; + } + } + + // min in + XmlObject mini = sType.getFacet(SchemaType.FACET_MIN_INCLUSIVE); + if (mini != null) + { + long m = getLongValue(mini); + if (!(v >= m)) + { + context.invalid(XmlErrorCodes.DATATYPE_MIN_INCLUSIVE_VALID, + new Object[] { "long", new Long(v), new Long(m), QNameHelper.readable(sType) }); + return; + } + } + + // max in + XmlObject maxi = sType.getFacet(SchemaType.FACET_MAX_INCLUSIVE); + if (maxi != null) + { + long m = getLongValue(maxi); + if (!(v <= m)) + { + context.invalid(XmlErrorCodes.DATATYPE_MAX_INCLUSIVE_VALID, + new Object[] { "long", new Long(v), new Long(m), QNameHelper.readable(sType) }); + return; + } + } + + // max ex + XmlObject maxe = sType.getFacet(SchemaType.FACET_MAX_EXCLUSIVE); + if (maxe != null) + { + long m = getLongValue(maxe); + if (!(v < m)) + { + context.invalid(XmlErrorCodes.DATATYPE_MAX_EXCLUSIVE_VALID, + new Object[] { "long", new Long(v), new Long(m), QNameHelper.readable(sType) }); + return; + } + } + + // enumeration + XmlObject[] vals = sType.getEnumerationValues(); + if (vals != null) + { + for (int i = 0; i < vals.length; i++) + { + if (v == getLongValue(vals[i])) + return; + } + context.invalid(XmlErrorCodes.DATATYPE_ENUM_VALID, + new Object[] { "long", new Long(v), QNameHelper.readable(sType) }); + } + } + + private static long getLongValue(XmlObject o) { + SchemaType s = o.schemaType(); + switch (s.getDecimalSize()) + { + case SchemaType.SIZE_BIG_DECIMAL: + return ((XmlObjectBase)o).getBigDecimalValue().longValue(); + case SchemaType.SIZE_BIG_INTEGER: + return ((XmlObjectBase)o).getBigIntegerValue().longValue(); + case SchemaType.SIZE_LONG: + return ((XmlObjectBase)o).getLongValue(); + default: + throw new IllegalStateException("Bad facet type: " + s); + } + + } + + protected void validate_simpleval(String lexical, ValidationContext ctx) + { + validateLexical(lexical, schemaType(), ctx); + validateValue(getLongValue(), schemaType(), ctx); + } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaNotationHolder.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaNotationHolder.java new file mode 100644 index 000000000..ff329c182 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaNotationHolder.java @@ -0,0 +1,30 @@ +/* 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.values; + +import org.apache.xmlbeans.SchemaType; + +import org.apache.xmlbeans.impl.schema.BuiltinSchemaTypeSystem; + +public abstract class JavaNotationHolder extends XmlQNameImpl +{ + public SchemaType schemaType() + { return BuiltinSchemaTypeSystem.ST_NOTATION; } + +// protected int get_wscanon_rule() +// { return SchemaType.WS_PRESERVE; } + +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaNotationHolderEx.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaNotationHolderEx.java new file mode 100644 index 000000000..a6eddc0bb --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaNotationHolderEx.java @@ -0,0 +1,142 @@ +/* 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.values; + +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.XmlAnySimpleType; +import org.apache.xmlbeans.XmlErrorCodes; +import org.apache.xmlbeans.impl.common.ValidationContext; +import org.apache.xmlbeans.impl.common.PrefixResolver; +import org.apache.xmlbeans.impl.common.QNameHelper; + +import javax.xml.namespace.QName; + +public abstract class JavaNotationHolderEx extends JavaNotationHolder +{ + private SchemaType _schemaType; + + + public SchemaType schemaType() + { return _schemaType; } + + public JavaNotationHolderEx(SchemaType type, boolean complex) + { _schemaType = type; initComplexType(complex, false); } + + protected int get_wscanon_rule() + { + return schemaType().getWhiteSpaceRule(); + } + + protected void set_text(String s) + { + if (_validateOnSet()) + { + if (!check(s, _schemaType)) + throw new XmlValueOutOfRangeException(); + + if (!_schemaType.matchPatternFacet(s)) + throw new XmlValueOutOfRangeException(); + } + + super.set_text(s); + } + + protected void set_notation(String v) + { set_text(v); } + + protected void set_xmlanysimple(XmlAnySimpleType value) + { + QName v; + if (_validateOnSet()) + { + v = validateLexical(value.getStringValue(), _schemaType, _voorVc, NamespaceContext.getCurrent()); + + if (v != null) + validateValue(v, _schemaType, _voorVc); + } + else + v = JavaNotationHolder.validateLexical(value.getStringValue(), _voorVc, NamespaceContext.getCurrent()); + + super.set_QName(v); + } + + public static QName validateLexical(String v, SchemaType sType, ValidationContext context, PrefixResolver resolver) + { + QName name = JavaQNameHolder.validateLexical(v, context, resolver); + + // check pattern + if (sType.hasPatternFacet()) + { + if (!sType.matchPatternFacet(v)) + { + // TODO - describe string and pattern here in error + context.invalid(XmlErrorCodes.DATATYPE_VALID$PATTERN_VALID, + new Object[] { "NOTATION", v, QNameHelper.readable(sType) }); + } + } + + check(v, sType); + + return name; + } + + private static boolean check(String v, SchemaType sType) + { + // check against length + XmlObject len = sType.getFacet(SchemaType.FACET_LENGTH); + if (len != null) + { + int m = ((XmlObjectBase)len).getBigIntegerValue().intValue(); + if (!(v.length() != m)) + return false; + } + + // check against min length + XmlObject min = sType.getFacet(SchemaType.FACET_MIN_LENGTH); + if (min != null) + { + int m = ((XmlObjectBase)min).getBigIntegerValue().intValue(); + if (!(v.length() >= m)) + return false; + } + + // check against min length + XmlObject max = sType.getFacet(SchemaType.FACET_MAX_LENGTH); + if (max != null) + { + int m = ((XmlObjectBase)max).getBigIntegerValue().intValue(); + if (!(v.length() <= m)) + return false; + } + + return true; + } + + public static void validateValue(QName v, SchemaType sType, ValidationContext context) + { + XmlObject[] vals = sType.getEnumerationValues(); + if (vals != null) + { + for (int i = 0; i < vals.length; i++) + if (v.equals(((XmlObjectBase)vals[i]).getQNameValue())) + return; + context.invalid(XmlErrorCodes.DATATYPE_ENUM_VALID, + new Object[] { "NOTATION", v, QNameHelper.readable(sType) }); + } + } + +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaQNameHolder.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaQNameHolder.java new file mode 100644 index 000000000..2035929e4 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaQNameHolder.java @@ -0,0 +1,199 @@ +/* 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.values; + +import org.apache.xmlbeans.impl.common.PrefixResolver; +import org.apache.xmlbeans.impl.schema.BuiltinSchemaTypeSystem; +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.XmlAnySimpleType; +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.XmlErrorCodes; +import org.apache.xmlbeans.impl.common.ValidationContext; +import org.apache.xmlbeans.impl.common.XMLChar; +import org.apache.xmlbeans.impl.common.QNameHelper; + +import javax.xml.namespace.QName; +import org.apache.xmlbeans.impl.values.NamespaceContext; + +public class JavaQNameHolder extends XmlObjectBase +{ + public JavaQNameHolder() {} + + public SchemaType schemaType() + { return BuiltinSchemaTypeSystem.ST_QNAME; } + + private QName _value; + + protected int get_wscanon_rule() + { return SchemaType.WS_PRESERVE; } + + // an ergonomic prefixer so that you can say stringValue() on a free-floating QName. + private static final NamespaceManager PRETTY_PREFIXER = new PrettyNamespaceManager(); + + private static class PrettyNamespaceManager implements NamespaceManager + { + public String find_prefix_for_nsuri(String nsuri, String suggested_prefix) + { + return QNameHelper.suggestPrefix(nsuri); + } + public String getNamespaceForPrefix(String prefix) + { + throw new RuntimeException( "Should not be called" ); + } + } + + // SIMPLE VALUE ACCESSORS BELOW ------------------------------------------- + public String compute_text(NamespaceManager nsm) + { + if (nsm == null) + { + // we used to: throw new IllegalStateException("Cannot create QName prefix outside of a document"); + // but it's not nice to throw on stringValue() + nsm = PRETTY_PREFIXER; + } + +// TODO - what I really need to do here is that if there is no +// namespace for this qname, then instead of finding the prefix for the +// uri, I should make a call to set the default namespace for the +// immediate context for this qname to be "". + + String namespace = _value.getNamespaceURI(); + String localPart = _value.getLocalPart(); + + if (namespace == null || namespace.length() == 0) + return localPart; + + String prefix = nsm.find_prefix_for_nsuri( namespace, null ); + + assert prefix != null; + + return "".equals(prefix) ? localPart : prefix + ":" + localPart; + } + + public static QName validateLexical( + String v, ValidationContext context, PrefixResolver resolver) + { + QName name; + + try + { + name = parse(v, resolver); + } + catch ( XmlValueOutOfRangeException e ) + { + context.invalid(e.getMessage()); + name = null; + } + + return name; + } + + private static QName parse(String v, PrefixResolver resolver) + { + String prefix, localname; + int start; + int end; + for (end = v.length(); end > 0; end -= 1) + if (!XMLChar.isSpace(v.charAt(end-1))) + break; + for (start = 0; start < end; start += 1) + if (!XMLChar.isSpace(v.charAt(start))) + break; + + int firstcolon = v.indexOf(':', start); + if (firstcolon >= 0) + { + prefix = v.substring(start, firstcolon); + localname = v.substring(firstcolon + 1, end); + } + else + { + prefix = ""; + localname = v.substring(start, end); + } + + if ( prefix.length()>0 && !XMLChar.isValidNCName(prefix) ) + throw new XmlValueOutOfRangeException(XmlErrorCodes.QNAME, new Object[] { "Prefix not a valid NCName in '" + v + "'" }); + + if ( !XMLChar.isValidNCName(localname) ) + throw new XmlValueOutOfRangeException(XmlErrorCodes.QNAME, new Object[] { "Localname not a valid NCName in '" + v + "'" }); + + String uri = + resolver == null ? null : resolver.getNamespaceForPrefix(prefix); + + if (uri == null) + { + if (prefix.length() > 0) + throw new XmlValueOutOfRangeException(XmlErrorCodes.QNAME, new Object[] { "Can't resolve prefix '" + prefix + "'"}); + + uri = ""; + } + + if ( prefix!=null && prefix.length()>0 ) + return new QName(uri, localname, prefix ); + else + return new QName( uri, localname ); + } + + protected void set_text(String s) + { + PrefixResolver resolver = NamespaceContext.getCurrent(); + + if (resolver == null && has_store()) + resolver = get_store(); + + _value = parse(s, resolver); + } + + // BUGBUG - having prefix here may not work + protected void set_QName(QName name) + { + assert name != null; + + // Sync force of creation of namesapce mapping .. + + if (has_store()) + get_store().find_prefix_for_nsuri( name.getNamespaceURI(), null ); + + _value = name; + } + + protected void set_xmlanysimple(XmlAnySimpleType value) + { + _value = parse(value.getStringValue(), NamespaceContext.getCurrent()); + } + + protected void set_nil() { _value = null; } + + // setters, getters (setter already handled via set_text) + + public QName getQNameValue() + { + check_dated(); + return _value; + } + + // comparators + protected boolean equal_to(XmlObject obj) + { + return _value.equals(((XmlObjectBase)obj).qNameValue()); + } + + protected int value_hash_code() + { + return _value.hashCode(); + } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaQNameHolderEx.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaQNameHolderEx.java new file mode 100644 index 000000000..67861c380 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaQNameHolderEx.java @@ -0,0 +1,143 @@ +/* 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.values; + +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.XmlErrorCodes; +import org.apache.xmlbeans.XmlAnySimpleType; +import org.apache.xmlbeans.impl.common.ValidationContext; +import org.apache.xmlbeans.impl.common.PrefixResolver; +import org.apache.xmlbeans.impl.common.QNameHelper; + +import javax.xml.namespace.QName; + +public abstract class JavaQNameHolderEx extends JavaQNameHolder +{ + private SchemaType _schemaType; + + + public SchemaType schemaType() + { return _schemaType; } + + public JavaQNameHolderEx(SchemaType type, boolean complex) + { _schemaType = type; initComplexType(complex, false); } + + protected int get_wscanon_rule() + { + return schemaType().getWhiteSpaceRule(); + } + + protected void set_text(String s) + { + PrefixResolver resolver = NamespaceContext.getCurrent(); + + if (resolver == null && has_store()) + resolver = get_store(); + + QName v; + if (_validateOnSet()) + { + v = validateLexical(s, _schemaType, _voorVc, resolver); + if (v != null) + validateValue(v, _schemaType, _voorVc); + } + else + v = JavaQNameHolder.validateLexical(s, _voorVc, resolver); + + super.set_QName(v); + } + + protected void set_QName(QName name) + { + if (_validateOnSet()) + validateValue(name, _schemaType, _voorVc); + super.set_QName( name ); + } + + protected void set_xmlanysimple(XmlAnySimpleType value) + { + QName v; + if (_validateOnSet()) + { + v = validateLexical(value.getStringValue(), _schemaType, _voorVc, NamespaceContext.getCurrent()); + + if (v != null) + validateValue(v, _schemaType, _voorVc); + } + else + v = JavaQNameHolder.validateLexical(value.getStringValue(), _voorVc, NamespaceContext.getCurrent()); + + super.set_QName(v); + } + + public static QName validateLexical(String v, SchemaType sType, ValidationContext context, PrefixResolver resolver) + { + QName name = JavaQNameHolder.validateLexical(v, context, resolver); + + // check pattern + if (sType.hasPatternFacet()) + { + if (!sType.matchPatternFacet(v)) + { + // TODO - describe string and pattern here in error + context.invalid(XmlErrorCodes.DATATYPE_VALID$PATTERN_VALID, + new Object[] { "QName", v, QNameHelper.readable(sType) }); + } + } + + /* length, minLength and maxLength facets deprecated - see http://www.w3.org/TR/xmlschema-2/#QName + XmlObject x; + int i; + + if ((x = sType.getFacet(SchemaType.FACET_LENGTH)) != null) + if ((i = ((XmlObjectBase)x).bigIntegerValue().intValue()) != v.length()) + context.invalid(XmlErrorCodes.DATATYPE_LENGTH_VALID$STRING, + new Object[] { "QName", v, new Integer(i), QNameHelper.readable(sType) }); + + if ((x = sType.getFacet(SchemaType.FACET_MIN_LENGTH)) != null) + if ((i = ((XmlObjectBase)x).bigIntegerValue().intValue()) > v.length()) + context.invalid(XmlErrorCodes.DATATYPE_MIN_LENGTH_VALID$STRING, + new Object[] { "QName", v, new Integer(i), QNameHelper.readable(sType) }); + + if ((x = sType.getFacet(SchemaType.FACET_MAX_LENGTH)) != null) + if ((i = ((XmlObjectBase)x).bigIntegerValue().intValue()) < v.length()) + context.invalid(XmlErrorCodes.DATATYPE_MAX_LENGTH_VALID$STRING, + new Object[] { "QName", v, new Integer(i), QNameHelper.readable(sType) }); + */ + + return name; + } + + public static void validateValue(QName v, SchemaType sType, ValidationContext context) + { + XmlObject[] vals = sType.getEnumerationValues(); + if (vals != null) + { + for (int i = 0; i < vals.length; i++) + if (v.equals(((XmlObjectBase)vals[i]).getQNameValue())) + return; + context.invalid(XmlErrorCodes.DATATYPE_ENUM_VALID, + new Object[] { "QName", v, QNameHelper.readable(sType) }); + } + } + + protected void validate_simpleval(String lexical, ValidationContext ctx) + { + validateValue(getQNameValue(), schemaType(), ctx); + } + +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaStringEnumerationHolderEx.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaStringEnumerationHolderEx.java new file mode 100644 index 000000000..d5f1288a4 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaStringEnumerationHolderEx.java @@ -0,0 +1,73 @@ +/* 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.values; + +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.StringEnumAbstractBase; +import org.apache.xmlbeans.XmlErrorCodes; +import org.apache.xmlbeans.impl.common.ValidationContext; +import org.apache.xmlbeans.impl.common.QNameHelper; + + +public abstract class JavaStringEnumerationHolderEx extends JavaStringHolderEx +{ + public JavaStringEnumerationHolderEx(SchemaType type, boolean complex) + { + super(type, complex); + } + + private StringEnumAbstractBase _val; + + // update the intval when setting via text, nil. + protected void set_text(String s) + { + StringEnumAbstractBase se = schemaType().enumForString(s); + if (se == null) + throw new XmlValueOutOfRangeException(XmlErrorCodes.DATATYPE_ENUM_VALID, + new Object[] { "string", s, QNameHelper.readable(schemaType()) }); + + super.set_text(s); + _val = se; + } + + public static void validateLexical(String v, SchemaType sType, ValidationContext context) + { + JavaStringHolderEx.validateLexical(v, sType, context); + } + + protected void set_nil() + { + _val = null; + super.set_nil(); + } + + // set/get the enum + public StringEnumAbstractBase getEnumValue() + { + check_dated(); + return _val; + } + + protected void set_enum(StringEnumAbstractBase se) + { + Class ejc = schemaType().getEnumJavaClass(); + if (ejc != null && !se.getClass().equals(ejc)) + throw new XmlValueOutOfRangeException(); + + super.set_text(se.toString()); + _val = se; + } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaStringHolder.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaStringHolder.java new file mode 100644 index 000000000..02472705f --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaStringHolder.java @@ -0,0 +1,56 @@ +/* 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.values; + +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.XmlObject; + +import org.apache.xmlbeans.impl.schema.BuiltinSchemaTypeSystem; + +public class JavaStringHolder extends XmlObjectBase +{ + public JavaStringHolder() {} + + public SchemaType schemaType() + { return BuiltinSchemaTypeSystem.ST_STRING; } + + private String _value; + + protected int get_wscanon_rule() + { return SchemaType.WS_PRESERVE; } + + // SIMPLE VALUE ACCESSORS BELOW ------------------------------------------- + public String compute_text(NamespaceManager nsm) { return _value; } + protected void set_text(String s) { _value = s; } + protected void set_nil() { _value = null; } + + // string setter and getter already handled by XmlObjectBase + + // comparators + protected boolean equal_to(XmlObject obj) + { + return _value.equals(((XmlObjectBase)obj).stringValue()); + } + + protected int value_hash_code() + { + return _value.hashCode(); + } + protected boolean is_defaultable_ws(String v) + { + return false; + } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaStringHolderEx.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaStringHolderEx.java new file mode 100644 index 000000000..0d74df7c2 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaStringHolderEx.java @@ -0,0 +1,129 @@ +/* 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.values; + +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.XmlErrorCodes; +import org.apache.xmlbeans.XmlAnySimpleType; +import org.apache.xmlbeans.impl.common.ValidationContext; +import org.apache.xmlbeans.impl.common.QNameHelper; + +public abstract class JavaStringHolderEx extends JavaStringHolder +{ + private SchemaType _schemaType; + + public SchemaType schemaType() + { return _schemaType; } + + public JavaStringHolderEx(SchemaType type, boolean complex) + { _schemaType = type; initComplexType(complex, false); } + + protected int get_wscanon_rule() + { + return schemaType().getWhiteSpaceRule(); + } + + protected void set_text(String s) + { + if (_validateOnSet()) + validateLexical(s, _schemaType, _voorVc); + + super.set_text(s); + } + + protected boolean is_defaultable_ws(String v) { + try { + validateLexical(v, _schemaType, _voorVc); + return false; + } + catch (XmlValueOutOfRangeException e) { + return true; + } + } + + public static void validateLexical(String v, SchemaType sType, ValidationContext context) + { + // check against pattern + if (!sType.matchPatternFacet(v)) + { + context.invalid(XmlErrorCodes.DATATYPE_VALID$PATTERN_VALID, new Object[] { "string", v, QNameHelper.readable(sType) }); + return; + } + + // check against length + XmlObject len = sType.getFacet(SchemaType.FACET_LENGTH); + if (len != null) + { + int m = ((XmlObjectBase)len).bigIntegerValue().intValue(); + if (v.length() != m) + { + context.invalid(XmlErrorCodes.DATATYPE_LENGTH_VALID$STRING, + new Object[] { "string", new Integer(v.length()), new Integer(m), QNameHelper.readable(sType) }); + return; + } + } + + // check against min length + XmlObject min = sType.getFacet(SchemaType.FACET_MIN_LENGTH); + if (min != null) + { + int m = ((XmlObjectBase)min).bigIntegerValue().intValue(); + if (v.length() < m) + { + context.invalid(XmlErrorCodes.DATATYPE_MIN_LENGTH_VALID$STRING, + new Object[] { "string", new Integer(v.length()), new Integer(m), QNameHelper.readable(sType) }); + return; + } + } + + // check against min length + XmlObject max = sType.getFacet(SchemaType.FACET_MAX_LENGTH); + if (max != null) + { + int m = ((XmlObjectBase)max).bigIntegerValue().intValue(); + if (v.length() > m) + { + context.invalid(XmlErrorCodes.DATATYPE_MAX_LENGTH_VALID$STRING, + new Object[] { "string", new Integer(v.length()), new Integer(m), QNameHelper.readable(sType) }); + return; + } + } + + // enumeration + // NOTE: can't use .hasStringEnumValues() or .enumForString() + // here since we may be validating against a string enum value + // during StscSimpleTypeResolver.resolveFacets() and the string + // enum table hasn't been constructed yet. + XmlAnySimpleType[] vals = sType.getEnumerationValues(); + if (vals != null) + { + for (int i = 0; i < vals.length; i++) + { + if (v.equals(vals[i].getStringValue())) + return; + } + context.invalid(XmlErrorCodes.DATATYPE_ENUM_VALID, + new Object[] { "string", v, QNameHelper.readable(sType) }); + } + } + + protected void validate_simpleval(String lexical, ValidationContext ctx) + { + validateLexical(stringValue(), schemaType(), ctx); + } + +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaUriHolder.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaUriHolder.java new file mode 100644 index 000000000..0221a96f8 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaUriHolder.java @@ -0,0 +1,66 @@ +/* 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.values; + +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.XmlAnyURI; +import org.apache.xmlbeans.XmlErrorCodes; +import org.apache.xmlbeans.impl.common.ValidationContext; + +import org.apache.xmlbeans.impl.schema.BuiltinSchemaTypeSystem; + +public abstract class JavaUriHolder extends XmlObjectBase +{ + public JavaUriHolder() {} + + public SchemaType schemaType() + { return BuiltinSchemaTypeSystem.ST_ANY_URI; } + + private String _value; + + public String compute_text(NamespaceManager nsm) { return _value == null ? "" : _value; } + protected void set_text(String s) + { + if (_validateOnSet()) + validateLexical(s, _voorVc); + _value = s; + } + + public static void validateLexical(String v, ValidationContext context) + { + // Enough validation to get schema for schema working + + if (v.startsWith( "##" )) + context.invalid(XmlErrorCodes.ANYURI, new Object[] { v }); + + } + + protected void set_nil() { _value = null; } + + // string setter and getter already handled by XmlObjectBase + + // comparators + protected boolean equal_to(XmlObject obj) + { + return _value.equals(((XmlAnyURI)obj).getStringValue()); + } + + protected int value_hash_code() + { + return _value.hashCode(); + } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaUriHolderEx.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaUriHolderEx.java new file mode 100644 index 000000000..566be4ed4 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/JavaUriHolderEx.java @@ -0,0 +1,153 @@ +/* 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.values; + +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.SimpleValue; +import org.apache.xmlbeans.XmlErrorCodes; +import org.apache.xmlbeans.impl.common.ValidationContext; +import org.apache.xmlbeans.impl.common.QNameHelper; + +public class JavaUriHolderEx extends JavaUriHolder +{ + private SchemaType _schemaType; + + public SchemaType schemaType() + { return _schemaType; } + + public JavaUriHolderEx(SchemaType type, boolean complex) + { _schemaType = type; initComplexType(complex, false); } + + protected int get_wscanon_rule() + { + return schemaType().getWhiteSpaceRule(); + } + + protected void set_text(String s) + { + if (_validateOnSet()) + { + if (!check(s, _schemaType)) + throw new XmlValueOutOfRangeException(); + + if (!_schemaType.matchPatternFacet(s)) + throw new XmlValueOutOfRangeException(); + } + + super.set_text(s); + } + +// // setters +// protected void set_uri(URI uri) +// { +// if (!check(uri.toString(), _schemaType)) +// throw new XmlValueOutOfRangeException(); +// +// super.set_uri(uri); +// } + + public static void validateLexical(String v, SchemaType sType, ValidationContext context) + { + XmlAnyUriImpl.validateLexical(v, context); + + XmlObject[] vals = sType.getEnumerationValues(); + + if (vals != null) + { + int i; + + for ( i = 0 ; i < vals.length ; i++ ) + { + String e = ((SimpleValue)vals[i]).getStringValue(); + + if (e.equals( v )) + break; + } + + if (i >= vals.length) + context.invalid(XmlErrorCodes.DATATYPE_ENUM_VALID, + new Object[] { "anyURI", v, QNameHelper.readable(sType) }); + } + + // check pattern + if (sType.hasPatternFacet()) + { + if (!sType.matchPatternFacet(v)) + { + // TODO - describe string and pattern here in error + context.invalid(XmlErrorCodes.DATATYPE_VALID$PATTERN_VALID, + new Object[] { "anyURI", v, QNameHelper.readable(sType) }); + } + } + + XmlObject x; + int i; + + if ((x = sType.getFacet(SchemaType.FACET_LENGTH)) != null) + if ((i = ((SimpleValue)x).getBigIntegerValue().intValue()) != v.length()) + context.invalid(XmlErrorCodes.DATATYPE_LENGTH_VALID$STRING, + new Object[] { "anyURI", v, new Integer(i), QNameHelper.readable(sType) }); + + if ((x = sType.getFacet(SchemaType.FACET_MIN_LENGTH)) != null) + if ((i = ((SimpleValue)x).getBigIntegerValue().intValue()) > v.length()) + context.invalid(XmlErrorCodes.DATATYPE_MIN_LENGTH_VALID$STRING, + new Object[] { "anyURI", v, new Integer(i), QNameHelper.readable(sType) }); + + if ((x = sType.getFacet(SchemaType.FACET_MAX_LENGTH)) != null) + if ((i = ((SimpleValue)x).getBigIntegerValue().intValue()) < v.length()) + context.invalid(XmlErrorCodes.DATATYPE_MAX_LENGTH_VALID$STRING, + new Object[] { "anyURI", v, new Integer(i), QNameHelper.readable(sType) }); + } + + private static boolean check(String v, SchemaType sType) + { + int length = v==null ? 0 : v.length(); + // check against length + XmlObject len = sType.getFacet(SchemaType.FACET_LENGTH); + if (len != null) + { + int m = ((SimpleValue)len).getBigIntegerValue().intValue(); + if (!(length != m)) + return false; + } + + // check against min length + XmlObject min = sType.getFacet(SchemaType.FACET_MIN_LENGTH); + if (min != null) + { + int m = ((SimpleValue)min).getBigIntegerValue().intValue(); + if (!(length >= m)) + return false; + } + + // check against min length + XmlObject max = sType.getFacet(SchemaType.FACET_MAX_LENGTH); + if (max != null) + { + int m = ((SimpleValue)max).getBigIntegerValue().intValue(); + if (!(length <= m)) + return false; + } + + return true; + } + + protected void validate_simpleval(String lexical, ValidationContext ctx) + { + validateLexical(stringValue(), schemaType(), ctx); + } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/NamespaceContext.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/NamespaceContext.java new file mode 100644 index 000000000..692197c69 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/NamespaceContext.java @@ -0,0 +1,167 @@ +/* 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.values; + +import org.apache.xmlbeans.impl.common.PrefixResolver; + +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.XmlCursor; + +import java.util.ArrayList; +import java.util.Map; +import java.lang.reflect.Proxy; +import java.lang.ref.SoftReference; + +import org.apache.xmlbeans.xml.stream.StartElement; + +public class NamespaceContext implements PrefixResolver +{ + private static final int TYPE_STORE = 1; + private static final int XML_OBJECT = 2; + private static final int MAP = 3; + private static final int START_ELEMENT = 4; + private static final int RESOLVER = 5; + + private Object _obj; + private int _code; + + public NamespaceContext(Map prefixToUriMap) + { + _code = MAP; + _obj = prefixToUriMap; + } + + public NamespaceContext(TypeStore typeStore) + { + _code = TYPE_STORE; + _obj = typeStore; + } + + public NamespaceContext(XmlObject xmlObject) + { + _code = XML_OBJECT; + _obj = xmlObject; + } + + public NamespaceContext(StartElement start) + { + _code = START_ELEMENT; + _obj = start; + } + + public NamespaceContext(PrefixResolver resolver) + { + _code = RESOLVER; + _obj = resolver; + } + + /** + * Stack management if (heaven help us) we ever need to do + * nested compilation of schema type system. + */ + private static final class NamespaceContextStack + { + NamespaceContext current; + ArrayList stack = new ArrayList(); + final void push(NamespaceContext next) + { + stack.add(current); + current = next; + } + final void pop() + { + current = (NamespaceContext)stack.get(stack.size() - 1); + stack.remove(stack.size() - 1); + } + } + + private static ThreadLocal tl_namespaceContextStack = new ThreadLocal(); + + private static NamespaceContextStack getNamespaceContextStack() + { + NamespaceContextStack namespaceContextStack = (NamespaceContextStack) tl_namespaceContextStack.get(); + if (namespaceContextStack==null) + { + namespaceContextStack = new NamespaceContextStack(); + tl_namespaceContextStack.set(namespaceContextStack); + } + return namespaceContextStack; + } + + public static void push(NamespaceContext next) + { + getNamespaceContextStack().push(next); + } + + public static void pop() + { + NamespaceContextStack nsContextStack = getNamespaceContextStack(); + nsContextStack.pop(); + + if (nsContextStack.stack.size()==0) + tl_namespaceContextStack.set(null); + } + + public static PrefixResolver getCurrent() + { + return getNamespaceContextStack().current; + } + + public String getNamespaceForPrefix(String prefix) + { + if (prefix != null && prefix.equals("xml")) + return "http://www.w3.org/XML/1998/namespace"; + + switch (_code) + { + case XML_OBJECT: + { + TypeStoreUser impl; + Object obj = _obj; + if (Proxy.isProxyClass(obj.getClass())) + obj = Proxy.getInvocationHandler(obj); + + if (obj instanceof TypeStoreUser) + return ((TypeStoreUser)obj).get_store().getNamespaceForPrefix(prefix); + + XmlCursor cur = ((XmlObject)_obj).newCursor(); + if (cur != null) + { + if (cur.currentTokenType() == XmlCursor.TokenType.ATTR) + cur.toParent(); + try { return cur.namespaceForPrefix(prefix); } + finally { cur.dispose(); } + } + } + + case MAP: + return (String)((Map)_obj).get(prefix); + + case TYPE_STORE: + return ((TypeStore)_obj).getNamespaceForPrefix(prefix); + + case START_ELEMENT: + return ((StartElement)_obj).getNamespaceUri(prefix); + + case RESOLVER: + return ((PrefixResolver)_obj).getNamespaceForPrefix(prefix); + + default: + assert false : "Improperly initialized NamespaceContext."; + return null; + } + } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/StringEnumValue.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/StringEnumValue.java new file mode 100644 index 000000000..b777fc462 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/StringEnumValue.java @@ -0,0 +1,24 @@ +/* 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.values; + +import org.apache.xmlbeans.StringEnumAbstractBase; + +public class StringEnumValue extends StringEnumAbstractBase +{ + public StringEnumValue(String s, int i) + { super(s, i); } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlAnySimpleTypeImpl.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlAnySimpleTypeImpl.java new file mode 100644 index 000000000..3ffe7e713 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlAnySimpleTypeImpl.java @@ -0,0 +1,73 @@ +/* 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.values; + +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.XmlAnySimpleType; +import org.apache.xmlbeans.impl.schema.BuiltinSchemaTypeSystem; + +/** + * This class implements the anySimpleType for XML. + * + */ +public class XmlAnySimpleTypeImpl extends XmlObjectBase implements XmlAnySimpleType +{ + public XmlAnySimpleTypeImpl(SchemaType type, boolean complex) + { _schemaType = type; initComplexType(complex, false); } + + public XmlAnySimpleTypeImpl() + { _schemaType = BuiltinSchemaTypeSystem.ST_ANY_SIMPLE; } + + public SchemaType schemaType() + { return _schemaType; } + + private SchemaType _schemaType; + + String _textvalue = ""; + + protected int get_wscanon_rule() + { + return SchemaType.WS_PRESERVE; + } + + // SIMPLE VALUE ACCESSORS BELOW ------------------------------------------- + // gets raw text value + protected String compute_text(NamespaceManager nsm) { return _textvalue; } + protected void set_text(String s) + { + _textvalue = s; + } + + protected void set_nil() + { + _textvalue = null; + } + + // comparators + protected boolean equal_to(XmlObject obj) + { + // compares against another anySimpleType + // rule is: lexical values must match. + return _textvalue.equals(((XmlAnySimpleType)obj).getStringValue()); + } + + protected int value_hash_code() + { + // matches JavaStringHolder's value_hash_code, so we can be hased against strings + return (_textvalue == null ? 0 : _textvalue.hashCode()); + } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlAnySimpleTypeRestriction.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlAnySimpleTypeRestriction.java new file mode 100644 index 000000000..4629cb693 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlAnySimpleTypeRestriction.java @@ -0,0 +1,29 @@ +/* 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.values; + +import org.apache.xmlbeans.SchemaType; + +public class XmlAnySimpleTypeRestriction extends XmlAnySimpleTypeImpl +{ + public XmlAnySimpleTypeRestriction(SchemaType type, boolean complex) + { _schemaType = type; initComplexType(complex, false); } + + private SchemaType _schemaType; + + public SchemaType schemaType() + { return _schemaType; } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlAnyTypeImpl.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlAnyTypeImpl.java new file mode 100644 index 000000000..eaea9ba2f --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlAnyTypeImpl.java @@ -0,0 +1,32 @@ +/* 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.values; + +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.SchemaType; + +/** + * This class implements the anyType for XML. + * + */ +public class XmlAnyTypeImpl extends XmlComplexContentImpl implements XmlObject +{ + public XmlAnyTypeImpl() + { super(type); } + + public XmlAnyTypeImpl(SchemaType type) + { super(type); } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlAnyUriImpl.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlAnyUriImpl.java new file mode 100644 index 000000000..61acd9763 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlAnyUriImpl.java @@ -0,0 +1,20 @@ +/* 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.values; + +public class XmlAnyUriImpl extends JavaUriHolder implements org.apache.xmlbeans.XmlAnyURI +{ +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlAnyUriRestriction.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlAnyUriRestriction.java new file mode 100644 index 000000000..2df9f0b68 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlAnyUriRestriction.java @@ -0,0 +1,24 @@ +/* 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.values; + +import org.apache.xmlbeans.SchemaType; + +public class XmlAnyUriRestriction extends JavaUriHolderEx implements org.apache.xmlbeans.XmlAnyURI +{ + public XmlAnyUriRestriction(SchemaType type, boolean complex) + { super(type, complex); } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlBase64BinaryImpl.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlBase64BinaryImpl.java new file mode 100644 index 000000000..3d4e34409 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlBase64BinaryImpl.java @@ -0,0 +1,24 @@ +/* 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.values; + +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.XmlBase64Binary; + + +public class XmlBase64BinaryImpl extends JavaBase64Holder implements XmlBase64Binary +{ +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlBase64BinaryRestriction.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlBase64BinaryRestriction.java new file mode 100644 index 000000000..cec661e51 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlBase64BinaryRestriction.java @@ -0,0 +1,25 @@ +/* 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.values; + +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.XmlBase64Binary; + +public class XmlBase64BinaryRestriction extends JavaBase64HolderEx implements XmlBase64Binary +{ + public XmlBase64BinaryRestriction(SchemaType type, boolean complex) + { super(type, complex); } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlBooleanImpl.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlBooleanImpl.java new file mode 100644 index 000000000..1002ec05d --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlBooleanImpl.java @@ -0,0 +1,22 @@ +/* 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.values; + +import org.apache.xmlbeans.XmlBoolean; + +public class XmlBooleanImpl extends JavaBooleanHolder implements XmlBoolean +{ +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlBooleanRestriction.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlBooleanRestriction.java new file mode 100644 index 000000000..a8da4ba6a --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlBooleanRestriction.java @@ -0,0 +1,25 @@ +/* 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.values; + +import org.apache.xmlbeans.XmlBoolean; +import org.apache.xmlbeans.SchemaType; + +public class XmlBooleanRestriction extends JavaBooleanHolderEx implements XmlBoolean +{ + public XmlBooleanRestriction(SchemaType type, boolean complex) + { super(type, complex); } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlByteImpl.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlByteImpl.java new file mode 100644 index 000000000..a218aacc8 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlByteImpl.java @@ -0,0 +1,28 @@ +/* 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.values; + +import org.apache.xmlbeans.XmlByte; +import org.apache.xmlbeans.SchemaType; + + +public class XmlByteImpl extends JavaIntHolderEx implements XmlByte +{ + public XmlByteImpl() + { super(XmlByte.type, false); } + public XmlByteImpl(SchemaType type, boolean complex) + { super(type, complex); } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlComplexContentImpl.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlComplexContentImpl.java new file mode 100644 index 000000000..fb279ff6c --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlComplexContentImpl.java @@ -0,0 +1,1335 @@ +/* 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.values; + +import org.apache.xmlbeans.*; + +import java.lang.String; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.Date; +import java.util.List; +import java.util.Calendar; +import javax.xml.namespace.QName; + +import org.apache.xmlbeans.impl.schema.SchemaTypeImpl; +import org.apache.xmlbeans.impl.schema.SchemaTypeVisitorImpl; + +public class XmlComplexContentImpl extends XmlObjectBase +{ + public XmlComplexContentImpl(SchemaType type) + { + _schemaType = (SchemaTypeImpl)type; + initComplexType(true, true); + } + + public SchemaType schemaType() + { return _schemaType; } + + private SchemaTypeImpl _schemaType; + + public String compute_text(NamespaceManager nsm) + { return null; } + + protected final void set_String(String v) + { + assert _schemaType.getContentType() != SchemaType.SIMPLE_CONTENT; + + if (_schemaType.getContentType() != SchemaType.MIXED_CONTENT && + !_schemaType.isNoType()) + { + throw new IllegalArgumentException( + "Type does not allow for textual content: " + _schemaType ); + } + + super.set_String(v); + } + + public void set_text(String str) + { + assert + _schemaType.getContentType() == SchemaType.MIXED_CONTENT || + _schemaType.isNoType(); + } + + protected void update_from_complex_content() + { + // No complex caching yet ... + } + + public void set_nil() + { /* BUGBUG: what to do? */ } + + // LEFT + public boolean equal_to(XmlObject complexObject) + { + if (!_schemaType.equals(complexObject.schemaType())) + return false; + + // BUGBUG: by-value structure comparison undone + return true; + } + + // LEFT + protected int value_hash_code() + { + throw new IllegalStateException("Complex types cannot be used as hash keys"); + } + + // DONE + public TypeStoreVisitor new_visitor() + { + return new SchemaTypeVisitorImpl(_schemaType.getContentModel()); + } + + // DONE + public boolean is_child_element_order_sensitive() + { + return schemaType().isOrderSensitive(); + } + + public int get_elementflags(QName eltName) + { + SchemaProperty prop = schemaType().getElementProperty(eltName); + if (prop == null) + return 0; + if (prop.hasDefault() == SchemaProperty.VARIABLE || + prop.hasFixed() == SchemaProperty.VARIABLE || + prop.hasNillable() == SchemaProperty.VARIABLE) + return -1; + return + (prop.hasDefault() == SchemaProperty.NEVER ? 0 : TypeStore.HASDEFAULT) | + (prop.hasFixed() == SchemaProperty.NEVER ? 0 : TypeStore.FIXED) | + (prop.hasNillable() == SchemaProperty.NEVER ? 0 : TypeStore.NILLABLE); + } + + // DONE + public String get_default_attribute_text(QName attrName) + { + return super.get_default_attribute_text(attrName); + } + + // DONE + public String get_default_element_text(QName eltName) + { + SchemaProperty prop = schemaType().getElementProperty(eltName); + if (prop == null) + return ""; + return prop.getDefaultText(); + } + + // + // Code gen helpers + // + // So much redundant code ..... what I'd give for generics! + // + + protected void unionArraySetterHelper ( Object[] sources, QName elemName ) + { + int n = sources == null ? 0 : sources.length; + + TypeStore store = get_store(); + + int m = store.count_elements( elemName ); + + for ( ; m > n ; m-- ) + store.remove_element( elemName, m - 1 ); + + for ( int i = 0 ; i < n ; i++ ) + { + TypeStoreUser user; + + if (i >= m) + user = store.add_element_user( elemName ); + else + user = store.find_element_user( elemName, i ); + + ((XmlObjectBase) user).objectSet( sources[ i ] ); + } + } + + protected SimpleValue[] arraySetterHelper ( int sourcesLength, QName elemName ) + { + SimpleValue[] dests = new SimpleValue[sourcesLength]; + + TypeStore store = get_store(); + + int m = store.count_elements( elemName ); + + for ( ; m > sourcesLength ; m-- ) + store.remove_element( elemName, m - 1 ); + + for ( int i = 0 ; i < sourcesLength ; i++ ) + { + TypeStoreUser user; + + if (i >= m) + user = store.add_element_user( elemName ); + else + user = store.find_element_user( elemName, i ); + + dests[i] = (SimpleValue) user; + } + + return dests; + } + + protected SimpleValue[] arraySetterHelper ( int sourcesLength, QName elemName, QNameSet set ) + { + SimpleValue[] dests = new SimpleValue[sourcesLength]; + + TypeStore store = get_store(); + + int m = store.count_elements( set ); + + for ( ; m > sourcesLength ; m-- ) + store.remove_element( set, m - 1 ); + + for ( int i = 0 ; i < sourcesLength ; i++ ) + { + TypeStoreUser user; + + if (i >= m) + user = store.add_element_user( elemName ); + else + user = store.find_element_user( set, i ); + + dests[i] = (SimpleValue) user; + } + + return dests; + } + + protected void arraySetterHelper ( boolean[] sources, QName elemName ) + { + int n = sources == null ? 0 : sources.length; + + TypeStore store = get_store(); + + int m = store.count_elements( elemName ); + + for ( ; m > n ; m-- ) + store.remove_element( elemName, m - 1 ); + + for ( int i = 0 ; i < n ; i++ ) + { + TypeStoreUser user; + + if (i >= m) + user = store.add_element_user( elemName ); + else + user = store.find_element_user( elemName, i ); + + ((XmlObjectBase) user).set( sources[ i ] ); + } + } + + protected void arraySetterHelper ( float[] sources, QName elemName ) + { + int n = sources == null ? 0 : sources.length; + + TypeStore store = get_store(); + + int m = store.count_elements( elemName ); + + for ( ; m > n ; m-- ) + store.remove_element( elemName, m - 1 ); + + for ( int i = 0 ; i < n ; i++ ) + { + TypeStoreUser user; + + if (i >= m) + user = store.add_element_user( elemName ); + else + user = store.find_element_user( elemName, i ); + + ((XmlObjectBase) user).set( sources[ i ] ); + } + } + + protected void arraySetterHelper ( double[] sources, QName elemName ) + { + int n = sources == null ? 0 : sources.length; + + TypeStore store = get_store(); + + int m = store.count_elements( elemName ); + + for ( ; m > n ; m-- ) + store.remove_element( elemName, m - 1 ); + + for ( int i = 0 ; i < n ; i++ ) + { + TypeStoreUser user; + + if (i >= m) + user = store.add_element_user( elemName ); + else + user = store.find_element_user( elemName, i ); + + ((XmlObjectBase) user).set( sources[ i ] ); + } + } + + protected void arraySetterHelper ( byte[] sources, QName elemName ) + { + int n = sources == null ? 0 : sources.length; + + TypeStore store = get_store(); + + int m = store.count_elements( elemName ); + + for ( ; m > n ; m-- ) + store.remove_element( elemName, m - 1 ); + + for ( int i = 0 ; i < n ; i++ ) + { + TypeStoreUser user; + + if (i >= m) + user = store.add_element_user( elemName ); + else + user = store.find_element_user( elemName, i ); + + ((XmlObjectBase) user).set( sources[ i ] ); + } + } + + protected void arraySetterHelper ( short[] sources, QName elemName ) + { + int n = sources == null ? 0 : sources.length; + + TypeStore store = get_store(); + + int m = store.count_elements( elemName ); + + for ( ; m > n ; m-- ) + store.remove_element( elemName, m - 1 ); + + for ( int i = 0 ; i < n ; i++ ) + { + TypeStoreUser user; + + if (i >= m) + user = store.add_element_user( elemName ); + else + user = store.find_element_user( elemName, i ); + + ((XmlObjectBase) user).set( sources[ i ] ); + } + } + + protected void arraySetterHelper ( int[] sources, QName elemName ) + { + int n = sources == null ? 0 : sources.length; + + TypeStore store = get_store(); + + int m = store.count_elements( elemName ); + + for ( ; m > n ; m-- ) + store.remove_element( elemName, m - 1 ); + + for ( int i = 0 ; i < n ; i++ ) + { + TypeStoreUser user; + + if (i >= m) + user = store.add_element_user( elemName ); + else + user = store.find_element_user( elemName, i ); + + ((XmlObjectBase) user).set( sources[ i ] ); + } + } + + protected void arraySetterHelper ( long[] sources, QName elemName ) + { + int n = sources == null ? 0 : sources.length; + + TypeStore store = get_store(); + + int m = store.count_elements( elemName ); + + for ( ; m > n ; m-- ) + store.remove_element( elemName, m - 1 ); + + for ( int i = 0 ; i < n ; i++ ) + { + TypeStoreUser user; + + if (i >= m) + user = store.add_element_user( elemName ); + else + user = store.find_element_user( elemName, i ); + + ((XmlObjectBase) user).set( sources[ i ] ); + } + } + + protected void arraySetterHelper ( BigDecimal[] sources, QName elemName ) + { + int n = sources == null ? 0 : sources.length; + + TypeStore store = get_store(); + + int m = store.count_elements( elemName ); + + for ( ; m > n ; m-- ) + store.remove_element( elemName, m - 1 ); + + for ( int i = 0 ; i < n ; i++ ) + { + TypeStoreUser user; + + if (i >= m) + user = store.add_element_user( elemName ); + else + user = store.find_element_user( elemName, i ); + + ((XmlObjectBase) user).set( sources[ i ] ); + } + } + + protected void arraySetterHelper ( BigInteger[] sources, QName elemName ) + { + int n = sources == null ? 0 : sources.length; + + TypeStore store = get_store(); + + int m = store.count_elements( elemName ); + + for ( ; m > n ; m-- ) + store.remove_element( elemName, m - 1 ); + + for ( int i = 0 ; i < n ; i++ ) + { + TypeStoreUser user; + + if (i >= m) + user = store.add_element_user( elemName ); + else + user = store.find_element_user( elemName, i ); + + ((XmlObjectBase) user).set( sources[ i ] ); + } + } + + protected void arraySetterHelper ( String[] sources, QName elemName ) + { + int n = sources == null ? 0 : sources.length; + + TypeStore store = get_store(); + + int m = store.count_elements( elemName ); + + for ( ; m > n ; m-- ) + store.remove_element( elemName, m - 1 ); + + for ( int i = 0 ; i < n ; i++ ) + { + TypeStoreUser user; + + if (i >= m) + user = store.add_element_user( elemName ); + else + user = store.find_element_user( elemName, i ); + + ((XmlObjectBase) user).set( sources[ i ] ); + } + } + + protected void arraySetterHelper ( byte[][] sources, QName elemName ) + { + int n = sources == null ? 0 : sources.length; + + TypeStore store = get_store(); + + int m = store.count_elements( elemName ); + + for ( ; m > n ; m-- ) + store.remove_element( elemName, m - 1 ); + + for ( int i = 0 ; i < n ; i++ ) + { + TypeStoreUser user; + + if (i >= m) + user = store.add_element_user( elemName ); + else + user = store.find_element_user( elemName, i ); + + ((XmlObjectBase) user).set( sources[ i ] ); + } + } + + protected void arraySetterHelper ( GDate[] sources, QName elemName ) + { + int n = sources == null ? 0 : sources.length; + + TypeStore store = get_store(); + + int m = store.count_elements( elemName ); + + for ( ; m > n ; m-- ) + store.remove_element( elemName, m - 1 ); + + for ( int i = 0 ; i < n ; i++ ) + { + TypeStoreUser user; + + if (i >= m) + user = store.add_element_user( elemName ); + else + user = store.find_element_user( elemName, i ); + + ((XmlObjectBase) user).set( sources[ i ] ); + } + } + + protected void arraySetterHelper ( GDuration[] sources, QName elemName ) + { + int n = sources == null ? 0 : sources.length; + + TypeStore store = get_store(); + + int m = store.count_elements( elemName ); + + for ( ; m > n ; m-- ) + store.remove_element( elemName, m - 1 ); + + for ( int i = 0 ; i < n ; i++ ) + { + TypeStoreUser user; + + if (i >= m) + user = store.add_element_user( elemName ); + else + user = store.find_element_user( elemName, i ); + + ((XmlObjectBase) user).set( sources[ i ] ); + } + } + + protected void arraySetterHelper ( Calendar[] sources, QName elemName ) + { + int n = sources == null ? 0 : sources.length; + + TypeStore store = get_store(); + + int m = store.count_elements( elemName ); + + for ( ; m > n ; m-- ) + store.remove_element( elemName, m - 1 ); + + for ( int i = 0 ; i < n ; i++ ) + { + TypeStoreUser user; + + if (i >= m) + user = store.add_element_user( elemName ); + else + user = store.find_element_user( elemName, i ); + + ((XmlObjectBase) user).set( sources[ i ] ); + } + } + + protected void arraySetterHelper ( Date[] sources, QName elemName ) + { + int n = sources == null ? 0 : sources.length; + + TypeStore store = get_store(); + + int m = store.count_elements( elemName ); + + for ( ; m > n ; m-- ) + store.remove_element( elemName, m - 1 ); + + for ( int i = 0 ; i < n ; i++ ) + { + TypeStoreUser user; + + if (i >= m) + user = store.add_element_user( elemName ); + else + user = store.find_element_user( elemName, i ); + + ((XmlObjectBase) user).set( sources[ i ] ); + } + } + + protected void arraySetterHelper ( QName[] sources, QName elemName ) + { + int n = sources == null ? 0 : sources.length; + + TypeStore store = get_store(); + + int m = store.count_elements( elemName ); + + for ( ; m > n ; m-- ) + store.remove_element( elemName, m - 1 ); + + for ( int i = 0 ; i < n ; i++ ) + { + TypeStoreUser user; + + if (i >= m) + user = store.add_element_user( elemName ); + else + user = store.find_element_user( elemName, i ); + + ((XmlObjectBase) user).set( sources[ i ] ); + } + } + + protected void arraySetterHelper ( StringEnumAbstractBase[] sources, QName elemName ) + { + int n = sources == null ? 0 : sources.length; + + TypeStore store = get_store(); + + int m = store.count_elements( elemName ); + + for ( ; m > n ; m-- ) + store.remove_element( elemName, m - 1 ); + + for ( int i = 0 ; i < n ; i++ ) + { + TypeStoreUser user; + + if (i >= m) + user = store.add_element_user( elemName ); + else + user = store.find_element_user( elemName, i ); + + ((XmlObjectBase) user).set( sources[ i ] ); + } + } + + protected void arraySetterHelper ( List[] sources, QName elemName ) + { + int n = sources == null ? 0 : sources.length; + + TypeStore store = get_store(); + + int m = store.count_elements( elemName ); + + for ( ; m > n ; m-- ) + store.remove_element( elemName, m - 1 ); + + for ( int i = 0 ; i < n ; i++ ) + { + TypeStoreUser user; + + if (i >= m) + user = store.add_element_user( elemName ); + else + user = store.find_element_user( elemName, i ); + + ((XmlObjectBase) user).set( sources[ i ] ); + } + } + + protected void unionArraySetterHelper ( Object[] sources, QName elemName, QNameSet set ) + { + int n = sources == null ? 0 : sources.length; + + TypeStore store = get_store(); + + int m = store.count_elements( set ); + + for ( ; m > n ; m-- ) + store.remove_element( set, m - 1 ); + + for ( int i = 0 ; i < n ; i++ ) + { + TypeStoreUser user; + + if (i >= m) + user = store.add_element_user( elemName ); + else + user = store.find_element_user( set, i ); + + ((XmlObjectBase) user).objectSet( sources[ i ] ); + } + } + + protected void arraySetterHelper ( boolean[] sources, QName elemName, QNameSet set ) + { + int n = sources == null ? 0 : sources.length; + + TypeStore store = get_store(); + + int m = store.count_elements( set ); + + for ( ; m > n ; m-- ) + store.remove_element( set, m - 1 ); + + for ( int i = 0 ; i < n ; i++ ) + { + TypeStoreUser user; + + if (i >= m) + user = store.add_element_user( elemName ); + else + user = store.find_element_user( set, i ); + + ((XmlObjectBase) user).set( sources[ i ] ); + } + } + + protected void arraySetterHelper ( float[] sources, QName elemName, QNameSet set ) + { + int n = sources == null ? 0 : sources.length; + + TypeStore store = get_store(); + + int m = store.count_elements( set ); + + for ( ; m > n ; m-- ) + store.remove_element( set, m - 1 ); + + for ( int i = 0 ; i < n ; i++ ) + { + TypeStoreUser user; + + if (i >= m) + user = store.add_element_user( elemName ); + else + user = store.find_element_user( set, i ); + + ((XmlObjectBase) user).set( sources[ i ] ); + } + } + + protected void arraySetterHelper ( double[] sources, QName elemName, QNameSet set ) + { + int n = sources == null ? 0 : sources.length; + + TypeStore store = get_store(); + + int m = store.count_elements( set ); + + for ( ; m > n ; m-- ) + store.remove_element( set, m - 1 ); + + for ( int i = 0 ; i < n ; i++ ) + { + TypeStoreUser user; + + if (i >= m) + user = store.add_element_user( elemName ); + else + user = store.find_element_user( set, i ); + + ((XmlObjectBase) user).set( sources[ i ] ); + } + } + + protected void arraySetterHelper ( byte[] sources, QName elemName, QNameSet set ) + { + int n = sources == null ? 0 : sources.length; + + TypeStore store = get_store(); + + int m = store.count_elements( set ); + + for ( ; m > n ; m-- ) + store.remove_element( set, m - 1 ); + + for ( int i = 0 ; i < n ; i++ ) + { + TypeStoreUser user; + + if (i >= m) + user = store.add_element_user( elemName ); + else + user = store.find_element_user( set, i ); + + ((XmlObjectBase) user).set( sources[ i ] ); + } + } + + protected void arraySetterHelper ( short[] sources, QName elemName, QNameSet set ) + { + int n = sources == null ? 0 : sources.length; + + TypeStore store = get_store(); + + int m = store.count_elements( set ); + + for ( ; m > n ; m-- ) + store.remove_element( set, m - 1 ); + + for ( int i = 0 ; i < n ; i++ ) + { + TypeStoreUser user; + + if (i >= m) + user = store.add_element_user( elemName ); + else + user = store.find_element_user( set, i ); + + ((XmlObjectBase) user).set( sources[ i ] ); + } + } + + protected void arraySetterHelper ( int[] sources, QName elemName, QNameSet set ) + { + int n = sources == null ? 0 : sources.length; + + TypeStore store = get_store(); + + int m = store.count_elements( set ); + + for ( ; m > n ; m-- ) + store.remove_element( set, m - 1 ); + + for ( int i = 0 ; i < n ; i++ ) + { + TypeStoreUser user; + + if (i >= m) + user = store.add_element_user( elemName ); + else + user = store.find_element_user( set, i ); + + ((XmlObjectBase) user).set( sources[ i ] ); + } + } + + protected void arraySetterHelper ( long[] sources, QName elemName, QNameSet set ) + { + int n = sources == null ? 0 : sources.length; + + TypeStore store = get_store(); + + int m = store.count_elements( set ); + + for ( ; m > n ; m-- ) + store.remove_element( set, m - 1 ); + + for ( int i = 0 ; i < n ; i++ ) + { + TypeStoreUser user; + + if (i >= m) + user = store.add_element_user( elemName ); + else + user = store.find_element_user( set, i ); + + ((XmlObjectBase) user).set( sources[ i ] ); + } + } + + protected void arraySetterHelper ( BigDecimal[] sources, QName elemName, QNameSet set ) + { + int n = sources == null ? 0 : sources.length; + + TypeStore store = get_store(); + + int m = store.count_elements( set ); + + for ( ; m > n ; m-- ) + store.remove_element( set, m - 1 ); + + for ( int i = 0 ; i < n ; i++ ) + { + TypeStoreUser user; + + if (i >= m) + user = store.add_element_user( elemName ); + else + user = store.find_element_user( set, i ); + + ((XmlObjectBase) user).set( sources[ i ] ); + } + } + + protected void arraySetterHelper ( BigInteger[] sources, QName elemName, QNameSet set ) + { + int n = sources == null ? 0 : sources.length; + + TypeStore store = get_store(); + + int m = store.count_elements( set ); + + for ( ; m > n ; m-- ) + store.remove_element( set, m - 1 ); + + for ( int i = 0 ; i < n ; i++ ) + { + TypeStoreUser user; + + if (i >= m) + user = store.add_element_user( elemName ); + else + user = store.find_element_user( set, i ); + + ((XmlObjectBase) user).set( sources[ i ] ); + } + } + + protected void arraySetterHelper ( String[] sources, QName elemName, QNameSet set ) + { + int n = sources == null ? 0 : sources.length; + + TypeStore store = get_store(); + + int m = store.count_elements( set ); + + for ( ; m > n ; m-- ) + store.remove_element( set, m - 1 ); + + for ( int i = 0 ; i < n ; i++ ) + { + TypeStoreUser user; + + if (i >= m) + user = store.add_element_user( elemName ); + else + user = store.find_element_user( set, i ); + + ((XmlObjectBase) user).set( sources[ i ] ); + } + } + + protected void arraySetterHelper ( byte[][] sources, QName elemName, QNameSet set ) + { + int n = sources == null ? 0 : sources.length; + + TypeStore store = get_store(); + + int m = store.count_elements( set ); + + for ( ; m > n ; m-- ) + store.remove_element( set, m - 1 ); + + for ( int i = 0 ; i < n ; i++ ) + { + TypeStoreUser user; + + if (i >= m) + user = store.add_element_user( elemName ); + else + user = store.find_element_user( set, i ); + + ((XmlObjectBase) user).set( sources[ i ] ); + } + } + + protected void arraySetterHelper ( GDate[] sources, QName elemName, QNameSet set ) + { + int n = sources == null ? 0 : sources.length; + + TypeStore store = get_store(); + + int m = store.count_elements( set ); + + for ( ; m > n ; m-- ) + store.remove_element( set, m - 1 ); + + for ( int i = 0 ; i < n ; i++ ) + { + TypeStoreUser user; + + if (i >= m) + user = store.add_element_user( elemName ); + else + user = store.find_element_user( set, i ); + + ((XmlObjectBase) user).set( sources[ i ] ); + } + } + + protected void arraySetterHelper ( GDuration[] sources, QName elemName, QNameSet set ) + { + int n = sources == null ? 0 : sources.length; + + TypeStore store = get_store(); + + int m = store.count_elements( set ); + + for ( ; m > n ; m-- ) + store.remove_element( set, m - 1 ); + + for ( int i = 0 ; i < n ; i++ ) + { + TypeStoreUser user; + + if (i >= m) + user = store.add_element_user( elemName ); + else + user = store.find_element_user( set, i ); + + ((XmlObjectBase) user).set( sources[ i ] ); + } + } + + protected void arraySetterHelper ( Calendar[] sources, QName elemName, QNameSet set ) + { + int n = sources == null ? 0 : sources.length; + + TypeStore store = get_store(); + + int m = store.count_elements( set ); + + for ( ; m > n ; m-- ) + store.remove_element( set, m - 1 ); + + for ( int i = 0 ; i < n ; i++ ) + { + TypeStoreUser user; + + if (i >= m) + user = store.add_element_user( elemName ); + else + user = store.find_element_user( set, i ); + + ((XmlObjectBase) user).set( sources[ i ] ); + } + } + + protected void arraySetterHelper ( Date[] sources, QName elemName, QNameSet set ) + { + int n = sources == null ? 0 : sources.length; + + TypeStore store = get_store(); + + int m = store.count_elements( set ); + + for ( ; m > n ; m-- ) + store.remove_element( set, m - 1 ); + + for ( int i = 0 ; i < n ; i++ ) + { + TypeStoreUser user; + + if (i >= m) + user = store.add_element_user( elemName ); + else + user = store.find_element_user( set, i ); + + ((XmlObjectBase) user).set( sources[ i ] ); + } + } + + protected void arraySetterHelper ( QName[] sources, QName elemName, QNameSet set ) + { + int n = sources == null ? 0 : sources.length; + + TypeStore store = get_store(); + + int m = store.count_elements( set ); + + for ( ; m > n ; m-- ) + store.remove_element( set, m - 1 ); + + for ( int i = 0 ; i < n ; i++ ) + { + TypeStoreUser user; + + if (i >= m) + user = store.add_element_user( elemName ); + else + user = store.find_element_user( set, i ); + + ((XmlObjectBase) user).set( sources[ i ] ); + } + } + + protected void arraySetterHelper ( StringEnumAbstractBase[] sources, QName elemName, QNameSet set ) + { + int n = sources == null ? 0 : sources.length; + + TypeStore store = get_store(); + + int m = store.count_elements( set ); + + for ( ; m > n ; m-- ) + store.remove_element( set, m - 1 ); + + for ( int i = 0 ; i < n ; i++ ) + { + TypeStoreUser user; + + if (i >= m) + user = store.add_element_user( elemName ); + else + user = store.find_element_user( set, i ); + + ((XmlObjectBase) user).set( sources[ i ] ); + } + } + + protected void arraySetterHelper ( List[] sources, QName elemName, QNameSet set ) + { + int n = sources == null ? 0 : sources.length; + + TypeStore store = get_store(); + + int m = store.count_elements( set ); + + for ( ; m > n ; m-- ) + store.remove_element( set, m - 1 ); + + for ( int i = 0 ; i < n ; i++ ) + { + TypeStoreUser user; + + if (i >= m) + user = store.add_element_user( elemName ); + else + user = store.find_element_user( set, i ); + + ((XmlObjectBase) user).set( sources[ i ] ); + } + } + + protected void arraySetterHelper ( XmlObject[] sources, QName elemName ) + { + TypeStore store = get_store(); + + if (sources == null || sources.length == 0) + { + int m = store.count_elements( elemName ); + for ( ; m > 0 ; m-- ) + store.remove_element( elemName, 0 ); + return; + } + + // Verify if the sources contain children of this node + int i; + int m = store.count_elements( elemName ); // how many elements in the original array + int startSrc = 0, startDest = 0; + for (i = 0; i < sources.length; i++) + { + if (sources[i].isImmutable()) + continue; + XmlCursor c = sources[i].newCursor(); + if (c.toParent() && c.getObject() == this) + { + c.dispose(); + break; + } + c.dispose(); + } + if (i < sources.length) + { + TypeStoreUser current = store.find_element_user( elemName, 0 ); + if (current == sources[i]) + { + // The new object matches what already exists in the array + // Heuristic: we optimize for the case where the new elements + // in the array are the same as the existing elements with + // potentially new elements inserted + + // First insert the new element in the array at position 0 + int j = 0; + for ( j = 0; j < i; j++ ) + { + TypeStoreUser user = store.insert_element_user( elemName, j ); + ((XmlObjectBase) user).set( sources[j] ); + } + for ( i++, j++; i < sources.length; i++, j++) + { + XmlCursor c = sources[i].isImmutable() ? null : sources[i].newCursor(); + if (c != null && c.toParent() && c.getObject() == this) + { + c.dispose(); + current = store.find_element_user( elemName, j ); + if (current == sources[i]) + ; // advance + else + { + // Fall back to the general case + break; + } + } + else + { + c.dispose(); + // Insert before the current element + TypeStoreUser user = store.insert_element_user( elemName, j ); + ((XmlObjectBase) user).set( sources[i] ); + } + } + startDest = j; + startSrc = i; + m = store.count_elements( elemName ); + } + // Fall through + } + else + { + // All of the elements in the existing array are to + // be deleted and replaced with elements from the + // sources array + } + + // The general case: we assume that some of the elements + // in the new array already exist, but at different indexes + + // Starting with position i in the sources array, copy the remaining elements + // to the end of the original array... + for (int j = i; j < sources.length; j++) + { + TypeStoreUser user = store.add_element_user( elemName ); + ((XmlObjectBase) user).set( sources[ j ] ); + } + + // ... then come back and insert the elements starting with startSource + // up to i from the sources array into the current array, starting with + // startDest + int n = i; + for ( ; m > n - startSrc + startDest; m-- ) + store.remove_element( elemName, m - 1 ); + + int j; + for ( i = startSrc, j = startDest ; i < n ; i++, j++ ) + { + TypeStoreUser user; + + if (j >= m) + user = store.add_element_user( elemName ); + else + user = store.find_element_user( elemName, j ); + + ((XmlObjectBase) user).set( sources[ i ] ); + } + + // We can't just delegate to array_setter because we need + // synchronization on the sources (potentially each element + // in the array on a different lock) +// get_store().array_setter( sources, elemName ); + } + + protected void arraySetterHelper ( XmlObject[] sources, QName elemName, QNameSet set ) + { + TypeStore store = get_store(); + + if (sources == null || sources.length == 0) + { + int m = store.count_elements( set ); + for ( ; m > 0 ; m-- ) + store.remove_element( set, 0 ); + return; + } + + // Verify if the sources contain children of this node + int i; + int m = store.count_elements( set ); // how many elements in the original array + int startSrc = 0, startDest = 0; + for (i = 0; i < sources.length; i++) + { + if (sources[i].isImmutable()) + continue; + XmlCursor c = sources[i].newCursor(); + if (c.toParent() && c.getObject() == this) + { + c.dispose(); + break; + } + c.dispose(); + } + if (i < sources.length) + { + TypeStoreUser current = store.find_element_user( set, 0 ); + if (current == sources[i]) + { + // The new object matches what already exists in the array + // Heuristic: we optimize for the case where the new elements + // in the array are the same as the existing elements with + // potentially new elements inserted + + // First insert the new element in the array at position 0 + int j = 0; + for ( j = 0; j < i; j++ ) + { + TypeStoreUser user = store.insert_element_user( set, elemName, j ); + ((XmlObjectBase) user).set( sources[j] ); + } + for ( i++, j++; i < sources.length; i++, j++) + { + XmlCursor c = sources[i].isImmutable() ? null : sources[i].newCursor(); + if (c != null && c.toParent() && c.getObject() == this) + { + c.dispose(); + current = store.find_element_user( set, j ); + if (current == sources[i]) + ; // advance + else + { + // Fall back to the general case + break; + } + } + else + { + c.dispose(); + // Insert before the current element + TypeStoreUser user = store.insert_element_user( set, elemName, j ); + ((XmlObjectBase) user).set( sources[i] ); + } + } + startDest = j; + startSrc = i; + m = store.count_elements( elemName ); + } + // Fall through + } + else + { + // All of the elements in the existing array are to + // be deleted and replaced with elements from the + // sources array + } + + // The general case: we assume that some of the elements + // in the new array already exist, but at different indexes + + // Starting with position i in the sources array, copy the remaining elements + // to the end of the original array... + for (int j = i; j < sources.length; j++) + { + TypeStoreUser user = store.add_element_user( elemName ); + ((XmlObjectBase) user).set( sources[ j ] ); + } + + // ... then come back and insert the elements starting with startSource + // up to i from the sources array into the current array, starting with + // startDest + int n = i; + for ( ; m > n - startSrc + startDest; m-- ) + store.remove_element( set, m - 1 ); + + int j; + for ( i = startSrc, j = startDest ; i < n ; i++, j++ ) + { + TypeStoreUser user; + + if (j >= m) + user = store.add_element_user( elemName ); + else + user = store.find_element_user( set, j ); + + ((XmlObjectBase) user).set( sources[ i ] ); + } + } + +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlDateImpl.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlDateImpl.java new file mode 100644 index 000000000..73c217e36 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlDateImpl.java @@ -0,0 +1,28 @@ +/* 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.values; + +import org.apache.xmlbeans.XmlDate; +import org.apache.xmlbeans.SchemaType; + + +public class XmlDateImpl extends JavaGDateHolderEx implements XmlDate +{ + public XmlDateImpl() + { super(XmlDate.type, false); } + public XmlDateImpl(SchemaType type, boolean complex) + { super(type, complex); } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlDateTimeImpl.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlDateTimeImpl.java new file mode 100644 index 000000000..7d2db6bc3 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlDateTimeImpl.java @@ -0,0 +1,28 @@ +/* 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.values; + +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.XmlDateTime; + + +public class XmlDateTimeImpl extends JavaGDateHolderEx implements XmlDateTime +{ + public XmlDateTimeImpl() + { super(XmlDateTime.type, false); } + public XmlDateTimeImpl(SchemaType type, boolean complex) + { super(type, complex); } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlDecimalImpl.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlDecimalImpl.java new file mode 100644 index 000000000..d7b3ea334 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlDecimalImpl.java @@ -0,0 +1,22 @@ +/* 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.values; + +import org.apache.xmlbeans.XmlDecimal; + +public class XmlDecimalImpl extends JavaDecimalHolder implements XmlDecimal +{ +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlDecimalRestriction.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlDecimalRestriction.java new file mode 100644 index 000000000..a6f20c7e3 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlDecimalRestriction.java @@ -0,0 +1,25 @@ +/* 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.values; + +import org.apache.xmlbeans.XmlDecimal; +import org.apache.xmlbeans.SchemaType; + +public class XmlDecimalRestriction extends JavaDecimalHolderEx implements XmlDecimal +{ + public XmlDecimalRestriction(SchemaType type, boolean complex) + { super(type, complex); } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlDoubleImpl.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlDoubleImpl.java new file mode 100644 index 000000000..92526f008 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlDoubleImpl.java @@ -0,0 +1,22 @@ +/* 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.values; + +import org.apache.xmlbeans.XmlDouble; + +public class XmlDoubleImpl extends JavaDoubleHolder implements XmlDouble +{ +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlDoubleRestriction.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlDoubleRestriction.java new file mode 100644 index 000000000..bdae8909e --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlDoubleRestriction.java @@ -0,0 +1,25 @@ +/* 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.values; + +import org.apache.xmlbeans.XmlDouble; +import org.apache.xmlbeans.SchemaType; + +public class XmlDoubleRestriction extends JavaDoubleHolderEx implements XmlDouble +{ + public XmlDoubleRestriction(SchemaType type, boolean complex) + { super(type, complex); } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlDurationImpl.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlDurationImpl.java new file mode 100644 index 000000000..9db131fdd --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlDurationImpl.java @@ -0,0 +1,28 @@ +/* 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.values; + +import org.apache.xmlbeans.XmlDuration; +import org.apache.xmlbeans.SchemaType; + + +public class XmlDurationImpl extends JavaGDurationHolderEx implements XmlDuration +{ + public XmlDurationImpl() + { super(XmlDuration.type, false); } + public XmlDurationImpl(SchemaType type, boolean complex) + { super(type, complex); } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlEntitiesImpl.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlEntitiesImpl.java new file mode 100644 index 000000000..a06212929 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlEntitiesImpl.java @@ -0,0 +1,28 @@ +/* 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.values; + +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.XmlENTITIES; + + +public class XmlEntitiesImpl extends XmlListImpl implements XmlENTITIES +{ + public XmlEntitiesImpl() + { super(XmlENTITIES.type, false); } + public XmlEntitiesImpl(SchemaType type, boolean complex) + { super(type, complex); } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlEntityImpl.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlEntityImpl.java new file mode 100644 index 000000000..7bc7f4bfb --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlEntityImpl.java @@ -0,0 +1,28 @@ +/* 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.values; + +import org.apache.xmlbeans.XmlENTITY; +import org.apache.xmlbeans.SchemaType; + + +public class XmlEntityImpl extends JavaStringHolderEx implements XmlENTITY +{ + public XmlEntityImpl() + { super(XmlENTITY.type, false); } + public XmlEntityImpl(SchemaType type, boolean complex) + { super(type, complex); } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlFloatImpl.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlFloatImpl.java new file mode 100644 index 000000000..3d4343dfe --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlFloatImpl.java @@ -0,0 +1,23 @@ +/* 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.values; + +import org.apache.xmlbeans.XmlFloat; + + +public class XmlFloatImpl extends JavaFloatHolder implements XmlFloat +{ +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlFloatRestriction.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlFloatRestriction.java new file mode 100644 index 000000000..7a2b6a0f5 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlFloatRestriction.java @@ -0,0 +1,25 @@ +/* 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.values; + +import org.apache.xmlbeans.XmlFloat; +import org.apache.xmlbeans.SchemaType; + +public class XmlFloatRestriction extends JavaFloatHolderEx implements XmlFloat +{ + public XmlFloatRestriction(SchemaType type, boolean complex) + { super(type, complex); } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlGDayImpl.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlGDayImpl.java new file mode 100644 index 000000000..3a665458a --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlGDayImpl.java @@ -0,0 +1,28 @@ +/* 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.values; + +import org.apache.xmlbeans.XmlGDay; +import org.apache.xmlbeans.SchemaType; + + +public class XmlGDayImpl extends JavaGDateHolderEx implements XmlGDay +{ + public XmlGDayImpl() + { super(XmlGDay.type, false); } + public XmlGDayImpl(SchemaType type, boolean complex) + { super(type, complex); } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlGMonthDayImpl.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlGMonthDayImpl.java new file mode 100644 index 000000000..58b76ed17 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlGMonthDayImpl.java @@ -0,0 +1,27 @@ +/* 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.values; + +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.XmlGMonthDay; + +public class XmlGMonthDayImpl extends JavaGDateHolderEx implements XmlGMonthDay +{ + public XmlGMonthDayImpl() + { super(XmlGMonthDay.type, false); } + public XmlGMonthDayImpl(SchemaType type, boolean complex) + { super(type, complex); } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlGMonthImpl.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlGMonthImpl.java new file mode 100644 index 000000000..5946b517d --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlGMonthImpl.java @@ -0,0 +1,27 @@ +/* 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.values; + +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.XmlGMonth; + +public class XmlGMonthImpl extends JavaGDateHolderEx implements XmlGMonth +{ + public XmlGMonthImpl() + { super(XmlGMonth.type, false); } + public XmlGMonthImpl(SchemaType type, boolean complex) + { super(type, complex); } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlGYearImpl.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlGYearImpl.java new file mode 100644 index 000000000..5c0f834da --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlGYearImpl.java @@ -0,0 +1,27 @@ +/* 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.values; + +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.XmlGYear; + +public class XmlGYearImpl extends JavaGDateHolderEx implements XmlGYear +{ + public XmlGYearImpl() + { super(XmlGYear.type, false); } + public XmlGYearImpl(SchemaType type, boolean complex) + { super(type, complex); } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlGYearMonthImpl.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlGYearMonthImpl.java new file mode 100644 index 000000000..b5897c7d0 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlGYearMonthImpl.java @@ -0,0 +1,27 @@ +/* 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.values; + +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.XmlGYearMonth; + +public class XmlGYearMonthImpl extends JavaGDateHolderEx implements XmlGYearMonth +{ + public XmlGYearMonthImpl() + { super(XmlGYearMonth.type, false); } + public XmlGYearMonthImpl(SchemaType type, boolean complex) + { super(type, complex); } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlHexBinaryImpl.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlHexBinaryImpl.java new file mode 100644 index 000000000..c489e34ba --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlHexBinaryImpl.java @@ -0,0 +1,23 @@ +/* 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.values; + +import org.apache.xmlbeans.XmlHexBinary; + + +public class XmlHexBinaryImpl extends JavaHexBinaryHolder implements XmlHexBinary +{ +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlHexBinaryRestriction.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlHexBinaryRestriction.java new file mode 100644 index 000000000..4b4202718 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlHexBinaryRestriction.java @@ -0,0 +1,25 @@ +/* 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.values; + +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.XmlHexBinary; + +public class XmlHexBinaryRestriction extends JavaHexBinaryHolderEx implements XmlHexBinary +{ + public XmlHexBinaryRestriction(SchemaType type, boolean complex) + { super(type, complex); } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlIdImpl.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlIdImpl.java new file mode 100644 index 000000000..f260b129d --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlIdImpl.java @@ -0,0 +1,28 @@ +/* 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.values; + +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.XmlID; + + +public class XmlIdImpl extends JavaStringHolderEx implements XmlID +{ + public XmlIdImpl() + { super(XmlID.type, false); } + public XmlIdImpl(SchemaType type, boolean complex) + { super(type, complex); } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlIdRefImpl.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlIdRefImpl.java new file mode 100644 index 000000000..6dfea621f --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlIdRefImpl.java @@ -0,0 +1,28 @@ +/* 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.values; + +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.XmlIDREF; + + +public class XmlIdRefImpl extends JavaStringHolderEx implements XmlIDREF +{ + public XmlIdRefImpl() + { super(XmlIDREF.type, false); } + public XmlIdRefImpl(SchemaType type, boolean complex) + { super(type, complex); } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlIdRefsImpl.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlIdRefsImpl.java new file mode 100644 index 000000000..1c9fb15ac --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlIdRefsImpl.java @@ -0,0 +1,27 @@ +/* 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.values; + +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.XmlIDREFS; + +public class XmlIdRefsImpl extends XmlListImpl implements XmlIDREFS +{ + public XmlIdRefsImpl() + { super(XmlIDREFS.type, false); } + public XmlIdRefsImpl(SchemaType type, boolean complex) + { super(type, complex); } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlIntImpl.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlIntImpl.java new file mode 100644 index 000000000..cb86181a4 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlIntImpl.java @@ -0,0 +1,23 @@ +/* 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.values; + +import org.apache.xmlbeans.XmlInt; + + +public class XmlIntImpl extends JavaIntHolder implements XmlInt +{ +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlIntRestriction.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlIntRestriction.java new file mode 100644 index 000000000..a608504d0 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlIntRestriction.java @@ -0,0 +1,25 @@ +/* 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.values; + +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.XmlInt; + +public class XmlIntRestriction extends JavaIntHolderEx implements XmlInt +{ + public XmlIntRestriction(SchemaType type, boolean complex) + { super(type, complex); } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlIntegerImpl.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlIntegerImpl.java new file mode 100644 index 000000000..031f61904 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlIntegerImpl.java @@ -0,0 +1,23 @@ +/* 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.values; + +import org.apache.xmlbeans.XmlInteger; + + +public class XmlIntegerImpl extends JavaIntegerHolder implements XmlInteger +{ +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlIntegerRestriction.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlIntegerRestriction.java new file mode 100644 index 000000000..57875acd5 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlIntegerRestriction.java @@ -0,0 +1,25 @@ +/* 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.values; + +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.XmlInteger; + +public class XmlIntegerRestriction extends JavaIntegerHolderEx implements XmlInteger +{ + public XmlIntegerRestriction(SchemaType type, boolean complex) + { super(type, complex); } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlLanguageImpl.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlLanguageImpl.java new file mode 100644 index 000000000..e2c500886 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlLanguageImpl.java @@ -0,0 +1,27 @@ +/* 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.values; + +import org.apache.xmlbeans.XmlLanguage; +import org.apache.xmlbeans.SchemaType; + +public class XmlLanguageImpl extends JavaStringHolderEx implements XmlLanguage +{ + public XmlLanguageImpl() + { super(XmlLanguage.type, false); } + public XmlLanguageImpl(SchemaType type, boolean complex) + { super(type, complex); } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlListImpl.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlListImpl.java new file mode 100644 index 000000000..bd1dbf590 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlListImpl.java @@ -0,0 +1,360 @@ +/* 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.values; + +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.XmlAnySimpleType; +import org.apache.xmlbeans.SimpleValue; +import org.apache.xmlbeans.XmlErrorCodes; +import org.apache.xmlbeans.XmlSimpleList; +import org.apache.xmlbeans.impl.common.ValidationContext; +import org.apache.xmlbeans.impl.common.QNameHelper; +import org.apache.xmlbeans.impl.common.PrefixResolver; +import org.apache.xmlbeans.impl.common.XMLChar; + +import java.util.Arrays; +import java.util.List; +import java.util.ArrayList; + +public class XmlListImpl extends XmlObjectBase implements XmlAnySimpleType +{ + public XmlListImpl(SchemaType type, boolean complex) + { _schemaType = type; initComplexType(complex, false); } + + public SchemaType schemaType() + { return _schemaType; } + + private SchemaType _schemaType; + private XmlSimpleList _value; + private XmlSimpleList _jvalue; + + + + // SIMPLE VALUE ACCESSORS BELOW ------------------------------------------- + // gets raw text value + + private static String nullAsEmpty(String s) + { + if (s == null) + return ""; + return s; + } + + private static String compute_list_text(List xList) + { + if (xList.size() == 0) + return ""; + + StringBuffer sb = new StringBuffer(); + sb.append(nullAsEmpty(((SimpleValue)xList.get(0)).getStringValue())); + + for (int i = 1; i < xList.size(); i++) + { + sb.append(' '); + sb.append(nullAsEmpty(((SimpleValue)xList.get(i)).getStringValue())); + } + + return sb.toString(); + } + + protected String compute_text(NamespaceManager nsm) + { + return compute_list_text(_value); + } + + protected boolean is_defaultable_ws(String v) { + try { + XmlSimpleList savedValue = _value; + set_text(v); + + // restore the saved value + _value = savedValue; + + return false; + } + catch (XmlValueOutOfRangeException e) { + return true; + } + } + + protected void set_text(String s) + { + // first check against any patterns... + if (_validateOnSet() && !_schemaType.matchPatternFacet(s)) + throw new XmlValueOutOfRangeException(XmlErrorCodes.DATATYPE_VALID$PATTERN_VALID, + new Object[] { "list", s, QNameHelper.readable(_schemaType) }); + + SchemaType itemType = _schemaType.getListItemType(); + + XmlSimpleList newval = lex(s, itemType, _voorVc, has_store() ? get_store() : null); + + // check enumeration + if (_validateOnSet()) + validateValue(newval, _schemaType, _voorVc); + + // we made it all the way through; so we're OK. + _value = newval; + _jvalue = null; + } + + private static final String[] EMPTY_STRINGARRAY = new String[0]; + + public static String[] split_list(String s) + { + if (s.length() == 0) + return EMPTY_STRINGARRAY; + + List result = new ArrayList(); + int i = 0; + int start = 0; + for (;;) + { + while (i < s.length() && XMLChar.isSpace(s.charAt(i))) + i += 1; + if (i >= s.length()) + return (String[])result.toArray(EMPTY_STRINGARRAY); + start = i; + while (i < s.length() && !XMLChar.isSpace(s.charAt(i))) + i += 1; + result.add(s.substring(start, i)); + } + } + + public static XmlSimpleList lex(String s, SchemaType itemType, ValidationContext ctx, PrefixResolver resolver) + { + String[] parts = split_list(s); + + XmlAnySimpleType[] newArray = new XmlAnySimpleType[parts.length]; + boolean pushed = false; + if (resolver != null) + { + NamespaceContext.push(new NamespaceContext(resolver)); + pushed = true; + } + int i = 0; + try + { + for (i = 0; i < parts.length; i++) + { + try + { + newArray[i] = itemType.newValue(parts[i]); + } + catch (XmlValueOutOfRangeException e) + { + ctx.invalid(XmlErrorCodes.LIST, new Object[] { "item '" + parts[i] + "' is not a valid value of " + QNameHelper.readable(itemType) }); + } + } + } + finally + { + if (pushed) + NamespaceContext.pop(); + } + return new XmlSimpleList(Arrays.asList(newArray)); + } + + protected void set_nil() + { + _value = null; + } + + public List xgetListValue() + { + check_dated(); + return _value; + } + + public List getListValue() + { + check_dated(); + if (_value == null) + return null; + if (_jvalue != null) + return _jvalue; + List javaResult = new ArrayList(); + for (int i = 0; i < _value.size(); i++) + javaResult.add(java_value((XmlObject)_value.get(i))); + _jvalue = new XmlSimpleList(javaResult); + return _jvalue; + } + + private static boolean permits_inner_space(XmlObject obj) + { + switch (((SimpleValue)obj).instanceType().getPrimitiveType().getBuiltinTypeCode()) + { + case SchemaType.BTC_STRING: + case SchemaType.BTC_ANY_URI: + case SchemaType.BTC_ANY_SIMPLE: + case SchemaType.BTC_ANY_TYPE: + return true; + default: + return false; + } + } + + private static boolean contains_white_space(String s) + { + return s.indexOf(' ') >= 0 || + s.indexOf('\t') >= 0 || + s.indexOf('\n') >= 0 || + s.indexOf('\r') >= 0; + } + + public void set_list(List list) + { + SchemaType itemType = _schemaType.getListItemType(); + XmlSimpleList xList; + + boolean pushed = false; + if (has_store()) + { + NamespaceContext.push(new NamespaceContext(get_store())); + pushed = true; + } + + try + { + XmlAnySimpleType[] newval = new XmlAnySimpleType[list.size()]; + for (int i = 0; i < list.size(); i++) + { + Object entry = list.get(i); + if ((entry instanceof XmlObject) && permits_inner_space((XmlObject)list.get(i))) + { + String stringrep = list.get(i).toString(); + if (contains_white_space(stringrep)) + throw new XmlValueOutOfRangeException(); + } + newval[i] = itemType.newValue(entry); + } + xList = new XmlSimpleList(Arrays.asList(newval)); + } + finally + { + if (pushed) + NamespaceContext.pop(); + } + + if (_validateOnSet()) + { + // check enumeration + min/max/etc + validateValue(xList, _schemaType, _voorVc); + } + + _value = xList; + _jvalue = null; + } + + public static void validateValue(XmlSimpleList items, SchemaType sType, ValidationContext context) + { + XmlObject[] enumvals = sType.getEnumerationValues(); + checkEnum: if (enumvals != null) + { + for (int i = 0; i < enumvals.length; i++) + { + if (equal_xmlLists(items, ((XmlObjectBase)enumvals[i]).xlistValue())) + break checkEnum; + } + context.invalid(XmlErrorCodes.DATATYPE_ENUM_VALID, + new Object[] { "list", items, QNameHelper.readable(sType) }); + } + + XmlObject o; + int i; + + if ((o = sType.getFacet( SchemaType.FACET_LENGTH )) != null) + { + if ((i = ((SimpleValue)o).getIntValue()) != items.size()) + { + context.invalid(XmlErrorCodes.DATATYPE_LENGTH_VALID$LIST_LENGTH, + new Object[] { items, new Integer(items.size()), new Integer(i), QNameHelper.readable(sType) }); + } + } + + if ((o = sType.getFacet( SchemaType.FACET_MIN_LENGTH )) != null) + { + if ((i = ((SimpleValue)o).getIntValue()) > items.size()) + { + context.invalid(XmlErrorCodes.DATATYPE_MIN_LENGTH_VALID$LIST_LENGTH, + new Object[] { items, new Integer(items.size()), new Integer(i), QNameHelper.readable(sType) }); + } + } + + if ((o = sType.getFacet( SchemaType.FACET_MAX_LENGTH )) != null) + { + if ((i = ((SimpleValue)o).getIntValue()) < items.size()) + { + context.invalid(XmlErrorCodes.DATATYPE_MAX_LENGTH_VALID$LIST_LENGTH, + new Object[] { items, new Integer(items.size()), new Integer(i), QNameHelper.readable(sType) }); + } + } + } + + // comparators + // protected int compare_to(XmlObject i) - no sorting order; inherit from base + + protected boolean equal_to(XmlObject obj) + { + return equal_xmlLists(_value, ((XmlObjectBase)obj).xlistValue()); + } + + + private static boolean equal_xmlLists(List a, List b) + { + if (a.size() != b.size()) + return false; + for (int i = 0; i < a.size(); i++) + { + if (!a.get(i).equals(b.get(i))) + return false; + } + return true; + } + + protected int value_hash_code() + { + if (_value == null) + return 0; + + // hash code probes 9 distributed values, plus the last + int hash = _value.size(); + int incr = _value.size() / 9; + if (incr < 1) + incr = 1; + + int i; + for (i = 0; i < _value.size(); i += incr) + { + hash *= 19; + hash += _value.get(i).hashCode(); + } + + if (i < _value.size()) + { + hash *= 19; + hash += _value.get(i).hashCode(); + } + + return hash; + } + + protected void validate_simpleval(String lexical, ValidationContext ctx) + { + validateValue((XmlSimpleList)xlistValue(), schemaType(), ctx); + } + +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlLongImpl.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlLongImpl.java new file mode 100644 index 000000000..285b0bc3a --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlLongImpl.java @@ -0,0 +1,23 @@ +/* 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.values; + +import org.apache.xmlbeans.XmlLong; + + +public class XmlLongImpl extends JavaLongHolder implements XmlLong +{ +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlLongRestriction.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlLongRestriction.java new file mode 100644 index 000000000..9ea36decf --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlLongRestriction.java @@ -0,0 +1,25 @@ +/* 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.values; + +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.XmlLong; + +public class XmlLongRestriction extends JavaLongHolderEx implements XmlLong +{ + public XmlLongRestriction(SchemaType type, boolean complex) + { super(type, complex); } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlNCNameImpl.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlNCNameImpl.java new file mode 100644 index 000000000..cde93447f --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlNCNameImpl.java @@ -0,0 +1,39 @@ +/* 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.values; + +import org.apache.xmlbeans.XmlErrorCodes; +import org.apache.xmlbeans.XmlNCName; +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.impl.common.ValidationContext; +import org.apache.xmlbeans.impl.common.XMLChar; + +public class XmlNCNameImpl extends JavaStringHolderEx implements XmlNCName +{ + public XmlNCNameImpl() + { super(XmlNCName.type, false); } + public XmlNCNameImpl(SchemaType type, boolean complex) + { super(type, complex); } + + public static void validateLexical(String v, ValidationContext context) + { + if ( !XMLChar.isValidNCName(v) ) + { + context.invalid(XmlErrorCodes.NCNAME, new Object[] { v }); + return; + } + } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlNameImpl.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlNameImpl.java new file mode 100644 index 000000000..1f3a08132 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlNameImpl.java @@ -0,0 +1,28 @@ +/* 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.values; + +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.XmlName; + + +public class XmlNameImpl extends JavaStringHolderEx implements XmlName +{ + public XmlNameImpl() + { super(XmlName.type, false); } + public XmlNameImpl(SchemaType type, boolean complex) + { super(type, complex); } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlNegativeIntegerImpl.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlNegativeIntegerImpl.java new file mode 100644 index 000000000..20dff353f --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlNegativeIntegerImpl.java @@ -0,0 +1,28 @@ +/* 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.values; + +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.XmlNegativeInteger; + + +public class XmlNegativeIntegerImpl extends JavaIntegerHolderEx implements XmlNegativeInteger +{ + public XmlNegativeIntegerImpl() + { super(XmlNegativeInteger.type, false); } + public XmlNegativeIntegerImpl(SchemaType type, boolean complex) + { super(type, complex); } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlNmTokenImpl.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlNmTokenImpl.java new file mode 100644 index 000000000..1afd2a6c5 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlNmTokenImpl.java @@ -0,0 +1,40 @@ +/* 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.values; + +import org.apache.xmlbeans.XmlNMTOKEN; +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.XmlErrorCodes; +import org.apache.xmlbeans.impl.common.ValidationContext; +import org.apache.xmlbeans.impl.common.XMLChar; + + +public class XmlNmTokenImpl extends JavaStringHolderEx implements XmlNMTOKEN +{ + public XmlNmTokenImpl() + { super(XmlNMTOKEN.type, false); } + public XmlNmTokenImpl(SchemaType type, boolean complex) + { super(type, complex); } + + public static void validateLexical(String v, ValidationContext context) + { + if ( !XMLChar.isValidNmtoken(v) ) + { + context.invalid(XmlErrorCodes.NMTOKEN, new Object[] { v }); + return; + } + } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlNmTokensImpl.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlNmTokensImpl.java new file mode 100644 index 000000000..3b8cd4b4b --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlNmTokensImpl.java @@ -0,0 +1,28 @@ +/* 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.values; + +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.XmlNMTOKENS; + + +public class XmlNmTokensImpl extends XmlListImpl implements XmlNMTOKENS +{ + public XmlNmTokensImpl() + { super(XmlNMTOKENS.type, false);} + public XmlNmTokensImpl(SchemaType type, boolean complex) + { super(type, complex); } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlNonNegativeIntegerImpl.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlNonNegativeIntegerImpl.java new file mode 100644 index 000000000..7026b98a6 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlNonNegativeIntegerImpl.java @@ -0,0 +1,28 @@ +/* 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.values; + +import org.apache.xmlbeans.XmlNonNegativeInteger; +import org.apache.xmlbeans.SchemaType; + + +public class XmlNonNegativeIntegerImpl extends JavaIntegerHolderEx implements XmlNonNegativeInteger +{ + public XmlNonNegativeIntegerImpl() + { super(XmlNonNegativeInteger.type, false); } + public XmlNonNegativeIntegerImpl(SchemaType type, boolean complex) + { super(type, complex); } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlNonPositiveIntegerImpl.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlNonPositiveIntegerImpl.java new file mode 100644 index 000000000..901e5ef9b --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlNonPositiveIntegerImpl.java @@ -0,0 +1,28 @@ +/* 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.values; + +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.XmlNonPositiveInteger; + + +public class XmlNonPositiveIntegerImpl extends JavaIntegerHolderEx implements XmlNonPositiveInteger +{ + public XmlNonPositiveIntegerImpl() + { super(XmlNonPositiveInteger.type, false); } + public XmlNonPositiveIntegerImpl(SchemaType type, boolean complex) + { super(type, complex); } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlNormalizedStringImpl.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlNormalizedStringImpl.java new file mode 100644 index 000000000..47de4635c --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlNormalizedStringImpl.java @@ -0,0 +1,27 @@ +/* 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.values; + +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.XmlNormalizedString; + +public class XmlNormalizedStringImpl extends JavaStringHolderEx implements XmlNormalizedString +{ + public XmlNormalizedStringImpl() + { super(XmlNormalizedString.type, false); } + public XmlNormalizedStringImpl(SchemaType type, boolean complex) + { super(type, complex); } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlNotationImpl.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlNotationImpl.java new file mode 100644 index 000000000..f2632b041 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlNotationImpl.java @@ -0,0 +1,22 @@ +/* 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.values; + +import org.apache.xmlbeans.XmlNOTATION; + +public class XmlNotationImpl extends JavaNotationHolder implements XmlNOTATION +{ +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlNotationRestriction.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlNotationRestriction.java new file mode 100644 index 000000000..18230579e --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlNotationRestriction.java @@ -0,0 +1,25 @@ +/* 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.values; + +import org.apache.xmlbeans.XmlNOTATION; +import org.apache.xmlbeans.SchemaType; + +public class XmlNotationRestriction extends JavaNotationHolderEx implements XmlNOTATION +{ + public XmlNotationRestriction(SchemaType type, boolean complex) + { super(type, complex); } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlObjectBase.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlObjectBase.java new file mode 100644 index 000000000..2a2a12aa2 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlObjectBase.java @@ -0,0 +1,3217 @@ +/* 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.values; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamReader; + +import org.apache.xmlbeans.xml.stream.XMLInputStream; + +import java.math.BigInteger; +import java.math.BigDecimal; +import java.io.Serializable; +import java.io.File; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.Reader; +import java.io.Writer; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.ObjectStreamException; +import java.io.ByteArrayInputStream; +import java.io.DataInputStream; +import java.lang.reflect.Array; +import java.util.Date; +import java.util.List; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; +import java.util.Calendar; +import java.util.Collection; +import java.util.ArrayList; + +import org.apache.xmlbeans.impl.common.XmlLocale; +import org.apache.xmlbeans.impl.common.XmlWhitespace; +import org.apache.xmlbeans.impl.common.ValidationContext; +import org.apache.xmlbeans.impl.common.GlobalLock; +import org.apache.xmlbeans.impl.common.XmlErrorWatcher; +import org.apache.xmlbeans.impl.common.QNameHelper; +import org.apache.xmlbeans.impl.schema.SchemaTypeImpl; +import org.apache.xmlbeans.impl.schema.SchemaTypeVisitorImpl; +import org.apache.xmlbeans.impl.validator.Validator; +import org.apache.xmlbeans.XmlErrorCodes; +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.SchemaAttributeModel; +import org.apache.xmlbeans.XmlAnySimpleType; +import org.apache.xmlbeans.XmlCursor; +import org.apache.xmlbeans.XmlOptions; +import org.apache.xmlbeans.XmlDocumentProperties; +import org.apache.xmlbeans.SimpleValue; +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.SchemaField; +import org.apache.xmlbeans.SchemaProperty; +import org.apache.xmlbeans.XmlException; +import org.apache.xmlbeans.XmlRuntimeException; +import org.apache.xmlbeans.QNameSet; +import org.apache.xmlbeans.GDate; +import org.apache.xmlbeans.GDuration; +import org.apache.xmlbeans.GDateSpecification; +import org.apache.xmlbeans.GDurationSpecification; +import org.apache.xmlbeans.StringEnumAbstractBase; +import org.apache.xmlbeans.XmlBeans; +import org.apache.xmlbeans.XmlError; +import org.apache.xmlbeans.SchemaLocalAttribute; +import org.apache.xmlbeans.DelegateXmlObject; +import org.apache.xmlbeans.SchemaTypeLoader; + +import org.w3c.dom.Node; + +import org.xml.sax.ContentHandler; +import org.xml.sax.ext.LexicalHandler; +import org.xml.sax.SAXException; + +public abstract class XmlObjectBase implements TypeStoreUser, Serializable, XmlObject, SimpleValue +{ + public static final short MAJOR_VERSION_NUMBER = (short) 1; // for serialization + public static final short MINOR_VERSION_NUMBER = (short) 1; // for serialization + + public static final short KIND_SETTERHELPER_SINGLETON = 1; + public static final short KIND_SETTERHELPER_ARRAYITEM = 2; + + public final Object monitor() + { + if (has_store()) + return get_store().get_locale(); + return this; + } + + private static XmlObjectBase underlying(XmlObject obj) + { + if (obj == null) + return null; + if (obj instanceof XmlObjectBase) + return (XmlObjectBase)obj; + while (obj instanceof DelegateXmlObject) + obj = ((DelegateXmlObject)obj).underlyingXmlObject(); + if (obj instanceof XmlObjectBase) + return (XmlObjectBase)obj; + throw new IllegalStateException("Non-native implementations of XmlObject should extend FilterXmlObject or implement DelegateXmlObject"); + } + + public final XmlObject copy() + { + if (preCheck()) + return _copy(); + else + synchronized (monitor()) + { + return _copy(); + } + } + + public final XmlObject copy(XmlOptions options) + { + if (preCheck()) + return _copy(options); + else + synchronized (monitor()) + { + return _copy(options); + } + } + + private boolean preCheck() + { +// if ( isImmutable() ) +// return true; + if ( has_store() ) + return get_store().get_locale().noSync(); + return false; + } + + /** + * Same as copy() but unsynchronized. + * Warning: Using this method in mutithreaded environment can cause invalid states. + */ + public final XmlObject _copy() + { + return _copy(null); + } + + /** + * Same as copy() but unsynchronized. + * If Locale.COPY_USE_NEW_LOCALE is set in the options, a new locale will be created for the copy. + * Warning: Using this method in mutithreaded environment can cause invalid states. + */ + public final XmlObject _copy(XmlOptions xmlOptions) + { + // immutable objects don't get copied. They're immutable + if (isImmutable()) + return this; + + check_orphaned(); + + SchemaTypeLoader stl = get_store().get_schematypeloader(); + XmlObject result = (XmlObject)get_store().copy(stl, schemaType(), xmlOptions); + + return result; + } + + public XmlDocumentProperties documentProperties() + { XmlCursor cur = newCursorForce(); try { return cur.documentProperties(); } finally { cur.dispose(); } } + + /** + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public XMLInputStream newXMLInputStream() + { return newXMLInputStream(null); } + + /** + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public XMLInputStream newXMLInputStream(XmlOptions options) + { XmlCursor cur = newCursorForce(); try { return cur.newXMLInputStream(makeInnerOptions(options)); } finally { cur.dispose(); } } + + public XMLStreamReader newXMLStreamReader() + { return newXMLStreamReader(null); } + + public XMLStreamReader newXMLStreamReader(XmlOptions options) + { XmlCursor cur = newCursorForce(); try { return cur.newXMLStreamReader(makeInnerOptions(options)); } finally { cur.dispose(); } } + + public InputStream newInputStream() + { return newInputStream(null); } + + public InputStream newInputStream(XmlOptions options) + { XmlCursor cur = newCursorForce(); try { return cur.newInputStream(makeInnerOptions(options)); } finally { cur.dispose(); } } + + public Reader newReader() + { return newReader(null); } + + public Reader newReader(XmlOptions options) + { XmlCursor cur = newCursorForce(); try { return cur.newReader(makeInnerOptions(options)); } finally { cur.dispose(); } } + + public Node getDomNode() + { XmlCursor cur = newCursorForce(); try { return cur.getDomNode(); } finally { cur.dispose(); } } + + public Node newDomNode() + { return newDomNode(null); } + + public Node newDomNode(XmlOptions options) + { XmlCursor cur = newCursorForce(); try { return cur.newDomNode(makeInnerOptions(options)); } finally { cur.dispose(); } } + + public void save(ContentHandler ch, LexicalHandler lh, XmlOptions options) throws SAXException + { XmlCursor cur = newCursorForce(); try { cur.save(ch, lh, makeInnerOptions(options)); } finally { cur.dispose(); } } + + public void save(File file, XmlOptions options) throws IOException + { XmlCursor cur = newCursorForce(); try { cur.save(file, makeInnerOptions(options)); } finally { cur.dispose(); } } + + public void save(OutputStream os, XmlOptions options) throws IOException + { XmlCursor cur = newCursorForce(); try { cur.save(os, makeInnerOptions(options)); } finally { cur.dispose(); } } + + public void save(Writer w, XmlOptions options) throws IOException + { XmlCursor cur = newCursorForce(); try { cur.save(w, makeInnerOptions(options)); } finally { cur.dispose(); } } + + public void save(ContentHandler ch, LexicalHandler lh) throws SAXException + { save( ch, lh, null ); } + + public void save(File file) throws IOException + { save( file, null ); } + + public void save(OutputStream os) throws IOException + { save( os, null ); } + + public void save(Writer w) throws IOException + { save( w, null ); } + + public void dump() + { XmlCursor cur = newCursorForce(); try { cur.dump(); } finally { cur.dispose(); } } + + public XmlCursor newCursorForce() + { + synchronized (monitor()) + { + return ensureStore().newCursor(); + } + } + + private XmlObject ensureStore() + { + if ((_flags & FLAG_STORE) != 0) + return this; + + check_dated(); + + String value = + (_flags & FLAG_NIL) != 0 + ? "" + : compute_text( has_store() ? get_store() : null ); + + XmlOptions options = new XmlOptions().setDocumentType(schemaType()); + + XmlObject x = XmlObject.Factory.newInstance( options ); + + XmlCursor c = x.newCursor(); + c.toNextToken(); + c.insertChars( value ); + + return x; + } + + private static XmlOptions makeInnerOptions(XmlOptions options) + { + XmlOptions innerOptions = new XmlOptions( options ); + innerOptions.put( XmlOptions.SAVE_INNER ); + return innerOptions; + } + + public XmlCursor newCursor() + { + if ((_flags & FLAG_STORE) == 0) + throw new IllegalStateException("XML Value Objects cannot create cursors"); + + check_orphaned(); + + // Note that new_cursor does not really need sync .... + + XmlLocale l = getXmlLocale(); + + if (l.noSync()) { l.enter(); try { return get_store().new_cursor(); } finally { l.exit(); } } + else synchronized ( l ) { l.enter(); try { return get_store().new_cursor(); } finally { l.exit(); } } + + } + + public abstract SchemaType schemaType(); + + public SchemaType instanceType() + { synchronized (monitor()) { return isNil() ? null : schemaType(); } } + + private SchemaField schemaField() { + SchemaType st = schemaType(); + SchemaField field; + + // First check if this field has an anonymous type + field = st.getContainerField(); + + if (field == null) + field = get_store().get_schema_field(); + + return field; + } + + /** + * Use _voorVc when you want to throw a ValueOutOfRangeException when + * validating a simple type. + */ + private static final class ValueOutOfRangeValidationContext implements ValidationContext + { + public void invalid(String message) + { + throw new XmlValueOutOfRangeException( message ); + } + + public void invalid(String code, Object[] args) + { + throw new XmlValueOutOfRangeException( code, args ); + } + } + + /** + * Used to supply validation context for the validate_value methods + */ + private static final class ImmutableValueValidationContext implements ValidationContext + { + private XmlObject _loc; + private Collection _coll; + ImmutableValueValidationContext(Collection coll, XmlObject loc) + { + _coll = coll; + _loc = loc; + } + public void invalid(String message) + { + _coll.add(XmlError.forObject(message, _loc)); + } + public void invalid(String code, Object[] args) + { + _coll.add(XmlError.forObject(code, args, _loc)); + } + } + + public static final ValidationContext _voorVc = new ValueOutOfRangeValidationContext(); + + public boolean validate() + { return validate(null); } + + public boolean validate(XmlOptions options) + { + if ((_flags & FLAG_STORE) == 0) + { + if ((_flags & FLAG_IMMUTABLE) != 0) + { + return validate_immutable(options); + } + + throw new IllegalStateException( + "XML objects with no underlying store cannot be validated"); + } + + synchronized (monitor()) + { + if ((_flags & FLAG_ORPHANED) != 0) + throw new XmlValueDisconnectedException(); + + SchemaField field = schemaField(); + SchemaType type = schemaType(); + + TypeStore typeStore = get_store(); + + Validator validator = + new Validator( + type, field, typeStore.get_schematypeloader(), options, null); + + typeStore.validate( validator ); + + return validator.isValid(); + } + } + + private boolean validate_immutable(XmlOptions options) + { + Collection errorListener = options == null ? null : (Collection)options.get(XmlOptions.ERROR_LISTENER); + XmlErrorWatcher watcher = new XmlErrorWatcher(errorListener); + if (!(schemaType().isSimpleType() || options != null && + options.hasOption(XmlOptions.VALIDATE_TEXT_ONLY))) + { + // cannot have any required attributes or elements + SchemaProperty[] properties = schemaType().getProperties(); + for (int i = 0; i < properties.length; i++) + { + if (properties[i].getMinOccurs().signum() > 0) + { + // KHK: error code? + if (properties[i].isAttribute()) + watcher.add(XmlError.forObject(XmlErrorCodes.ELEM_COMPLEX_TYPE_LOCALLY_VALID$MISSING_REQUIRED_ATTRIBUTE, new Object[]{QNameHelper.pretty(properties[i].getName()), }, this)); + else + watcher.add(XmlError.forObject(XmlErrorCodes.ELEM_COMPLEX_TYPE_LOCALLY_VALID$MISSING_ELEMENT, new Object[]{properties[i].getMinOccurs(), QNameHelper.pretty(properties[i].getName()), }, this)); + } + } + + if (schemaType().getContentType() != SchemaType.SIMPLE_CONTENT) + return !watcher.hasError(); // don't validate non-simple-content + } + + String text = (String)_textsource; + if (text == null) + text = ""; + validate_simpleval(text, new ImmutableValueValidationContext(watcher, this)); + return !watcher.hasError(); + } + + protected void validate_simpleval(String lexical, ValidationContext ctx) + { + return; + } + + private static XmlObject[] _typedArray(XmlObject[] input) + { + if (input.length == 0) + return input; + SchemaType commonType = input[0].schemaType(); + if (commonType.equals(XmlObject.type) || commonType.isNoType()) + return input; + for (int i = 1; i < input.length; i++) + { + if (input[i].schemaType().isNoType()) + return input; + commonType = commonType.getCommonBaseType(input[i].schemaType()); + if (commonType.equals(XmlObject.type)) + return input; + } + Class desiredClass = commonType.getJavaClass(); + while (desiredClass == null) + { + commonType = commonType.getBaseType(); + if (XmlObject.type.equals(commonType)) + return input; + desiredClass = commonType.getJavaClass(); + } + + XmlObject[] result = (XmlObject[])Array.newInstance(desiredClass, input.length); + System.arraycopy(input, 0, result, 0, input.length); + return result; + } + + public XmlObject[] selectPath ( String path ) + { + return selectPath( path, null ); + } + + public XmlObject[] selectPath ( String path, XmlOptions options ) + { + XmlObject [] selections; + + // all user-level code; doesn't need to be synchronized + + XmlCursor c = newCursor(); + + if (c == null) + throw new XmlValueDisconnectedException(); + + try + { + c.selectPath( path, options ); + + if (!c.hasNextSelection()) + selections = EMPTY_RESULT; + else + { + selections = new XmlObject [ c.getSelectionCount() ]; + + for (int i = 0 ; c.toNextSelection() ; i++) + { + if ((selections[ i ] = c.getObject()) == null) + { + if ( !c.toParent() || (selections[ i ] = c.getObject()) == null ) + throw + new XmlRuntimeException( + "Path must select only elements " + + "and attributes" ); + } + } + } + } + finally + { + c.dispose(); + } + + return _typedArray(selections); + } + + public XmlObject[] execQuery ( String path ) + { + return execQuery( path, null ); + } + + public XmlObject[] execQuery ( String queryExpr, XmlOptions options ) + { + synchronized (monitor()) + { + TypeStore typeStore = get_store(); + + if (typeStore == null) + { + throw + new XmlRuntimeException( + "Cannot do XQuery on XML Value Objects" ); + } + + try + { + return _typedArray(typeStore.exec_query( queryExpr, options )); + } + catch (XmlException e) + { + throw new XmlRuntimeException( e ); + } + } + } + + public XmlObject changeType(SchemaType type) + { + if (type == null) + throw new IllegalArgumentException( "Invalid type (null)" ); + + if ((_flags & FLAG_STORE) == 0) + { + throw + new IllegalStateException( + "XML Value Objects cannot have thier type changed" ); + } + + synchronized (monitor()) + { + check_orphaned(); + return (XmlObject) get_store().change_type( type ); + } + } + + public XmlObject substitute(QName name, SchemaType type) + { + if (name == null) + throw new IllegalArgumentException( "Invalid name (null)" ); + + if (type == null) + throw new IllegalArgumentException( "Invalid type (null)" ); + + if ((_flags & FLAG_STORE) == 0) + { + throw + new IllegalStateException( + "XML Value Objects cannot be used with substitution" ); + } + + synchronized (monitor()) + { + check_orphaned(); + return (XmlObject) get_store().substitute( name, type ); + } + } + + private int _flags; + private Object _textsource; + + protected XmlObjectBase() + { + _flags = FLAG_NILLABLE | FLAG_NIL; + } + + public void init_flags(SchemaProperty prop) + { + if (prop == null) return; + + if (prop.hasDefault() == SchemaProperty.VARIABLE || + prop.hasFixed() == SchemaProperty.VARIABLE || + prop.hasNillable() == SchemaProperty.VARIABLE) + return; + + _flags &= ~FLAGS_ELEMENT; + _flags |= + (prop.hasDefault() == SchemaProperty.NEVER ? 0 : TypeStore.HASDEFAULT) | + (prop.hasFixed() == SchemaProperty.NEVER ? 0 : TypeStore.FIXED) | + (prop.hasNillable() == SchemaProperty.NEVER ? 0 : TypeStore.NILLABLE) | + (FLAG_NOT_VARIABLE); + } + + { + assert TypeStore.NILLABLE == 1; + assert TypeStore.HASDEFAULT == 2; + assert TypeStore.FIXED == 4; + } + + private static final int FLAG_NILLABLE = TypeStore.NILLABLE; + private static final int FLAG_HASDEFAULT = TypeStore.HASDEFAULT; + private static final int FLAG_FIXED = TypeStore.FIXED; + private static final int FLAG_ATTRIBUTE = 8; + private static final int FLAG_STORE = 16; + private static final int FLAG_VALUE_DATED = 32; + private static final int FLAG_NIL = 64; + private static final int FLAG_NIL_DATED = 128; + private static final int FLAG_ISDEFAULT = 256; + private static final int FLAG_ELEMENT_DATED = 512; + private static final int FLAG_SETTINGDEFAULT = 1024; + private static final int FLAG_ORPHANED = 2048; + private static final int FLAG_IMMUTABLE = 4096; + private static final int FLAG_COMPLEXTYPE = 8192; + private static final int FLAG_COMPLEXCONTENT = 16384; + private static final int FLAG_NOT_VARIABLE = 32768; + private static final int FLAG_VALIDATE_ON_SET = 65536; + + + /** + * The three dated flags are always stacked: + * FLAG_ELEMENT_DATED implies FLAG_NIL_DATED is set + * FLAG_NIL_DATED implies FLAG_TEXT_DATED is set. + * checkers work on the flags from top to bottom. + */ + private static final int FLAGS_DATED = + FLAG_VALUE_DATED | FLAG_NIL_DATED | FLAG_ELEMENT_DATED; + + /** + * The three element status flags have one interrlationshiop: + * FLAG_FIXED implies FLAG_HASDEFAULT is set. + * These flags are used when setting nils, defaults, strings. + * Since an initial get implies setting from text, they're + * also used during getting. + */ + private static final int FLAGS_ELEMENT = + FLAG_NILLABLE | FLAG_FIXED | FLAG_HASDEFAULT; + + + /** + * Called by restriction subclasses within their constructors to enable + * complex type support. + */ + protected void initComplexType(boolean complexType, boolean complexContent) + { + _flags |= (complexType ? FLAG_COMPLEXTYPE : 0) | + (complexContent ? FLAG_COMPLEXCONTENT : 0); + } + + protected boolean _isComplexType() + { return (_flags & FLAG_COMPLEXTYPE) != 0; } + + protected boolean _isComplexContent() + { return (_flags & FLAG_COMPLEXCONTENT) != 0; } + + public void setValidateOnSet() { + _flags |= FLAG_VALIDATE_ON_SET; + } + + protected boolean _validateOnSet() + { return (_flags & FLAG_VALIDATE_ON_SET) != 0; } + + /** + * True if the value is nilled. + */ + public final boolean isNil() + { + synchronized (monitor()) + { + check_dated(); + return ((_flags & FLAG_NIL) != 0); + } + } + + /** + * True if the value is fixed. + */ + public final boolean isFixed() + { + check_element_dated(); + return ((_flags & FLAG_FIXED) != 0); + } + + /** + * True if the value is allowed to be nil. + */ + public final boolean isNillable() + { + check_element_dated(); + return ((_flags & FLAG_NILLABLE) != 0); + } + + /** + * True if the value is currently defaulted. + */ + public final boolean isDefaultable() + { + check_element_dated(); + return ((_flags & FLAG_HASDEFAULT) != 0); + } + + /** + * True if the value is currently defaulted. + */ + public final boolean isDefault() + { + check_dated(); + return ((_flags & FLAG_ISDEFAULT) != 0); + } + + + /** + * Nils the value. + */ + public final void setNil() + { + synchronized (monitor()) + { + set_prepare(); + + // if we're not nillable, throw exception on setNil(true) + if ((_flags & FLAG_NILLABLE) == 0 && + (_flags & FLAG_VALIDATE_ON_SET) != 0) + throw new XmlValueNotNillableException(); + + // the implementation should zero the value to reflect nil + set_nil(); + + // set the nil flag + _flags |= FLAG_NIL; + + // ordinary commit except no clearing of nil flag + if ((_flags & FLAG_STORE) != 0) + { + get_store().invalidate_text(); + _flags &= ~FLAGS_DATED; + get_store().invalidate_nil(); + } + else + { + _textsource = null; + } + } + } + + /** + * Used for situations where these flags must be passed on to + * chained values. (See XmlAnySimpleType (allSimpleValue), union + * implementations). + */ + protected int elementFlags() + { + check_element_dated(); + return (_flags & FLAGS_ELEMENT); + } + + /** + * Used to make a free-standing xml simple value instance immutable. + * This is a one-way street, and it is illegal to attempt to make a + * value that is embedded in an xml document immutable. + * + * Once a value is marked as immutable, it is illegal to call setters + * of any kind. + */ + public void setImmutable() + { + if ((_flags & (FLAG_IMMUTABLE | FLAG_STORE)) != 0) + throw new IllegalStateException(); + + _flags |= FLAG_IMMUTABLE; + } + + /** + * Is this instance an immutable value? + */ + public boolean isImmutable() + { + return (_flags & FLAG_IMMUTABLE) != 0; + } + + + + + // TEXTUSER implementation + + /** + * Called to initialize the TypeStore associated with this XmlObject + * implementation. If not called, this is a free-floating value holder. + * + * When a value is first attached, it is put in a completely invalidated + * state. + */ + public final void attach_store(TypeStore store) + { + _textsource = store; + if ((_flags & FLAG_IMMUTABLE) != 0) + throw new IllegalStateException(); + _flags |= FLAG_STORE | FLAG_VALUE_DATED | FLAG_NIL_DATED | FLAG_ELEMENT_DATED; + + if (store.is_attribute()) + _flags |= FLAG_ATTRIBUTE; + + if (store.validate_on_set()) + _flags |= FLAG_VALIDATE_ON_SET; + } + + /** + * Called by a TypeStore to indicate that the text has been + * invalidated and should be fetched next time the value is + * needed. + */ + public final void invalidate_value() + { + assert((_flags & FLAG_STORE) != 0); + _flags |= FLAG_VALUE_DATED; + } + + public final boolean uses_invalidate_value() + { + SchemaType type = schemaType(); + return type.isSimpleType() || type.getContentType() == SchemaType.SIMPLE_CONTENT; + } + + /** + * Called by a TypeStore to indicate that the xsi:nil attribute + * on the containing element (and possibly the text) has been + * invalidated and both should be consulted next time the value + * is needed. + */ + public final void invalidate_nilvalue() + { + assert((_flags & FLAG_STORE) != 0); + _flags |= FLAG_VALUE_DATED | FLAG_NIL_DATED; + } + + /** + * Called by a TypeStore to indicate that the element's default + * value, nillability, fixedness, etc, may have changed by + * virtue of the element order changing (and xsi:nil and the + * text may have changed too); so the store should be consulted + * next time any setter or getter is called. + */ + public final void invalidate_element_order() + { + assert((_flags & FLAG_STORE) != 0); + _flags |= FLAG_VALUE_DATED | FLAG_NIL_DATED | FLAG_ELEMENT_DATED; + } + + /** + * Used by the ComplexTypeImpl subclass to get direct access + * to the store. + */ + public final TypeStore get_store() + { + assert((_flags & FLAG_STORE) != 0); + return (TypeStore)_textsource; + } + + public final XmlLocale getXmlLocale ( ) + { + return get_store().get_locale(); + } + + protected final boolean has_store() + { + return (_flags & FLAG_STORE) != 0; + } + + /** + * Called by a TypeStore to pull out the most reasonable + * text value from us. This is done after we have invalidated + * the store (typically when our value has been set). + */ + public final String build_text(NamespaceManager nsm) + { + assert((_flags & FLAG_STORE) != 0); + assert((_flags & FLAG_VALUE_DATED) == 0); + if ((_flags & (FLAG_NIL | FLAG_ISDEFAULT)) != 0) + return ""; + return compute_text( + nsm == null ? has_store() ? get_store() : null : nsm); + } + + /** + * A store will call back on build_nil after we've called invalidate_nil + * and it needs to know what the nil value is. + */ + public boolean build_nil() + { + assert((_flags & FLAG_STORE) != 0); + assert((_flags & FLAG_VALUE_DATED) == 0); + return (_flags & FLAG_NIL) != 0; + } + + /** + * A store will call back on validate_now to force us to look at + * the text if we're in an invalid state. We're allowed to throw + * an exception if the text isn't valid for our type. + */ + public void validate_now() + { + check_dated(); + } + + /** + * A store calls back here in order to force a disconnect. + * After this is done, the object should be considered invalid. + * Any attempt to access or set a value should result in an + * exception. + * + * Note that this is how we handle deletions and xsi:type changes. + */ + public void disconnect_store() + { + assert((_flags & FLAG_STORE) != 0); + _flags |= FLAGS_DATED | FLAG_ORPHANED; + // do NOT null out _textsource, because we need it non-null for synchronization + } + + /** + * A typestore user can create a new TypeStoreUser instance for + * a given element child name as long as you also pass the + * qname contained by the xsi:type attribute, if any. + * + * Note that we will ignore the xsiType if it turns out to be invalid. + * + * Returns null if there is no strongly typed information for that + * given element (which implies, recusively, no strongly typed information + * downwards). + */ + public TypeStoreUser create_element_user(QName eltName, QName xsiType) + { + return + (TypeStoreUser) + ((SchemaTypeImpl) schemaType()).createElementType( + eltName, xsiType, get_store().get_schematypeloader() ); + + /* + SchemaTypeImpl stype = (SchemaTypeImpl)schemaType().getElementType(eltName, xsiType, get_store().get_schematypeloader()); + if (stype == null) + return null; + return (TypeStoreUser)stype.createUnattachedNode(); + */ + } + + /** + * A typestore user can create a new TypeStoreUser instance for + * a given attribute child, based on the attribute name. + * + * Returns null if there is no strongly typed information for that + * given attributes. + */ + public TypeStoreUser create_attribute_user(QName attrName) + { + return (TypeStoreUser)((SchemaTypeImpl)schemaType()).createAttributeType(attrName, get_store().get_schematypeloader()); + } + + public SchemaType get_schema_type() + { + return schemaType(); + } + + public SchemaType get_element_type(QName eltName, QName xsiType) + { + return schemaType().getElementType( + eltName, xsiType, get_store().get_schematypeloader() ); + } + + public SchemaType get_attribute_type(QName attrName) + { + return schemaType().getAttributeType( + attrName, get_store().get_schematypeloader() ); + } + + /** + * Returns the default element text, if it's consistent. If it's + * not consistent, returns null, and requires a visitor walk. + * + * Also returns null if there is no default at all (although + * that can also be discovered via get_elementflags without + * doing a walk). + */ + public String get_default_element_text(QName eltName) + { + assert(_isComplexContent()); + if (!_isComplexContent()) + throw new IllegalStateException(); + + SchemaProperty prop = schemaType().getElementProperty(eltName); + if (prop == null) + return ""; + return prop.getDefaultText(); + } + + /** + * Returns the default attribute text for the attribute with + * the given name, or null if no default. + */ + public String get_default_attribute_text(QName attrName) + { + assert(_isComplexType()); + if (!_isComplexType()) + throw new IllegalStateException(); + + SchemaProperty prop = schemaType().getAttributeProperty(attrName); + if (prop == null) + return ""; + return prop.getDefaultText(); + } + + /** + * Returns the elementflags, if they're consistent. If they're + * not, returns -1, and requires a vistor walk. + */ + public int get_elementflags(QName eltName) + { + if (!_isComplexContent()) + return 0; + + SchemaProperty prop = schemaType().getElementProperty(eltName); + if (prop == null) + return 0; + if (prop.hasDefault() == SchemaProperty.VARIABLE || + prop.hasFixed() == SchemaProperty.VARIABLE || + prop.hasNillable() == SchemaProperty.VARIABLE) + return -1; + return + (prop.hasDefault() == SchemaProperty.NEVER ? 0 : TypeStore.HASDEFAULT) | + (prop.hasFixed() == SchemaProperty.NEVER ? 0 : TypeStore.FIXED) | + (prop.hasNillable() == SchemaProperty.NEVER ? 0 : TypeStore.NILLABLE); + } + + /** + * Returns the flags for the given attribute. + */ + public int get_attributeflags(QName attrName) + { + if (!_isComplexType()) + return 0; + SchemaProperty prop = schemaType().getAttributeProperty(attrName); + if (prop == null) + return 0; + return + (prop.hasDefault() == SchemaProperty.NEVER ? 0 : TypeStore.HASDEFAULT) | + (prop.hasFixed() == SchemaProperty.NEVER ? 0 : TypeStore.FIXED); + // BUGBUG: todo: hook up required? + } + + /** + * Returns false if child elements are insensitive to order; + * if it returns true, you're required to call invalidate_element_order + * on children to the right of any child order rearrangement. + */ + public boolean is_child_element_order_sensitive() + { + if (!_isComplexType()) + return false; + return schemaType().isOrderSensitive(); + } + + /** + * Inserting a new element is always unambiguous except in one + * situation: when adding an element after the last one with + * that name (or the first one if there are none). + * + * In that case, add the element at the first possible slot + * BEFORE any element whose qname is contained in the QNameSet + * given. (If the QNameSet is empty, that means add the new + * element at the very end.) + * + * If the returned QNameSet is null, treat it as if the QNameSet + * contained all QNames, i.e., add the new element at the very + * first position possible (adjacent to the last element of the + * same name, or at the very first slot if it is the first elt + * with that name). + */ + public final QNameSet get_element_ending_delimiters(QName eltname) + { + SchemaProperty prop = schemaType().getElementProperty(eltname); + if (prop == null) + return null; + return prop.getJavaSetterDelimiter(); + } + + /** + * A typestore user can return a visitor that is used to compute + * default text and elementflags for an arbitrary element. + */ + public TypeStoreVisitor new_visitor() + { + if (!_isComplexContent()) + return null; + return new SchemaTypeVisitorImpl(schemaType().getContentModel()); + } + + public SchemaField get_attribute_field(QName attrName) + { + SchemaAttributeModel model = schemaType().getAttributeModel(); + if (model == null) + return null; + return model.getAttribute(attrName); + } + + + /** + * Setting a string preserves any noncanonical literal + * representation. This is done by storing the actual + * string in the underlying store after checking it + * against the primitive type for validity. + */ + protected void set_String(String v) + { + if ((_flags & FLAG_IMMUTABLE) != 0) + throw new IllegalStateException(); + + boolean wasNilled = ((_flags & FLAG_NIL) != 0); + + // update the underlying value from the string + String wscanon = apply_wscanon(v); + update_from_wscanon_text(wscanon); + + // Now store the literal text immediately in the underlying + if ((_flags & FLAG_STORE) != 0) + { + _flags &= ~FLAG_VALUE_DATED; + if ((_flags & FLAG_SETTINGDEFAULT) == 0) + get_store().store_text(v); + if (wasNilled) + get_store().invalidate_nil(); + } + else + _textsource = v; + } + + /** + * Update the value based on complex content. + */ + protected void update_from_complex_content() + { + throw new XmlValueNotSupportedException("Complex content"); + } + + /** + * Utility to update the value based on a string that + * was passed either from the text store or from the user. + * This function handles the cases where there is a default + * that must be applied, and where the value must match + * a fixed value. + */ + private final void update_from_wscanon_text(String v) + { + // Whitespace is default if this type treats this space as defaultable + if ((_flags & FLAG_HASDEFAULT) != 0 && (_flags & FLAG_SETTINGDEFAULT) == 0) + { + // This isn't quite correct since the .equals("") test should be + // done on the actual text, not the wscanon text + if ((_flags & FLAG_ATTRIBUTE) == 0 && v.equals("")) + { + String def = get_store().compute_default_text(); + if (def == null) + throw new XmlValueOutOfRangeException(); + + // protect against recursion with this flag + _flags |= FLAG_SETTINGDEFAULT; + try { this.setStringValue(def); } + finally { _flags &= ~FLAG_SETTINGDEFAULT; } + _flags &= ~FLAG_NIL; + _flags |= FLAG_ISDEFAULT; + return; + } + } + // If we haven't returned yet, the default doesn't apply. + + // Ask underlying impl to parse ordinary non-default text + set_text(v); + _flags &= ~(FLAG_NIL | FLAG_ISDEFAULT); + } + + /** + * Types should return false if they don't treat the given + * whitespace as a default value. + */ + protected boolean is_defaultable_ws(String v) + { + return true; + } + + /** + * Returns the whitespace rule that will be applied before + * building a string to pass to get_text(). + * + * Overridden by subclasses that don't need their text + * for set_text canonicalized; perhaps they already implement + * scanners that can deal with whitespace, and they know + * they have no regex pattern restrictions. + */ + protected int get_wscanon_rule() + { + return SchemaType.WS_COLLAPSE; + } + + /** + * Called to canonicalize whitespace before calling set_text. + * + * Tries to avoid allocation when the string is already canonical, but + * otherwise this is not particularly efficient. Hopefully the common + * case is that we pass our wscanon rule to the store via fetch_text + * and it's canonicalized before we even see it as a string. + */ + private final String apply_wscanon(String v) + { + return XmlWhitespace.collapse(v, get_wscanon_rule()); + } + + /** + * Called before every set and get, to ensure that we have + * a correct picture of whether we're nillable, fixed, or + * if we have a default that can be applied. + */ + private final void check_element_dated() + { + if ((_flags & FLAG_ELEMENT_DATED) != 0 && + (_flags & FLAG_NOT_VARIABLE) == 0) + { + if ((_flags & FLAG_ORPHANED) != 0) + throw new XmlValueDisconnectedException(); + + int eltflags = get_store().compute_flags(); + // int eltflags = 0; + _flags &= ~(FLAGS_ELEMENT | FLAG_ELEMENT_DATED); + _flags |= eltflags; + } + if ((_flags & FLAG_NOT_VARIABLE) != 0) + _flags &= ~(FLAG_ELEMENT_DATED); + } + + /** + * Describes the orphaned status of this object. + */ + protected final boolean is_orphaned() + { + return (_flags & FLAG_ORPHANED) != 0; + } + + /** + * Called before every getter and setter on the strongly + * typed classes to ensure that the object has not been + * orphaned. + */ + protected final void check_orphaned() + { + if (is_orphaned()) + throw new XmlValueDisconnectedException(); + } + + /** + * Called prior to every get operation, to ensure + * that the value being read is valid. If the value + * has been invalidated, it is re-read from the underlying + * text store, and this may cause an out of range exception. + * + * This method deals with nils, nillability, defaults, etc. + */ + public final void check_dated() + { + if ((_flags & FLAGS_DATED) != 0) + { + if ((_flags & FLAG_ORPHANED) != 0) + throw new XmlValueDisconnectedException(); + + assert((_flags & FLAG_STORE) != 0); + + check_element_dated(); + + if ((_flags & FLAG_ELEMENT_DATED) != 0) + { + int eltflags = get_store().compute_flags(); + _flags &= ~(FLAGS_ELEMENT | FLAG_ELEMENT_DATED); + _flags |= eltflags; + } + + boolean nilled = false; + + if ((_flags & FLAG_NIL_DATED) != 0) + { + if (get_store().find_nil()) + { + if ((_flags & FLAG_NILLABLE) == 0 && + (_flags & FLAG_VALIDATE_ON_SET) != 0) + throw new XmlValueOutOfRangeException(); // nil not allowed + + // let the implementation know that we're nil now + set_nil(); + + _flags |= FLAG_NIL; + nilled = true; + } + else + { + _flags &= ~FLAG_NIL; + } + _flags &= ~FLAG_NIL_DATED; + } + + if (!nilled) + { + String text; + + if ((_flags & FLAG_COMPLEXCONTENT) != 0 || (text = get_wscanon_text()) == null) + update_from_complex_content(); + else + { + NamespaceContext.push(new NamespaceContext(get_store())); + try { update_from_wscanon_text(text); } + finally { NamespaceContext.pop(); } + } + } + + _flags &= ~FLAG_VALUE_DATED; + } + } + + /** + * Called before every set operation (except for the + * special case of setting a string) to: + * (1) get the nillable, fixed, etc flags + * (2) throw an exception if it's fixed (not for strings) + */ + private final void set_prepare() + { + check_element_dated(); + if ((_flags & FLAG_IMMUTABLE) != 0) + throw new IllegalStateException(); + } + + /** + * Called after every set operation to invalidate + * the attached raw text. Also, if we were dated, + * we make a note that we're now current, since the + * latest set beats the previous invalidate. Also, + * if we were nil, we're no longer. + */ + private final void set_commit() + { + boolean wasNilled = ((_flags & FLAG_NIL) != 0); + _flags &= ~(FLAG_NIL | FLAG_ISDEFAULT); + + if ((_flags & FLAG_STORE) != 0) + { + _flags &= ~(FLAGS_DATED); + get_store().invalidate_text(); + if (wasNilled) + get_store().invalidate_nil(); + } + else + { + _textsource = null; + } + } + + /** + * Grabs the undelying litral representation, applying the + * implementation's wscanon rule. + * Null if not simple content. + */ + public final String get_wscanon_text() + { + if ((_flags & FLAG_STORE) == 0) + { + return apply_wscanon((String)_textsource); + } + else return get_store().fetch_text(get_wscanon_rule()); + } + + /** + * This should set the value of the type from text, + * or throw an XmlValueOutOfRangeException if it can't. + */ + abstract protected void set_text(String text); + + /** + * This should clear the value, and set it to whatever + * is supposed to be returned when the value is nilled. + */ + abstract protected void set_nil(); + + /** + * This should return the canonical string value of the primitive. + * Only called when non-nil. + */ + abstract protected String compute_text(NamespaceManager nsm); + + // SIMPLE VALUE ACCESSORS BELOW ------------------------------------------- + + // numerics: fractional + public float getFloatValue() + { BigDecimal bd = getBigDecimalValue(); return bd == null ? 0.0f : bd.floatValue(); } + public double getDoubleValue() + { BigDecimal bd = getBigDecimalValue(); return bd == null ? 0.0 : bd.doubleValue(); } + public BigDecimal getBigDecimalValue() + { throw new XmlValueNotSupportedException(XmlErrorCodes.EXCEPTION_VALUE_NOT_SUPPORTED_S2J, + new Object[] {getPrimitiveTypeName(), "numeric"}); } + + // numerics: integral + public BigInteger getBigIntegerValue() + { BigDecimal bd = bigDecimalValue(); return bd == null ? null : bd.toBigInteger(); } + + public byte getByteValue() + { + long l = getIntValue(); + if (l > Byte.MAX_VALUE) throw new XmlValueOutOfRangeException(); + if (l < Byte.MIN_VALUE) throw new XmlValueOutOfRangeException(); + return (byte)l; + } + + public short getShortValue() + { + long l = getIntValue(); + if (l > Short.MAX_VALUE) throw new XmlValueOutOfRangeException(); + if (l < Short.MIN_VALUE) throw new XmlValueOutOfRangeException(); + return (short)l; + } + + public int getIntValue() + { + long l = getLongValue(); + if (l > Integer.MAX_VALUE) throw new XmlValueOutOfRangeException(); + if (l < Integer.MIN_VALUE) throw new XmlValueOutOfRangeException(); + return (int)l; + } + private static final BigInteger _max = BigInteger.valueOf(Long.MAX_VALUE); + private static final BigInteger _min = BigInteger.valueOf(Long.MIN_VALUE); + + public long getLongValue() + { + BigInteger b = getBigIntegerValue(); + if (b == null) return 0L; + if (b.compareTo(_max) >= 0) throw new XmlValueOutOfRangeException(); + if (b.compareTo(_min) <= 0) throw new XmlValueOutOfRangeException(); + return b.longValue(); + } + + private static final XmlOptions _toStringOptions = + buildInnerPrettyOptions(); + + static final XmlOptions buildInnerPrettyOptions() + { + XmlOptions options = new XmlOptions(); + options.put( XmlOptions.SAVE_INNER ); + options.put( XmlOptions.SAVE_PRETTY_PRINT ); + options.put( XmlOptions.SAVE_AGGRESSIVE_NAMESPACES ); + options.put( XmlOptions.SAVE_USE_DEFAULT_NAMESPACE ); + return options; + } + + /* + private static final void dumpStack ( String msg ) + { + try + { + java.io.FileOutputStream fos = new java.io.FileOutputStream( "C:\\ee.txt", true ); + java.io.PrintStream ps = new java.io.PrintStream( fos ); + ps.println( "======================================" ); + ps.println( msg ); + new Exception().printStackTrace( ps ); + ps.close(); + fos.close(); + } + catch ( Exception e ) + { + } + + } + */ + + public final String toString( ) + { + synchronized (monitor()) + { + return ensureStore().xmlText(_toStringOptions); + } + } + + public String xmlText() + { + return xmlText(null); + } + + public String xmlText (XmlOptions options) + { + XmlCursor cur = newCursorForce(); + + try + { + return cur.xmlText(makeInnerOptions(options)); + } + finally + { + cur.dispose(); + } + } + + // enums + public StringEnumAbstractBase getEnumValue() + { throw new XmlValueNotSupportedException(XmlErrorCodes.EXCEPTION_VALUE_NOT_SUPPORTED_S2J, + new Object[] {getPrimitiveTypeName(), "enum"}); } + + // various + public String getStringValue() + { + if (isImmutable()) + { + if ((_flags & FLAG_NIL) != 0) + return null; + return compute_text(null); + } + // Since complex-content types don't have a "natural" string value, we + // emit the deeply concatenated, tag-removed content of the tag. + synchronized (monitor()) + { + if (_isComplexContent()) + return get_store().fetch_text(TypeStore.WS_PRESERVE); + + check_dated(); + if ((_flags & FLAG_NIL) != 0) + return null; + return compute_text(has_store() ? get_store() : null); + } + } + + /** @deprecated replaced with {@link #getStringValue} */ + public String stringValue() + { return getStringValue(); } + /** @deprecated replaced with {@link #getBooleanValue} */ + public boolean booleanValue() + { return getBooleanValue(); } + /** @deprecated replaced with {@link #getByteValue} */ + public byte byteValue() + { return getByteValue(); } + /** @deprecated replaced with {@link #getShortValue} */ + public short shortValue() + { return getShortValue(); } + /** @deprecated replaced with {@link #getIntValue} */ + public int intValue() + { return getIntValue(); } + /** @deprecated replaced with {@link #getLongValue} */ + public long longValue() + { return getLongValue(); } + /** @deprecated replaced with {@link #getBigIntegerValue} */ + public BigInteger bigIntegerValue() + { return getBigIntegerValue(); } + /** @deprecated replaced with {@link #getBigDecimalValue} */ + public BigDecimal bigDecimalValue() + { return getBigDecimalValue(); } + /** @deprecated replaced with {@link #getFloatValue} */ + public float floatValue() + { return getFloatValue(); } + /** @deprecated replaced with {@link #getDoubleValue} */ + public double doubleValue() + { return getDoubleValue(); } + /** @deprecated replaced with {@link #getByteArrayValue} */ + public byte[] byteArrayValue() + { return getByteArrayValue(); } + /** @deprecated replaced with {@link #getEnumValue} */ + public StringEnumAbstractBase enumValue() + { return getEnumValue(); } + /** @deprecated replaced with {@link #getCalendarValue} */ + public Calendar calendarValue() + { return getCalendarValue(); } + /** @deprecated replaced with {@link #getDateValue} */ + public Date dateValue() + { return getDateValue(); } + /** @deprecated replaced with {@link #getGDateValue} */ + public GDate gDateValue() + { return getGDateValue(); } + /** @deprecated replaced with {@link #getGDurationValue} */ + public GDuration gDurationValue() + { return getGDurationValue(); } + /** @deprecated replaced with {@link #getQNameValue} */ + public QName qNameValue() + { return getQNameValue(); } + /** @deprecated replaced with {@link #xgetListValue} */ + public List xlistValue() + { return xgetListValue(); } + /** @deprecated replaced with {@link #getListValue} */ + public List listValue() + { return getListValue(); } + /** @deprecated replaced with {@link #getObjectValue} */ + public Object objectValue() + { return getObjectValue(); } + + /** @deprecated replaced with {@link #setStringValue} */ + public void set(String obj) + { setStringValue(obj); } + /** @deprecated replaced with {@link #setBooleanValue} */ + public void set(boolean v) + { setBooleanValue(v); } + /** @deprecated replaced with {@link #setByteValue} */ + public void set(byte v) + { setByteValue(v); } + /** @deprecated replaced with {@link #setShortValue} */ + public void set(short v) + { setShortValue(v); } + /** @deprecated replaced with {@link #setIntValue} */ + public void set(int v) + { setIntValue(v); } + /** @deprecated replaced with {@link #setLongValue} */ + public void set(long v) + { setLongValue(v); } + /** @deprecated replaced with {@link #setBigIntegerValue} */ + public void set(BigInteger obj) + { setBigIntegerValue(obj); } + /** @deprecated replaced with {@link #setBigDecimalValue} */ + public void set(BigDecimal obj) + { setBigDecimalValue(obj); } + /** @deprecated replaced with {@link #setFloatValue} */ + public void set(float v) + { setFloatValue(v); } + /** @deprecated replaced with {@link #setDoubleValue} */ + public void set(double v) + { setDoubleValue(v); } + /** @deprecated replaced with {@link #setByteArrayValue} */ + public void set(byte[] obj) + { setByteArrayValue(obj); } + /** @deprecated replaced with {@link #setEnumValue} */ + public void set(StringEnumAbstractBase obj) + { setEnumValue(obj); } + /** @deprecated replaced with {@link #setCalendarValue} */ + public void set(Calendar obj) + { setCalendarValue(obj); } + /** @deprecated replaced with {@link #setDateValue} */ + public void set(Date obj) + { setDateValue(obj); } + /** @deprecated replaced with {@link #setGDateValue} */ + public void set(GDateSpecification obj) + { setGDateValue(obj); } + /** @deprecated replaced with {@link #setGDurationValue} */ + public void set(GDurationSpecification obj) + { setGDurationValue(obj); } + /** @deprecated replaced with {@link #setQNameValue} */ + public void set(QName obj) + { setQNameValue(obj); } + /** @deprecated replaced with {@link #setListValue} */ + public void set(List obj) + { setListValue(obj); } + /** @deprecated replaced with {@link #setObjectValue} */ + public void objectSet(Object obj) + { setObjectValue(obj); } + + public byte[] getByteArrayValue() + { throw new XmlValueNotSupportedException(XmlErrorCodes.EXCEPTION_VALUE_NOT_SUPPORTED_S2J, + new Object[] {getPrimitiveTypeName(), "byte[]"}); } + public boolean getBooleanValue() + { throw new XmlValueNotSupportedException(XmlErrorCodes.EXCEPTION_VALUE_NOT_SUPPORTED_S2J, + new Object[] {getPrimitiveTypeName(), "boolean"}); } + public GDate getGDateValue() + { throw new XmlValueNotSupportedException(XmlErrorCodes.EXCEPTION_VALUE_NOT_SUPPORTED_S2J, + new Object[] {getPrimitiveTypeName(), "Date"}); } + public Date getDateValue() + { throw new XmlValueNotSupportedException(XmlErrorCodes.EXCEPTION_VALUE_NOT_SUPPORTED_S2J, + new Object[] {getPrimitiveTypeName(), "Date"}); } + public Calendar getCalendarValue() + { throw new XmlValueNotSupportedException(XmlErrorCodes.EXCEPTION_VALUE_NOT_SUPPORTED_S2J, + new Object[] {getPrimitiveTypeName(), "Calendar"}); } + public GDuration getGDurationValue() + { throw new XmlValueNotSupportedException(XmlErrorCodes.EXCEPTION_VALUE_NOT_SUPPORTED_S2J, + new Object[] {getPrimitiveTypeName(), "Duration"}); } + public QName getQNameValue() + { throw new XmlValueNotSupportedException(XmlErrorCodes.EXCEPTION_VALUE_NOT_SUPPORTED_S2J, + new Object[] {getPrimitiveTypeName(), "QName"}); } + public List getListValue() + { throw new XmlValueNotSupportedException(XmlErrorCodes.EXCEPTION_VALUE_NOT_SUPPORTED_S2J, + new Object[] {getPrimitiveTypeName(), "List"}); } + public List xgetListValue() + { throw new XmlValueNotSupportedException(XmlErrorCodes.EXCEPTION_VALUE_NOT_SUPPORTED_S2J, + new Object[] {getPrimitiveTypeName(), "List"}); } + public Object getObjectValue() + { return java_value(this); } + + // set this value + public final void setBooleanValue(boolean v) + { synchronized (monitor()) { set_prepare(); set_boolean(v); set_commit(); } } + public final void setByteValue(byte v) + { synchronized (monitor()) { set_prepare(); set_byte(v); set_commit(); } } + public final void setShortValue(short v) + { synchronized (monitor()) { set_prepare(); set_short(v); set_commit(); } } + public final void setIntValue(int v) + { synchronized (monitor()) { set_prepare(); set_int(v); set_commit(); } } + public final void setLongValue(long v) + { synchronized (monitor()) { set_prepare(); set_long(v); set_commit(); } } + public final void setFloatValue(float v) + { synchronized (monitor()) { set_prepare(); set_float(v); set_commit(); } } + public final void setDoubleValue(double v) + { synchronized (monitor()) { set_prepare(); set_double(v); set_commit(); } } + public final void setByteArrayValue(byte[] obj) + { if (obj == null) setNil(); else { synchronized (monitor()) { set_prepare(); set_ByteArray(obj); set_commit(); } } } + public final void setEnumValue(StringEnumAbstractBase obj) + { if (obj == null) setNil(); else { synchronized (monitor()) { set_prepare(); set_enum(obj); set_commit(); } } } + public final void setBigIntegerValue(BigInteger obj) + { if (obj == null) setNil(); else { synchronized (monitor()) { set_prepare(); set_BigInteger(obj); set_commit(); } } } + public final void setBigDecimalValue(BigDecimal obj) + { if (obj == null) setNil(); else { synchronized (monitor()) { set_prepare(); set_BigDecimal(obj); set_commit(); } } } + public final void setCalendarValue(Calendar obj) + { if (obj == null) setNil(); else { synchronized (monitor()) { set_prepare(); set_Calendar(obj); set_commit(); } } } + public final void setDateValue(Date obj) + { if (obj == null) setNil(); else { synchronized (monitor()) { set_prepare(); set_Date(obj); set_commit(); } } } + public final void setGDateValue(GDate obj) + { if (obj == null) setNil(); else { synchronized (monitor()) { set_prepare(); set_GDate(obj); set_commit(); } } } + public final void setGDateValue(GDateSpecification obj) + { if (obj == null) setNil(); else { synchronized (monitor()) { set_prepare(); set_GDate(obj); set_commit(); } } } + public final void setGDurationValue(GDuration obj) + { if (obj == null) setNil(); else { synchronized (monitor()) { set_prepare(); set_GDuration(obj); set_commit(); } } } + public final void setGDurationValue(GDurationSpecification obj) + { if (obj == null) setNil(); else { synchronized (monitor()) { set_prepare(); set_GDuration(obj); set_commit(); } } } + public final void setQNameValue(QName obj) + { if (obj == null) setNil(); else { synchronized (monitor()) { set_prepare(); set_QName(obj); set_commit(); } } } + public final void setListValue(List obj) + { if (obj == null) setNil(); else { synchronized (monitor()) { set_prepare(); set_list(obj); set_commit(); } } } + public final void setStringValue(String obj) + { if (obj == null) setNil(); else { synchronized (monitor()) { set_prepare(); set_String(obj); /* strings are special, so set_String does its own commit.*/ } } } + + public void setObjectValue(Object o) + { + if (o == null) + { + setNil(); + return; + } + + if (o instanceof XmlObject) + set( (XmlObject) o ); + else if (o instanceof String) + setStringValue( (String) o ); + else if (o instanceof StringEnumAbstractBase) + setEnumValue( (StringEnumAbstractBase) o ); + else if (o instanceof BigInteger) + setBigIntegerValue( (BigInteger) o ); + else if (o instanceof BigDecimal) + setBigDecimalValue( (BigDecimal) o ); + else if (o instanceof Byte) + setByteValue( ((Byte)o).byteValue() ); + else if (o instanceof Short) + setShortValue( ((Short)o).shortValue() ); + else if (o instanceof Integer) + setIntValue( ((Integer)o).intValue() ); + else if (o instanceof Long) + setLongValue( ((Long)o).longValue() ); + else if (o instanceof Boolean) + setBooleanValue( ((Boolean)o).booleanValue() ); + else if (o instanceof Float) + setFloatValue( ((Float)o).floatValue() ); + else if (o instanceof Double) + setDoubleValue( ((Double)o).doubleValue() ); + else if (o instanceof Calendar) + setCalendarValue( ((Calendar)o) ); + else if (o instanceof Date) + setDateValue( (Date) o ); + else if (o instanceof GDateSpecification) + setGDateValue( (GDateSpecification) o ); + else if (o instanceof GDurationSpecification) + setGDurationValue( (GDurationSpecification) o ); + else if (o instanceof QName) + setQNameValue( (QName) o ); + else if (o instanceof List) + setListValue( (List) o ); + else if (o instanceof byte[]) + setByteArrayValue( (byte[]) o ); + else + { + throw + new XmlValueNotSupportedException( + "Can't set union object of class : " + + o.getClass().getName() ); + } + } + + public final void set_newValue(XmlObject obj) + { + if (obj == null || obj.isNil()) + { + setNil(); + return; + } + + primitive: + if (obj instanceof XmlAnySimpleType) + { + XmlAnySimpleType v = (XmlAnySimpleType)obj; + SchemaType instanceType = ((SimpleValue)v).instanceType(); + assert(instanceType != null) : "Nil case should have been handled already"; + + // handle lists + if (instanceType.getSimpleVariety() == SchemaType.LIST) + { + synchronized (monitor()) + { + set_prepare(); + set_list(((SimpleValue)v).xgetListValue()); + set_commit(); + return; + } + } + + // handle atomic types + synchronized (monitor()) + { + assert(instanceType.getSimpleVariety() == SchemaType.ATOMIC); + switch (instanceType.getPrimitiveType().getBuiltinTypeCode()) + { + default: + assert(false) : "encountered nonprimitive type."; + // case SchemaType.BTC_ANY_SIMPLE: This is handled below... + // but we eventually want to handle it with a treecopy, so + // eventually we should break here. + break primitive; + + case SchemaType.BTC_BOOLEAN: + { + boolean bool = ((SimpleValue)v).getBooleanValue(); + set_prepare(); + set_boolean(bool); + break; + } + case SchemaType.BTC_BASE_64_BINARY: + { + byte[] byteArr = ((SimpleValue)v).getByteArrayValue(); + set_prepare(); + set_b64(byteArr); + break; + } + case SchemaType.BTC_HEX_BINARY: + { + byte[] byteArr = ((SimpleValue)v).getByteArrayValue(); + set_prepare(); + set_hex(byteArr); + break; + } + case SchemaType.BTC_QNAME: + { + QName name = ((SimpleValue)v).getQNameValue(); + set_prepare(); + set_QName(name); + break; + } + case SchemaType.BTC_FLOAT: + { + float f = ((SimpleValue)v).getFloatValue(); + set_prepare(); + set_float(f); + break; + } + case SchemaType.BTC_DOUBLE: + { + double d = ((SimpleValue)v).getDoubleValue(); + set_prepare(); + set_double(d); + break; + } + case SchemaType.BTC_DECIMAL: + { + switch (instanceType.getDecimalSize()) + { + case SchemaType.SIZE_BYTE: + { + byte b = ((SimpleValue)v).getByteValue(); + set_prepare(); + set_byte(b); + break; + } + case SchemaType.SIZE_SHORT: + { + short s = ((SimpleValue)v).getShortValue(); + set_prepare(); + set_short(s); + break; + } + case SchemaType.SIZE_INT: + { + int i = ((SimpleValue)v).getIntValue(); + set_prepare(); + set_int(i); + break; + } + case SchemaType.SIZE_LONG: + { + long l = ((SimpleValue)v).getLongValue(); + set_prepare(); + set_long(l); + break; + } + case SchemaType.SIZE_BIG_INTEGER: + { + BigInteger bi = ((SimpleValue)v).getBigIntegerValue(); + set_prepare(); + set_BigInteger(bi); + break; + } + default: + { + assert(false) : "invalid numeric bit count"; + // fallthrough + } + case SchemaType.SIZE_BIG_DECIMAL: + { + BigDecimal bd = ((SimpleValue)v).getBigDecimalValue(); + set_prepare(); + set_BigDecimal(bd); + break; + } + } + break; + } + case SchemaType.BTC_ANY_URI: + { + String uri = v.getStringValue(); + set_prepare(); + set_text(uri); + break; + } + case SchemaType.BTC_NOTATION: + { + String s = v.getStringValue(); + set_prepare(); + set_notation(s); + break; + } + case SchemaType.BTC_DURATION: + { + GDuration gd = ((SimpleValue)v).getGDurationValue(); + set_prepare(); + set_GDuration(gd); + break; + } + 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: + { + GDate gd = ((SimpleValue)v).getGDateValue(); + set_prepare(); + set_GDate(gd); + break; + } + case SchemaType.BTC_STRING: + { + String s = v.getStringValue(); + set_prepare(); + set_String(s); + break; + } + case SchemaType.BTC_ANY_SIMPLE: + { + boolean pushed = false; + if (!v.isImmutable()) + { + pushed = true; + NamespaceContext.push(new NamespaceContext(v)); + } + try + { + set_prepare(); + set_xmlanysimple(v); + } + finally + { + if (pushed) + NamespaceContext.pop(); + } + break; + } + } + set_commit(); + return; // primitive node tree copy handled. + } + } + + throw new IllegalStateException("Complex type unexpected"); + } + + private TypeStoreUser setterHelper ( XmlObjectBase src ) + { + check_orphaned(); + + src.check_orphaned(); + + return + get_store().copy_contents_from( src.get_store() ). + get_store().change_type( src.schemaType() ); + } + + public final XmlObject set(XmlObject src) + { + if (isImmutable()) + throw new IllegalStateException("Cannot set the value of an immutable XmlObject"); + + XmlObjectBase obj = underlying(src); + + TypeStoreUser newObj = this; + + if (obj == null) + { + setNil(); + return this; + } + + if (obj.isImmutable()) + setStringValue(obj.getStringValue()); + else + { + boolean noSyncThis = preCheck(); + boolean noSyncObj = obj.preCheck(); + + if (monitor() == obj.monitor()) // both are in the same locale + { + if (noSyncThis) // the locale is not sync + newObj = setterHelper( obj ); + else // the locale is sync + { + synchronized (monitor()) { + newObj = setterHelper( obj ); + } + } + } + else // on different locale's + { + if (noSyncThis) + { + if (noSyncObj) // both unsync + { + newObj = setterHelper( obj ); + } + else // only obj is sync + { + synchronized (obj.monitor()) { + newObj = setterHelper( obj ); + } + } + } + else + { + if (noSyncObj) // only this is sync + { + synchronized (monitor()) { + newObj = setterHelper( obj ); + } + } + else // both are sync can't avoid the global lock + { + boolean acquired = false; + + try + { + // about to grab two locks: don't deadlock ourselves + GlobalLock.acquire(); + acquired = true; + + synchronized (monitor()) + { + synchronized (obj.monitor()) + { + GlobalLock.release(); + acquired = false; + + newObj = setterHelper( obj ); + } + } + } + catch (InterruptedException e) + { + throw new XmlRuntimeException(e); + } + finally + { + if (acquired) + GlobalLock.release(); + } + } + } + } + } + + return (XmlObject) newObj; + } + + public final XmlObject generatedSetterHelperImpl(XmlObject src, QName propName, int index, + short kindSetterHelper) + { + + XmlObjectBase srcObj = underlying(src); + + if (srcObj == null) + { + synchronized (monitor()) + { + XmlObjectBase target = getTargetForSetter(propName, index, kindSetterHelper); + target.setNil(); + return target; + } + } + + if (srcObj.isImmutable()) + { + synchronized (monitor()) + { + XmlObjectBase target = getTargetForSetter(propName, index, kindSetterHelper); + target.setStringValue(srcObj.getStringValue()); + return (XmlObject) target; + } + } + + + boolean noSyncThis = preCheck(); + boolean noSyncObj = srcObj.preCheck(); + + if (monitor() == srcObj.monitor()) // both are in the same locale + { + if (noSyncThis) // the locale is not sync + { + return (XmlObject)objSetterHelper(srcObj, propName, index, kindSetterHelper); + } + else // the locale is sync + { + synchronized (monitor()) + { + return (XmlObject)objSetterHelper(srcObj, propName, index, kindSetterHelper); + } + } + } + + // on different locale's + if (noSyncThis) + { + if (noSyncObj) // both unsync + { + return (XmlObject)objSetterHelper(srcObj, propName, index, kindSetterHelper); + } + else // only obj is sync + { + synchronized (srcObj.monitor()) + { + return (XmlObject)objSetterHelper(srcObj, propName, index, kindSetterHelper); + } + } + } + else + { + if (noSyncObj) // only this is sync + { + synchronized (monitor()) + { + return (XmlObject)objSetterHelper(srcObj, propName, index, kindSetterHelper); + } + } + else // both are sync can't avoid the global lock + { + boolean acquired = false; + + try + { + // about to grab two locks: don't deadlock ourselves + GlobalLock.acquire(); + acquired = true; + + synchronized (monitor()) + { + synchronized (srcObj.monitor()) + { + GlobalLock.release(); + acquired = false; + + return (XmlObject)objSetterHelper(srcObj, propName, index, kindSetterHelper); + } + } + } + catch (InterruptedException e) + { + throw new XmlRuntimeException(e); + } + finally + { + if (acquired) + GlobalLock.release(); + } + } + } + } + + private TypeStoreUser objSetterHelper(XmlObjectBase srcObj, QName propName, int index, short kindSetterHelper) + { + XmlObjectBase target = getTargetForSetter(propName, index, kindSetterHelper); + + target.check_orphaned(); + srcObj.check_orphaned(); + + return target.get_store().copy_contents_from( srcObj.get_store() ). + get_store().change_type( srcObj.schemaType() ); + } + + private XmlObjectBase getTargetForSetter(QName propName, int index, short kindSetterHelper) + { + switch (kindSetterHelper) + { + case KIND_SETTERHELPER_SINGLETON: + { + check_orphaned(); + XmlObjectBase target = null; + target = (XmlObjectBase)get_store().find_element_user(propName, index); + if (target == null) + { + target = (XmlObjectBase)get_store().add_element_user(propName); + } + + if (target.isImmutable()) + throw new IllegalStateException("Cannot set the value of an immutable XmlObject"); + + return target; + } + + case KIND_SETTERHELPER_ARRAYITEM: + { + check_orphaned(); + XmlObjectBase target = null; + target = (XmlObjectBase)get_store().find_element_user(propName, index); + if (target == null) + { + throw new IndexOutOfBoundsException(); + } + + if (target.isImmutable()) + throw new IllegalStateException("Cannot set the value of an immutable XmlObject"); + + return target; + } + + default: + throw new IllegalArgumentException("Unknown kindSetterHelper: " + kindSetterHelper); + } + } + + /** + * Same as set() but unsynchronized. + * Warning: Using this method in mutithreaded environment can cause invalid states. + */ + public final XmlObject _set(XmlObject src) + { + if (isImmutable()) + throw new IllegalStateException("Cannot set the value of an immutable XmlObject"); + + XmlObjectBase obj = underlying(src); + + TypeStoreUser newObj = this; + + if (obj == null) + { + setNil(); + return this; + } + + if (obj.isImmutable()) + set(obj.stringValue()); + else + { + check_orphaned(); + obj.check_orphaned(); + + newObj = get_store().copy_contents_from( obj.get_store() ). + get_store().change_type( obj.schemaType() ); + } + return (XmlObject) newObj; + } + + protected void set_list(List list) + { throw new XmlValueNotSupportedException(XmlErrorCodes.EXCEPTION_VALUE_NOT_SUPPORTED_J2S, + new Object[] {"List", getPrimitiveTypeName() }); } + protected void set_boolean(boolean v) + { throw new XmlValueNotSupportedException(XmlErrorCodes.EXCEPTION_VALUE_NOT_SUPPORTED_J2S, + new Object[] {"boolean", getPrimitiveTypeName() }); } + protected void set_byte(byte v) + { set_int((int) v); } + protected void set_short(short v) + { set_int((int) v); } + protected void set_int(int v) + { set_long((long) v); } + protected void set_long(long v) + { set_BigInteger(BigInteger.valueOf(v)); } + protected void set_char(char v) + { set_String(Character.toString(v)); } + protected void set_float(float v) + { set_BigDecimal(new BigDecimal(v)); } + protected void set_double(double v) + { set_BigDecimal(new BigDecimal(v)); } + + protected void set_enum(StringEnumAbstractBase e) + { throw new XmlValueNotSupportedException(XmlErrorCodes.EXCEPTION_VALUE_NOT_SUPPORTED_J2S, + new Object[] {"enum", getPrimitiveTypeName() }); } + + protected void set_ByteArray(byte[] b) + { throw new XmlValueNotSupportedException(XmlErrorCodes.EXCEPTION_VALUE_NOT_SUPPORTED_J2S, + new Object[] {"byte[]", getPrimitiveTypeName() }); } + protected void set_b64(byte[] b) + { set_ByteArray(b); } + protected void set_hex(byte[] b) + { set_ByteArray(b); } + protected void set_BigInteger(BigInteger v) + { set_BigDecimal(new BigDecimal(v)); } + protected void set_BigDecimal(BigDecimal v) + { throw new XmlValueNotSupportedException(XmlErrorCodes.EXCEPTION_VALUE_NOT_SUPPORTED_J2S, + new Object[] {"numeric", getPrimitiveTypeName() }); } + protected void set_Date(Date v) + { throw new XmlValueNotSupportedException(XmlErrorCodes.EXCEPTION_VALUE_NOT_SUPPORTED_J2S, + new Object[] {"Date", getPrimitiveTypeName() }); } + protected void set_Calendar(Calendar v) + { throw new XmlValueNotSupportedException(XmlErrorCodes.EXCEPTION_VALUE_NOT_SUPPORTED_J2S, + new Object[] {"Calendar", getPrimitiveTypeName() }); } + protected void set_GDate(GDateSpecification v) + { throw new XmlValueNotSupportedException(XmlErrorCodes.EXCEPTION_VALUE_NOT_SUPPORTED_J2S, + new Object[] {"Date", getPrimitiveTypeName() }); } + protected void set_GDuration(GDurationSpecification v) + { throw new XmlValueNotSupportedException(XmlErrorCodes.EXCEPTION_VALUE_NOT_SUPPORTED_J2S, + new Object[] {"Duration", getPrimitiveTypeName() }); } + protected void set_ComplexXml(XmlObject v) + { throw new XmlValueNotSupportedException(XmlErrorCodes.EXCEPTION_VALUE_NOT_SUPPORTED_J2S, + new Object[] {"complex content", getPrimitiveTypeName() }); } + protected void set_QName(QName v) + { throw new XmlValueNotSupportedException(XmlErrorCodes.EXCEPTION_VALUE_NOT_SUPPORTED_J2S, + new Object[] {"QName", getPrimitiveTypeName() }); } + + protected void set_notation(String v) + { throw new XmlValueNotSupportedException(); } + + protected void set_xmlanysimple(XmlAnySimpleType v) + { set_String(v.getStringValue()); } + + private final String getPrimitiveTypeName() + { + SchemaType type = schemaType(); + if (type.isNoType()) + return "unknown"; + SchemaType t = type.getPrimitiveType(); + if (t == null) + return "complex"; + else + return t.getName().getLocalPart(); + } + + private final boolean comparable_value_spaces(SchemaType t1, SchemaType t2) + { + assert(t1.getSimpleVariety() != SchemaType.UNION && t2.getSimpleVariety() != SchemaType.UNION); + + if (!t1.isSimpleType() && !t2.isSimpleType()) + return (t1.getContentType() == t2.getContentType()); + + if (!t1.isSimpleType() || !t2.isSimpleType()) + return false; + + if (t1.getSimpleVariety() == SchemaType.LIST && t2.getSimpleVariety() == SchemaType.LIST) + return true; + + if (t1.getSimpleVariety() == SchemaType.LIST || t2.getSimpleVariety() == SchemaType.LIST) + return false; + + return (t1.getPrimitiveType().equals(t2.getPrimitiveType())); + } + + private final boolean valueEqualsImpl(XmlObject xmlobj) + { + check_dated(); + + SchemaType typethis = instanceType(); + SchemaType typeother = ((SimpleValue)xmlobj).instanceType(); + + if (typethis == null && typeother == null) // detects nil + return true; + + if (typethis == null || typeother == null) + return false; + + if (!comparable_value_spaces(typethis, typeother)) + return false; + + if (xmlobj.schemaType().getSimpleVariety() == SchemaType.UNION) + return (underlying(xmlobj)).equal_to(this); + + return equal_to(xmlobj); + } + + public final boolean valueEquals(XmlObject xmlobj) + { + boolean acquired = false; + try + { + if (isImmutable()) + { + if (xmlobj.isImmutable()) + { + return valueEqualsImpl(xmlobj); + } + else + { + synchronized (xmlobj.monitor()) + { + return valueEqualsImpl(xmlobj); + } + } + } + else + { + if (xmlobj.isImmutable() || monitor() == xmlobj.monitor()) + { + synchronized (monitor()) + { + return valueEqualsImpl(xmlobj); + } + } + else + { + GlobalLock.acquire(); + acquired = true; + synchronized (monitor()) + { + synchronized (xmlobj.monitor()) + { + GlobalLock.release(); + acquired = false; + return valueEqualsImpl(xmlobj); + } + } + } + } + + } + catch (InterruptedException e) + { + throw new XmlRuntimeException(e); + } + finally + { + if (acquired) + GlobalLock.release(); + } + } + + /** + * Implements Comparable. This compareTo is inconsistent with + * equals unless isImmutable() is true. + */ + public final int compareTo(Object obj) + { + int result = compareValue((XmlObject)obj); // can throw ClassCast + if (result == 2) + throw new ClassCastException(); + return result; + } + + /** + * Allowed to return 2 for incomparable. + */ + private final int compareValueImpl(XmlObject xmlobj) + { + SchemaType type1, type2; + + try + { + type1 = instanceType(); + type2 = ((SimpleValue)xmlobj).instanceType(); + } + catch (XmlValueOutOfRangeException e) + { + return 2; + } + + if (type1 == null && type2 == null) + return 0; + if (type1 == null || type2 == null) + return 2; + + if (!type1.isSimpleType() || type1.isURType()) + return 2; + + if (!type2.isSimpleType() || type2.isURType()) + return 2; + + type1 = type1.getPrimitiveType(); + type2 = type2.getPrimitiveType(); + + // Different value spaces: different + if (type1.getBuiltinTypeCode() != type2.getBuiltinTypeCode()) + return 2; + + // now we'll depend on our impl class to do the work + return compare_to(xmlobj); + } + + public final int compareValue(XmlObject xmlobj) + { + if (xmlobj == null) + return 2; + + boolean acquired = false; + try + { + if (isImmutable()) + { + if (xmlobj.isImmutable()) + { + return compareValueImpl(xmlobj); + } + else + { + synchronized (xmlobj.monitor()) + { + return compareValueImpl(xmlobj); + } + } + } + else + { + if (xmlobj.isImmutable() || monitor() == xmlobj.monitor()) + { + synchronized (monitor()) + { + return compareValueImpl(xmlobj); + } + } + else + { + GlobalLock.acquire(); + acquired = true; + synchronized (monitor()) + { + synchronized (xmlobj.monitor()) + { + GlobalLock.release(); + acquired = false; + return compareValueImpl(xmlobj); + } + } + } + } + + } + catch (InterruptedException e) + { + throw new XmlRuntimeException(e); + } + finally + { + if (acquired) + GlobalLock.release(); + } + } + /** + * This implementation of compare_to is allowed to do two + * unusual things: + * (1) it can assume that the xmlobj passed has a primitive + * type underlying the instance type that matches the + * current instance, and that neither is nil. + * (2) it is allowed to return 2 for "incomparable"; + * it should not throw an exception. + */ + protected int compare_to(XmlObject xmlobj) + { + if (equal_to(xmlobj)) + return 0; + return 2; + } + + protected abstract boolean equal_to(XmlObject xmlobj); + + protected abstract int value_hash_code(); + + public int valueHashCode() + { + synchronized (monitor()) + { + return value_hash_code(); + } + } + + + public boolean isInstanceOf(SchemaType type) + { + SchemaType myType; + + if (type.getSimpleVariety() != SchemaType.UNION) + { + for (myType = instanceType(); myType != null; myType = myType.getBaseType()) + if (type == myType) + return true; + return false; + } + else + { + Set ctypes = new HashSet(Arrays.asList(type.getUnionConstituentTypes())); + for (myType = instanceType(); myType != null; myType = myType.getBaseType()) + if (ctypes.contains(myType)) + return true; + return false; + } + } + + public final boolean equals(Object obj) + { + if (!isImmutable()) + return super.equals(obj); + + if (!(obj instanceof XmlObject)) + return false; + + XmlObject xmlobj = (XmlObject)obj; + if (!xmlobj.isImmutable()) + return false; + + return valueEquals(xmlobj); + } + + public final int hashCode() + { + if (!isImmutable()) + return super.hashCode(); + + synchronized (monitor()) + { + if (isNil()) + return 0; + + return value_hash_code(); + } + } + + private static final XmlObject[] EMPTY_RESULT = new XmlObject[0]; + + /** + * Selects the contents of the children elements with the given name. + */ + public XmlObject[] selectChildren(QName elementName) + { + XmlCursor xc = this.newCursor(); + try + { + if (!xc.isContainer()) + return EMPTY_RESULT; + + List result = new ArrayList(); + + if (xc.toChild(elementName)) + { + // look for elements + do + { + result.add(xc.getObject()); + } + while (xc.toNextSibling(elementName)); + } + if (result.size() == 0) + return EMPTY_RESULT; + else + return (XmlObject[]) result.toArray(EMPTY_RESULT); + } + finally + { + xc.dispose(); + } + } + + /** + * Selects the contents of the children elements with the given name. + */ + public XmlObject[] selectChildren(String elementUri, String elementLocalName) + { + return selectChildren(new QName(elementUri, elementLocalName)); + } + + /** + * Selects the contents of the children elements that are contained in the elementNameSet. + */ + public XmlObject[] selectChildren(QNameSet elementNameSet) + { + if (elementNameSet==null) + throw new IllegalArgumentException(); + + XmlCursor xc = this.newCursor(); + try + { + if (!xc.isContainer()) + return EMPTY_RESULT; + + List result = new ArrayList(); + + if (xc.toFirstChild()) + { + // look for elements + do + { + assert xc.isContainer(); + if (elementNameSet.contains(xc.getName())) + { + result.add(xc.getObject()); + } + } + while (xc.toNextSibling()); + } + if (result.size() == 0) + return EMPTY_RESULT; + else + return (XmlObject[]) result.toArray(EMPTY_RESULT); + } + finally + { + xc.dispose(); + } + } + + /** + * Selects the content of the attribute with the given name. + */ + public XmlObject selectAttribute(QName attributeName) + { + XmlCursor xc = this.newCursor(); + + try + { + if (!xc.isContainer()) + return null; + + if (xc.toFirstAttribute()) + { + //look for attributes + do + { + if (xc.getName().equals(attributeName)) + { + return xc.getObject(); + } + } + while (xc.toNextAttribute()); + } + return null; + } + finally + { + xc.dispose(); + } + } + + /** + * Selects the content of the attribute with the given name. + */ + public XmlObject selectAttribute(String attributeUri, String attributeLocalName) + { + return selectAttribute(new QName(attributeUri, attributeLocalName)); + } + + /** + * Selects the contents of the attributes that are contained in the elementNameSet. + */ + public XmlObject[] selectAttributes(QNameSet attributeNameSet) + { + if (attributeNameSet==null) + throw new IllegalArgumentException(); + + XmlCursor xc = this.newCursor(); + try + { + if (!xc.isContainer()) + return EMPTY_RESULT; + + List result = new ArrayList(); + + if (xc.toFirstAttribute()) + { + //look for attributes + do + { + if (attributeNameSet.contains(xc.getName())) + { + result.add(xc.getObject()); + } + } + while (xc.toNextAttribute()); + } + + if (result.size() == 0) + return EMPTY_RESULT; + else + return (XmlObject[]) result.toArray(EMPTY_RESULT); + } + finally + { + xc.dispose(); + } + } + + /** + * This method can writeReplace either an unwrapped XmlObjectBase + * or an XBean proxy. A "true" argument means unwrapped. + * + * The serialization strategy for XmlObjects is this: + * + * (1) Only the root XmlObject for a document actually gets + * fully serialized; it is serialized as a SerializedRootObject, + * which simply saves itself as XML text. + * + * (2) Interior XmlObjects get serialized as a reference to the + * root XmlObject for their document, plus an integer which + * indicates the position of the XmlObject within the owner + * document. This pair is stored as a SerializedInteriorObject. + * + * Both objects can be maked as wrapped or unwrapped. If wrapped, + * then the proxy is returned when deserializing; if unwrapped, then + * the proxy is stripped when deserializing. + */ + public Object writeReplace() + { + synchronized (monitor()) + { + if (isRootXmlObject()) + return new SerializedRootObject(this); + + return new SerializedInteriorObject(this, getRootXmlObject()); + } + } + + /** + * True if the object is at the root of the document. + */ + private boolean isRootXmlObject() + { + XmlCursor cur = newCursor(); + if (cur == null) + return false; + + boolean result = !cur.toParent(); + cur.dispose(); + return result; + } + + /** + * Gets the root XmlObject for this document. + */ + private XmlObject getRootXmlObject() + { + XmlCursor cur = newCursor(); + if (cur == null) + return this; + cur.toStartDoc(); + XmlObject result = cur.getObject(); + cur.dispose(); + return result; + } + + /** + * Serializable rewrite object that knows how to resolve + * to an XmlObjectBase or a proxy for the root object of + * a document. + */ + private static class SerializedRootObject implements Serializable + { + private static final long serialVersionUID = 1; + + transient Class _xbeanClass; + transient XmlObject _impl; + + private SerializedRootObject() + { + } + + private SerializedRootObject(XmlObject impl) + { + _xbeanClass = impl.schemaType().getJavaClass(); + _impl = impl; + } + + private void writeObject(ObjectOutputStream out) throws IOException + { + out.writeObject(_xbeanClass); + // the first short is written out for backwards compatibility + // it will always be zero for objects written with + // this code, but it used to be the first 2 bytes of the + // writeUTF() method + out.writeShort((short)0); + out.writeShort(MAJOR_VERSION_NUMBER); + out.writeShort(MINOR_VERSION_NUMBER); + // CR122401 - need to use writeObject instead of writeUTF + // for xmlText as writeUTF has a length limitation of + // 65535 bytes + String xmlText = _impl.xmlText(); + out.writeObject(xmlText); + out.writeBoolean(false); + } + + private void readObject(ObjectInputStream in) throws IOException + { + try + { + // read class object first - this is + // first just for historical reasons - really + // it would be better to have the version numbers + // first + _xbeanClass = (Class)in.readObject(); + + int utfBytes = in.readUnsignedShort(); + + // determine version numbers + // if utfBytes is non-zero then we default to 0.0 + // otherwise expect major and minor version numbers + // to be next entries in stream + int majorVersionNum = 0; + int minorVersionNum = 0; + if (utfBytes == 0) + { + majorVersionNum = in.readUnsignedShort(); + minorVersionNum = in.readUnsignedShort(); + } + + String xmlText = null; + switch (majorVersionNum) + { + case 0: // original, unnumbered version + // minorVersionNum is always zero + xmlText = readObjectV0(in, utfBytes); + in.readBoolean(); // ignored + break; + + case 1: + switch (minorVersionNum) + { + case 1: + xmlText = (String)in.readObject(); + in.readBoolean(); // ignored + break; + + default: + throw new IOException("Deserialization error: " + + "version number " + majorVersionNum + "." + + minorVersionNum + " not supported."); + } + break; + + default: + throw new IOException("Deserialization error: " + + "version number " + majorVersionNum + "." + + minorVersionNum + " not supported."); + } + + XmlOptions opts = new XmlOptions().setDocumentType(XmlBeans.typeForClass(_xbeanClass)); + _impl = XmlBeans.getContextTypeLoader().parse(xmlText, null, opts); + } + catch (Exception e) + { + throw (IOException)(new IOException(e.getMessage()).initCause(e)); + } + } + + // this method is for reading the UTF-8 String that used to be + // written out for a serialized XmlObject according to the + // original format before this fix, i.e. it expects it + // to have been written using the following algorithm: + // + // writeObject(Class object) + // writeUTF(xmlText of object as String) + // writeBoolean() + // + // this method is passed the original input stream positioned as though + // it had just read the class object plus the next 2 bytes. Those 2 + // bytes are interpreted as an unsigned short saying how many more + // bytes there are representing the bytes of the UTF-8-formatted String; + // this value is passed in as the argument utfBytes + private String readObjectV0(ObjectInputStream in, int utfBytes) + throws IOException + { + // allow an extra 2 bytes up front for the unsigned short + byte[] bArray = new byte[utfBytes+2]; + + // for format of these first 2 bytes see + // Java API docs - DataOutputStream.writeShort() + bArray[0] = (byte)( 0xff & (utfBytes >> 8) ); + bArray[1] = (byte)( 0xff & utfBytes ); + + // read the next numBytes bytes from the input stream + // into the byte array starting at offset 2; this may + // take multiple calls to read() + int totalBytesRead = 0; + int numRead; + while (totalBytesRead < utfBytes) + { + numRead = + in.read(bArray, 2+totalBytesRead, utfBytes-totalBytesRead); + if (numRead == -1) // reached end of stream + break; + + totalBytesRead += numRead; + } + + if (totalBytesRead != utfBytes) + { + throw new IOException("Error reading backwards compatible " + + "XmlObject: number of bytes read (" + totalBytesRead + + ") != number expected (" + utfBytes + ")" ); + } + + // now set up a DataInputStream to read those + // bytes as a UTF-8 String i.e. as though we'd never + // read the first 2 bytes from the original stream + DataInputStream dis = null; + String str = null; + try + { + dis = new DataInputStream(new ByteArrayInputStream(bArray)); + str = dis.readUTF(); + } + finally + { + if (dis != null) + dis.close(); + } + + return str; + } + + private Object readResolve() throws ObjectStreamException + { + return _impl; + } + } + + /** + * Serializable rewrite object that knows how to resolve + * to an XmlObjectBase or a proxy for an interior position + * within a document. + */ + private static class SerializedInteriorObject implements Serializable + { + private static final long serialVersionUID = 1; + + transient XmlObject _impl; + transient XmlObject _root; + + private SerializedInteriorObject() + { + } + + private SerializedInteriorObject(XmlObject impl, XmlObject root) + { + _impl = impl; + _root = root; + } + + private void writeObject(ObjectOutputStream out) throws IOException + { + out.writeObject(_root); + out.writeBoolean(false); + out.writeInt(distanceToRoot()); + } + + private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException + { + _root = (XmlObject)in.readObject(); + in.readBoolean(); + _impl = objectAtDistance(in.readInt()); + } + + private Object readResolve() throws ObjectStreamException + { + return _impl; + } + + private int distanceToRoot() + { + XmlCursor cur = _impl.newCursor(); + int count = 0; + while (!cur.toPrevToken().isNone()) + { + if (!cur.currentTokenType().isNamespace()) + { + count += 1; + // System.out.println("Count: " + count + " " + cur.currentTokenType().toString() + " " + QName.pretty(cur.getName())); + } + } + cur.dispose(); + return count; + } + + private XmlObject objectAtDistance(int count) + { + XmlCursor cur = _root.newCursor(); + while (count > 0) + { + cur.toNextToken(); + if (!cur.currentTokenType().isNamespace()) + { + count -= 1; + // System.out.println("Count: " + count + " " + cur.currentTokenType().toString() + " " + QName.pretty(cur.getName())); + } + } + XmlObject result = cur.getObject(); + cur.dispose(); + return result; + } + } + + protected static Object java_value(XmlObject obj) + { + if (obj.isNil()) + return null; + + if (!(obj instanceof XmlAnySimpleType)) + return obj; + + SchemaType instanceType = ((SimpleValue)obj).instanceType(); + assert(instanceType != null) : "Nil case should have been handled above"; + + // handle lists + if (instanceType.getSimpleVariety() == SchemaType.LIST) + return ((SimpleValue)obj).getListValue(); + + SimpleValue base = (SimpleValue)obj; + + switch (instanceType.getPrimitiveType().getBuiltinTypeCode()) + { + case SchemaType.BTC_BOOLEAN: + return base.getBooleanValue() ? Boolean.TRUE : Boolean.FALSE; + + case SchemaType.BTC_BASE_64_BINARY: + case SchemaType.BTC_HEX_BINARY: + return base.getByteArrayValue(); + + case SchemaType.BTC_QNAME: + return base.getQNameValue(); + + case SchemaType.BTC_FLOAT: + return new Float(base.getFloatValue()); + + case SchemaType.BTC_DOUBLE: + return new Double(base.getDoubleValue()); + + case SchemaType.BTC_DECIMAL: + { + switch (instanceType.getDecimalSize()) + { + case SchemaType.SIZE_BYTE: + return new Byte(base.getByteValue()); + + case SchemaType.SIZE_SHORT: + return new Short(base.getShortValue()); + + case SchemaType.SIZE_INT: + return new Integer(base.getIntValue()); + + case SchemaType.SIZE_LONG: + return new Long(base.getLongValue()); + + case SchemaType.SIZE_BIG_INTEGER: + return base.getBigIntegerValue(); + + default: + assert(false) : "invalid numeric bit count"; + // fallthrough + case SchemaType.SIZE_BIG_DECIMAL: + return base.getBigDecimalValue(); + } + } + case SchemaType.BTC_ANY_URI: + return base.getStringValue(); + + case SchemaType.BTC_DURATION: + return base.getGDurationValue(); + + 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: + return base.getCalendarValue(); + + default: + assert(false) : "encountered nonprimitive type."; + // fallthrough + + // NB: for string enums we just do java.lang.String + // when in the context of unions. It's easier on users. + case SchemaType.BTC_NOTATION: + case SchemaType.BTC_STRING: + case SchemaType.BTC_ANY_SIMPLE: + // return base.getStringValue(); + return base.getStringValue(); + } + } + + /** + * Called by code generated code to get the default attribute value + * for a given attribute name, or null if none. + */ + protected XmlAnySimpleType get_default_attribute_value(QName name) + { + SchemaType sType = schemaType(); + SchemaAttributeModel aModel = sType.getAttributeModel(); + if (aModel == null) + return null; + SchemaLocalAttribute sAttr = aModel.getAttribute(name); + if (sAttr == null) + return null; + return sAttr.getDefaultValue(); + } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlPositiveIntegerImpl.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlPositiveIntegerImpl.java new file mode 100644 index 000000000..08b7f35e7 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlPositiveIntegerImpl.java @@ -0,0 +1,27 @@ +/* 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.values; + +import org.apache.xmlbeans.XmlPositiveInteger; +import org.apache.xmlbeans.SchemaType; + +public class XmlPositiveIntegerImpl extends JavaIntegerHolderEx implements XmlPositiveInteger +{ + public XmlPositiveIntegerImpl() + { super(XmlPositiveInteger.type, false); } + public XmlPositiveIntegerImpl(SchemaType type, boolean complex) + { super(type, complex); } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlQNameImpl.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlQNameImpl.java new file mode 100644 index 000000000..95062eba7 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlQNameImpl.java @@ -0,0 +1,23 @@ +/* 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.values; + +import org.apache.xmlbeans.XmlQName; + + +public class XmlQNameImpl extends JavaQNameHolder implements XmlQName +{ +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlQNameRestriction.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlQNameRestriction.java new file mode 100644 index 000000000..34250e585 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlQNameRestriction.java @@ -0,0 +1,25 @@ +/* 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.values; + +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.XmlQName; + +public class XmlQNameRestriction extends JavaQNameHolderEx implements XmlQName +{ + public XmlQNameRestriction(SchemaType type, boolean complex) + { super(type, complex); } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlShortImpl.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlShortImpl.java new file mode 100644 index 000000000..1fa2b7f8f --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlShortImpl.java @@ -0,0 +1,28 @@ +/* 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.values; + +import org.apache.xmlbeans.XmlShort; +import org.apache.xmlbeans.SchemaType; + + +public class XmlShortImpl extends JavaIntHolderEx implements XmlShort +{ + public XmlShortImpl() + { super(XmlShort.type, false); } + public XmlShortImpl(SchemaType type, boolean complex) + { super(type, complex); } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlStringEnumeration.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlStringEnumeration.java new file mode 100644 index 000000000..b576a98b6 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlStringEnumeration.java @@ -0,0 +1,25 @@ +/* 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.values; + +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.XmlString; + +public class XmlStringEnumeration extends JavaStringEnumerationHolderEx implements XmlString +{ + public XmlStringEnumeration(SchemaType type, boolean complex) + { super(type, complex); } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlStringImpl.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlStringImpl.java new file mode 100644 index 000000000..ac0a78202 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlStringImpl.java @@ -0,0 +1,23 @@ +/* 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.values; + +import org.apache.xmlbeans.XmlString; + + +public class XmlStringImpl extends JavaStringHolder implements XmlString +{ +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlStringRestriction.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlStringRestriction.java new file mode 100644 index 000000000..e54f670d1 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlStringRestriction.java @@ -0,0 +1,25 @@ +/* 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.values; + +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.XmlString; + +public class XmlStringRestriction extends JavaStringHolderEx implements XmlString +{ + public XmlStringRestriction(SchemaType type, boolean complex) + { super(type, complex); } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlTimeImpl.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlTimeImpl.java new file mode 100644 index 000000000..b11c3da95 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlTimeImpl.java @@ -0,0 +1,28 @@ +/* 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.values; + +import org.apache.xmlbeans.XmlTime; +import org.apache.xmlbeans.SchemaType; + + +public class XmlTimeImpl extends JavaGDateHolderEx implements XmlTime +{ + public XmlTimeImpl() + { super(XmlTime.type, false); } + public XmlTimeImpl(SchemaType type, boolean complex) + { super(type, complex); } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlTokenImpl.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlTokenImpl.java new file mode 100644 index 000000000..d6e78c8aa --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlTokenImpl.java @@ -0,0 +1,28 @@ +/* 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.values; + +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.XmlToken; + + +public class XmlTokenImpl extends JavaStringHolderEx implements XmlToken +{ + public XmlTokenImpl() + { super(XmlToken.type, false); } + public XmlTokenImpl(SchemaType type, boolean complex) + { super(type, complex); } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlUnionImpl.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlUnionImpl.java new file mode 100644 index 000000000..cfde14bed --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlUnionImpl.java @@ -0,0 +1,665 @@ +/* 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.values; + +import java.util.Date; +import java.util.List; +import java.util.Calendar; +import java.math.BigInteger; +import java.math.BigDecimal; + +import org.apache.xmlbeans.GDate; +import org.apache.xmlbeans.GDuration; +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.XmlAnySimpleType; +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.XmlErrorCodes; +import org.apache.xmlbeans.StringEnumAbstractBase; +import org.apache.xmlbeans.GDateSpecification; +import org.apache.xmlbeans.GDurationSpecification; +import org.apache.xmlbeans.SimpleValue; + +import org.apache.xmlbeans.impl.schema.SchemaTypeImpl; +import org.apache.xmlbeans.impl.common.ValidationContext; +import org.apache.xmlbeans.impl.common.QNameHelper; + +import javax.xml.namespace.QName; + + +/** + * This class implements simple union types. + * + */ +public class XmlUnionImpl extends XmlObjectBase implements XmlAnySimpleType +{ + public XmlUnionImpl(SchemaType type, boolean complex) + { _schemaType = type; initComplexType(complex, false); } + + public SchemaType schemaType() + { return _schemaType; } + + public SchemaType instanceType() + { check_dated(); return _value == null ? null : ((SimpleValue)_value).instanceType(); } + + private SchemaType _schemaType; + private XmlAnySimpleType _value; // underlying value + private String _textvalue = ""; // textual value + + + + + // SIMPLE VALUE ACCESSORS BELOW ------------------------------------------- + // gets raw text value + + protected String compute_text(NamespaceManager nsm) + { return _textvalue; } + + protected boolean is_defaultable_ws(String v) { + try { + XmlAnySimpleType savedValue = _value; + set_text(v); + + // restore the saved value + _value = savedValue; + + return false; + } + catch (XmlValueOutOfRangeException e) { + return true; + } + } + + protected void set_text(String s) + { + // first check against any patterns... + if (!_schemaType.matchPatternFacet(s) && _validateOnSet()) + throw new XmlValueOutOfRangeException(XmlErrorCodes.DATATYPE_VALID$PATTERN_VALID, + new Object[] { "string", s, QNameHelper.readable(_schemaType) }); + + + // save state for rollback + String original = _textvalue; + _textvalue = s; + + // iterate through the types, trying to create a type + SchemaType[] members = _schemaType.getUnionConstituentTypes(); + assert(members != null); + + boolean pushed = false; + // boolean wasstrict = set_strict(true); // tell types to complain ferverently about errors + if (has_store()) + { + NamespaceContext.push(new NamespaceContext(get_store())); + pushed = true; + } + try + { + for (boolean validate = true; validate || !_validateOnSet(); validate = false) + { + for (int i = 0; i < members.length; i++) + { + // From the point of view of the following call, "this" is a generic + // XmlAnySimpleType implementation, for which only getText can be called. + // (Note that "this" is not wrapped in the proxy object.) + try + { + XmlAnySimpleType newval = ((SchemaTypeImpl)members[i]).newValue(s, validate); + + // now we need to check against (enuemration) restrictions + if (!check(newval, _schemaType)) + continue; + + // found one that works! + _value = newval; + return; + } + catch (XmlValueOutOfRangeException e) + { + continue; + } + catch (Exception e) + { + throw new RuntimeException("Troublesome union exception caused by unexpected " + e, e); + // assert(false) : "Unexpected " + e; + // continue; + } + } + if (!validate) + break; + } + } + finally + { + if (pushed) + NamespaceContext.pop(); + // set_strict(wasstrict); + } + + + // doesn't match any of the members; rollback and throw + _textvalue = original; + throw new XmlValueOutOfRangeException(XmlErrorCodes.DATATYPE_VALID$UNION, + new Object[] { s, QNameHelper.readable(_schemaType) }); + } + + protected void set_nil() + { + _value = null; + _textvalue = null; + } + + protected int get_wscanon_rule() { return SchemaType.WS_PRESERVE; } + + + // numerics + public float getFloatValue() + { check_dated(); return _value == null ? 0.0f : ((SimpleValue)_value).getFloatValue(); } + + public double getDoubleValue() + { check_dated(); return _value == null ? 0.0 : ((SimpleValue)_value).getDoubleValue(); } + + public BigDecimal getBigDecimalValue() + { check_dated(); return _value == null ? null : ((SimpleValue)_value).getBigDecimalValue(); } + + public BigInteger getBigIntegerValue() + { check_dated(); return _value == null ? null : ((SimpleValue)_value).getBigIntegerValue(); } + + public byte getByteValue() + { check_dated(); return _value == null ? 0 : ((SimpleValue)_value).getByteValue(); } + + public short getShortValue() + { check_dated(); return _value == null ? 0 : ((SimpleValue)_value).getShortValue(); } + + public int getIntValue() + { check_dated(); return _value == null ? 0 : ((SimpleValue)_value).getIntValue(); } + + public long getLongValue() + { check_dated(); return _value == null ? 0 : ((SimpleValue)_value).getLongValue(); } + + + // various + public byte[] getByteArrayValue() + { check_dated(); return _value == null ? null : ((SimpleValue)_value).getByteArrayValue(); } + + public boolean getBooleanValue() + { check_dated(); return _value == null ? false : ((SimpleValue)_value).getBooleanValue(); } + + public Calendar getCalendarValue() + { check_dated(); return _value == null ? null : ((SimpleValue)_value).getCalendarValue(); } + + public Date getDateValue() + { check_dated(); return _value == null ? null : ((SimpleValue)_value).getDateValue(); } + + public GDate getGDateValue() + { check_dated(); return _value == null ? null : ((SimpleValue)_value).getGDateValue(); } + + public GDuration getGDurationValue() + { check_dated(); return _value == null ? null : ((SimpleValue)_value).getGDurationValue(); } + + public QName getQNameValue() + { check_dated(); return _value == null ? null : ((SimpleValue)_value).getQNameValue(); } + + public List getListValue() + { check_dated(); return _value == null ? null : ((SimpleValue)_value).getListValue(); } + + public List xgetListValue() + { check_dated(); return _value == null ? null : ((SimpleValue)_value).xgetListValue(); } + + public StringEnumAbstractBase getEnumValue() + { check_dated(); return _value == null ? null : ((SimpleValue)_value).getEnumValue(); } + + public String getStringValue() + { check_dated(); return _value == null ? null : _value.getStringValue(); } + + /** + * Returns true if the space of canonical lexical forms + * of the first (source) type overlaps with the full lexical space + * of the second (target) type. Both types must be primitives. + */ + static boolean lexical_overlap(int source, int target) + { + // types are the same + if (source == target) + return true; + + // one of the types has the full lexical space + if (source == SchemaType.BTC_ANY_SIMPLE || + target == SchemaType.BTC_ANY_SIMPLE || + source == SchemaType.BTC_STRING || + target == SchemaType.BTC_STRING || + source == SchemaType.BTC_ANY_URI || + target == SchemaType.BTC_ANY_URI) + return true; + + switch (source) + { + case SchemaType.BTC_BOOLEAN: switch(target) + { + case SchemaType.BTC_QNAME: // "true" is valid NcName and therefore QName + case SchemaType.BTC_NOTATION: // "true" is valid NCName + return true; + default: + return false; + } + case SchemaType.BTC_BASE_64_BINARY: switch(target) + { + case SchemaType.BTC_BOOLEAN: // "0" is valid boolean + case SchemaType.BTC_HEX_BINARY: // "0" is valid hex + case SchemaType.BTC_QNAME: // "a" is valid NcName and therefore QName + case SchemaType.BTC_NOTATION: // "a" is valid NcName + case SchemaType.BTC_FLOAT: // "0" is valid float + case SchemaType.BTC_DOUBLE: // "0" is valid double + case SchemaType.BTC_DECIMAL: // "0" is valid decimal + case SchemaType.BTC_DURATION: // "P1Y2M3DT10H30M" is both b64 and duration + case SchemaType.BTC_G_YEAR: // "1999" is valid year + return true; + default: + return false; // "-" and ":" cannot come from b64 + } + case SchemaType.BTC_HEX_BINARY: switch(target) + { + case SchemaType.BTC_BOOLEAN: // "0" is valid boolean + case SchemaType.BTC_BASE_64_BINARY: // "0" is valid b64 + case SchemaType.BTC_QNAME: // "A" is valid NcName and therefore QName + case SchemaType.BTC_NOTATION: // "A" is valid NcName + case SchemaType.BTC_FLOAT: // "0" is valid float + case SchemaType.BTC_DOUBLE: // "0" is valid double + case SchemaType.BTC_DECIMAL: // "0" is valid decimal + case SchemaType.BTC_G_YEAR: // "1999" is valid year + return true; + default: + return false; // "-" and ":" cannot come from b64 + } + case SchemaType.BTC_QNAME: + case SchemaType.BTC_NOTATION: switch(target) + { + case SchemaType.BTC_BOOLEAN: // "true" is valid boolean + case SchemaType.BTC_BASE_64_BINARY: // "a" is valid b64 + case SchemaType.BTC_HEX_BINARY: // "a" is valid hex + case SchemaType.BTC_QNAME: // "A" is valid NcName and therefore QName + case SchemaType.BTC_NOTATION: // "A" is valid NcName and therefore QName + case SchemaType.BTC_DURATION: // "P1Y2M3DT10H30M" is both NcName and duration + return true; + default: + return false; + } + case SchemaType.BTC_FLOAT: + case SchemaType.BTC_DOUBLE: + case SchemaType.BTC_DECIMAL: + case SchemaType.BTC_G_YEAR: switch(target) + { + case SchemaType.BTC_BASE_64_BINARY: // "0" is valid b64 + case SchemaType.BTC_HEX_BINARY: // "0" is valid hex + case SchemaType.BTC_FLOAT: // "0" is valid float + case SchemaType.BTC_DOUBLE: // "0" is valid double + case SchemaType.BTC_DECIMAL: // "0" is valid decimal + case SchemaType.BTC_G_YEAR: // "1999" is valid year + return true; + default: + return false; + } + case SchemaType.BTC_DURATION: switch(target) + { + case SchemaType.BTC_QNAME: + case SchemaType.BTC_NOTATION: + case SchemaType.BTC_BASE_64_BINARY: + return true; + default: + return false; + } + case SchemaType.BTC_DATE_TIME: + case SchemaType.BTC_TIME: + case SchemaType.BTC_DATE: + case SchemaType.BTC_G_YEAR_MONTH: + case SchemaType.BTC_G_MONTH_DAY: + case SchemaType.BTC_G_DAY: + case SchemaType.BTC_G_MONTH: + default: + return false; + } + } + + /** + * True if the given schema type's logical type is a match for + * the given category of java concepts. + */ + + private static final int JAVA_NUMBER = SchemaType.BTC_LAST_BUILTIN + 1; + private static final int JAVA_DATE = SchemaType.BTC_LAST_BUILTIN + 2; + private static final int JAVA_CALENDAR = SchemaType.BTC_LAST_BUILTIN + 3; + private static final int JAVA_BYTEARRAY = SchemaType.BTC_LAST_BUILTIN + 4; + private static final int JAVA_LIST = SchemaType.BTC_LAST_BUILTIN + 5; + + private static boolean logical_overlap(SchemaType type, int javacode) + { + // non-union types because it's being applied on irreducible union members! + assert(type.getSimpleVariety() != SchemaType.UNION); + + if (javacode <= SchemaType.BTC_LAST_BUILTIN) + { + if (type.getSimpleVariety() != SchemaType.ATOMIC) + return false; + + return (type.getPrimitiveType().getBuiltinTypeCode() == javacode); + } + + switch (javacode) + { + case JAVA_NUMBER: + { + if (type.getSimpleVariety() != SchemaType.ATOMIC) + return false; + + switch (type.getPrimitiveType().getBuiltinTypeCode()) + { + case SchemaType.BTC_FLOAT: + case SchemaType.BTC_DOUBLE: + case SchemaType.BTC_DECIMAL: + case SchemaType.BTC_G_YEAR: + case SchemaType.BTC_G_MONTH: + case SchemaType.BTC_G_DAY: + return true; + } + return false; + } + case JAVA_DATE: + { + if (type.getSimpleVariety() != SchemaType.ATOMIC) + return false; + + switch (type.getPrimitiveType().getBuiltinTypeCode()) + { + case SchemaType.BTC_DATE_TIME: + case SchemaType.BTC_DATE: + return true; + } + return false; + } + case JAVA_CALENDAR: + { + if (type.getSimpleVariety() != SchemaType.ATOMIC) + return false; + + switch (type.getPrimitiveType().getBuiltinTypeCode()) + { + case SchemaType.BTC_DATE_TIME: + case SchemaType.BTC_DATE: + case SchemaType.BTC_TIME: + case SchemaType.BTC_G_YEAR_MONTH: + case SchemaType.BTC_G_MONTH_DAY: + case SchemaType.BTC_G_YEAR: + case SchemaType.BTC_G_MONTH: + case SchemaType.BTC_G_DAY: + return true; + } + return false; + } + + case JAVA_BYTEARRAY: + { + if (type.getSimpleVariety() != SchemaType.ATOMIC) + return false; + + switch (type.getPrimitiveType().getBuiltinTypeCode()) + { + case SchemaType.BTC_BASE_64_BINARY: + case SchemaType.BTC_HEX_BINARY: + return true; + } + return false; + } + case JAVA_LIST: + { + return (type.getSimpleVariety() == SchemaType.LIST); + } + } + + assert(false) : "missing case"; + return false; + } + + /** + * Grabs a chained value of type st, creating and attaching + * one if not present. + */ + private void set_primitive(int typecode, Object val) + { + SchemaType[] members = _schemaType.getUnionConstituentTypes(); + assert(members != null); + + boolean pushed = false; + if (has_store()) + { + NamespaceContext.push(new NamespaceContext(get_store())); + pushed = true; + } + try + { + for (boolean validate = true; validate || !_validateOnSet(); validate = false) + { + outer: for (int i = 0; i < members.length; i++) + { + // candidates must be a logical match for the desired typecode + if (logical_overlap(members[i], typecode)) + { + XmlAnySimpleType newval; + + try + { + newval = ((SchemaTypeImpl) members[i]).newValue(val, validate); + } + catch (XmlValueOutOfRangeException e) + { + // doesn't match this type even though logical categories + // line up (probably because of restriciton); try the next type. + continue outer; + } + catch (Exception e) + { + assert(false) : "Unexpected " + e; + continue outer; + } + + /* TODO: rethink this - disabling for now. + + // OK, now we've got a newval... We have to verify + // that lexically it doesn't overlap with previous types + + String newvaltext = null; + + inner: for (int j = 0; j < i; j++) + { + if (members[j].getSimpleVariety() == SchemaType.LIST || + lexical_overlap(members[j].getPrimitiveType().getBuiltinTypeCode(), + newval.schemaType().getPrimitiveType().getBuiltinTypeCode())) + { + // there is a preceding type that may lexically overlap with ours... + // if it lexically contains the string representation of our new + // proposed value, then it's impossible for the union to have our + // logical value (because it would have been masked) and throw an + // error. + if (newvaltext == null) + newvaltext = newval.stringValue(); + try + { + // discard return value + members[i].newValue(newvaltext); + + // oh bad, we succeeded. Our instance lexically looks like a + // previous type, and this isn't a valid value. Keep on hunting. + continue outer; + } + catch (XmlValueOutOfRangeException e) + { + // this is good: this error means that our value doesn't look like + // the other type. + continue inner; + } + } + } + + */ + + // No lexical masking: we're OK + _value = newval; + _textvalue = _value.stringValue(); + return; + } + } + if (!validate) + break; + } + } + finally + { + if (pushed) + NamespaceContext.pop(); + } + + // doesn't match any of the members; throw + throw new XmlValueOutOfRangeException(XmlErrorCodes.DATATYPE_VALID$UNION, + new Object[] { val.toString(), QNameHelper.readable(_schemaType) }); + } + + // here are the setters + + protected void set_boolean(boolean v) + { set_primitive(SchemaType.BTC_BOOLEAN, new Boolean(v)); } + + protected void set_byte(byte v) + { set_primitive(JAVA_NUMBER, new Byte(v)); } + protected void set_short(short v) + { set_primitive(JAVA_NUMBER, new Short(v)); } + protected void set_int(int v) + { set_primitive(JAVA_NUMBER, new Integer(v)); } + protected void set_long(long v) + { set_primitive(JAVA_NUMBER, new Long(v)); } + protected void set_float(float v) + { set_primitive(JAVA_NUMBER, new Float(v)); } + protected void set_double(double v) + { set_primitive(JAVA_NUMBER, new Double(v)); } + + protected void set_ByteArray(byte[] b) + { set_primitive(JAVA_BYTEARRAY, b); } + protected void set_hex(byte[] b) + { set_primitive(JAVA_BYTEARRAY, b); } + protected void set_b64(byte[] b) + { set_primitive(JAVA_BYTEARRAY, b); } + protected void set_BigInteger(BigInteger v) + { set_primitive(JAVA_NUMBER, v); } + protected void set_BigDecimal(BigDecimal v) + { set_primitive(JAVA_NUMBER, v); } + protected void set_QName(QName v) + { set_primitive(SchemaType.BTC_QNAME, v); } + + protected void set_Calendar(Calendar c) + { set_primitive(JAVA_CALENDAR, c); } + protected void set_Date(Date d) + { set_primitive(JAVA_DATE, d); } + protected void set_GDate(GDateSpecification d) + { + int btc = d.getBuiltinTypeCode(); + if (btc <= 0) + throw new XmlValueOutOfRangeException(); + set_primitive(btc, d); + } + + protected void set_GDuration(GDurationSpecification d) + { set_primitive(SchemaType.BTC_DURATION, d); } + + protected void set_enum(StringEnumAbstractBase e) + { set_primitive(SchemaType.BTC_STRING, e); } + + protected void set_list(List v) + { set_primitive(JAVA_LIST, v); } + + + protected void set_xmlfloat(XmlObject v) + { set_primitive(SchemaType.BTC_FLOAT, v); } + protected void set_xmldouble(XmlObject v) + { set_primitive(SchemaType.BTC_DOUBLE, v); } + protected void set_xmldecimal(XmlObject v) + { set_primitive(SchemaType.BTC_DECIMAL, v); } + protected void set_xmlduration(XmlObject v) + { set_primitive(SchemaType.BTC_DURATION, v); } + protected void set_xmldatetime(XmlObject v) + { set_primitive(SchemaType.BTC_DATE_TIME, v); } + protected void set_xmltime(XmlObject v) + { set_primitive(SchemaType.BTC_TIME, v); } + protected void set_xmldate(XmlObject v) + { set_primitive(SchemaType.BTC_DATE, v); } + protected void set_xmlgyearmonth(XmlObject v) + { set_primitive(SchemaType.BTC_G_YEAR_MONTH, v); } + protected void set_xmlgyear(XmlObject v) + { set_primitive(SchemaType.BTC_G_YEAR, v); } + protected void set_xmlgmonthday(XmlObject v) + { set_primitive(SchemaType.BTC_G_MONTH_DAY, v); } + protected void set_xmlgday(XmlObject v) + { set_primitive(SchemaType.BTC_G_DAY, v); } + protected void set_xmlgmonth(XmlObject v) + { set_primitive(SchemaType.BTC_G_MONTH, v); } + + + + private static boolean check(XmlObject v, SchemaType sType) + { + XmlObject[] vals = sType.getEnumerationValues(); + if (vals != null) + { + for (int i = 0; i < vals.length; i++) + { + if (vals[i].valueEquals(v)) + return true; + } + return false; + } + + return true; + } + + protected boolean equal_to(XmlObject xmlobj) + { + return _value.valueEquals(xmlobj); + } + + protected int value_hash_code() + { + return _value.hashCode(); + } + + protected void validate_simpleval(String lexical, ValidationContext ctx) + { + try + { + check_dated(); + } + catch (Exception e) + { + ctx.invalid(XmlErrorCodes.UNION, new Object[] { "'" + lexical + "' does not match any of the member types for " + QNameHelper.readable(schemaType()) }); + return; + } + if (_value == null) + { + ctx.invalid(XmlErrorCodes.UNION, new Object[] { "'" + lexical + "' does not match any of the member types for " + QNameHelper.readable(schemaType()) }); + return; + } + + ((XmlObjectBase)_value).validate_simpleval(lexical, ctx); + } + + +} + diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlUnsignedByteImpl.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlUnsignedByteImpl.java new file mode 100644 index 000000000..235895a93 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlUnsignedByteImpl.java @@ -0,0 +1,28 @@ +/* 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.values; + +import org.apache.xmlbeans.XmlUnsignedByte; +import org.apache.xmlbeans.SchemaType; + + +public class XmlUnsignedByteImpl extends JavaIntHolderEx implements XmlUnsignedByte +{ + public XmlUnsignedByteImpl() + { super(XmlUnsignedByte.type, false); } + public XmlUnsignedByteImpl(SchemaType type, boolean complex) + { super(type, complex); } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlUnsignedIntImpl.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlUnsignedIntImpl.java new file mode 100644 index 000000000..fa127d118 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlUnsignedIntImpl.java @@ -0,0 +1,28 @@ +/* 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.values; + +import org.apache.xmlbeans.XmlUnsignedInt; +import org.apache.xmlbeans.SchemaType; + + +public class XmlUnsignedIntImpl extends JavaLongHolderEx implements XmlUnsignedInt +{ + public XmlUnsignedIntImpl() + { super(XmlUnsignedInt.type, false); } + public XmlUnsignedIntImpl(SchemaType type, boolean complex) + { super(type, complex); } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlUnsignedLongImpl.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlUnsignedLongImpl.java new file mode 100644 index 000000000..5f7867902 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlUnsignedLongImpl.java @@ -0,0 +1,28 @@ +/* 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.values; + +import org.apache.xmlbeans.XmlUnsignedLong; +import org.apache.xmlbeans.SchemaType; + + +public class XmlUnsignedLongImpl extends JavaIntegerHolderEx implements XmlUnsignedLong +{ + public XmlUnsignedLongImpl() + { super(XmlUnsignedLong.type, false); } + public XmlUnsignedLongImpl(SchemaType type, boolean complex) + { super(type, complex); } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlUnsignedShortImpl.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlUnsignedShortImpl.java new file mode 100644 index 000000000..74a6b43c1 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlUnsignedShortImpl.java @@ -0,0 +1,27 @@ +/* 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.values; + +import org.apache.xmlbeans.XmlUnsignedShort; +import org.apache.xmlbeans.SchemaType; + +public class XmlUnsignedShortImpl extends JavaIntHolderEx implements XmlUnsignedShort +{ + public XmlUnsignedShortImpl() + { super(XmlUnsignedShort.type, false); } + public XmlUnsignedShortImpl(SchemaType type, boolean complex) + { super(type, complex); } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlValueDisconnectedException.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlValueDisconnectedException.java new file mode 100644 index 000000000..cfa4b3eb1 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlValueDisconnectedException.java @@ -0,0 +1,33 @@ +/* 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.values; + +public class XmlValueDisconnectedException extends RuntimeException +{ + XmlValueDisconnectedException ( ) + { + } + + XmlValueDisconnectedException ( String message ) + { + super( message ); + } + + XmlValueDisconnectedException ( String message, Throwable cause ) + { + super( message, cause ); + } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlValueNotNillableException.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlValueNotNillableException.java new file mode 100644 index 000000000..0f5e2eac0 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlValueNotNillableException.java @@ -0,0 +1,20 @@ +/* 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.values; + +public class XmlValueNotNillableException extends RuntimeException +{ +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlValueNotSupportedException.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlValueNotSupportedException.java new file mode 100644 index 000000000..17a4bcb4b --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlValueNotSupportedException.java @@ -0,0 +1,25 @@ +/* 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.values; + +import org.apache.xmlbeans.XmlError; + +public class XmlValueNotSupportedException extends XmlValueOutOfRangeException +{ + public XmlValueNotSupportedException() {} + public XmlValueNotSupportedException(String message) { super(message); } + public XmlValueNotSupportedException(String code, Object[] args) { super(XmlError.formattedMessage(code, args)); } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlValueOutOfRangeException.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlValueOutOfRangeException.java new file mode 100644 index 000000000..992b919ee --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/impl/values/XmlValueOutOfRangeException.java @@ -0,0 +1,25 @@ +/* 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.values; + +import org.apache.xmlbeans.XmlError; + +public class XmlValueOutOfRangeException extends IllegalArgumentException +{ + public XmlValueOutOfRangeException() {} + public XmlValueOutOfRangeException(String message) { super(message); } + public XmlValueOutOfRangeException(String code, Object[] args) { super(XmlError.formattedMessage(code, args)); } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/soap/SOAPArrayType.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/soap/SOAPArrayType.java new file mode 100644 index 000000000..5f8a7aaa9 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/soap/SOAPArrayType.java @@ -0,0 +1,457 @@ +/* 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.soap; + +import javax.xml.namespace.QName; + +import java.util.ArrayList; +import java.util.List; +import java.util.Iterator; + +import org.apache.xmlbeans.impl.values.XmlValueOutOfRangeException; +import org.apache.xmlbeans.impl.common.XmlWhitespace; +import org.apache.xmlbeans.impl.common.QNameHelper; +import org.apache.xmlbeans.impl.common.PrefixResolver; + +public final class SOAPArrayType +{ + // Example foo:bar[,][][,,][7,9] + // -> _type = QName(foo:bar) + // -> _ranks = {2,1,3} + // -> _dimensions = {7,9} + private QName _type; + private int[] _ranks; // if ranks is empty, it means there are no nested arrays + private int[] _dimensions; // Any dimension can be -1 to indicate "any". + + /** + * True if the ranks for the passed SOAPArrayType + * are equal to this one. + * + * Does NOT compare the _type fields. + */ + public boolean isSameRankAs(SOAPArrayType otherType) + { + if (_ranks.length != otherType._ranks.length) + return false; + for (int i = 0; i < _ranks.length; i++) + { + if (_ranks[i] != otherType._ranks[i]) + return false; + } + if (_dimensions.length != otherType._dimensions.length) + return false; + return true; + } + + /** + * Given SOAP 1.1-formatted index string, returns an array + * index. For example, given "[4,3,5]", returns an int array + * containing 4, 3, and 5. + */ + public static int[] parseSoap11Index(String inbraces) + { + inbraces = XmlWhitespace.collapse(inbraces, XmlWhitespace.WS_COLLAPSE); + if (!inbraces.startsWith("[") || !inbraces.endsWith("]")) + throw new IllegalArgumentException("Misformed SOAP 1.1 index: must be contained in braces []"); + return internalParseCommaIntString(inbraces.substring(1, inbraces.length() - 1)); + } + + private static int[] internalParseCommaIntString(String csl) + { + List dimStrings = new ArrayList(); + int i = 0; + for (;;) + { + int j = csl.indexOf(',', i); + if (j < 0) + { + dimStrings.add(csl.substring(i)); + break; + } + dimStrings.add(csl.substring(i, j)); + i = j + 1; + } + + int[] result = new int[dimStrings.size()]; + i = 0; + for (Iterator it = dimStrings.iterator(); it.hasNext(); i++) + { + String dimString = XmlWhitespace.collapse((String)it.next(), XmlWhitespace.WS_COLLAPSE); + if (dimString.equals("*") || dimString.equals("")) + { + result[i] = -1; + } + else + { + try + { + result[i] = Integer.parseInt(dimString); + } + catch (Exception e) + { + throw new XmlValueOutOfRangeException("Malformed integer in SOAP array index"); + } + } + } + return result; + } + + /** + * Parses a SOAP 1.1 array type string. + * + * Since an array type string contains a QName, a prefix resolver + * must be passed. + */ + public SOAPArrayType(String s, PrefixResolver m) + { + int firstbrace = s.indexOf('['); + if (firstbrace < 0) + throw new XmlValueOutOfRangeException(); + + // grab the QName + String firstpart = XmlWhitespace.collapse(s.substring(0, firstbrace), XmlWhitespace.WS_COLLAPSE); + int firstcolon = firstpart.indexOf(':'); + String prefix = ""; + if (firstcolon >= 0) + prefix = firstpart.substring(0, firstcolon); + + String uri = m.getNamespaceForPrefix(prefix); + if (uri == null) + throw new XmlValueOutOfRangeException(); + + _type = QNameHelper.forLNS(firstpart.substring(firstcolon + 1), uri); + + initDimensions(s, firstbrace); + } + + private static int[] EMPTY_INT_ARRAY = new int[0]; + + /** + * Parses SOAP 1.1(advanced) array type strings. + * + * Since in SOAP 1.1(advanced) the dimension specification is separated from the + * QName for the underlying type, these are passed in separate + * arguments. + */ + public SOAPArrayType(QName name, String dimensions) + { + int firstbrace = dimensions.indexOf('['); + if (firstbrace < 0) + { + _type = name; + _ranks = EMPTY_INT_ARRAY; + dimensions = XmlWhitespace.collapse(dimensions, XmlWhitespace.WS_COLLAPSE); + String[] dimStrings = dimensions.split(" "); + for (int i = 0; i < dimStrings.length; i++) + { + String dimString = dimStrings[i]; + if (dimString.equals("*")) + { + _dimensions[i] = -1; + // _hasIndeterminateDimensions = true; + } + else + { + try + { + _dimensions[i] = Integer.parseInt(dimStrings[i]); + } + catch (Exception e) + { + throw new XmlValueOutOfRangeException(); + } + } + } + } + else + { + _type = name; + initDimensions(dimensions, firstbrace); + } + } + + /** + * Given a nested SOAPArrayType and a set of dimensions for the outermost + * array, comes up with the right SOAPArrayType for the whole thing. + * + * E.g., + * Nested foo:bar[,][][,,][1,2] + * Dimensions [6,7,8] + * Result -> foo:bar[,][][,,][,][6,7,8] + */ + public SOAPArrayType(SOAPArrayType nested, int[] dimensions) + { + _type = nested._type; + + _ranks = new int[nested._ranks.length + 1]; + System.arraycopy(nested._ranks, 0, _ranks, 0, nested._ranks.length); + _ranks[_ranks.length - 1] = nested._dimensions.length; + + _dimensions = new int[dimensions.length]; + System.arraycopy(dimensions, 0, _dimensions, 0, dimensions.length); + } + + /** + * Initialize dimensions based on SOAP11 parsed dimension substring + */ + private void initDimensions(String s, int firstbrace) + { + List braces = new ArrayList(); + int lastbrace = -1; + for (int i = firstbrace; i >= 0; ) + { + lastbrace = s.indexOf(']', i); + if (lastbrace < 0) + throw new XmlValueOutOfRangeException(); + braces.add(s.substring(i + 1, lastbrace)); + i = s.indexOf('[', lastbrace); + } + + String trailer = s.substring(lastbrace + 1); + if (!XmlWhitespace.isAllSpace(trailer)) + throw new XmlValueOutOfRangeException(); + + // now fill in rank array + _ranks = new int[braces.size() - 1]; + for (int i = 0; i < _ranks.length; i++) + { + String commas = (String)braces.get(i); + int commacount = 0; + for (int j = 0; j < commas.length(); j++) + { + char ch = commas.charAt(j); + if (ch == ',') + commacount += 1; + else if (!XmlWhitespace.isSpace(ch)) + throw new XmlValueOutOfRangeException(); + } + _ranks[i] = commacount + 1; + } + + // finally fill in dimension array + _dimensions = internalParseCommaIntString((String)braces.get(braces.size() - 1)); + + /* + for (int i = 0; i < _dimensions.length; i++) + { + if (_dimensions[i] < 0) + _hasIndeterminateDimensions = true; + } + */ + } + + /** + * Returns the QName for the referenced type. + */ + public QName getQName() + { + return _type; + } + + /** + * Returns the array of ranks for inner nested arrays. + * In SOAP 1.1-advanced, this is always an array of length zero. + * In SOAP 1.1, this array reflects the ranks of nested + * arrays. For example foo:bar[,][,,][][5,6] will produce + * a ranks result of 2, 3, 1. + */ + public int[] getRanks() + { + int[] result = new int[_ranks.length]; + System.arraycopy(_ranks, 0, result, 0, result.length); + return result; + } + + /** + * Returns the array of dimensions. + */ + public int[] getDimensions() + { + int[] result = new int[_dimensions.length]; + System.arraycopy(_dimensions, 0, result, 0, result.length); + return result; + } + + /** + * True if this array contains nested arrays. Equivalent + * to (getRanks().length > 0). + */ + public boolean containsNestedArrays() + { + return (_ranks.length > 0); + } + + /** + * Returns the dimensions as a string, e.g., [,][2,3,4] + */ + public String soap11DimensionString() + { + return soap11DimensionString(_dimensions); + } + + /** + * Given an actual set of dimensions that may differ from + * the default that is stored, outputs the soap arrayType + * string. + */ + public String soap11DimensionString(int[] actualDimensions) + { + StringBuffer sb = new StringBuffer(); + for (int i = 0; i < _ranks.length; i++) + { + sb.append('['); + for (int j = 1; j < _ranks[i]; j++) + sb.append(','); + sb.append(']'); + } + + sb.append('['); + for (int i = 0; i < actualDimensions.length; i++) + { + if (i > 0) + sb.append(','); + if (actualDimensions[i] >= 0) + sb.append(actualDimensions[i]); + } + sb.append(']'); + return sb.toString(); + } + + private SOAPArrayType() + { + } + + /** + * SOAP 1.2 + * Constructs a SOAPArrayType from soap-enc:itemType and + * soap-enc:arraySize attributes + * @param itemType the item type QName + * @param arraySize a string with dimentions like: * 3 4 + * @return a SOAPArrayType to represent this + */ + public static SOAPArrayType newSoap12Array(QName itemType, String arraySize) + { + int [] ranks = EMPTY_INT_ARRAY; + arraySize = XmlWhitespace.collapse(arraySize, XmlWhitespace.WS_COLLAPSE); + String[] dimStrings = arraySize.split(" "); + int[] dimensions = new int[dimStrings.length]; + for (int i = 0; i < dimStrings.length; i++) + { + String dimString = dimStrings[i]; + if (i==0 && dimString.equals("*")) + { + dimensions[i] = -1; + // _hasIndeterminateDimensions = true; + } + else + { + try + { + dimensions[i] = Integer.parseInt(dimStrings[i]); + } + catch (Exception e) + { + throw new XmlValueOutOfRangeException(); + } + } + } + SOAPArrayType sot = new SOAPArrayType(); + sot._ranks = ranks; + sot._type = itemType; + sot._dimensions = dimensions; + return sot; + } + + /** + * SOAP 1.2 + * Given an actual set of dimensions that may differ from + * the default that is stored, outputs the soap arraySize + * string. + */ + public String soap12DimensionString(int[] actualDimensions) + { + StringBuffer sb = new StringBuffer(); + + for (int i = 0; i < actualDimensions.length; i++) + { + if (i > 0) + sb.append(' '); + if (actualDimensions[i] >= 0) + sb.append(actualDimensions[i]); + } + return sb.toString(); + } + + /** + * Constructs a SOAPArrayType reflecting the dimensions + * of the next nested array. + */ + public SOAPArrayType nestedArrayType() + { + if (!containsNestedArrays()) + throw new IllegalStateException(); + + SOAPArrayType result = new SOAPArrayType(); + + result._type = _type; + + result._ranks = new int[_ranks.length - 1]; + System.arraycopy(_ranks, 0, result._ranks, 0, result._ranks.length); + + result._dimensions = new int[_ranks[_ranks.length - 1]]; + for (int i = 0; i < result._dimensions.length; i++) + result._dimensions[i] = -1; + + // result._hasIndeterminateDimensions = (result._dimensions.length > 0); + + return result; + } + + public int hashCode() + { + return (_type.hashCode() + _dimensions.length + _ranks.length + (_dimensions.length == 0 ? 0 : _dimensions[0])); + } + + public boolean equals(Object obj) + { + if (obj == this) + return true; + + if (!obj.getClass().equals(getClass())) + return false; + + SOAPArrayType sat = (SOAPArrayType)obj; + + if (!_type.equals(sat._type)) + return false; + + if (_ranks.length != sat._ranks.length) + return false; + + if (_dimensions.length != sat._dimensions.length) + return false; + + for (int i = 0; i < _ranks.length; i++) + if (_ranks[i] != sat._ranks[i]) + return false; + + for (int i = 0; i < _dimensions.length; i++) + if (_dimensions[i] != sat._dimensions[i]) + return false; + + return true; + } +} diff --git a/xmlbeans/src/typeimpl/org/apache/xmlbeans/soap/SchemaWSDLArrayType.java b/xmlbeans/src/typeimpl/org/apache/xmlbeans/soap/SchemaWSDLArrayType.java new file mode 100644 index 000000000..4f6624397 --- /dev/null +++ b/xmlbeans/src/typeimpl/org/apache/xmlbeans/soap/SchemaWSDLArrayType.java @@ -0,0 +1,26 @@ +/* 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.soap; + +/** + * In the current implementation, schema elements and attributes + * can be coerced to this interface in order to retrieve the value + * of the wsdl:arrayType attributes on attributes and elements. + */ +public interface SchemaWSDLArrayType +{ + SOAPArrayType getWSDLArrayType(); +} diff --git a/xmlbeans/src/typestore/org/apache/xmlbeans/impl/values/NamespaceManager.java b/xmlbeans/src/typestore/org/apache/xmlbeans/impl/values/NamespaceManager.java new file mode 100644 index 000000000..1ba9f3d35 --- /dev/null +++ b/xmlbeans/src/typestore/org/apache/xmlbeans/impl/values/NamespaceManager.java @@ -0,0 +1,30 @@ +/* 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.values; + +import org.apache.xmlbeans.impl.common.PrefixResolver; + +public interface NamespaceManager extends PrefixResolver +{ + /** + * Caled when the user needs a prefix by which to reference a given + * Xml namespace. A suggested prefix is passed, which may be null; + * the suggestion may be ignored. + */ + + String find_prefix_for_nsuri ( String nsuri, String suggested_prefix ); +} + \ No newline at end of file diff --git a/xmlbeans/src/typestore/org/apache/xmlbeans/impl/values/TypeStore.java b/xmlbeans/src/typestore/org/apache/xmlbeans/impl/values/TypeStore.java new file mode 100644 index 000000000..8dba3fa5a --- /dev/null +++ b/xmlbeans/src/typestore/org/apache/xmlbeans/impl/values/TypeStore.java @@ -0,0 +1,353 @@ +/* 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.values; + +import org.apache.xmlbeans.SchemaField; +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.SchemaTypeLoader; +import org.apache.xmlbeans.XmlCursor; +import org.apache.xmlbeans.XmlOptions; +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.XmlException; +import org.apache.xmlbeans.QNameSet; +import java.util.List; +import javax.xml.namespace.QName; +import org.apache.xmlbeans.impl.common.ValidatorListener; +import org.apache.xmlbeans.impl.common.XmlLocale; + +public interface TypeStore extends NamespaceManager +{ + /** + * Creates a new cursor positioned just before the part of the tree + * where this TypeStore is located. + */ + XmlCursor new_cursor(); + + /** + */ + void validate ( ValidatorListener vEventSink ); + + /** + * Get the SchemaTypeLoader associated with the store contianing this + * TypeStore. + */ + SchemaTypeLoader get_schematypeloader ( ); + + /** + * Change the type of this store (perhaps by applying xsi:type) and + * return the new TypeStoreUser (or old one if the new type is not + * different). + */ + TypeStoreUser change_type ( SchemaType sType ); + + TypeStoreUser substitute ( QName name, SchemaType sType ); + + /** + * Tells if this store is an attribute or not + */ + boolean is_attribute ( ); + + /** + * Get the value of xsi:type. Return null if none or this is an attribute + * store. + */ + QName get_xsi_type ( ); + + /** + * A user of a TypeStore calls invalidate_text when the underlying + * value has changed and he wants the textstore to call him back with + * a fetch_text (TypeStore/TypeStoreUsers work in pairs). + */ + void invalidate_text(); + + /** + * A user of a TypeStore calls fetch_text when he knows his view + * of the text is invalid and he wants to see what the actual text + * value is. + */ + // BUGBUG (ericvas) 12111 + String fetch_text(int whitespaceRule); + + public static int WS_UNSPECIFIED = 0; + public static int WS_PRESERVE = 1; + public static int WS_REPLACE = 2; + public static int WS_COLLAPSE = 3; + + /** + * A user of a TypeStore calls store_text when he wants the TypeStore + * to remember the given text immediately. This typically happens when + * the user has a noncanonical (but valid) string representation to save, + * but doesn't have the storage in which to save it. + */ + void store_text(String text); + + /** + * Here the TypeStore is responsible for locating the default value. + * This is done as follows + * (1) go to the parent TypeStoreUser + * (2) ask it to get_default_element_text(qname) (or _attribute_), and return it if not null. + * (2) otherwise, grab a new TypeStoreUserVisitor via v = parentuser.new_visitor(); + * (3) call v.visit(name) on _every_ element qname up to and including this one in order + * (4) return the result of v.get_default_text(). + */ + String compute_default_text(); + + /** + * Here the TypeStore is responsible for figuring if this value is + * nillable and/or fixed. This is done by + * (1) go to the parent TypeStoreUser + * (2) ask it to get_elementflags(qname), and return it if not -1. + * (2) otherwise, grab a new TypeStoreUserVisitor via v = parentuser.new_visitor(); + * (3) call v.visit(name) on _every_ element qname up to and including this one in order + * (4) return the result of v.get_elementflags(). + */ + int compute_flags(); + + + /** + * Tells if this store was created with this option which tells the strongly typed + * objects to perform lexical and value validation after a setter is called. + */ + boolean validate_on_set(); + + /** + * Here the typestore is resposible for finding the schema field for + * this object. This is done by + * (1) otherwise, grab a new TypeStoreUserVisitor via v = parentuser.new_visitor(); + * (2) call v.visit(name) on _every_ element qname up to and including this one in order + * (3) return the result of v.get_schema_field(). + */ + SchemaField get_schema_field(); + + public static final int NILLABLE = 1; + public static final int HASDEFAULT = 2; + public static final int FIXED = 4; // always set with HASDEFAULT + + /** + * Called when the value has been nilled or unnilled, so the textstore + * knows it needs to update the xsi:nil attribute. + */ + void invalidate_nil(); + + /** + * The TypeStore is reponsible for discovering if this value is nil. + * This is done by (1) going to the element and (2) finding the + * xsi:nil attribute if present and (3) return true if the collapsed + * textual value is either exactly the string "true" or "1". + */ + boolean find_nil(); + + /** + * Returns the count of elements with the given name owned by this + * textstore. + */ + int count_elements(QName name); + + /** + * Returns the count of elements that match of the names. + */ + int count_elements(QNameSet names); + + /** + * Returns the TypeStoreUser underneath the ith element with the given + * name owned by this textstore, or null if none was found. + * + * Do not throw an IndexOutOfBoundsException if i is bad - + * return null instead. The reason is to allow us to fail + * and then follow with an add_element_etc if we choose to, + * without randomly catching exceptions. + */ +// BUGBUG - this should be called find_element +// BUGBUG - this should be called find_element +// BUGBUG - this should be called find_element +// BUGBUG - this should be called find_element +// BUGBUG - this should be called find_element + TypeStoreUser find_element_user(QName name, int i); + + /** + * Like find_element_user but accepts a set of names to search for. + */ + TypeStoreUser find_element_user(QNameSet names, int i); + + /** + * Returns all the TypeStoreUsers corresponding to elements with the + * given name owned by this typestore, or the empty array of + * TypeStoreUsers if none was found. + */ +// BUGBUG - this should be called find_all_element +// BUGBUG - this should be called find_all_element +// BUGBUG - this should be called find_all_element +// BUGBUG - this should be called find_all_element + void find_all_element_users(QName name, List fillMeUp); + + + /** + * Returns all TypeStoreUsers corresponding to elements with one + * of the names is the QNameSet. + */ + void find_all_element_users(QNameSet name, List fillMeUp); + + /** + * Inserts a new element at the position that will make it + * the ith element with the given name owned by this textstore, + * and returns a TypeStoreUser for that element. + * + * Note that if there are no existing elements of the given + * name, you may need to call back to discover the proper + * ordering to use to insert the first one. Otherwise, + * it should be inserted adjacent to existing elements with + * the same name. + * + * Should throw an IndexOutOfBoundsException if i < 0 + * or if i > # of elts + */ + +// BUGBUG - this should be called insert_element +// BUGBUG - this should be called insert_element +// BUGBUG - this should be called insert_element + TypeStoreUser insert_element_user(QName name, int i); + + /** + * Like the above method, except that it inserts an element named + * name, after the ith member of set. + */ + TypeStoreUser insert_element_user(QNameSet set, QName name, int i); + + /** + * Adds a new element at the last position adjacent to existing + * elements of the same name. + * + * Note that if there are no existing elements of the given + * name, the same comment applies as with insert_element_user. + */ +// BUGBUG - this should be called add_element +// BUGBUG - this should be called add_element +// BUGBUG - this should be called add_element +// BUGBUG - this should be called add_element + TypeStoreUser add_element_user(QName name); + + /** + * Removes the ith element with the given name. + * + * Should throw an IndexOutOfBoundsException if i < 0 + * or if i > # of elts-1. + */ + void remove_element(QName name, int i); + + /** + * Removes the ith element that matches names. + */ + void remove_element(QNameSet names, int i); + + + /** + * Returns the TypeStoreUser underneath the attribute with the given + * name, or null if there is no such attribute. + */ +// BUGBUG - this should be called find_attribute +// BUGBUG - this should be called find_attribute +// BUGBUG - this should be called find_attribute +// BUGBUG - this should be called find_attribute + TypeStoreUser find_attribute_user(QName name); + + /** + * Adds an attribute with the given name and returns a TypeStoreUser + * underneath it. Should throw an IndexOutOfBoundsException if there + * is already an existing attribute with the given name. + */ +// BUGBUG - this should be called add_attribute +// BUGBUG - this should be called add_attribute +// BUGBUG - this should be called add_attribute +// BUGBUG - this should be called add_attribute + TypeStoreUser add_attribute_user(QName name); + + /** + * Removes the attribute with the given name. + */ + void remove_attribute(QName name); + + /** + * Copies the contents of the given TypeStore (including attributes, + * elements, and mixed content), to the target type store. + * + * SPECIAL NOTE: The xsi:type attribute should not be removed from + * the target or copied from the soruce, and the TypeStoreUser attached + * to this TypeStore should not be disconnected. + * + * This is for implementing obj.set(foo). + */ + TypeStoreUser copy_contents_from(TypeStore source); + + /** + * Makes a copy of this store. + * NOTE: Even if st is NO_TYPE, the store can be a document. This method will make an exact copy. + */ + TypeStoreUser copy(SchemaTypeLoader schemaTypeLoader, SchemaType schemaType, XmlOptions options); + +// BUGBUG - Need to use this in the future +// /** +// * Copies the contents of the given TypeStore (including attributes, +// * elemets, mixed content), to the child element given by the given +// * name and index. Any TypeStoreUser that might be currently attached +// * to that element is disconnected. The xsi:type attribute of the +// * element should be set according to the given QName (or deleted if +// * the xsitype argument is null) +// */ +// void copy_to_element( +// TypeStore source, QName xsitype, QName name, int i); + + /** + * Copies the contents of the given array of XmlObject (including + * attributes, elements, mixed content), over all the elements of the + * given name under the current typestore. + * + * The lengths of the two arrays that are passed should be the same. + * + * If there are n current elements of the given name and m elements + * in the source array, there are several cases for individual elements: + * + * 1. If i < n and i < m, then the contents of the ith source are copied + * underneath the ith element; the ith element is not moved, but its + * TypeStoreUser is disconnected. + * 2. if i >= n and i < m, then first enough new elements are appended + * so that there is an element with the name i, then rule #1 is followed. + * 3. if i >= m and i < n, then the element #i and all its contents + * are removed. + */ + + void array_setter ( XmlObject[] sources, QName elementName ); + + /** + * Visits all the elements immediately, using the given visitor. + * A TypeStoreUser calls this when somebody has requested validation. + */ + void visit_elements(TypeStoreVisitor visitor); + + XmlObject[] exec_query ( String queryExpr, XmlOptions options ) + throws XmlException; + + /** + * Returns the monitor object, used for synchronizing access to the doc. + * @deprecated + */ + Object get_root_object(); + + /** + * Returns the locale object which is used to manage thread safty and the + * gateway requirements for calls into the xml store + */ + XmlLocale get_locale ( ); +} diff --git a/xmlbeans/src/typestore/org/apache/xmlbeans/impl/values/TypeStoreUser.java b/xmlbeans/src/typestore/org/apache/xmlbeans/impl/values/TypeStoreUser.java new file mode 100644 index 000000000..97284b5fa --- /dev/null +++ b/xmlbeans/src/typestore/org/apache/xmlbeans/impl/values/TypeStoreUser.java @@ -0,0 +1,185 @@ +/* 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.values; + +import javax.xml.namespace.QName; +import org.apache.xmlbeans.QNameSet; +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.SchemaField; + +/** + * Represents the strongly-typed user of a typestore. + * A typestore is responsible for all the lexical aspects of XML, and + * a typestore user is responsible for all strongly-typed aspects. + * Where there is interaction between the two models, it is represented + * by the TypeStore and TypeStoreUser interfaces. + */ +public interface TypeStoreUser +{ + /** + * Called to attach to the given textStore. When a TypeStoreUser is + * attached, it is put into a completely invalidated state. + */ + void attach_store(TypeStore store); + + /** + * Returns the schema type of this user + */ + SchemaType get_schema_type(); + + /** + * Returns the store to which this typestoreuser is attached, or + * null if none. + */ + TypeStore get_store(); + + /** + * A store will call back on invalidate_value when its text has + * changed and it therefore knows that any cached type value is + * invalid. It is the responsibilty of the type to call fetch_text + * and reparse next time the user does a strongly-typed get. + */ + void invalidate_value(); + + /** + * A store can call uses_invalidate_value to know if calls to + * invalidate_value will be fruitful. If uses_invalidate_value + * returns false, invalidate_value need never be called. + */ + boolean uses_invalidate_value(); + + /** + * A store will call back on build_text when it knows its own text + * is invalid and needs to fill it in. If forExternal is true, then + * the value returned will be used to replenish the store's cache of + * the value. Otherwise, the value is being computed for purposes + * other than validation, like persistence. + * + * Also, the only member on TypeStore which may be called while build_text + * is on the stack is find_prefix_for_nsuri which must have the + * forExternal state passed to it as it is passed here. + */ + String build_text(NamespaceManager nsm); + + /** + * A store will call back on build_nil after you've called invalidate_nil + * and it needs to know what the nil value is. + */ + boolean build_nil(); + + /** + * A store calls back on invalidate_nilvalue when the value of + * the xsi:nil tag has changed. + */ + void invalidate_nilvalue(); + + /** + * A store calls back on invalidate_element_order when a rearrangment + * of sibling elements to the left of this element means that the + * nillable value may no longer be valid. + */ + void invalidate_element_order(); + + /** + * A store will call back on validate_now to force us to look at + * the text if we're in an invalid state. This function is allowed + * and expected to throw an exception if the text isn't valid for + * our type. + */ + void validate_now(); + + /** + * A store calls back on this call in order to force a disconnect. + * After this is done, the object should be considered invalid. + */ + void disconnect_store(); + + /** + * A typestore user can create a new TypeStoreUser instance for + * a given element child name as long as you also pass the + * qname contained by the xsi:type attribute, if any. + * + * Note that we will ignore the xsiType if it turns out to be invalid. + */ + TypeStoreUser create_element_user(QName eltName, QName xsiType); + + /** + * A typestore user can create a new TypeStoreUser instance for + * a given attribute child, based on the attribute name. + */ + TypeStoreUser create_attribute_user(QName attrName); + + /** + * Return the SchemaType which a child element of this name and xsi:type + * would be. + */ + + SchemaType get_element_type(QName eltName, QName xsiType); + + /** + * Return the SchemaType which an attribute of this name would be. + */ + + SchemaType get_attribute_type(QName attrName); + + /** + * Returns the default element text, if it's consistent. If it's + * not consistent, returns null, and requires a visitor walk. + */ + String get_default_element_text(QName eltName); + + /** + * Returns the default attribute text for the attribute with + * the given name. + */ + String get_default_attribute_text(QName attrName); + + /** + * Returns the elementflags, if they're consistent. If they're + * not, returns -1, and requires a vistor walk. + */ + int get_elementflags(QName eltName); + + /** + * Returns the flags for an attribute. + */ + int get_attributeflags(QName attrName); + + /** + * Returns the schema field for an attribute + */ + SchemaField get_attribute_field(QName attrName); + + /** + * Returns false if child elements are insensitive to order; + * if it returns true, you're required to call invalidate_element_order + * on children to the right of any child order rearrangement. + */ + boolean is_child_element_order_sensitive(); + + /** + * A typestore user can return the element sort order to use for + * insertion operations if needed. Settable elements should + * be stored in this order if possible. + */ + QNameSet get_element_ending_delimiters(QName eltname); + + /** + * A typestore user can return a visitor that is used to compute + * default text and elementflags for an arbitrary element. + */ + TypeStoreVisitor new_visitor(); +} diff --git a/xmlbeans/src/typestore/org/apache/xmlbeans/impl/values/TypeStoreUserFactory.java b/xmlbeans/src/typestore/org/apache/xmlbeans/impl/values/TypeStoreUserFactory.java new file mode 100644 index 000000000..b87582125 --- /dev/null +++ b/xmlbeans/src/typestore/org/apache/xmlbeans/impl/values/TypeStoreUserFactory.java @@ -0,0 +1,28 @@ +/* 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.values; + +/** + * Every SchemaTypeLoader is actually a TypeStoreUserFactory. + * + * To get and use the default TypeStoreUserFactory, do the following: + * + * TypeStoreUser user = ((TypeStoreUserFactory)SchemaTypeLoader.global()).createTypeStoreUser(store); + */ +public interface TypeStoreUserFactory +{ + TypeStoreUser createTypeStoreUser(); +} diff --git a/xmlbeans/src/typestore/org/apache/xmlbeans/impl/values/TypeStoreVisitor.java b/xmlbeans/src/typestore/org/apache/xmlbeans/impl/values/TypeStoreVisitor.java new file mode 100644 index 000000000..f80b7ba54 --- /dev/null +++ b/xmlbeans/src/typestore/org/apache/xmlbeans/impl/values/TypeStoreVisitor.java @@ -0,0 +1,51 @@ +/* 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.values; + +import javax.xml.namespace.QName; +import org.apache.xmlbeans.SchemaField; + +/** + * This interface is used by the TypeStore to visit every element in order + * to compute nillable flags and default values. + */ +public interface TypeStoreVisitor +{ + /** + * When using a visitor, you must call "visit" on every qname of + * every element in order up to the one you're interested in. + * + * If you're using it for validation, call visit(null) at the end + * of the sequence of children. If you're not validating, you can + * just walk away once you get the info you need. + */ + boolean visit(QName eltName); + + /** + * Returns the elementflags for this element. + */ + int get_elementflags(); + + /** + * Returns the default text for this element. + */ + String get_default_text(); + + /** + * Returns the schema field for this field. + */ + SchemaField get_schema_field(); +} diff --git a/xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/BaseSchemaResourceManager.java b/xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/BaseSchemaResourceManager.java new file mode 100644 index 000000000..d6ae6ffbd --- /dev/null +++ b/xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/BaseSchemaResourceManager.java @@ -0,0 +1,719 @@ +/* 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.tool; + +import org.apache.xmlbeans.impl.xb.xsdownload.DownloadedSchemasDocument; +import org.apache.xmlbeans.impl.xb.xsdownload.DownloadedSchemaEntry; +import org.apache.xmlbeans.impl.xb.xsdownload.DownloadedSchemasDocument.DownloadedSchemas; +import org.apache.xmlbeans.impl.util.HexBin; +import org.apache.xmlbeans.impl.common.IOUtil; +import org.apache.xmlbeans.XmlOptions; +import org.apache.xmlbeans.XmlBeans; + +import java.io.IOException; +import java.io.InputStream; +import java.io.ByteArrayOutputStream; +import java.io.ByteArrayInputStream; +import java.util.Set; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.HashMap; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.net.URLConnection; +import java.security.DigestInputStream; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +import org.apache.xmlbeans.impl.xb.xsdschema.SchemaDocument.Schema; +import org.apache.xmlbeans.impl.xb.xsdschema.SchemaDocument; + +public abstract class BaseSchemaResourceManager extends SchemaImportResolver +{ + private static final String USER_AGENT = "XMLBeans/" + XmlBeans.getVersion() + " (" + XmlBeans.getTitle() + ")"; + + private String _defaultCopyDirectory; + private DownloadedSchemasDocument _importsDoc; + private Map _resourceForFilename = new HashMap(); + private Map _resourceForURL = new HashMap(); + private Map _resourceForNamespace = new HashMap(); + private Map _resourceForDigest = new HashMap(); + private Map _resourceForCacheEntry = new HashMap(); + private Set _redownloadSet = new HashSet(); + + protected BaseSchemaResourceManager() + { + // concrete subclasses should call init in their constructors + } + + protected final void init() + { + if (fileExists(getIndexFilename())) + { + try + { + _importsDoc = DownloadedSchemasDocument.Factory.parse( inputStreamForFile( getIndexFilename() ) ); + } + catch (IOException e) + { + _importsDoc = null; + } + catch (Exception e) + { + throw (IllegalStateException)(new IllegalStateException("Problem reading xsdownload.xml: please fix or delete this file")).initCause(e); + } + } + if (_importsDoc == null) + { + try + { + _importsDoc = DownloadedSchemasDocument.Factory.parse( + "" + ); + } + catch (Exception e) + { + throw (IllegalStateException)(new IllegalStateException()).initCause(e); + } + } + + String defaultDir = _importsDoc.getDownloadedSchemas().getDefaultDirectory(); + if (defaultDir == null) + defaultDir = getDefaultSchemaDir();; + _defaultCopyDirectory = defaultDir; + + // now initialize data structures + DownloadedSchemaEntry[] entries = _importsDoc.getDownloadedSchemas().getEntryArray(); + for (int i = 0; i < entries.length; i++) + { + updateResource(entries[i]); + } + } + + public final void writeCache() throws IOException + { + InputStream input = _importsDoc.newInputStream(new XmlOptions().setSavePrettyPrint()); + writeInputStreamToFile(input, getIndexFilename()); + } + + public final void processAll(boolean sync, boolean refresh, boolean imports) + { + if (refresh) + { + _redownloadSet = new HashSet(); + } + else + { + _redownloadSet = null; + } + + String[] allFilenames = getAllXSDFilenames(); + + if (sync) + syncCacheWithLocalXsdFiles(allFilenames, false); + + SchemaResource[] starters = (SchemaResource[]) + _resourceForFilename.values().toArray(new SchemaResource[0]); + + if (refresh) + redownloadEntries(starters); + + if (imports) + resolveImports(starters); + + _redownloadSet = null; + } + + public final void process(String[] uris, String[] filenames, boolean sync, boolean refresh, boolean imports) + { + if (refresh) + { + _redownloadSet = new HashSet(); + } + else + { + _redownloadSet = null; + } + + if (filenames.length > 0) + syncCacheWithLocalXsdFiles(filenames, true); + else if (sync) + syncCacheWithLocalXsdFiles(getAllXSDFilenames(), false); + + Set starterset = new HashSet(); + + for (int i = 0; i < uris.length; i++) + { + SchemaResource resource = (SchemaResource)lookupResource(null, uris[i]); + if (resource != null) + starterset.add(resource); + } + + for (int i = 0; i < filenames.length; i++) + { + SchemaResource resource = (SchemaResource)_resourceForFilename.get(filenames); + if (resource != null) + starterset.add(resource); + } + + SchemaResource[] starters = (SchemaResource[]) + starterset.toArray(new SchemaResource[0]); + + if (refresh) + redownloadEntries(starters); + + if (imports) + resolveImports(starters); + + _redownloadSet = null; + } + + /** + * Adds items to the cache that point to new files that aren't + * described in the cache, and optionally deletes old entries. + * + * If an old file is gone and a new file is + * found with exactly the same contents, the cache entry is moved + * to point to the new file. + */ + public final void syncCacheWithLocalXsdFiles(String[] filenames, boolean deleteOnlyMentioned) + { + Set seenResources = new HashSet(); + Set vanishedResources = new HashSet(); + + for (int i = 0; i < filenames.length; i++) + { + String filename = filenames[i]; + + // first, if the filename matches exactly, trust the filename + SchemaResource resource = (SchemaResource)_resourceForFilename.get(filename); + if (resource != null) + { + if (fileExists(filename)) + seenResources.add(resource); + else + vanishedResources.add(resource); + continue; + } + + // new file that is not in the index? + // not if the digest is known to the index and the original file is gone - that's a rename! + String digest = null; + try + { + digest = shaDigestForFile(filename); + resource = (SchemaResource)_resourceForDigest.get(digest); + if (resource != null) + { + String oldFilename = resource.getFilename(); + if (!fileExists(oldFilename)) + { + warning("File " + filename + " is a rename of " + oldFilename); + resource.setFilename(filename); + seenResources.add(resource); + if (_resourceForFilename.get(oldFilename) == resource) + _resourceForFilename.remove(oldFilename); + if (_resourceForFilename.containsKey(filename)) + _resourceForFilename.put(filename, resource); + continue; + } + } + } + catch (IOException e) + { + // unable to read digest... no problem, ignore then + } + + // ok, this really is a new XSD file then, of unknown URL origin + DownloadedSchemaEntry newEntry = addNewEntry(); + newEntry.setFilename(filename); + warning("Caching information on new local file " + filename); + if (digest != null) + newEntry.setSha1(digest); + + seenResources.add(updateResource(newEntry)); + } + + if (deleteOnlyMentioned) + deleteResourcesInSet(vanishedResources, true); + else + deleteResourcesInSet(seenResources, false); + } + + /** + * Iterates through every entry and refetches it from its primary URL, + * if known. Replaces the contents of the file if the data is different. + */ + private void redownloadEntries(SchemaResource[] resources) + { + for (int i = 0; i < resources.length; i++) + { + redownloadResource(resources[i]); + } + } + + private void deleteResourcesInSet(Set seenResources, boolean setToDelete) + { + Set seenCacheEntries = new HashSet(); + for (Iterator i = seenResources.iterator(); i.hasNext(); ) + { + SchemaResource resource = (SchemaResource)i.next(); + seenCacheEntries.add(resource._cacheEntry); + } + + DownloadedSchemas downloadedSchemas = _importsDoc.getDownloadedSchemas(); + for (int i = 0; i < downloadedSchemas.sizeOfEntryArray(); i++) + { + DownloadedSchemaEntry cacheEntry = downloadedSchemas.getEntryArray(i); + + if (seenCacheEntries.contains(cacheEntry) == setToDelete) + { + SchemaResource resource = (SchemaResource)_resourceForCacheEntry.get(cacheEntry); + warning("Removing obsolete cache entry for " + resource.getFilename()); + + if (resource != null) + { + _resourceForCacheEntry.remove(cacheEntry); + + if (resource == _resourceForFilename.get(resource.getFilename())) + _resourceForFilename.remove(resource.getFilename()); + + if (resource == _resourceForDigest.get(resource.getSha1())) + _resourceForDigest.remove(resource.getSha1()); + + if (resource == _resourceForNamespace.get(resource.getNamespace())) + _resourceForNamespace.remove(resource.getNamespace()); + + // Finally, any or all URIs + String[] urls = resource.getSchemaLocationArray(); + for (int j = 0; j < urls.length; j++) + { + if (resource == _resourceForURL.get(urls[j])) + _resourceForURL.remove(urls[j]); + } + } + + downloadedSchemas.removeEntry(i); + i -= 1; + } + } + } + + private SchemaResource updateResource(DownloadedSchemaEntry entry) + { + // The file + String filename = entry.getFilename(); + if (filename == null) + return null; + + SchemaResource resource = new SchemaResource(entry); + _resourceForCacheEntry.put(entry, resource); + + if (!_resourceForFilename.containsKey(filename)) + _resourceForFilename.put(filename, resource); + + // The digest + String digest = resource.getSha1(); + if (digest != null) + { + if (!_resourceForDigest.containsKey(digest)) + _resourceForDigest.put(digest, resource); + } + + // Next, the namespace + String namespace = resource.getNamespace(); + if (namespace != null) + { + if (!_resourceForNamespace.containsKey(namespace)) + _resourceForNamespace.put(namespace, resource); + } + + // Finally, any or all URIs + String[] urls = resource.getSchemaLocationArray(); + for (int j = 0; j < urls.length; j++) + { + if (!_resourceForURL.containsKey(urls[j])) + _resourceForURL.put(urls[j], resource); + } + + return resource; + } + + private static DigestInputStream digestInputStream(InputStream input) + { + MessageDigest sha; + try + { + sha = MessageDigest.getInstance("SHA"); + } + catch (NoSuchAlgorithmException e) + { + throw (IllegalStateException)(new IllegalStateException().initCause(e)); + } + + DigestInputStream str = new DigestInputStream(input, sha); + + return str; + } + + private DownloadedSchemaEntry addNewEntry() + { + return _importsDoc.getDownloadedSchemas().addNewEntry(); + } + + private class SchemaResource implements SchemaImportResolver.SchemaResource + { + SchemaResource(DownloadedSchemaEntry entry) + { + _cacheEntry = entry; + } + + DownloadedSchemaEntry _cacheEntry; + + public void setFilename(String filename) + { + _cacheEntry.setFilename(filename); + } + + public String getFilename() + { + return _cacheEntry.getFilename(); + } + + public Schema getSchema() + { + if (!fileExists(getFilename())) + redownloadResource(this); + + try + { + return SchemaDocument.Factory.parse(inputStreamForFile(getFilename())).getSchema(); + } + catch (Exception e) + { + return null; // return null if _any_ problems reading schema file + } + } + + public String getSha1() + { + return _cacheEntry.getSha1(); + } + + public String getNamespace() + { + return _cacheEntry.getNamespace(); + } + + public void setNamespace(String namespace) + { + _cacheEntry.setNamespace(namespace); + } + + public String getSchemaLocation() + { + if (_cacheEntry.sizeOfSchemaLocationArray() > 0) + return _cacheEntry.getSchemaLocationArray(0); + return null; + } + + public String[] getSchemaLocationArray() + { + return _cacheEntry.getSchemaLocationArray(); + } + + public int hashCode() + { + return getFilename().hashCode(); + } + + public boolean equals(Object obj) + { + return this == obj || getFilename().equals(((SchemaResource)obj).getFilename()); + } + + public void addSchemaLocation(String schemaLocation) + { + _cacheEntry.addSchemaLocation(schemaLocation); + } + } + + /** + * Called when the ImportLoader wishes to resolve the + * given import. Should return a SchemaResource whose + * "equals" relationship reveals when a SchemaResource is + * duplicated and shouldn't be examined again. + * + * Returns null if the resource reference should be ignored. + */ + public SchemaImportResolver.SchemaResource lookupResource(String nsURI, String schemaLocation) + { + SchemaResource result = fetchFromCache(nsURI, schemaLocation); + if (result != null) + { + if (_redownloadSet != null) + { + redownloadResource(result); + } + return result; + } + + if (schemaLocation == null) + { + warning("No cached schema for namespace '" + nsURI + "', and no url specified"); + return null; + } + + result = copyOrIdentifyDuplicateURL(schemaLocation, nsURI); + if (_redownloadSet != null) + _redownloadSet.add(result); + return result; + } + + private SchemaResource fetchFromCache(String nsURI, String schemaLocation) + { + SchemaResource result; + + if (schemaLocation != null) + { + result = (SchemaResource)_resourceForURL.get(schemaLocation); + if (result != null) + return result; + } + + if (nsURI != null) + { + result = (SchemaResource)_resourceForNamespace.get(nsURI); + if (result != null) + return result; + } + + return null; + } + + private String uniqueFilenameForURI(String schemaLocation) throws IOException, URISyntaxException + { + String localFilename = new URI( schemaLocation ).getRawPath(); + int i = localFilename.lastIndexOf('/'); + if (i >= 0) + localFilename = localFilename.substring(i + 1); + if (localFilename.endsWith(".xsd")) + localFilename = localFilename.substring(0, localFilename.length() - 4); + if (localFilename.length() == 0) + localFilename = "schema"; + + // TODO: remove other unsafe characters for filenames? + + String candidateFilename = localFilename; + int suffix = 1; + while (suffix < 1000) + { + String candidate = _defaultCopyDirectory + "/" + candidateFilename + ".xsd"; + if (!fileExists(candidate)) + return candidate; + suffix += 1; + candidateFilename = localFilename + suffix; + } + + throw new IOException("Problem with filename " + localFilename + ".xsd"); + } + + private void redownloadResource(SchemaResource resource) + { + if (_redownloadSet != null) + { + if (_redownloadSet.contains(resource)) + return; + _redownloadSet.add(resource); + } + + String filename = resource.getFilename(); + String schemaLocation = resource.getSchemaLocation(); + String digest = null; + + // nothing to do? + if (schemaLocation == null || filename == null) + return; + + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + + try + { + URL url = new URL( schemaLocation ); + URLConnection conn = url.openConnection(); + conn.addRequestProperty("User-Agent", USER_AGENT); + conn.addRequestProperty("Accept", "application/xml, text/xml, */*"); + DigestInputStream input = digestInputStream(conn.getInputStream()); + IOUtil.copyCompletely(input, buffer); + digest = HexBin.bytesToString(input.getMessageDigest().digest()); + } + catch (Exception e) + { + warning("Could not copy remote resource " + schemaLocation + ":" + e.getMessage()); + return; + } + + if (digest.equals(resource.getSha1()) && fileExists(filename)) + { + warning("Resource " + filename + " is unchanged from " + schemaLocation + "."); + return; + } + + try + { + InputStream source = new ByteArrayInputStream(buffer.toByteArray()); + writeInputStreamToFile(source, filename); + } + catch (IOException e) + { + warning("Could not write to file " + filename + " for " + schemaLocation + ":" + e.getMessage()); + return; + } + + warning("Refreshed " + filename + " from " + schemaLocation); + } + + private SchemaResource copyOrIdentifyDuplicateURL(String schemaLocation, String namespace) + { + String targetFilename; + String digest; + SchemaResource result; + + try + { + targetFilename = uniqueFilenameForURI(schemaLocation); + } + catch (URISyntaxException e) + { + warning("Invalid URI '" + schemaLocation + "':" + e.getMessage()); + return null; + } + catch (IOException e) + { + warning("Could not create local file for " + schemaLocation + ":" + e.getMessage()); + return null; + } + + try + { + URL url = new URL( schemaLocation ); + DigestInputStream input = digestInputStream(url.openStream()); + writeInputStreamToFile(input, targetFilename); + digest = HexBin.bytesToString(input.getMessageDigest().digest()); + } + catch (Exception e) + { + warning("Could not copy remote resource " + schemaLocation + ":" + e.getMessage()); + return null; + } + + result = (SchemaResource)_resourceForDigest.get(digest); + if (result != null) + { + deleteFile(targetFilename); + result.addSchemaLocation(schemaLocation); + if (!_resourceForURL.containsKey(schemaLocation)) + _resourceForURL.put(schemaLocation, result); + return result; + } + + warning("Downloaded " + schemaLocation + " to " + targetFilename); + + DownloadedSchemaEntry newEntry = addNewEntry(); + newEntry.setFilename(targetFilename); + newEntry.setSha1(digest); + if (namespace != null) + newEntry.setNamespace(namespace); + newEntry.addSchemaLocation(schemaLocation); + return updateResource(newEntry); + } + + /** + * Updates actual namespace in the table. + */ + public void reportActualNamespace(SchemaImportResolver.SchemaResource rresource, String actualNamespace) + { + SchemaResource resource = (SchemaResource)rresource; + String oldNamespace = resource.getNamespace(); + if (oldNamespace != null && _resourceForNamespace.get(oldNamespace) == resource) + _resourceForNamespace.remove(oldNamespace); + if (!_resourceForNamespace.containsKey(actualNamespace)) + _resourceForNamespace.put(actualNamespace, resource); + resource.setNamespace(actualNamespace); + } + + private String shaDigestForFile(String filename) throws IOException + { + DigestInputStream str = digestInputStream(inputStreamForFile(filename)); + + byte[] dummy = new byte[4096]; + for (int i = 1; i > 0; i = str.read(dummy)); + + str.close(); + + return HexBin.bytesToString(str.getMessageDigest().digest()); + } + + // SOME METHODS TO OVERRIDE ============================ + + protected String getIndexFilename() + { + return "./xsdownload.xml"; + } + + protected String getDefaultSchemaDir() + { + return "./schema"; + } + + /** + * Produces diagnostic messages such as "downloading X to file Y". + */ + abstract protected void warning(String msg); + + /** + * Returns true if the given filename exists. The filenames + * are of the form "/foo/bar/zee.xsd" and should be construed + * as rooted at the root of the project. + */ + abstract protected boolean fileExists(String filename); + + /** + * Gets the data in the given filename as an InputStream. + */ + abstract protected InputStream inputStreamForFile(String filename) throws IOException; + + /** + * Writes an entire file in one step. An InputStream is passed and + * copied to the file. + */ + abstract protected void writeInputStreamToFile(InputStream input, String filename) throws IOException; + + /** + * Deletes a file. Sometimes immediately after writing a new file + * we notice that it's exactly the same as an existing file and + * we delete it. We never delete a file that was given to us + * by the user. + */ + abstract protected void deleteFile(String filename); + + /** + * Returns a list of all the XSD filesnames in the project. + */ + abstract protected String[] getAllXSDFilenames(); +} diff --git a/xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/CodeGenUtil.java b/xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/CodeGenUtil.java new file mode 100644 index 000000000..03c72dec1 --- /dev/null +++ b/xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/CodeGenUtil.java @@ -0,0 +1,424 @@ +/* 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.tool; + +import org.apache.xmlbeans.SystemProperties; + +import java.util.ArrayList; +import java.util.List; +import java.util.Iterator; +import java.util.Arrays; +import java.io.File; +import java.io.InputStream; +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.io.FileFilter; +import java.io.FileWriter; +import java.net.URI; +import java.net.URISyntaxException; + +public class CodeGenUtil +{ + public static String DEFAULT_MEM_START = "8m"; + public static String DEFAULT_MEM_MAX = "256m"; + public static String DEFAULT_COMPILER = "javac"; + public static String DEFAULT_JAR = "jar"; + + //workaround for Sun bug # 4723726 + public static URI resolve(URI base, URI child) + { + URI ruri = base.resolve(child); + + //fix up normalization bug + if ("file".equals(ruri.getScheme()) && ! child.equals(ruri)) + { + if (base.getPath().startsWith("//") && !ruri.getPath().startsWith("//")) + { + String path = "///".concat(ruri.getPath()); + try + { + ruri = new URI("file", null, path, ruri.getQuery(), ruri.getFragment()); + } + catch(URISyntaxException uris) + {} + } + } + return ruri; + } + + static void addAllJavaFiles(List srcFiles, List args) + { + for (Iterator i = srcFiles.iterator(); i.hasNext(); ) + { + File f = (File)i.next(); + if (!f.isDirectory()) + { + args.add(quoteAndEscapeFilename(f.getAbsolutePath())); + } + else + { + List inside = (Arrays.asList(f.listFiles( + new FileFilter() + { + public boolean accept(File file) + { return (file.isFile() && file.getName().endsWith(".java")) || file.isDirectory(); } + } + ))); + addAllJavaFiles(inside, args); + } + } + } + + static private String quoteAndEscapeFilename(String filename) + { + // don't quote if there's no space + if (filename.indexOf(" ") < 0) + return filename; + + // bizarre. javac expects backslash escaping if we quote the classpath + // bizarre also. replaceAll expects replacement backslashes to be double escaped. + return "\"" + filename.replaceAll("\\\\", "\\\\\\\\") + "\""; + } + + static private String quoteNoEscapeFilename(String filename) + { + // don't quote if there's no space, and don't quote on linux + if (filename.indexOf(" ") < 0 || File.separatorChar == '/') + return filename; + + return "\"" + filename + "\""; + } + + /** + * Invokes javac on the generated source files in order to turn them + * into binary files in the output directory. This will return a list of + * GenFiles for all of the classes produced or null if an + * error occurred. + * + * @deprecated + */ + static public boolean externalCompile(List srcFiles, File outdir, File[] cp, boolean debug) + { + return externalCompile(srcFiles, outdir, cp, debug, DEFAULT_COMPILER, null, DEFAULT_MEM_START, DEFAULT_MEM_MAX, false, false); + } + + // KHK: temporary to avoid build break + static public boolean externalCompile(List srcFiles, File outdir, File[] cp, boolean debug, String javacPath, String memStart, String memMax, boolean quiet, boolean verbose) + { + return externalCompile(srcFiles, outdir, cp, debug, javacPath, null, memStart, memMax, quiet, verbose); + } + + /** + * Invokes javac on the generated source files in order to turn them + * into binary files in the output directory. This will return a list of + * GenFiles for all of the classes produced or null if an + * error occurred. + */ + static public boolean externalCompile(List srcFiles, File outdir, File[] cp, boolean debug, String javacPath, String genver, String memStart, String memMax, boolean quiet, boolean verbose) + { + List args = new ArrayList(); + + File javac = findJavaTool(javacPath == null ? DEFAULT_COMPILER : javacPath); + assert (javac.exists()) : "compiler not found " + javac; + args.add(javac.getAbsolutePath()); + + if (outdir == null) + { + outdir = new File("."); + } + else + { + args.add("-d"); + args.add(quoteAndEscapeFilename(outdir.getAbsolutePath())); + } + + if (cp == null) + { + cp = systemClasspath(); + } + + if (cp.length > 0) + { + StringBuffer classPath = new StringBuffer(); + // Add the output directory to the classpath. We do this so that + // javac will be able to find classes that were compiled + // previously but are not in the list of sources this time. + classPath.append(outdir.getAbsolutePath()); + + // Add everything on our classpath. + for (int i = 0; i < cp.length; i++) + { + classPath.append(File.pathSeparator); + classPath.append(cp[i].getAbsolutePath()); + } + + args.add("-classpath"); + + // bizarre. javac expects backslash escaping if we quote the classpath + args.add(quoteAndEscapeFilename(classPath.toString())); + } + + if (genver == null) + genver = "1.4"; + + args.add("-source"); + args.add(genver); + + args.add("-target"); + args.add(genver); + + args.add(debug ? "-g" : "-g:none"); + + if (verbose) + args.add("-verbose"); + + addAllJavaFiles(srcFiles, args); + + File clFile = null; + try + { + clFile = File.createTempFile("javac", ""); + FileWriter fw = new FileWriter(clFile); + Iterator i = args.iterator(); + for (i.next(); i.hasNext();) + { + String arg = (String)i.next(); + fw.write(arg); + fw.write('\n'); + } + fw.close(); + List newargs = new ArrayList(); + newargs.add(args.get(0)); + + if (memStart != null && memStart.length() != 0) + newargs.add("-J-Xms" + memStart); + if (memMax != null && memMax.length() != 0) + newargs.add("-J-Xmx" + memMax); + + newargs.add("@" + clFile.getAbsolutePath()); + args = newargs; + } + catch (Exception e) + { + System.err.println("Could not create command-line file for javac"); + } + + try + { + String[] strArgs = (String[]) args.toArray(new String[args.size()]); + + if (verbose) + { + System.out.print("compile command:"); + for (int i = 0; i < strArgs.length; i++) + System.out.print(" " + strArgs[i]); + System.out.println(); + } + + final Process proc = Runtime.getRuntime().exec(strArgs); + + StringBuffer errorBuffer = new StringBuffer(); + StringBuffer outputBuffer = new StringBuffer(); + + ThreadedReader out = new ThreadedReader(proc.getInputStream(), outputBuffer); + ThreadedReader err = new ThreadedReader(proc.getErrorStream(), errorBuffer); + + proc.waitFor(); + + if (verbose || proc.exitValue() != 0) + { + if (outputBuffer.length() > 0) { + System.out.println(outputBuffer.toString()); + System.out.flush(); + } + if (errorBuffer.length() > 0) { + System.err.println(errorBuffer.toString()); + System.err.flush(); + } + + if (proc.exitValue() != 0) + return false; + } + } + catch (Throwable e) + { + System.err.println(e.toString()); + System.err.println(e.getCause()); + e.printStackTrace(System.err); + return false; + } + + if (clFile != null) + clFile.delete(); + + return true; + } + + public static File[] systemClasspath() + { + List cp = new ArrayList(); + String[] systemcp = SystemProperties.getProperty("java.class.path").split(File.pathSeparator); + for (int i = 0; i < systemcp.length; i++) + { + cp.add(new File(systemcp[i])); + } + return (File[])cp.toArray(new File[cp.size()]); + } + + /** + * @deprecated Use org.apache.xmlbeans.impl.common.JarHelper instead. + */ + static public boolean externalJar(File srcdir, File outfile) + { + return externalJar(srcdir, outfile, DEFAULT_JAR, false, false); + } + + /** + * @deprecated Use org.apache.xmlbeans.impl.common.JarHelper instead. + */ + static public boolean externalJar(File srcdir, File outfile, String jarPath, boolean quiet, boolean verbose) + { + List args = new ArrayList(); + + File jar = findJavaTool(jarPath == null ? DEFAULT_JAR : jarPath); + assert (jar.exists()) : "jar not found " + jar; + args.add(jar.getAbsolutePath()); + + args.add("cf"); + args.add(quoteNoEscapeFilename(outfile.getAbsolutePath())); + + args.add("-C"); + args.add(quoteNoEscapeFilename(srcdir.getAbsolutePath())); + + args.add("."); + + try + { + String[] strArgs = (String[]) args.toArray(new String[args.size()]); + + if (verbose) + { + System.out.print("jar command:"); + for (int i = 0; i < strArgs.length; i++) + System.out.print(" " + strArgs[i]); + System.out.println(); + } + + final Process proc = Runtime.getRuntime().exec(strArgs); + + StringBuffer errorBuffer = new StringBuffer(); + StringBuffer outputBuffer = new StringBuffer(); + + ThreadedReader out = new ThreadedReader(proc.getInputStream(), outputBuffer); + ThreadedReader err = new ThreadedReader(proc.getErrorStream(), errorBuffer); + + proc.waitFor(); + + if (verbose || proc.exitValue() != 0) + { + if (outputBuffer.length() > 0) { + System.out.println(outputBuffer.toString()); + System.out.flush(); + } + if (errorBuffer.length() > 0) { + System.err.println(errorBuffer.toString()); + System.err.flush(); + } + + if (proc.exitValue() != 0) + return false; + } + } + catch (Throwable e) + { + e.printStackTrace(System.err); + return false; + } + return true; + } + + /** + * Look for tool in current directory and ${JAVA_HOME}/../bin and + * try with .exe file extension. + */ + private static File findJavaTool(String tool) + { + File toolFile = new File(tool); + if (toolFile.isFile()) { + return toolFile; + } + + File result = new File(tool + ".exe"); + if (result.isFile()) { + return result; + } + + String home = SystemProperties.getProperty("java.home"); + + String sep = File.separator; + result = new File(home + sep + ".." + sep + "bin", tool); + + if (result.isFile()) { + return result; + } + + result = new File(result.getPath() + ".exe"); + if (result.isFile()) { + return result; + } + + result = new File(home + sep + "bin", tool); + if (result.isFile()) { + return result; + } + + result = new File(result.getPath() + ".exe"); + if (result.isFile()) { + return result; + } + + // just return the original toolFile and hope that it is on the PATH. + return toolFile; + } + + /** + * Reads the given input stream into the given buffer until there is + * nothing left to read. + */ + static private class ThreadedReader + { + public ThreadedReader(InputStream stream, final StringBuffer output) + { + final BufferedReader reader = + new BufferedReader(new InputStreamReader(stream)); + + Thread readerThread = new Thread(new Runnable() { + public void run() + { + String s; + try + { + while ((s = reader.readLine()) != null) + output.append(s + "\n"); + } + catch (Exception e) + {} + } + }); + readerThread.start(); + } + } +} diff --git a/xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/CommandLine.java b/xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/CommandLine.java new file mode 100644 index 000000000..ab2ec4f8a --- /dev/null +++ b/xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/CommandLine.java @@ -0,0 +1,230 @@ +/* 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.tool; + +import org.apache.xmlbeans.XmlBeans; +import org.apache.xmlbeans.impl.common.IOUtil; + +import java.io.File; +import java.net.URI; +import java.net.URL; +import java.net.MalformedURLException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +public class CommandLine +{ + public CommandLine(String[] args, Collection flags, Collection scheme) + { + if (flags == null || scheme == null) + throw new IllegalArgumentException("collection required (use Collections.EMPTY_SET if no options)"); + + _options = new LinkedHashMap(); + ArrayList badopts = new ArrayList(); + ArrayList endargs = new ArrayList(); + + for (int i = 0; i < args.length; i++) + { + if (args[i].indexOf('-') == 0) + { + String opt = args[i].substring(1); + String val = null; + + if (flags.contains(opt)) + val = ""; + else if (scheme.contains(opt)) + { + if (i+1 < args.length) + val = args[++i]; + else + val = ""; + } + else + badopts.add(args[i]); + + _options.put(opt, val); + } + else + { + endargs.add(args[i]); + } + } + + _badopts = (String[])badopts.toArray(new String[badopts.size()]); + _args = (String[])endargs.toArray(new String[endargs.size()]); + } + + public static void printLicense() + { + try + { + IOUtil.copyCompletely(CommandLine.class.getClassLoader().getResourceAsStream("LICENSE.txt"), System.out); + } + catch (Exception e) + { + System.out.println("License available in this JAR in LICENSE.txt"); + } + } + + public static void printVersion() + { + System.out.println(XmlBeans.getVendor() + ", " + XmlBeans.getTitle() + ".XmlBeans version " + XmlBeans.getVersion()); + } + + private Map _options; + private String[] _badopts; + private String[] _args; + + public String[] args() + { + String[] result = new String[_args.length]; + System.arraycopy(_args, 0, result, 0, _args.length); + return result; + } + + public String[] getBadOpts() + { + return _badopts; + } + + public String getOpt(String opt) + { + return (String)_options.get(opt); + } + + private static List collectFiles(File[] dirs) + { + List files = new ArrayList(); + for (int i = 0; i < dirs.length; i++) + { + File f = dirs[i]; + if (!f.isDirectory()) + { + files.add(f); + } + else + { + files.addAll(collectFiles(f.listFiles())); + } + } + return files; + } + + private List _files; + private List _urls; + private File _baseDir; + private static final File[] EMPTY_FILEARRAY = new File[0]; + private static final URL[] EMPTY_URLARRAY = new URL[0]; + + private List getFileList() + { + if (_files == null) + { + String[] args = args(); + File[] files = new File[args.length]; + boolean noBaseDir = false; + for (int i = 0; i < args.length; i++) + { + files[i] = new File(args[i]); + if (!noBaseDir && (_baseDir == null)) + { + if (files[i].isDirectory()) + _baseDir = files[i]; + else + _baseDir = files[i].getParentFile(); + } + else + { + URI currUri = files[i].toURI(); + + // Give up on the basedir. There may be none + if (_baseDir != null && _baseDir.toURI().relativize(currUri).equals(currUri)) + { + _baseDir = null; + noBaseDir = true; + } + } + } + _files = Collections.unmodifiableList(collectFiles(files)); + } + return _files; + } + + private List getUrlList() + { + if (_urls == null) + { + String[] args = args(); + List urls = new ArrayList(); + + for (int i = 0; i < args.length; i++) + { + if (looksLikeURL(args[i])) + { + try + { + urls.add(new URL(args[i])); + } + catch (MalformedURLException mfEx) + { + System.err.println("ignoring invalid url: " + args[i] + ": " + mfEx.getMessage()); + } + } + } + + _urls = Collections.unmodifiableList(urls); + } + + return _urls; + } + + private static boolean looksLikeURL(String str) + { + return str.startsWith("http:") || str.startsWith("https:") || str.startsWith("ftp:") || str.startsWith("file:"); + } + + public URL[] getURLs() + { + return (URL[]) getUrlList().toArray(EMPTY_URLARRAY); + } + + public File[] getFiles() + { + return (File[])getFileList().toArray(EMPTY_FILEARRAY); + } + + public File getBaseDir() + { + return _baseDir; + } + + public File[] filesEndingWith(String ext) + { + List result = new ArrayList(); + for (Iterator i = getFileList().iterator(); i.hasNext(); ) + { + File f = (File)i.next(); + if (f.getName().endsWith(ext) && !looksLikeURL(f.getPath())) + result.add(f); + } + return (File[])result.toArray(EMPTY_FILEARRAY); + } +} diff --git a/xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/Diff.java b/xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/Diff.java new file mode 100644 index 000000000..b8837ea7d --- /dev/null +++ b/xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/Diff.java @@ -0,0 +1,384 @@ +/* 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.tool; + +import org.apache.xmlbeans.SystemProperties; +import org.apache.xmlbeans.impl.schema.SchemaTypeSystemImpl; + +import java.io.*; +import java.util.List; +import java.util.Arrays; +import java.util.Comparator; +import java.util.ArrayList; +import java.util.jar.JarFile; +import java.util.Enumeration; +import java.util.zip.ZipEntry; + +public class Diff +{ + public static void main(String[] args) + { + if (args.length != 2) + { + System.out.println("Usage: diff to compare two jars"); + System.out.println(" or diff to compare two dirs"); + return; + } + File file1 = new File(args[0]); + if (!file1.exists()) + { + System.out.println("File \"" + args[0] + "\" not found."); + return; + } + File file2 = new File(args[1]); + if (!file2.exists()) + { + System.out.println("File \"" + args[1] + "\" not found."); + return; + } + List result = new ArrayList(); + if (file1.isDirectory()) + { + if (!file2.isDirectory()) + { + System.out.println("Both parameters have to be directories if the first parameter is a directory."); + return; + } + dirsAsTypeSystems(file1, file2, result); + } + else + { + if (file2.isDirectory()) + { + System.out.println("Both parameters have to be jar files if the first parameter is a jar file."); + return; + } + try + { + JarFile jar1 = new JarFile(file1); + JarFile jar2 = new JarFile(file2); + jarsAsTypeSystems(jar1, jar2, result); + } + catch (IOException ioe) + { ioe.printStackTrace(); } + } + if (result.size() < 1) + System.out.println("No differences encountered."); + else + { + System.out.println("Differences:"); + for (int i = 0; i < result.size(); i++) + System.out.println(result.get(i).toString()); + } + } + + /** + * Diffs the contents of two jars, looking only at the schema typesystems + * saved inside those jars + */ + public static void jarsAsTypeSystems(JarFile jar1, JarFile jar2, List diffs) + { + Enumeration entries1 = jar1.entries(); + Enumeration entries2 = jar2.entries(); + List list1 = new ArrayList(); + List list2 = new ArrayList(); + for (; entries1.hasMoreElements(); ) + { + ZipEntry ze = (ZipEntry) entries1.nextElement(); + String name = ze.getName(); + if (name.startsWith("schema" + SchemaTypeSystemImpl.METADATA_PACKAGE_GEN + "/system/s") && name.endsWith(".xsb")) + list1.add(ze); + } + for (; entries2.hasMoreElements(); ) + { + ZipEntry ze = (ZipEntry) entries2.nextElement(); + String name = ze.getName(); + if (name.startsWith("schema" + SchemaTypeSystemImpl.METADATA_PACKAGE_GEN + "/system/s") && name.endsWith(".xsb")) + list2.add(ze); + } + ZipEntry[] files1 = (ZipEntry[]) list1.toArray(new ZipEntry[list1.size()]); + ZipEntry[] files2 = (ZipEntry[]) list2.toArray(new ZipEntry[list2.size()]); + ZipEntryNameComparator comparator = new ZipEntryNameComparator(); + Arrays.sort(files1, comparator); + Arrays.sort(files2, comparator); + int i1 = 0; + int i2 = 0; + while (i1 < files1.length && i2 < files2.length) + { + String name1 = files1[i1].getName(); + String name2 = files2[i2].getName(); + int dif = name1.compareTo(name2); + if (dif == 0) + { + // Compare the files + zipEntriesAsXsb(files1[i1], jar1, files2[i2], jar2, diffs); + i1++; i2++; // Move to next pair + } + else if (dif < 0) + { + // dir1 contains a file that dir2 doesn't + diffs.add("Jar \"" + jar1.getName() + "\" contains an extra file: \"" + + name1 + "\""); + i1++; + } + else if (dif > 0) + { + // dir2 contains a file that dir1 doesn't + diffs.add("Jar \"" + jar2.getName() + "\" contains an extra file: \"" + + name2 + "\""); + i2++; + } + } + while (i1 < files1.length) + { + diffs.add("Jar \"" + jar1.getName() + "\" contains an extra file: \"" + + files1[i1].getName() + "\""); + i1++; + } + while (i2 < files2.length) + { + diffs.add("Jar \"" + jar2.getName() + "\" contains an extra file: \"" + + files2[i2].getName() + "\""); + i2++; + } + } + + /** + * Diffs the contents of two dirs looking only at the xsb files + * contained in these two dirs + * Updated diffs with a list of differences (for the time being, strings + * describing the difference) + */ + public static void dirsAsTypeSystems(File dir1, File dir2, List diffs) + { + assert dir1.isDirectory() : "Parameters must be directories"; + assert dir2.isDirectory() : "Parameters must be directories"; + + /** + * Navigate three directories deep to get to the type system. + * Assume the schema[METADATA_PACKAGE_LOAD]/system/* structure + */ + File temp1 = new File(dir1, "schema" + SchemaTypeSystemImpl.METADATA_PACKAGE_GEN + "/system"); + File temp2 = new File(dir2, "schema" + SchemaTypeSystemImpl.METADATA_PACKAGE_GEN + "/system"); + if (temp1.exists() && temp2.exists()) + { + File[] files1 = temp1.listFiles(); + File[] files2 = temp2.listFiles(); + if (files1.length == 1 && files2.length == 1) + { + temp1 = files1[0]; + temp2 = files2[0]; + } + else + { + if (files1.length == 0) + temp1 = null; + if (files2.length == 0) + temp2 = null; + if (files1.length > 1) + { + diffs.add("More than one typesystem found in dir \"" + + dir1.getName() + "\""); + return; + } + if (files2.length > 1) + { + diffs.add("More than one typesystem found in dir \"" + + dir2.getName() + "\""); + return; + } + } + } + else + { + if (!temp1.exists()) + temp1 = null; + if (!temp2.exists()) + temp2 = null; + } + if (temp1 == null && temp2 == null) + return; + else if (temp1 == null || temp2 == null) + { + if (temp1 == null) + diffs.add("No typesystems found in dir \"" + dir1 + "\""); + if (temp2 == null) + diffs.add("No typesystems found in dir \"" + dir2 + "\""); + return; + } + else + { + dir1 = temp1; + dir2 = temp2; + } + + boolean diffIndex = isDiffIndex(); + XsbFilenameFilter xsbName = new XsbFilenameFilter(); + File[] files1 = dir1.listFiles(xsbName); + File[] files2 = dir2.listFiles(xsbName); + FileNameComparator comparator = new FileNameComparator(); + Arrays.sort(files1, comparator); + Arrays.sort(files2, comparator); + int i1 = 0; + int i2 = 0; + while (i1 < files1.length && i2 < files2.length) + { + String name1 = files1[i1].getName(); + String name2 = files2[i2].getName(); + int dif = name1.compareTo(name2); + if (dif == 0) + { + if (diffIndex || !files1[i1].getName().equals("index.xsb")) + filesAsXsb(files1[i1], files2[i2], diffs); // Compare the files + i1++; i2++; // Move to next pair + } + else if (dif < 0) + { + // dir1 contains a file that dir2 doesn't + diffs.add("Dir \"" + dir1.getName() + "\" contains an extra file: \"" + + name1 + "\""); + i1++; + } + else if (dif > 0) + { + // dir2 contains a file that dir1 doesn't + diffs.add("Dir \"" + dir2.getName() + "\" contains an extra file: \"" + + name2 + "\""); + i2++; + } + } + while (i1 < files1.length) + { + diffs.add("Dir \"" + dir1.getName() + "\" contains an extra file: \"" + + files1[i1].getName() + "\""); + i1++; + } + while (i2 < files2.length) + { + diffs.add("Dir \"" + dir2.getName() + "\" contains an extra file: \"" + + files2[i2].getName() + "\""); + i2++; + } + } + + private static boolean isDiffIndex() + { + String prop = SystemProperties.getProperty("xmlbeans.diff.diffIndex"); + if (prop == null) + return true; + if ("0".equals(prop) || "false".equalsIgnoreCase(prop)) + return false; + return true; + } + + /** + * Diffs the two given files assuming they are in xsb format + * Updates diffs with differences in string format + */ + public static void filesAsXsb(File file1, File file2, List diffs) + { + assert file1.exists() : "File \"" + file1.getAbsolutePath() + "\" does not exist."; + assert file2.exists() : "File \"" + file2.getAbsolutePath() + "\" does not exist."; + try + { + FileInputStream stream1 = new FileInputStream(file1); + FileInputStream stream2 = new FileInputStream(file2); + streamsAsXsb(stream1, file1.getName(), stream2, file2.getName(), diffs); + } + catch (FileNotFoundException fnfe) + { } + catch (IOException ioe) + { } + } + + public static void zipEntriesAsXsb(ZipEntry file1, JarFile jar1, + ZipEntry file2, JarFile jar2, List diffs) + { + try + { + InputStream stream1 = jar1.getInputStream(file1); + InputStream stream2 = jar2.getInputStream(file2); + streamsAsXsb(stream1, file1.getName(), stream2, file2.getName(), diffs); + } + catch (IOException ioe) + { } + } + + public static void streamsAsXsb(InputStream stream1, String name1, + InputStream stream2, String name2, List diffs) + throws IOException + { + ByteArrayOutputStream buf1 = new ByteArrayOutputStream(); + ByteArrayOutputStream buf2 = new ByteArrayOutputStream(); + XsbDumper.dump(stream1, "", new PrintStream(buf1)); + XsbDumper.dump(stream2, "", new PrintStream(buf2)); + stream1.close(); + stream2.close(); + readersAsText(new StringReader(buf1.toString()), name1, + new StringReader(buf2.toString()), name2, diffs); + } + + public static void readersAsText(Reader r1, String name1, Reader r2, String name2, + List diffs) + throws IOException + { + org.apache.xmlbeans.impl.util.Diff.readersAsText(r1, name1, r2, name2, diffs); + } + + private static class XsbFilenameFilter implements FilenameFilter + { + public boolean accept(File dir, String name) + { + return name.endsWith(".xsb"); + } + } + + private static class ZipEntryNameComparator implements Comparator + { + public boolean equals(Object object) + { + return this == object; + } + + public int compare(Object object1, Object object2) + { + assert (object1 instanceof ZipEntry) : "Must pass in a java.util.zip.ZipEntry as argument"; + assert (object2 instanceof ZipEntry) : "Must pass in a java.util.zip.ZipEntry as argument"; + + String name1 = ((ZipEntry) object1).getName(); + String name2 = ((ZipEntry) object2).getName(); + return name1.compareTo(name2); + } + } + + private static class FileNameComparator implements Comparator + { + public boolean equals(Object object) + { + return this == object; + } + + public int compare(Object object1, Object object2) + { + assert (object1 instanceof File) : "Must pass in a java.io.File as argument"; + assert (object2 instanceof File) : "Must pass in a java.io.File as argument"; + + String name1 = ((File) object1).getName(); + String name2 = ((File) object2).getName(); + return name1.compareTo(name2); + } + } +} diff --git a/xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/Extension.java b/xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/Extension.java new file mode 100644 index 000000000..ffd7b8d78 --- /dev/null +++ b/xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/Extension.java @@ -0,0 +1,70 @@ +/* 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.tool; + +import java.util.List; +import java.util.ArrayList; + + + /** + * An extension is a javabean that represents a SchemaCompilerExtension to be passed for callback into the + * XmlBeans Schema Compiler. + */ +public class Extension { + private Class className; + private List params = new ArrayList(); + + public Class getClassName() { + return className; + } + + public void setClassName(Class className) { + this.className = className; + } + public List getParams() { + return params; + } + + public Param createParam() { + Param p = new Param(); + params.add(p); + return p; + } + + /** + * A Param is just a name value pair applicable to the extension. + */ + public class Param { + private String name; + private String value; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + } + } \ No newline at end of file diff --git a/xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/FactorImports.java b/xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/FactorImports.java new file mode 100644 index 000000000..bf1dd210b --- /dev/null +++ b/xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/FactorImports.java @@ -0,0 +1,475 @@ +/* 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.tool; + +import org.apache.xmlbeans.impl.xb.xsdschema.SchemaDocument; +import org.apache.xmlbeans.impl.xb.xsdschema.TopLevelComplexType; +import org.apache.xmlbeans.impl.xb.xsdschema.TopLevelSimpleType; +import org.apache.xmlbeans.impl.xb.xsdschema.TopLevelElement; +import org.apache.xmlbeans.impl.xb.xsdschema.TopLevelAttribute; +import org.apache.xmlbeans.impl.xb.xsdschema.NamedGroup; +import org.apache.xmlbeans.impl.xb.xsdschema.NamedAttributeGroup; +import org.apache.xmlbeans.impl.xb.xsdschema.FormChoice; +import org.apache.xmlbeans.impl.xb.xsdschema.IncludeDocument; + +import java.util.Arrays; +import java.util.Set; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.HashMap; +import java.io.File; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; + +import org.apache.xmlbeans.XmlException; +import org.apache.xmlbeans.XmlOptions; + +import javax.xml.namespace.QName; + +/** + * This program takes a collection of .xsd files as input, finds all duplicate + * name definitions, and factors out the first instance of each of those into + * a common.xsd file, adding an appropriate statement in the original + * xsd file. + */ +public class FactorImports +{ + public static void printUsage() + { + System.out.println("Refactors a directory of XSD files to remove name conflicts."); + System.out.println("Usage: sfactor [-import common.xsd] [-out outputdir] inputdir"); + System.out.println(" -import common.xsd - The XSD file to contain redundant "); + System.out.println(" definitions for importing."); + System.out.println(" -out outputdir - The directory into which to place XSD "); + System.out.println(" files resulting from refactoring, "); + System.out.println(" plus a commonly imported common.xsd."); + System.out.println(" inputdir - The directory containing the XSD files with"); + System.out.println(" redundant definitions."); + System.out.println(" -license - Print license information."); + System.out.println(); + + } + + public static void main(String[] args) throws Exception + { + Set flags = new HashSet(); + flags.add("h"); + flags.add("help"); + flags.add("usage"); + flags.add("license"); + flags.add("version"); + + CommandLine cl = new CommandLine(args, flags, Arrays.asList(new String[] {"import", "out"})); + if (cl.getOpt("h") != null || cl.getOpt("help") != null || cl.getOpt("usage") != null || args.length < 1) + { + printUsage(); + System.exit(0); + return; + } + + String[] badopts = cl.getBadOpts(); + if (badopts.length > 0) + { + for (int i = 0; i < badopts.length; i++) + System.out.println("Unrecognized option: " + badopts[i]); + printUsage(); + System.exit(0); + return; + } + + if (cl.getOpt("license") != null) + { + CommandLine.printLicense(); + System.exit(0); + return; + } + + if (cl.getOpt("version") != null) + { + CommandLine.printVersion(); + System.exit(0); + return; + } + + args = cl.args(); + if (args.length != 1) + { + System.exit(0); + return; + } + + String commonName = cl.getOpt("import"); + if (commonName == null) + commonName = "common.xsd"; + + String out = cl.getOpt("out"); + if (out == null) + { + System.out.println("Using output directory 'out'"); + out = "out"; + } + File outdir = new File(out); + File basedir = new File(args[0]); + + // first, parse all the schema files + File[] files = cl.getFiles(); + Map schemaDocs = new HashMap(); + Set elementNames = new HashSet(); + Set attributeNames = new HashSet(); + Set typeNames = new HashSet(); + Set modelGroupNames = new HashSet(); + Set attrGroupNames = new HashSet(); + + Set dupeElementNames = new HashSet(); + Set dupeAttributeNames = new HashSet(); + Set dupeTypeNames = new HashSet(); + Set dupeModelGroupNames = new HashSet(); + Set dupeAttrGroupNames = new HashSet(); + Set dupeNamespaces = new HashSet(); + + for (int i = 0; i < files.length; i++) + { + try + { + // load schema + SchemaDocument doc = SchemaDocument.Factory.parse(files[i]); + schemaDocs.put(doc, files[i]); + + // warn about for imports, includes + if (doc.getSchema().sizeOfImportArray() > 0 || doc.getSchema().sizeOfIncludeArray() > 0) + System.out.println("warning: " + files[i] + " contains imports or includes that are being ignored."); + + // collect together names + String targetNamespace = doc.getSchema().getTargetNamespace(); + if (targetNamespace == null) + targetNamespace = ""; + + TopLevelComplexType ct[] = doc.getSchema().getComplexTypeArray(); + for (int j = 0; j < ct.length; j++) + noteName(ct[j].getName(), targetNamespace, typeNames, dupeTypeNames, dupeNamespaces); + + TopLevelSimpleType st[] = doc.getSchema().getSimpleTypeArray(); + for (int j = 0; j < st.length; j++) + noteName(st[j].getName(), targetNamespace, typeNames, dupeTypeNames, dupeNamespaces); + + TopLevelElement el[] = doc.getSchema().getElementArray(); + for (int j = 0; j < el.length; j++) + noteName(el[j].getName(), targetNamespace, elementNames, dupeElementNames, dupeNamespaces); + + TopLevelAttribute at[] = doc.getSchema().getAttributeArray(); + for (int j = 0; j < at.length; j++) + noteName(at[j].getName(), targetNamespace, attributeNames, dupeAttributeNames, dupeNamespaces); + + NamedGroup gr[] = doc.getSchema().getGroupArray(); + for (int j = 0; j < gr.length; j++) + noteName(gr[j].getName(), targetNamespace, modelGroupNames, dupeModelGroupNames, dupeNamespaces); + + NamedAttributeGroup ag[] = doc.getSchema().getAttributeGroupArray(); + for (int j = 0; j < ag.length; j++) + noteName(ag[j].getName(), targetNamespace, attrGroupNames, dupeAttrGroupNames, dupeNamespaces); + + } + catch (XmlException e) + { + System.out.println("warning: " + files[i] + " is not a schema file - " + e.getError().toString()); + } + catch (IOException e) + { + System.err.println("Unable to load " + files[i] + " - " + e.getMessage()); + System.exit(1); + return; + } + } + + if (schemaDocs.size() == 0) + { + System.out.println("No schema files found."); + System.exit(0); + return; + } + + if (dupeTypeNames.size() + dupeElementNames.size() + dupeAttributeNames.size() + + dupeModelGroupNames.size() + dupeAttrGroupNames.size() == 0) + { + System.out.println("No duplicate names found."); + System.exit(0); + return; + } + + // create a schema doc for each namespace to be imported + Map commonDocs = new HashMap(); + Map commonFiles = new HashMap(); + int count = dupeNamespaces.size() == 1 ? 0 : 1; + for (Iterator i = dupeNamespaces.iterator(); i.hasNext(); ) + { + String namespace = (String)i.next(); + SchemaDocument commonDoc = SchemaDocument.Factory.parse( + "" + ); + if (namespace.length() > 0) + commonDoc.getSchema().setTargetNamespace(namespace); + commonDoc.getSchema().setElementFormDefault(FormChoice.QUALIFIED); + commonDocs.put(namespace, commonDoc); + commonFiles.put(commonDoc, commonFileFor(commonName, namespace, count++, outdir)); + } + + // pull out all the duplicate definitions and drop them into the file + // we reuse the elementNames (etc) sets to keep track of which definitions + // we have already inserted. + for (Iterator i = schemaDocs.keySet().iterator(); i.hasNext(); ) + { + SchemaDocument doc = (SchemaDocument)i.next(); + + // collect together names + String targetNamespace = doc.getSchema().getTargetNamespace(); + if (targetNamespace == null) + targetNamespace = ""; + + SchemaDocument commonDoc = (SchemaDocument)commonDocs.get(targetNamespace); + + boolean needImport = false; + + TopLevelComplexType ct[] = doc.getSchema().getComplexTypeArray(); + for (int j = ct.length - 1; j >= 0; j--) + { + if (!isDuplicate(ct[j].getName(), targetNamespace, dupeTypeNames)) + continue; + if (isFirstDuplicate(ct[j].getName(), targetNamespace, typeNames, dupeTypeNames)) + commonDoc.getSchema().addNewComplexType().set(ct[j]); + needImport = true; + doc.getSchema().removeComplexType(j); + } + + TopLevelSimpleType st[] = doc.getSchema().getSimpleTypeArray(); + for (int j = 0; j < st.length; j++) + { + if (!isDuplicate(st[j].getName(), targetNamespace, dupeTypeNames)) + continue; + if (isFirstDuplicate(st[j].getName(), targetNamespace, typeNames, dupeTypeNames)) + commonDoc.getSchema().addNewSimpleType().set(st[j]); + needImport = true; + doc.getSchema().removeSimpleType(j); + } + + TopLevelElement el[] = doc.getSchema().getElementArray(); + for (int j = 0; j < el.length; j++) + { + if (!isDuplicate(el[j].getName(), targetNamespace, dupeElementNames)) + continue; + if (isFirstDuplicate(el[j].getName(), targetNamespace, elementNames, dupeElementNames)) + commonDoc.getSchema().addNewElement().set(el[j]); + needImport = true; + doc.getSchema().removeElement(j); + } + + TopLevelAttribute at[] = doc.getSchema().getAttributeArray(); + for (int j = 0; j < at.length; j++) + { + if (!isDuplicate(at[j].getName(), targetNamespace, dupeAttributeNames)) + continue; + if (isFirstDuplicate(at[j].getName(), targetNamespace, attributeNames, dupeAttributeNames)) + commonDoc.getSchema().addNewElement().set(at[j]); + needImport = true; + doc.getSchema().removeElement(j); + } + + NamedGroup gr[] = doc.getSchema().getGroupArray(); + for (int j = 0; j < gr.length; j++) + { + if (!isDuplicate(gr[j].getName(), targetNamespace, dupeModelGroupNames)) + continue; + if (isFirstDuplicate(gr[j].getName(), targetNamespace, modelGroupNames, dupeModelGroupNames)) + commonDoc.getSchema().addNewElement().set(gr[j]); + needImport = true; + doc.getSchema().removeElement(j); + } + + NamedAttributeGroup ag[] = doc.getSchema().getAttributeGroupArray(); + for (int j = 0; j < ag.length; j++) + { + if (!isDuplicate(ag[j].getName(), targetNamespace, dupeAttrGroupNames)) + continue; + if (isFirstDuplicate(ag[j].getName(), targetNamespace, attrGroupNames, dupeAttrGroupNames)) + commonDoc.getSchema().addNewElement().set(ag[j]); + needImport = true; + doc.getSchema().removeElement(j); + } + + if (needImport) + { + IncludeDocument.Include newInclude = doc.getSchema().addNewInclude(); + File inputFile = (File)schemaDocs.get(doc); + File outputFile = outputFileFor(inputFile, basedir, outdir); + File commonFile = (File)commonFiles.get(commonDoc); + if (targetNamespace != null) + newInclude.setSchemaLocation(relativeURIFor(outputFile, commonFile)); + } + } + + // make the directory for output + if (!outdir.isDirectory() && !outdir.mkdirs()) + { + System.err.println("Unable to makedir " + outdir); + System.exit(1); + return; + } + + // now write all those docs back out. + for (Iterator i = schemaDocs.keySet().iterator(); i.hasNext(); ) + { + SchemaDocument doc = (SchemaDocument)i.next(); + File inputFile = (File)schemaDocs.get(doc); + File outputFile = outputFileFor(inputFile, basedir, outdir); + if (outputFile == null) + System.out.println("Cannot copy " + inputFile); + else + doc.save(outputFile, new XmlOptions().setSavePrettyPrint().setSaveAggresiveNamespaces()); + } + + for (Iterator i = commonFiles.keySet().iterator(); i.hasNext(); ) + { + SchemaDocument doc = (SchemaDocument)i.next(); + File outputFile = (File)commonFiles.get(doc); + doc.save(outputFile, new XmlOptions().setSavePrettyPrint().setSaveAggresiveNamespaces()); + } + + } + + private static File outputFileFor(File file, File baseDir, File outdir) + { + URI base = baseDir.getAbsoluteFile().toURI(); + URI abs = file.getAbsoluteFile().toURI(); + URI rel = base.relativize(abs); + if (rel.isAbsolute()) + { + System.out.println("Cannot relativize " + file); + return null; + } + + URI outbase = outdir.toURI(); + URI out = CodeGenUtil.resolve(outbase, rel); + return new File(out); + } + + private static URI commonAncestor(URI first, URI second) + { + String firstStr = first.toString(); + String secondStr = second.toString(); + int len = firstStr.length(); + if (secondStr.length() < len) + len = secondStr.length(); + int i; + for (i = 0; i < len; i++) + { + if (firstStr.charAt(i) != secondStr.charAt(i)) + break; + } + i -= 1; + if (i >= 0) + i = firstStr.lastIndexOf('/', i); + if (i < 0) + return null; + try + { + return new URI(firstStr.substring(0, i)); + } + catch (URISyntaxException e) + { + return null; + } + } + + + private static String relativeURIFor(File source, File target) + { + URI base = source.getAbsoluteFile().toURI(); + URI abs = target.getAbsoluteFile().toURI(); + // find common substring... + URI commonBase = commonAncestor(base, abs); + if (commonBase == null) + return abs.toString(); + + URI baserel = commonBase.relativize(base); + URI targetrel = commonBase.relativize(abs); + if (baserel.isAbsolute() || targetrel.isAbsolute()) + return abs.toString(); + String prefix = ""; + String sourceRel = baserel.toString(); + for (int i = 0; i < sourceRel.length();) + { + i = sourceRel.indexOf('/', i); + if (i < 0) + break; + prefix += "../"; + i += 1; + } + return prefix + targetrel.toString(); + } + + private static File commonFileFor(String commonName, String namespace, int i, File outdir) + { + String name = commonName; + if (i > 0) + { + int index = commonName.lastIndexOf('.'); + if (index < 0) + index = commonName.length(); + name = commonName.substring(0, index) + i + commonName.substring(index); + } + return new File(outdir, name); + } + + + private static void noteName(String name, String targetNamespace, Set seen, Set dupes, Set dupeNamespaces) + { + if (name == null) + return; + QName qName = new QName(targetNamespace, name); + if (seen.contains(qName)) + { + dupes.add(qName); + dupeNamespaces.add(targetNamespace); + } + else + seen.add(qName); + + } + + private static boolean isFirstDuplicate(String name, String targetNamespace, Set notseen, Set dupes) + { + if (name == null) + return false; + QName qName = new QName(targetNamespace, name); + if (dupes.contains(qName) && notseen.contains(qName)) + { + notseen.remove(qName); + return true; + } + return false; + } + + private static boolean isDuplicate(String name, String targetNamespace, Set dupes) + { + if (name == null) + return false; + QName qName = new QName(targetNamespace, name); + return (dupes.contains(qName)); + } + + +} diff --git a/xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/InstanceValidator.java b/xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/InstanceValidator.java new file mode 100644 index 000000000..f0e9dace5 --- /dev/null +++ b/xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/InstanceValidator.java @@ -0,0 +1,225 @@ +/* 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.tool; + +import org.apache.xmlbeans.XmlBeans; +import org.apache.xmlbeans.XmlOptions; +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.SchemaTypeLoader; +import org.apache.xmlbeans.XmlException; + +import java.util.Collections; +import java.util.List; +import java.util.ArrayList; +import java.util.Set; +import java.util.HashSet; +import java.util.Collection; +import java.util.Iterator; +import java.io.File; + +public class InstanceValidator +{ + public static void printUsage() + { + System.out.println("Validates the specified instance against the specified schema."); + System.out.println("Contrast with the svalidate tool, which validates using a stream."); + System.out.println("Usage: validate [-dl] [-nopvr] [-noupa] [-license] schema.xsd instance.xml"); + System.out.println("Options:"); + System.out.println(" -dl - permit network downloads for imports and includes (default is off)"); + System.out.println(" -noupa - do not enforce the unique particle attribution rule"); + System.out.println(" -nopvr - do not enforce the particle valid (restriction) rule"); + System.out.println(" -strict - performs strict(er) validation"); + System.out.println(" -partial - allow partial schema type system"); + System.out.println(" -license - prints license information"); + } + + public static void main(String[] args) + { + System.exit(extraMain(args)); + } + + /** + * Use this method to avoid calling {@link java.lang.System#exit(int)} + * @param args are command line options + * @return exitCode + */ + public static int extraMain(String[] args) + { + Set flags = new HashSet(); + flags.add("h"); + flags.add("help"); + flags.add("usage"); + flags.add("license"); + flags.add("version"); + flags.add("dl"); + flags.add("noupa"); + flags.add("nopvr"); + flags.add("strict"); + flags.add("partial"); + + CommandLine cl = new CommandLine(args, flags, Collections.EMPTY_SET); + + if (cl.getOpt("h") != null || cl.getOpt("help") != null || cl.getOpt("usage") != null || args.length < 1) + { + printUsage(); + return 0; + } + + String[] badopts = cl.getBadOpts(); + if (badopts.length > 0) + { + for (int i = 0; i < badopts.length; i++) + System.out.println("Unrecognized option: " + badopts[i]); + printUsage(); + return 0; + } + + if (cl.getOpt("license") != null) + { + CommandLine.printLicense(); + return 0; + } + + if (cl.getOpt("version") != null) + { + CommandLine.printVersion(); + return 0; + } + + if (cl.args().length == 0) + { + return 0; + } + + boolean dl = (cl.getOpt("dl") != null); + boolean nopvr = (cl.getOpt("nopvr") != null); + boolean noupa = (cl.getOpt("noupa") != null); + boolean strict = (cl.getOpt("strict") != null); + boolean partial = (cl.getOpt("partial") != null); + + File[] schemaFiles = cl.filesEndingWith(".xsd"); + File[] instanceFiles = cl.filesEndingWith(".xml"); + File[] jarFiles = cl.filesEndingWith(".jar"); + + List sdocs = new ArrayList(); + + + for (int i = 0; i < schemaFiles.length; i++) + { + try + { + sdocs.add( + XmlObject.Factory.parse( + schemaFiles[i], (new XmlOptions()).setLoadLineNumbers().setLoadMessageDigest())); + } + catch (Exception e) + { + System.err.println( schemaFiles[i] + " not loadable: " + e ); + } + } + + XmlObject[] schemas = (XmlObject[])sdocs.toArray(new XmlObject[0]); + + SchemaTypeLoader sLoader = null; + Collection compErrors = new ArrayList(); + XmlOptions schemaOptions = new XmlOptions(); + schemaOptions.setErrorListener(compErrors); + if (dl) + schemaOptions.setCompileDownloadUrls(); + if (nopvr) + schemaOptions.setCompileNoPvrRule(); + if (noupa) + schemaOptions.setCompileNoUpaRule(); + if (partial) + schemaOptions.put("COMPILE_PARTIAL_TYPESYSTEM"); + + if (jarFiles != null && jarFiles.length > 0) + sLoader = XmlBeans.typeLoaderForResource(XmlBeans.resourceLoaderForPath(jarFiles)); + + int returnCode = 0; + + try + { + if (schemas != null && schemas.length > 0) + sLoader = XmlBeans.compileXsd(schemas, sLoader, schemaOptions); + } + catch (Exception e) + { + if (compErrors.isEmpty() || !(e instanceof XmlException)) + { + e.printStackTrace(System.err); + } + System.out.println("Schema invalid:" + (partial ? " couldn't recover from errors" : "")); + for (Iterator i = compErrors.iterator(); i.hasNext(); ) + System.out.println(i.next()); + + returnCode = 10; + return returnCode; + } + + // recovered from errors, print out errors + if (partial && !compErrors.isEmpty()) + { + returnCode = 11; + System.out.println("Schema invalid: partial schema type system recovered"); + for (Iterator i = compErrors.iterator(); i.hasNext(); ) + System.out.println(i.next()); + } + + if (sLoader == null) + sLoader = XmlBeans.getContextTypeLoader(); + + for (int i = 0; i < instanceFiles.length; i++) + { + XmlObject xobj; + + try + { + xobj = + sLoader.parse( instanceFiles[i], null, (new XmlOptions()).setLoadLineNumbers(XmlOptions.LOAD_LINE_NUMBERS_END_ELEMENT) ); + } + catch (Exception e) + { + System.err.println(instanceFiles[i] + " not loadable: " + e); + e.printStackTrace(System.err); + continue; + } + + Collection errors = new ArrayList(); + + if (xobj.schemaType() == XmlObject.type) + { + System.out.println(instanceFiles[i] + " NOT valid. "); + System.out.println(" Document type not found." ); + } + else if (xobj.validate(strict ? + new XmlOptions().setErrorListener(errors).setValidateStrict() : + new XmlOptions().setErrorListener(errors))) + System.out.println(instanceFiles[i] + " valid."); + else + { + returnCode = 1; + System.out.println(instanceFiles[i] + " NOT valid."); + for (Iterator it = errors.iterator(); it.hasNext(); ) + { + System.out.println(it.next()); + } + } + } + + return returnCode; + } +} diff --git a/xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/PrettyPrinter.java b/xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/PrettyPrinter.java new file mode 100644 index 000000000..b96d1fd3f --- /dev/null +++ b/xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/PrettyPrinter.java @@ -0,0 +1,132 @@ +/* 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.tool; + +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.XmlOptions; +import org.apache.xmlbeans.XmlException; + +import java.util.Set; +import java.util.HashSet; +import java.util.Collections; +import java.io.File; +import java.io.IOException; +import java.io.StringWriter; + +public class PrettyPrinter +{ + private static final int DEFAULT_INDENT = 2; + + public static void printUsage() + { + System.out.println("Pretty prints XML files."); + System.out.println("Usage: xpretty [switches] file.xml"); + System.out.println("Switches:"); + System.out.println(" -indent # use the given indent"); + System.out.println(" -license prints license information"); + } + + public static void main(String[] args) + { + Set flags = new HashSet(); + flags.add("h"); + flags.add("help"); + flags.add("usage"); + flags.add("license"); + flags.add("version"); + + CommandLine cl = new CommandLine(args, flags, Collections.singleton("indent")); + + if (cl.getOpt("h") != null || cl.getOpt("help") != null || cl.getOpt("usage") != null) + { + printUsage(); + System.exit(0); + return; + } + + String[] badopts = cl.getBadOpts(); + if (badopts.length > 0) + { + for (int i = 0; i < badopts.length; i++) + System.out.println("Unrecognized option: " + badopts[i]); + printUsage(); + System.exit(0); + return; + } + + if (cl.getOpt("license") != null) + { + CommandLine.printLicense(); + System.exit(0); + return; + } + + if (cl.getOpt("version") != null) + { + CommandLine.printVersion(); + System.exit(0); + return; + } + + if (cl.args().length == 0) + { + printUsage(); + return; + } + + String indentStr = cl.getOpt("indent"); + int indent; + if (indentStr == null) + indent = DEFAULT_INDENT; + else + indent = Integer.parseInt(indentStr); + + File[] files = cl.getFiles(); + + for (int i = 0; i < files.length; i++) + { + XmlObject doc; + try + { + doc = XmlObject.Factory.parse(files[i], (new XmlOptions()).setLoadLineNumbers()); + } + catch (Exception e) + { + System.err.println(files[i] + " not loadable: " + e.getMessage()); + continue; + } + + try + { + doc.save(System.out, new XmlOptions().setSavePrettyPrint().setSavePrettyPrintIndent(indent)); + } + catch (IOException e) + { + System.err.println("Unable to pretty print " + files[i] + ": " + e.getMessage()); + } + } + } + + public static String indent(String xmldoc) + throws IOException, XmlException + { + StringWriter sw = new StringWriter(); + XmlObject doc = XmlObject.Factory.parse(xmldoc, (new XmlOptions()).setLoadLineNumbers()); + doc.save(sw, new XmlOptions().setSavePrettyPrint().setSavePrettyPrintIndent(DEFAULT_INDENT)); + sw.close(); + return sw.getBuffer().toString(); + } +} diff --git a/xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/RunXQuery.java b/xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/RunXQuery.java new file mode 100644 index 000000000..c93c6c16f --- /dev/null +++ b/xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/RunXQuery.java @@ -0,0 +1,244 @@ +/* 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.tool; + +import java.io.*; +import java.util.*; +import org.apache.xmlbeans.*; + +public class RunXQuery +{ + public static void printUsage() + { + System.out.println("Run an XQuery against an XML instance"); + System.out.println("Usage:"); + System.out.println("xquery [-verbose] [-pretty] [-q | -qf query.xq] [file.xml]*"); + System.out.println(" -q to specify a query on the command-line"); + System.out.println(" -qf to specify a file containing a query"); + System.out.println(" -pretty pretty-prints the results"); + System.out.println(" -license prints license information"); + System.out.println(" the query is run on each XML file specified"); + System.out.println(""); + } + + public static void main ( String[] args ) throws Exception + { + Set flags = new HashSet(); + flags.add("h"); + flags.add("help"); + flags.add("usage"); + flags.add("license"); + flags.add("version"); + flags.add("verbose"); + flags.add("pretty"); + + CommandLine cl = + new CommandLine( + args, flags, + Arrays.asList( new String[] { "q", "qf" } ) ); + + if (cl.getOpt("h") != null || cl.getOpt("help") != null || cl.getOpt("usage") != null) + { + printUsage(); + System.exit(0); + return; + } + + String[] badopts = cl.getBadOpts(); + if (badopts.length > 0) + { + for (int i = 0; i < badopts.length; i++) + System.out.println("Unrecognized option: " + badopts[i]); + printUsage(); + System.exit(0); + return; + } + + if (cl.getOpt("license") != null) + { + CommandLine.printLicense(); + System.exit(0); + return; + } + + if (cl.getOpt("version") != null) + { + CommandLine.printVersion(); + System.exit(0); + return; + } + + args = cl.args(); + + if (args.length == 0) + { + printUsage(); + System.exit(0); + return; + } + + boolean verbose = cl.getOpt( "verbose" ) != null; + boolean pretty = cl.getOpt( "pretty" ) != null; + + // + // Get and compile the query + // + + String query = cl.getOpt( "q" ); + String queryfile = cl.getOpt( "qf" ); + + if (query == null && queryfile == null) + { + System.err.println( "No query specified" ); + System.exit(0); + return; + } + + if (query != null && queryfile != null) + { + System.err.println( "Specify -qf or -q, not both." ); + System.exit(0); + return; + } + + try + { + if (queryfile != null) + { + File queryFile = new File( queryfile ); + FileInputStream is = new FileInputStream( queryFile ); + InputStreamReader r = new InputStreamReader( is ); + + StringBuffer sb = new StringBuffer(); + + for ( ; ; ) + { + int ch = r.read(); + + if (ch < 0) + break; + + sb.append( (char) ch ); + } + + r.close(); + is.close(); + + query = sb.toString(); + } + } + catch ( Throwable e ) + { + System.err.println( "Cannot read query file: " + e.getMessage() ); + System.exit(1); + return; + } + + if (verbose) + { + System.out.println( "Compile Query:" ); + System.out.println( query ); + System.out.println(); + } + + try + { + query= XmlBeans.compileQuery( query ); + } + catch ( Exception e ) + { + System.err.println( "Error compiling query: " + e.getMessage() ); + System.exit(1); + return; + } + + // + // Get the instance + // + + File[] files = cl.getFiles(); + + for (int i = 0; i < files.length; i++) + { + XmlObject x; + + try + { + if (verbose) + { + InputStream is = new FileInputStream( files[i] ); + + for ( ; ; ) + { + int ch = is.read(); + + if (ch < 0) + break; + + System.out.write( ch ); + } + + is.close(); + + System.out.println(); + } + + x = XmlObject.Factory.parse( files[i] ); + } + catch ( Throwable e ) + { + System.err.println( "Error parsing instance: " + e.getMessage() ); + System.exit(1); + return; + } + + if (verbose) + { + System.out.println( "Executing Query..." ); + System.err.println(); + } + + XmlObject[] result = null; + + try + { + result = x.execQuery( query ); + } + catch ( Throwable e ) + { + System.err.println( "Error executing query: " + e.getMessage() ); + System.exit(1); + return; + } + + if (verbose) + { + System.out.println( "Query Result:" ); + } + + XmlOptions opts = new XmlOptions(); + opts.setSaveOuter(); + if (pretty) + opts.setSavePrettyPrint(); + + for (int j = 0; j < result.length; j++) + { + result[j].save( System.out, opts ); + System.out.println(); + } + } + } +} diff --git a/xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/SchemaCodeGenerator.java b/xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/SchemaCodeGenerator.java new file mode 100644 index 000000000..e8bd8dc28 --- /dev/null +++ b/xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/SchemaCodeGenerator.java @@ -0,0 +1,253 @@ +/* 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.tool; + +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.SchemaTypeSystem; +import org.apache.xmlbeans.SystemProperties; +import org.apache.xmlbeans.impl.common.IOUtil; +import org.apache.xmlbeans.impl.common.XmlErrorWatcher; +import org.apache.xmlbeans.impl.schema.SchemaTypeCodePrinter; +import org.apache.xmlbeans.impl.schema.SchemaTypeSystemCompiler; +import org.apache.xmlbeans.impl.util.FilerImpl; +import org.apache.xmlbeans.SchemaCodePrinter; +import org.apache.xmlbeans.XmlOptions; +import org.apache.xmlbeans.Filer; +import repackage.Repackager; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.StringWriter; +import java.io.Reader; +import java.io.Writer; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +public class SchemaCodeGenerator +{ + /** + * Saves a SchemaTypeSystem to the specified directory. + * + * @param system the SchemaTypeSystem to save + * @param classesDir the destination directory for xsb's + * @param sourceFile if present, the TypeSystemHolder source will be + * generated in this file for subsequent compilation, + * if null then the source will be generated in a temp + * directory and then compiled to the destination dir + * @param repackager the repackager to use when generating the holder class + * @param options options. Can be null + * @deprecated Use {@link SchemaTypeSystem.save()} instead. + */ + public static void saveTypeSystem(SchemaTypeSystem system, File classesDir, + File sourceFile, Repackager repackager, XmlOptions options) + throws IOException + { + Filer filer = new FilerImpl(classesDir, null, repackager, false, false); + system.save(filer); + } + + static void deleteObsoleteFiles(File rootDir, File srcDir, Set seenFiles) + { + if (!(rootDir.isDirectory() && srcDir.isDirectory())) + throw new IllegalArgumentException(); + String absolutePath = srcDir.getAbsolutePath(); + // Do a sanity check to make sure we don't delete by mistake some important dir + if (absolutePath.length() <= 5) + return; + if (absolutePath.startsWith("/home/") && + (absolutePath.indexOf("/", 6) >= absolutePath.length() - 1 || + absolutePath.indexOf("/", 6) < 0)) + return; + + // Go recursively starting with srcDir and delete all files that are + // not in the given Set + File[] files = srcDir.listFiles(); + for (int i = 0; i < files.length; i++) + { + if (files[i].isDirectory()) + deleteObsoleteFiles(rootDir, files[i], seenFiles); + else if (seenFiles.contains(files[i])) + ; + else + { + deleteXmlBeansFile(files[i]); + deleteDirRecursively(rootDir, files[i].getParentFile()); + } + } + } + + private static void deleteXmlBeansFile(File file) + { + if (file.getName().endsWith(".java")) + file.delete(); + } + + private static void deleteDirRecursively(File root, File dir) + { + String[] list = dir.list(); + while (list != null && list.length == 0 && !dir.equals(root)) + { + dir.delete(); + dir = dir.getParentFile(); + list = dir.list(); + } + } + + protected static File createTempDir() throws IOException + { + +// Some beta builds of JDK1.5 are having troubles creating temp directories +// if the java.io.tmpdir doesn't exist. This seems to help. +try { + File tmpDirFile = new File(SystemProperties.getProperty("java.io.tmpdir")); + tmpDirFile.mkdirs(); +} catch(Exception e) { e.printStackTrace(); } + + File tmpFile = File.createTempFile("xbean", null); + String path = tmpFile.getAbsolutePath(); + if (!path.endsWith(".tmp")) + throw new IOException("Error: createTempFile did not create a file ending with .tmp"); + path = path.substring(0, path.length() - 4); + File tmpSrcDir = null; + + for (int count = 0; count < 100; count++) + { + String name = path + ".d" + (count == 0 ? "" : Integer.toString(count++)); + + tmpSrcDir = new File(name); + + if (!tmpSrcDir.exists()) + { + boolean created = tmpSrcDir.mkdirs(); + assert created : "Could not create " + tmpSrcDir.getAbsolutePath(); + break; + } + } + tmpFile.deleteOnExit(); + + return tmpSrcDir; + } + + protected static void tryHardToDelete(File dir) + { + tryToDelete(dir); + if (dir.exists()) + tryToDeleteLater(dir); + } + + private static void tryToDelete(File dir) + { + if (dir.exists()) + { + if (dir.isDirectory()) + { + String[] list = dir.list(); // can return null if I/O error + if (list != null) + for (int i = 0; i < list.length; i++) + tryToDelete(new File(dir, list[i])); + } + if (!dir.delete()) + return; // don't try very hard, because we're just deleting tmp + } + } + + private static Set deleteFileQueue = new HashSet(); + private static int triesRemaining = 0; + + private static boolean tryNowThatItsLater() + { + List files; + + synchronized (deleteFileQueue) + { + files = new ArrayList(deleteFileQueue); + deleteFileQueue.clear(); + } + + List retry = new ArrayList(); + + for (Iterator i = files.iterator(); i.hasNext(); ) + { + File file = (File)i.next(); + tryToDelete(file); + if (file.exists()) + retry.add(file); + } + + synchronized (deleteFileQueue) + { + if (triesRemaining > 0) + triesRemaining -= 1; + + if (triesRemaining <= 0 || retry.size() == 0) // done? + triesRemaining = 0; + else + deleteFileQueue.addAll(retry); // try again? + + return (triesRemaining <= 0); + } + } + + private static void giveUp() + { + synchronized (deleteFileQueue) + { + deleteFileQueue.clear(); + triesRemaining = 0; + } + } + + private static void tryToDeleteLater(File dir) + { + synchronized (deleteFileQueue) + { + deleteFileQueue.add(dir); + if (triesRemaining == 0) + { + new Thread() + { + public void run() + { + // repeats tryNow until triesRemaining == 0 + try + { + for (;;) + { + if (tryNowThatItsLater()) + return; // succeeded + Thread.sleep(1000 * 3); // wait three seconds + } + } + catch (InterruptedException e) + { + giveUp(); + } + } + }; + } + + if (triesRemaining < 10) + triesRemaining = 10; + } + } + +} diff --git a/xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/SchemaCompiler.java b/xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/SchemaCompiler.java new file mode 100644 index 000000000..11f4c9dd7 --- /dev/null +++ b/xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/SchemaCompiler.java @@ -0,0 +1,1269 @@ +/* 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.tool; + +import org.apache.xmlbeans.SchemaCodePrinter; +import org.apache.xmlbeans.SchemaTypeLoader; +import org.apache.xmlbeans.SchemaTypeSystem; +import org.apache.xmlbeans.SystemProperties; +import org.apache.xmlbeans.SimpleValue; +import org.apache.xmlbeans.XmlBeans; +import org.apache.xmlbeans.XmlErrorCodes; +import org.apache.xmlbeans.XmlException; +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.XmlOptions; +import org.apache.xmlbeans.ResourceLoader; +import org.apache.xmlbeans.impl.common.IOUtil; +import org.apache.xmlbeans.impl.common.ResolverUtil; +import org.apache.xmlbeans.impl.common.XmlErrorPrinter; +import org.apache.xmlbeans.impl.common.XmlErrorWatcher; +import org.apache.xmlbeans.impl.schema.PathResourceLoader; +import org.apache.xmlbeans.impl.schema.SchemaTypeLoaderImpl; +import org.apache.xmlbeans.impl.schema.SchemaTypeSystemCompiler; +import org.apache.xmlbeans.impl.schema.SchemaTypeSystemImpl; +import org.apache.xmlbeans.impl.schema.StscState; +import org.apache.xmlbeans.impl.common.JarHelper; +import org.apache.xmlbeans.impl.util.FilerImpl; +import org.apache.xmlbeans.impl.values.XmlListImpl; +import org.apache.xmlbeans.impl.xb.xmlconfig.ConfigDocument; +import org.apache.xmlbeans.impl.xb.xmlconfig.Extensionconfig; +import org.apache.xmlbeans.impl.xb.xsdschema.SchemaDocument; +import org.xml.sax.EntityResolver; +import org.apache.xmlbeans.impl.config.BindingConfigImpl; + +import java.io.File; +import java.io.IOException; +import java.net.URI; +import java.net.URL; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.StringTokenizer; +import repackage.Repackager; + +public class SchemaCompiler +{ + public static void printUsage() + { + System.out.println("Compiles a schema into XML Bean classes and metadata."); + System.out.println("Usage: scomp [opts] [dirs]* [schema.xsd]* [service.wsdl]* [config.xsdconfig]*"); + System.out.println("Options include:"); + System.out.println(" -cp [a;b;c] - classpath"); + System.out.println(" -d [dir] - target binary directory for .class and .xsb files"); + System.out.println(" -src [dir] - target directory for generated .java files"); + System.out.println(" -srconly - do not compile .java files or jar the output."); + System.out.println(" -out [xmltypes.jar] - the name of the output jar"); + System.out.println(" -dl - permit network downloads for imports and includes (default is off)"); + System.out.println(" -noupa - do not enforce the unique particle attribution rule"); + System.out.println(" -nopvr - do not enforce the particle valid (restriction) rule"); + System.out.println(" -noann - ignore annotations"); + System.out.println(" -novdoc - do not validate contents of "); + System.out.println(" -noext - ignore all extension (Pre/Post and Interface) found in .xsdconfig files"); + System.out.println(" -compiler - path to external java compiler"); + System.out.println(" -javasource [version] - generate java source compatible for a Java version (1.4 or 1.5)"); + System.out.println(" -ms - initial memory for external java compiler (default '" + CodeGenUtil.DEFAULT_MEM_START + "')"); + System.out.println(" -mx - maximum memory for external java compiler (default '" + CodeGenUtil.DEFAULT_MEM_MAX + "')"); + System.out.println(" -debug - compile with debug symbols"); + System.out.println(" -quiet - print fewer informational messages"); + System.out.println(" -verbose - print more informational messages"); + System.out.println(" -version - prints version information"); + System.out.println(" -license - prints license information"); + System.out.println(" -allowmdef \"[ns] [ns] [ns]\" - ignores multiple defs in given namespaces (use ##local for no-namespace)"); + System.out.println(" -catalog [file] - catalog file for org.apache.xml.resolver.tools.CatalogResolver. (Note: needs resolver.jar from http://xml.apache.org/commons/components/resolver/index.html)"); + /* Undocumented feature - pass in one schema compiler extension and related parameters + System.out.println(" -repackage - repackage specification"); + System.out.println(" -extension - registers a schema compiler extension"); + System.out.println(" -extensionParms - specify parameters for the compiler extension"); + System.out.println(" -schemaCodePrinter - specify SchemaCodePrinter class"); + */ + System.out.println(); + } + + public static void main(String[] args) + { + if (args.length == 0) + { + printUsage(); + System.exit(0); + return; + } + + Set flags = new HashSet(); + flags.add("h"); + flags.add("help"); + flags.add("usage"); + flags.add("license"); + flags.add("quiet"); + flags.add("verbose"); + flags.add("version"); + flags.add("dl"); + flags.add("noupa"); + flags.add("nopvr"); + flags.add("noann"); + flags.add("novdoc"); + flags.add("noext"); + flags.add("srconly"); + flags.add("debug"); + + Set opts = new HashSet(); + opts.add("out"); + opts.add("name"); + opts.add("src"); + opts.add("d"); + opts.add("cp"); + opts.add("compiler"); + opts.add("javasource"); + opts.add("jar"); // deprecated + opts.add("ms"); + opts.add("mx"); + opts.add("repackage"); + opts.add("schemaCodePrinter"); + opts.add("extension"); + opts.add("extensionParms"); + opts.add("allowmdef"); + opts.add("catalog"); + CommandLine cl = new CommandLine(args, flags, opts); + + if (cl.getOpt("h") != null || cl.getOpt("help") != null || cl.getOpt("usage") != null) + { + printUsage(); + System.exit(0); + return; + } + + String[] badopts = cl.getBadOpts(); + if (badopts.length > 0) + { + for (int i = 0; i < badopts.length; i++) + System.out.println("Unrecognized option: " + badopts[i]); + printUsage(); + System.exit(0); + return; + } + + if (cl.getOpt("license") != null) + { + CommandLine.printLicense(); + System.exit(0); + return; + } + + if (cl.getOpt("version") != null) + { + CommandLine.printVersion(); + System.exit(0); + return; + } + + args = cl.args(); + boolean verbose = (cl.getOpt("verbose") != null); + boolean quiet = (cl.getOpt("quiet") != null); + if (verbose) + quiet = false; + + if (verbose) + CommandLine.printVersion(); + + String outputfilename = cl.getOpt("out"); + + String repackage = cl.getOpt("repackage"); + + String codePrinterClass = cl.getOpt("schemaCodePrinter"); + SchemaCodePrinter codePrinter = null; + if (codePrinterClass != null) + { + try + { + codePrinter = (SchemaCodePrinter) + Class.forName(codePrinterClass).newInstance(); + } + catch (Exception e) + { + System.err.println + ("Failed to load SchemaCodePrinter class " + + codePrinterClass + "; proceeding with default printer"); + } + } + + String name = cl.getOpt("name"); + + boolean download = (cl.getOpt("dl") != null); + boolean noUpa = (cl.getOpt("noupa") != null); + boolean noPvr = (cl.getOpt("nopvr") != null); + boolean noAnn = (cl.getOpt("noann") != null); + boolean noVDoc= (cl.getOpt("novdoc") != null); + boolean noExt= (cl.getOpt("noext") != null); + boolean nojavac = (cl.getOpt("srconly") != null); + boolean debug = (cl.getOpt("debug") != null); + + String allowmdef = cl.getOpt("allowmdef"); + Set mdefNamespaces = (allowmdef == null ? Collections.EMPTY_SET : + new HashSet(Arrays.asList(XmlListImpl.split_list(allowmdef)))); + + List extensions = new ArrayList(); + if (cl.getOpt("extension") != null) { + try { + Extension e = new Extension(); + e.setClassName(Class.forName(cl.getOpt("extension"), false, Thread.currentThread().getContextClassLoader())); + extensions.add(e); + } catch (ClassNotFoundException e) { + System.err.println("Could not find extension class: " + cl.getOpt("extension") + " Is it on your classpath?"); + System.exit(1); + } + } + + if (extensions.size() > 0) + { + // example: -extensionParms typeMappingFileLocation=d:\types + if (cl.getOpt("extensionParms") != null) { + Extension e = (Extension) extensions.get(0); + // extensionParms are delimited by ';' + StringTokenizer parmTokens = new StringTokenizer(cl.getOpt("extensionParms"), ";"); + while (parmTokens.hasMoreTokens()) { + // get name value pair for each extension parms and stick into extension parms + String nvPair = parmTokens.nextToken(); + int index = nvPair.indexOf('='); + if (index < 0) + { + System.err.println("extensionParms should be name=value;name=value"); + System.exit(1); + } + String n = nvPair.substring(0, index); + String v = nvPair.substring(index + 1); + Extension.Param param = e.createParam(); + param.setName(n); + param.setValue(v); + } + } + } + + String classesdir = cl.getOpt("d"); + File classes = null; + if (classesdir != null) + classes = new File(classesdir); + + String srcdir = cl.getOpt("src"); + File src = null; + if (srcdir != null) + src = new File(srcdir); + if (nojavac && srcdir == null && classes != null) + src = classes; + + // create temp directory + File tempdir = null; + if (src == null || classes == null) + { + try + { + tempdir = SchemaCodeGenerator.createTempDir(); + } + catch (java.io.IOException e) + { + System.err.println("Error creating temp dir " + e); + System.exit(1); + } + } + + File jarfile = null; + if (outputfilename == null && classes == null && !nojavac) + outputfilename = "xmltypes.jar"; + if (outputfilename != null) + jarfile = new File(outputfilename); + + if (src == null) + src = IOUtil.createDir(tempdir, "src"); + if (classes == null) + classes = IOUtil.createDir(tempdir, "classes"); + + File[] classpath = null; + String cpString = cl.getOpt("cp"); + if (cpString != null) + { + String[] cpparts = cpString.split(File.pathSeparator); + List cpList = new ArrayList(); + for (int i = 0; i < cpparts.length; i++) + cpList.add(new File(cpparts[i])); + classpath = (File[])cpList.toArray(new File[cpList.size()]); + } + else + { + classpath = CodeGenUtil.systemClasspath(); + } + + String javasource = cl.getOpt("javasource"); + String compiler = cl.getOpt("compiler"); + String jar = cl.getOpt("jar"); + if (verbose && jar != null) + System.out.println("The 'jar' option is no longer supported."); + + String memoryInitialSize = cl.getOpt("ms"); + String memoryMaximumSize = cl.getOpt("mx"); + + File[] xsdFiles = cl.filesEndingWith(".xsd"); + File[] wsdlFiles = cl.filesEndingWith(".wsdl"); + File[] javaFiles = cl.filesEndingWith(".java"); + File[] configFiles = cl.filesEndingWith(".xsdconfig"); + URL[] urlFiles = cl.getURLs(); + + if (xsdFiles.length + wsdlFiles.length + urlFiles.length == 0) + { + System.out.println("Could not find any xsd or wsdl files to process."); + System.exit(0); + } + File baseDir = cl.getBaseDir(); + URI baseURI = baseDir == null ? null : baseDir.toURI(); + + XmlErrorPrinter err = new XmlErrorPrinter(verbose, baseURI); + + String catString = cl.getOpt("catalog"); + + Parameters params = new Parameters(); + params.setBaseDir(baseDir); + params.setXsdFiles(xsdFiles); + params.setWsdlFiles(wsdlFiles); + params.setJavaFiles(javaFiles); + params.setConfigFiles(configFiles); + params.setUrlFiles(urlFiles); + params.setClasspath(classpath); + params.setOutputJar(jarfile); + params.setName(name); + params.setSrcDir(src); + params.setClassesDir(classes); + params.setCompiler(compiler); + params.setJavaSource(javasource); + params.setMemoryInitialSize(memoryInitialSize); + params.setMemoryMaximumSize(memoryMaximumSize); + params.setNojavac(nojavac); + params.setQuiet(quiet); + params.setVerbose(verbose); + params.setDownload(download); + params.setNoUpa(noUpa); + params.setNoPvr(noPvr); + params.setNoAnn(noAnn); + params.setNoVDoc(noVDoc); + params.setNoExt(noExt); + params.setDebug(debug); + params.setErrorListener(err); + params.setRepackage(repackage); + params.setExtensions(extensions); + params.setMdefNamespaces(mdefNamespaces); + params.setCatalogFile(catString); + params.setSchemaCodePrinter(codePrinter); + + boolean result = compile(params); + + if (tempdir != null) + SchemaCodeGenerator.tryHardToDelete(tempdir); + + if (!result) + System.exit(1); + + System.exit(0); + } + + public static class Parameters + { + private File baseDir; + private File[] xsdFiles; + private File[] wsdlFiles; + private File[] javaFiles; + private File[] configFiles; + private URL[] urlFiles; + private File[] classpath; + private File outputJar; + private String name; + private File srcDir; + private File classesDir; + private String memoryInitialSize; + private String memoryMaximumSize; + private String compiler; + private String javasource; + private boolean nojavac; + private boolean quiet; + private boolean verbose; + private boolean download; + private Collection errorListener; + private boolean noUpa; + private boolean noPvr; + private boolean noAnn; + private boolean noVDoc; + private boolean noExt; + private boolean debug; + private boolean incrementalSrcGen; + private String repackage; + private List extensions = Collections.EMPTY_LIST; + private Set mdefNamespaces = Collections.EMPTY_SET; + private String catalogFile; + private SchemaCodePrinter schemaCodePrinter; + private EntityResolver entityResolver; + + public File getBaseDir() + { + return baseDir; + } + + public void setBaseDir(File baseDir) + { + this.baseDir = baseDir; + } + + public File[] getXsdFiles() + { + return xsdFiles; + } + + public void setXsdFiles(File[] xsdFiles) + { + this.xsdFiles = xsdFiles; + } + + public File[] getWsdlFiles() + { + return wsdlFiles; + } + + public void setWsdlFiles(File[] wsdlFiles) + { + this.wsdlFiles = wsdlFiles; + } + + public File[] getJavaFiles() + { + return javaFiles; + } + + public void setJavaFiles(File[] javaFiles) + { + this.javaFiles = javaFiles; + } + + public File[] getConfigFiles() + { + return configFiles; + } + + public void setConfigFiles(File[] configFiles) + { + this.configFiles = configFiles; + } + + public URL[] getUrlFiles() + { + return urlFiles; + } + + public void setUrlFiles(URL[] urlFiles) + { + this.urlFiles = urlFiles; + } + + public File[] getClasspath() + { + return classpath; + } + + public void setClasspath(File[] classpath) + { + this.classpath = classpath; + } + + public File getOutputJar() + { + return outputJar; + } + + public void setOutputJar(File outputJar) + { + this.outputJar = outputJar; + } + + public String getName() + { + return name; + } + + public void setName(String name) + { + this.name = name; + } + + public File getSrcDir() + { + return srcDir; + } + + public void setSrcDir(File srcDir) + { + this.srcDir = srcDir; + } + + public File getClassesDir() + { + return classesDir; + } + + public void setClassesDir(File classesDir) + { + this.classesDir = classesDir; + } + + public boolean isNojavac() + { + return nojavac; + } + + public void setNojavac(boolean nojavac) + { + this.nojavac = nojavac; + } + + public boolean isQuiet() + { + return quiet; + } + + public void setQuiet(boolean quiet) + { + this.quiet = quiet; + } + + public boolean isVerbose() + { + return verbose; + } + + public void setVerbose(boolean verbose) + { + this.verbose = verbose; + } + + public boolean isDownload() + { + return download; + } + + public void setDownload(boolean download) + { + this.download = download; + } + + public boolean isNoUpa() + { + return noUpa; + } + + public void setNoUpa(boolean noUpa) + { + this.noUpa = noUpa; + } + + public boolean isNoPvr() + { + return noPvr; + } + + public void setNoPvr(boolean noPvr) + { + this.noPvr = noPvr; + } + + public boolean isNoAnn() + { + return noAnn; + } + + public void setNoAnn(boolean noAnn) + { + this.noAnn = noAnn; + } + + public boolean isNoVDoc() + { + return noVDoc; + } + + public void setNoVDoc(boolean newNoVDoc) + { + this.noVDoc = newNoVDoc; + } + + public boolean isNoExt() + { + return noExt; + } + + public void setNoExt(boolean newNoExt) + { + this.noExt = newNoExt; + } + + public boolean isIncrementalSrcGen() + { + return incrementalSrcGen; + } + + public void setIncrementalSrcGen(boolean incrSrcGen) + { + this.incrementalSrcGen = incrSrcGen; + } + + public boolean isDebug() + { + return debug; + } + + public void setDebug(boolean debug) + { + this.debug = debug; + } + + public String getMemoryInitialSize() + { + return memoryInitialSize; + } + + public void setMemoryInitialSize(String memoryInitialSize) + { + this.memoryInitialSize = memoryInitialSize; + } + + public String getMemoryMaximumSize() + { + return memoryMaximumSize; + } + + public void setMemoryMaximumSize(String memoryMaximumSize) + { + this.memoryMaximumSize = memoryMaximumSize; + } + + public String getCompiler() + { + return compiler; + } + + public void setCompiler(String compiler) + { + this.compiler = compiler; + } + + public String getJavaSource() + { + return javasource; + } + + public void setJavaSource(String javasource) + { + this.javasource = javasource; + } + + /** @deprecated */ + public String getJar() + { + return null; + } + + /** @deprecated */ + public void setJar(String jar) + { + // no op + } + + public Collection getErrorListener() + { + return errorListener; + } + + public void setErrorListener(Collection errorListener) + { + this.errorListener = errorListener; + } + + public String getRepackage() + { + return repackage; + } + + public void setRepackage(String newRepackage) + { + repackage = newRepackage; + } + + public List getExtensions() { + return extensions; + } + + public void setExtensions(List extensions) { + this.extensions = extensions; + } + + public Set getMdefNamespaces() + { + return mdefNamespaces; + } + + public void setMdefNamespaces(Set mdefNamespaces) + { + this.mdefNamespaces = mdefNamespaces; + } + + public String getCatalogFile() + { + return catalogFile; + } + + public void setCatalogFile(String catalogPropFile) + { + this.catalogFile = catalogPropFile; + } + + public SchemaCodePrinter getSchemaCodePrinter() + { + return schemaCodePrinter; + } + + public void setSchemaCodePrinter(SchemaCodePrinter schemaCodePrinter) + { + this.schemaCodePrinter = schemaCodePrinter; + } + + public EntityResolver getEntityResolver() { + return entityResolver; + } + + public void setEntityResolver(EntityResolver entityResolver) { + this.entityResolver = entityResolver; + } + } + + private static SchemaTypeSystem loadTypeSystem(String name, File[] xsdFiles, File[] wsdlFiles, URL[] urlFiles, File[] configFiles, + File[] javaFiles, ResourceLoader cpResourceLoader, + boolean download, boolean noUpa, boolean noPvr, boolean noAnn, boolean noVDoc, boolean noExt, + Set mdefNamespaces, File baseDir, Map sourcesToCopyMap, + Collection outerErrorListener, File schemasDir, EntityResolver entResolver, File[] classpath, String javasource) + { + XmlErrorWatcher errorListener = new XmlErrorWatcher(outerErrorListener); + + // construct the state (have to initialize early in case of errors) + StscState state = StscState.start(); + state.setErrorListener(errorListener); + + // For parsing XSD and WSDL files, we should use the SchemaDocument + // classloader rather than the thread context classloader. This is + // because in some situations (such as when being invoked by ant + // underneath the ide) the context classloader is potentially weird + // (because of the design of ant). + + SchemaTypeLoader loader = XmlBeans.typeLoaderForClassLoader(SchemaDocument.class.getClassLoader()); + + // step 1, parse all the XSD files. + ArrayList scontentlist = new ArrayList(); + if (xsdFiles != null) + { + for (int i = 0; i < xsdFiles.length; i++) + { + try + { + XmlOptions options = new XmlOptions(); + options.setLoadLineNumbers(); + options.setLoadMessageDigest(); + options.setEntityResolver(entResolver); + + XmlObject schemadoc = loader.parse(xsdFiles[i], null, options); + if (!(schemadoc instanceof SchemaDocument)) + { + StscState.addError(errorListener, XmlErrorCodes.INVALID_DOCUMENT_TYPE, + new Object[] { xsdFiles[i], "schema" }, schemadoc); + } + else + { + addSchema(xsdFiles[i].toString(), (SchemaDocument)schemadoc, + errorListener, noVDoc, scontentlist); + } + } + catch (XmlException e) + { + errorListener.add(e.getError()); + } + catch (Exception e) + { + StscState.addError(errorListener, XmlErrorCodes.CANNOT_LOAD_FILE, + new Object[] { "xsd", xsdFiles[i], e.getMessage() }, xsdFiles[i]); + } + } + } + + // step 2, parse all WSDL files + if (wsdlFiles != null) + { + for (int i = 0; i < wsdlFiles.length; i++) + { + try + { + XmlOptions options = new XmlOptions(); + options.setLoadLineNumbers(); + options.setLoadSubstituteNamespaces(Collections.singletonMap( + "http://schemas.xmlsoap.org/wsdl/", "http://www.apache.org/internal/xmlbeans/wsdlsubst" + )); + options.setEntityResolver(entResolver); + + XmlObject wsdldoc = loader.parse(wsdlFiles[i], null, options); + + if (!(wsdldoc instanceof org.apache.xmlbeans.impl.xb.substwsdl.DefinitionsDocument)) + StscState.addError(errorListener, XmlErrorCodes.INVALID_DOCUMENT_TYPE, + new Object[] { wsdlFiles[i], "wsdl" }, wsdldoc); + else + { + addWsdlSchemas(wsdlFiles[i].toString(), (org.apache.xmlbeans.impl.xb.substwsdl.DefinitionsDocument)wsdldoc, errorListener, noVDoc, scontentlist); + } + } + catch (XmlException e) + { + errorListener.add(e.getError()); + } + catch (Exception e) + { + StscState.addError(errorListener, XmlErrorCodes.CANNOT_LOAD_FILE, + new Object[] { "wsdl", wsdlFiles[i], e.getMessage() }, wsdlFiles[i]); + } + } + } + + // step 3, parse all URL files + // XMLBEANS-58 - Ability to pass URLs instead of Files for Wsdl/Schemas + if (urlFiles != null) + { + for (int i = 0; i < urlFiles.length; i++) + { + try + { + XmlOptions options = new XmlOptions(); + options.setLoadLineNumbers(); + options.setLoadSubstituteNamespaces(Collections.singletonMap("http://schemas.xmlsoap.org/wsdl/", "http://www.apache.org/internal/xmlbeans/wsdlsubst")); + options.setEntityResolver(entResolver); + + XmlObject urldoc = loader.parse(urlFiles[i], null, options); + + if ((urldoc instanceof org.apache.xmlbeans.impl.xb.substwsdl.DefinitionsDocument)) + { + addWsdlSchemas(urlFiles[i].toString(), (org.apache.xmlbeans.impl.xb.substwsdl.DefinitionsDocument)urldoc, errorListener, noVDoc, scontentlist); + } + else if ((urldoc instanceof SchemaDocument)) + { + addSchema(urlFiles[i].toString(), (SchemaDocument)urldoc, + errorListener, noVDoc, scontentlist); + } + else + { + StscState.addError(errorListener, XmlErrorCodes.INVALID_DOCUMENT_TYPE, + new Object[]{urlFiles[i], "wsdl or schema"}, urldoc); + } + + } + catch (XmlException e) + { + errorListener.add(e.getError()); + } + catch (Exception e) + { + StscState.addError(errorListener, XmlErrorCodes.CANNOT_LOAD_FILE, + new Object[]{"url", urlFiles[i], e.getMessage()}, urlFiles[i]); + } + } + } + + SchemaDocument.Schema[] sdocs = (SchemaDocument.Schema[])scontentlist.toArray(new SchemaDocument.Schema[scontentlist.size()]); + + // now the config files. + ArrayList cdoclist = new ArrayList(); + if (configFiles != null) + { + if (noExt) + System.out.println("Pre/Post and Interface extensions will be ignored."); + + for (int i = 0; i < configFiles.length; i++) + { + try + { + XmlOptions options = new XmlOptions(); + options.put( XmlOptions.LOAD_LINE_NUMBERS ); + options.setEntityResolver(entResolver); + options.setLoadSubstituteNamespaces(MAP_COMPATIBILITY_CONFIG_URIS); + + XmlObject configdoc = loader.parse(configFiles[i], null, options); + if (!(configdoc instanceof ConfigDocument)) + StscState.addError(errorListener, XmlErrorCodes.INVALID_DOCUMENT_TYPE, + new Object[] { configFiles[i], "xsd config" }, configdoc); + else + { + StscState.addInfo(errorListener, "Loading config file " + configFiles[i]); + if (configdoc.validate(new XmlOptions().setErrorListener(errorListener))) + { + ConfigDocument.Config config = ((ConfigDocument)configdoc).getConfig(); + cdoclist.add(config); + if (noExt) + { + //disable extensions + config.setExtensionArray(new Extensionconfig[] {}); + } + } + } + } + catch (XmlException e) + { + errorListener.add(e.getError()); + } + catch (Exception e) + { + StscState.addError(errorListener, XmlErrorCodes.CANNOT_LOAD_FILE, + new Object[] { "xsd config", configFiles[i], e.getMessage() }, configFiles[i]); + } + } + } + ConfigDocument.Config[] cdocs = (ConfigDocument.Config[])cdoclist.toArray(new ConfigDocument.Config[cdoclist.size()]); + + SchemaTypeLoader linkTo = SchemaTypeLoaderImpl.build(null, cpResourceLoader, null); + + URI baseURI = null; + if (baseDir != null) + baseURI = baseDir.toURI(); + + XmlOptions opts = new XmlOptions(); + if (download) + opts.setCompileDownloadUrls(); + if (noUpa) + opts.setCompileNoUpaRule(); + if (noPvr) + opts.setCompileNoPvrRule(); + if (noAnn) + opts.setCompileNoAnnotations(); + if (mdefNamespaces != null) + opts.setCompileMdefNamespaces(mdefNamespaces); + opts.setCompileNoValidation(); // already validated here + opts.setEntityResolver(entResolver); + if (javasource != null) + opts.setGenerateJavaVersion(javasource); + + // now pass it to the main compile function + SchemaTypeSystemCompiler.Parameters params = new SchemaTypeSystemCompiler.Parameters(); + params.setName(name); + params.setSchemas(sdocs); + params.setConfig(BindingConfigImpl.forConfigDocuments(cdocs, javaFiles, classpath)); + params.setLinkTo(linkTo); + params.setOptions(opts); + params.setErrorListener(errorListener); + params.setJavaize(true); + params.setBaseURI(baseURI); + params.setSourcesToCopyMap(sourcesToCopyMap); + params.setSchemasDir(schemasDir); + return SchemaTypeSystemCompiler.compile(params); + } + + private static void addSchema(String name, SchemaDocument schemadoc, + XmlErrorWatcher errorListener, boolean noVDoc, List scontentlist) + { + StscState.addInfo(errorListener, "Loading schema file " + name); + XmlOptions opts = new XmlOptions().setErrorListener(errorListener); + if (noVDoc) + opts.setValidateTreatLaxAsSkip(); + if (schemadoc.validate(opts)) + scontentlist.add((schemadoc).getSchema()); + } + + private static void addWsdlSchemas(String name, + org.apache.xmlbeans.impl.xb.substwsdl.DefinitionsDocument wsdldoc, + XmlErrorWatcher errorListener, boolean noVDoc, List scontentlist) + { + if (wsdlContainsEncoded(wsdldoc)) + StscState.addWarning(errorListener, "The WSDL " + name + " uses SOAP encoding. SOAP encoding is not compatible with literal XML Schema.", XmlErrorCodes.GENERIC_ERROR, wsdldoc); + StscState.addInfo(errorListener, "Loading wsdl file " + name); + XmlOptions opts = new XmlOptions().setErrorListener(errorListener); + if (noVDoc) + opts.setValidateTreatLaxAsSkip(); + XmlObject[] types = wsdldoc.getDefinitions().getTypesArray(); + int count = 0; + for (int j = 0; j < types.length; j++) + { + XmlObject[] schemas = types[j].selectPath("declare namespace xs=\"http://www.w3.org/2001/XMLSchema\" xs:schema"); + if (schemas.length == 0) + { + StscState.addWarning(errorListener, "The WSDL " + name + " did not have any schema documents in namespace 'http://www.w3.org/2001/XMLSchema'", XmlErrorCodes.GENERIC_ERROR, wsdldoc); + continue; + } + + for (int k = 0; k < schemas.length; k++) + { + if (schemas[k] instanceof SchemaDocument.Schema && + schemas[k].validate(opts)) + { + count++; + scontentlist.add(schemas[k]); + } + } + } + StscState.addInfo(errorListener, "Processing " + count + " schema(s) in " + name); + } + + public static boolean compile(Parameters params) + { + File baseDir = params.getBaseDir(); + File[] xsdFiles = params.getXsdFiles(); + File[] wsdlFiles = params.getWsdlFiles(); + URL[] urlFiles = params.getUrlFiles(); + File[] javaFiles = params.getJavaFiles(); + File[] configFiles = params.getConfigFiles(); + File[] classpath = params.getClasspath(); + File outputJar = params.getOutputJar(); + String name = params.getName(); + File srcDir = params.getSrcDir(); + File classesDir = params.getClassesDir(); + String compiler = params.getCompiler(); + String javasource = params.getJavaSource(); + String memoryInitialSize = params.getMemoryInitialSize(); + String memoryMaximumSize = params.getMemoryMaximumSize(); + boolean nojavac = params.isNojavac(); + boolean debug = params.isDebug(); + boolean verbose = params.isVerbose(); + boolean quiet = params.isQuiet(); + boolean download = params.isDownload(); + boolean noUpa = params.isNoUpa(); + boolean noPvr = params.isNoPvr(); + boolean noAnn = params.isNoAnn(); + boolean noVDoc = params.isNoVDoc(); + boolean noExt = params.isNoExt(); + boolean incrSrcGen = params.isIncrementalSrcGen(); + Collection outerErrorListener = params.getErrorListener(); + + String repackage = params.getRepackage(); + + if (repackage!=null) + { + SchemaTypeLoaderImpl.METADATA_PACKAGE_LOAD = SchemaTypeSystemImpl.METADATA_PACKAGE_GEN; + + String stsPackage = SchemaTypeSystem.class.getPackage().getName(); + Repackager repackager = new Repackager( repackage ); + + SchemaTypeSystemImpl.METADATA_PACKAGE_GEN = repackager.repackage(new StringBuffer(stsPackage)).toString().replace('.','_'); + + System.out.println("\n\n\n" + stsPackage + ".SchemaCompiler Metadata LOAD:" + SchemaTypeLoaderImpl.METADATA_PACKAGE_LOAD + " GEN:" + SchemaTypeSystemImpl.METADATA_PACKAGE_GEN); + } + + SchemaCodePrinter codePrinter = params.getSchemaCodePrinter(); + List extensions = params.getExtensions(); + Set mdefNamespaces = params.getMdefNamespaces(); + + EntityResolver cmdLineEntRes = params.getEntityResolver() == null ? + ResolverUtil.resolverForCatalog(params.getCatalogFile()) : params.getEntityResolver(); + + if (srcDir == null || classesDir == null) + throw new IllegalArgumentException("src and class gen directories may not be null."); + + long start = System.currentTimeMillis(); + + // Calculate the usenames based on the relativized filenames on the filesystem + if (baseDir == null) + baseDir = new File(SystemProperties.getProperty("user.dir")); + + ResourceLoader cpResourceLoader = null; + + Map sourcesToCopyMap = new HashMap(); + + if (classpath != null) + cpResourceLoader = new PathResourceLoader(classpath); + + boolean result = true; + + File schemasDir = IOUtil.createDir(classesDir, "schema" + SchemaTypeSystemImpl.METADATA_PACKAGE_GEN + "/src"); + + // build the in-memory type system + XmlErrorWatcher errorListener = new XmlErrorWatcher(outerErrorListener); + SchemaTypeSystem system = loadTypeSystem(name, xsdFiles, wsdlFiles, urlFiles, configFiles, + javaFiles, cpResourceLoader, download, noUpa, noPvr, noAnn, noVDoc, noExt, mdefNamespaces, + baseDir, sourcesToCopyMap, errorListener, schemasDir, cmdLineEntRes, classpath, javasource); + if (errorListener.hasError()) + result = false; + long finish = System.currentTimeMillis(); + if (!quiet) + System.out.println("Time to build schema type system: " + ((double)(finish - start) / 1000.0) + " seconds" ); + + // now code generate and compile the JAR + if (result && system != null) // todo: don't check "result" here if we want to compile anyway, ignoring invalid schemas + { + start = System.currentTimeMillis(); + + // filer implementation writes binary .xsd and generated source to disk + Repackager repackager = (repackage == null ? null : new Repackager(repackage)); + FilerImpl filer = new FilerImpl(classesDir, srcDir, repackager, verbose, incrSrcGen); + + // currently just for schemaCodePrinter + XmlOptions options = new XmlOptions(); + if (codePrinter != null) + options.setSchemaCodePrinter(codePrinter); + if (javasource != null) + options.setGenerateJavaVersion(javasource); + + // save .xsb files + system.save(filer); + + // gen source files + result &= SchemaTypeSystemCompiler.generateTypes(system, filer, options); + + if (incrSrcGen) + { + // We have to delete extra source files that may be out of date + SchemaCodeGenerator.deleteObsoleteFiles(srcDir, srcDir, + new HashSet(filer.getSourceFiles())); + } + + if (result) + { + finish = System.currentTimeMillis(); + if (!quiet) + System.out.println("Time to generate code: " + ((double)(finish - start) / 1000.0) + " seconds" ); + } + + // compile source + if (result && !nojavac) + { + start = System.currentTimeMillis(); + + List sourcefiles = filer.getSourceFiles(); + + if (javaFiles != null) + sourcefiles.addAll(java.util.Arrays.asList(javaFiles)); + if (!CodeGenUtil.externalCompile(sourcefiles, classesDir, classpath, debug, compiler, javasource, memoryInitialSize, memoryMaximumSize, quiet, verbose)) + result = false; + + finish = System.currentTimeMillis(); + if (result && !params.isQuiet()) + System.out.println("Time to compile code: " + ((double)(finish - start) / 1000.0) + " seconds" ); + + // jar classes and .xsb + if (result && outputJar != null) + { + try + { + new JarHelper().jarDir(classesDir, outputJar); + } + catch (IOException e) + { + System.err.println("IO Error " + e); + result = false; + } + + if (result && !params.isQuiet()) + System.out.println("Compiled types to: " + outputJar); + } + } + } + + if (!result && !quiet) + { + System.out.println("BUILD FAILED"); + } + else { + // call schema compiler extension if registered + runExtensions(extensions, system, classesDir); + } + + if (cpResourceLoader != null) + cpResourceLoader.close(); + return result; + } + + private static void runExtensions(List extensions, SchemaTypeSystem system, File classesDir) + { + if (extensions != null && extensions.size() > 0) + { + SchemaCompilerExtension sce = null; + Iterator i = extensions.iterator(); + Map extensionParms = null; + String classesDirName = null; + try + { + classesDirName = classesDir.getCanonicalPath(); + } + catch(java.io.IOException e) + { + System.out.println("WARNING: Unable to get the path for schema jar file"); + classesDirName = classesDir.getAbsolutePath(); + } + + while (i.hasNext()) + { + Extension extension = (Extension) i.next(); + try + { + sce = (SchemaCompilerExtension) extension.getClassName().newInstance(); + } + catch (InstantiationException e) + { + System.out.println("UNABLE to instantiate schema compiler extension:" + extension.getClassName().getName()); + System.out.println("EXTENSION Class was not run"); + break; + } + catch (IllegalAccessException e) + { + System.out.println("ILLEGAL ACCESS Exception when attempting to instantiate schema compiler extension: " + extension.getClassName().getName()); + System.out.println("EXTENSION Class was not run"); + break; + } + + System.out.println("Running Extension: " + sce.getExtensionName()); + extensionParms = new HashMap(); + Iterator parmsi = extension.getParams().iterator(); + while (parmsi.hasNext()) + { + Extension.Param p = (Extension.Param) parmsi.next(); + extensionParms.put(p.getName(), p.getValue()); + } + extensionParms.put("classesDir", classesDirName); + sce.schemaCompilerExtension(system, extensionParms); + } + } + } + + + private static boolean wsdlContainsEncoded(XmlObject wsdldoc) + { + // search for any etc. + XmlObject[] useAttrs = wsdldoc.selectPath( + "declare namespace soap='http://schemas.xmlsoap.org/wsdl/soap/' " + + ".//soap:body/@use|.//soap:header/@use|.//soap:fault/@use"); + for (int i = 0; i < useAttrs.length; i++) + { + if ("encoded".equals(((SimpleValue)useAttrs[i]).getStringValue())) + return true; + } + return false; + } + + private static final String CONFIG_URI = "http://xml.apache.org/xmlbeans/2004/02/xbean/config"; + private static final String COMPATIBILITY_CONFIG_URI = "http://www.bea.com/2002/09/xbean/config"; + private static final Map MAP_COMPATIBILITY_CONFIG_URIS; + static + { + MAP_COMPATIBILITY_CONFIG_URIS = new HashMap(); + MAP_COMPATIBILITY_CONFIG_URIS.put(COMPATIBILITY_CONFIG_URI, CONFIG_URI); + } +} diff --git a/xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/SchemaCompilerExtension.java b/xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/SchemaCompilerExtension.java new file mode 100644 index 000000000..0641576fe --- /dev/null +++ b/xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/SchemaCompilerExtension.java @@ -0,0 +1,39 @@ +/* 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.tool; + +import org.apache.xmlbeans.SchemaTypeSystem; + +import java.util.Map; + + +/** + * This interface is implemented by Schema Compiler Extensions. By implementing this class + * you can then pass this class via the command line param extension to the SchemaCompiler class + * which will then in turn call this class back once the compilation is complete with the resulting + * SchemaTypeSystem. + */ +public interface SchemaCompilerExtension { + /** + * Implement this function to be called back by the XmlBeans Schema Compiler with + * the Schema Type System that has been created as a result of the compile. + * @param schemaTypeSystem - The schema type systems that has been created by the compiler just prior to calling + * this extension class. + * @param parms - name value pairs of options to this schema compiler extension + */ + public void schemaCompilerExtension(SchemaTypeSystem schemaTypeSystem, Map parms); + public String getExtensionName(); +} diff --git a/xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/SchemaCopy.java b/xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/SchemaCopy.java new file mode 100644 index 000000000..313f522eb --- /dev/null +++ b/xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/SchemaCopy.java @@ -0,0 +1,258 @@ +/* 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.tool; + +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.XmlOptions; +import org.apache.xmlbeans.XmlCursor; +import org.apache.xmlbeans.impl.common.IOUtil; +import org.apache.xmlbeans.impl.xb.substwsdl.DefinitionsDocument; +import org.apache.xmlbeans.impl.xb.substwsdl.TImport; + +import java.net.URI; +import java.net.URL; +import java.net.URISyntaxException; +import java.util.Map; +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.Collections; +import java.util.Iterator; +import java.io.File; + +import org.apache.xmlbeans.impl.xb.xsdschema.SchemaDocument; +import org.apache.xmlbeans.impl.xb.xsdschema.ImportDocument; +import org.apache.xmlbeans.impl.xb.xsdschema.IncludeDocument; + +public class SchemaCopy +{ + public static void printUsage() + { + System.out.println("Copies the XML schema at the specified URL to the specified file."); + System.out.println("Usage: scopy sourceurl [targetfile]"); + System.out.println(" sourceurl - The URL at which the schema is located."); + System.out.println(" targetfile - The file to which the schema should be copied."); + System.out.println(); + + } + + public static void main(String[] args) + { + if (args.length < 1 || args.length > 2) + { + printUsage(); + return; + } + + URI source = null; + URI target = null; + + try + { + if(args[0].compareToIgnoreCase("-usage") == 0){ + printUsage(); + return; + } + + source = new URI(args[0]); + source.toURL(); // to trigger exception + } + catch (Exception e) + { + System.err.println("Badly formed URL " + source); + return; + } + + if (args.length < 2) + { + try + { + URI dir = new File(".").getCanonicalFile().toURI(); + String lastPart = source.getPath(); + lastPart = lastPart.substring(lastPart.lastIndexOf('/') + 1); + target = CodeGenUtil.resolve(dir, URI.create(lastPart)); + } + catch (Exception e) + { + System.err.println("Cannot canonicalize current directory"); + return; + } + } + else + { + try + { + target = new URI(args[1]); + if (!target.isAbsolute()) + target = null; + else if (!target.getScheme().equals("file")) + target = null; + } + catch (Exception e) + { + target = null; + } + + if (target == null) + { + try + { + target = new File(target).getCanonicalFile().toURI(); + } + catch (Exception e) + { + System.err.println("Cannot canonicalize current directory"); + return; + } + } + } + + Map thingsToCopy = findAllRelative(source, target); + copyAll(thingsToCopy, true); + } + + private static void copyAll(Map uriMap, boolean stdout) + { + for (Iterator i = uriMap.keySet().iterator(); i.hasNext(); ) + { + URI source = (URI)i.next(); + URI target = (URI)uriMap.get(source); + try + { + IOUtil.copyCompletely(source, target); + } + catch (Exception e) + { + if (stdout) + System.out.println("Could not copy " + source + " -> " + target); + continue; + } + if (stdout) + System.out.println("Copied " + source + " -> " + target); + } + } + + + /** + * Copies the schema or wsdl at the source URI to the target URI, along + * with any relative references. The target URI should be a file URI. + * If doCopy is false, the file copies are not actually done; the map + * returned just describes the copies that would have been done. + * + * @param source an arbitrary URI describing a source Schema or WSDL + * @param target a file URI describing a target filename + * @return a map of all the source/target URIs needed to copy + * the file along with all its relative referents. + */ + public static Map findAllRelative(URI source, URI target) + { + Map result = new LinkedHashMap(); + result.put(source, target); + + LinkedList process = new LinkedList(); + process.add(source); + + while (!process.isEmpty()) + { + URI nextSource = (URI)process.removeFirst(); + URI nextTarget = (URI)result.get(nextSource); + Map nextResults = findRelativeInOne(nextSource, nextTarget); + for (Iterator i = nextResults.keySet().iterator(); i.hasNext(); ) + { + URI newSource = (URI)i.next(); + if (result.containsKey(newSource)) + continue; + result.put(newSource, nextResults.get(newSource)); + process.add(newSource); + } + } + + return result; + } + + private static final XmlOptions loadOptions = new XmlOptions(). + setLoadSubstituteNamespaces(Collections.singletonMap( + "http://schemas.xmlsoap.org/wsdl/", "http://www.apache.org/internal/xmlbeans/wsdlsubst" + )); + + private static Map findRelativeInOne(URI source, URI target) + { + try + { + URL sourceURL = source.toURL(); + XmlObject xobj = XmlObject.Factory.parse(sourceURL, loadOptions); + XmlCursor xcur = xobj.newCursor(); + xcur.toFirstChild(); + + Map result = new LinkedHashMap(); + + if (xobj instanceof SchemaDocument) + putMappingsFromSchema(result, source, target, ((SchemaDocument)xobj).getSchema()); + else if (xobj instanceof DefinitionsDocument) + putMappingsFromWsdl(result, source, target, ((DefinitionsDocument)xobj).getDefinitions()); + return result; + } + catch (Exception e) + { + // any exceptions parsing the given URL? Then skip this file silently + } + return Collections.EMPTY_MAP; + } + + private static void putNewMapping(Map result, URI origSource, URI origTarget, String literalURI) + { + try + { + if (literalURI == null) + return; + URI newRelative = new URI(literalURI); + if (newRelative.isAbsolute()) + return; + URI newSource = CodeGenUtil.resolve(origSource, newRelative); + URI newTarget = CodeGenUtil.resolve(origTarget, newRelative); + result.put(newSource, newTarget); + } + catch (URISyntaxException e) + { + // uri syntax problem? do nothing silently. + } + } + + private static void putMappingsFromSchema(Map result, URI source, URI target, SchemaDocument.Schema schema) + { + ImportDocument.Import[] imports = schema.getImportArray(); + for (int i = 0; i < imports.length; i++) + putNewMapping(result, source, target, imports[i].getSchemaLocation()); + + IncludeDocument.Include[] includes = schema.getIncludeArray(); + for (int i = 0; i < includes.length; i++) + putNewMapping(result, source, target, includes[i].getSchemaLocation()); + } + + private static void putMappingsFromWsdl(Map result, URI source, URI target, DefinitionsDocument.Definitions wdoc) + { + XmlObject[] types = wdoc.getTypesArray(); + for (int i = 0; i < types.length; i++) + { + SchemaDocument.Schema[] schemas = (SchemaDocument.Schema[])types[i].selectPath("declare namespace xs='http://www.w3.org/2001/XMLSchema' xs:schema"); + for (int j = 0; j < schemas.length; j++) + putMappingsFromSchema(result, source, target, schemas[j]); + } + + TImport[] imports = wdoc.getImportArray(); + for (int i = 0; i < imports.length; i++) + putNewMapping(result, source, target, imports[i].getLocation()); + } +} diff --git a/xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/SchemaImportResolver.java b/xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/SchemaImportResolver.java new file mode 100644 index 000000000..36ed8b925 --- /dev/null +++ b/xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/SchemaImportResolver.java @@ -0,0 +1,147 @@ +/* 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.tool; + +import org.apache.xmlbeans.impl.xb.xsdschema.SchemaDocument.Schema; +import org.apache.xmlbeans.impl.xb.xsdschema.ImportDocument.Import; +import org.apache.xmlbeans.impl.xb.xsdschema.IncludeDocument.Include; + +import java.util.LinkedList; +import java.util.Set; +import java.util.HashSet; +import java.util.Arrays; + +public abstract class SchemaImportResolver +{ + /** + * Called when the ImportLoader wishes to resolve the + * given import. Should return a SchemaResource whose + * "equals" relationship reveals when a SchemaResource is + * duplicated and shouldn't be examined again. + * + * Returns null if the resource reference should be ignored. + */ + public abstract SchemaResource lookupResource(String nsURI, String URL); + + /** + * Called to notify that the expected namespace is different from the + * actual namespace, or if no namespace is known, to report the + * discovered namespace. + */ + public abstract void reportActualNamespace(SchemaResource resource, String actualNamespace); + + /** + * Used to supply a schema resource with an optional associated + * expected-namespace-URI and original-location-URL. + * + * The equals (and hashCode) implementations of the SchemaResource + * objects will be used to avoid examining the same resource twice; + * these must be implemented according to the desired rules for + * determining that two resources are the same. + */ + public interface SchemaResource + { + /** + * Returns a parsed schema object. + */ + + public Schema getSchema(); + + public String getNamespace(); + public String getSchemaLocation(); + } + + protected final void resolveImports(SchemaResource[] resources) + { + LinkedList queueOfResources = new LinkedList(Arrays.asList(resources)); + LinkedList queueOfLocators = new LinkedList(); + Set seenResources = new HashSet(); + + for (;;) + { + SchemaResource nextResource; + + // fetch next resource. + if (!queueOfResources.isEmpty()) + { + // either off the initial queue + nextResource = (SchemaResource)queueOfResources.removeFirst(); + } + else if (!queueOfLocators.isEmpty()) + { + // or off the list of locators + SchemaLocator locator = (SchemaLocator)queueOfLocators.removeFirst(); + nextResource = lookupResource(locator.namespace, locator.schemaLocation); + if (nextResource == null) + continue; + } + else + { + // if no more, then terminate loop + break; + } + + // track and skip duplicates + if (seenResources.contains(nextResource)) + continue; + seenResources.add(nextResource); + + // get resource contents + Schema schema = nextResource.getSchema(); + if (schema == null) + continue; + + // check actual namespace + String actualTargetNamespace = schema.getTargetNamespace(); + if (actualTargetNamespace == null) + actualTargetNamespace = ""; + + // report actual namespace + String expectedTargetNamespace = nextResource.getNamespace(); + if (expectedTargetNamespace == null || + !actualTargetNamespace.equals(expectedTargetNamespace)) + { + reportActualNamespace(nextResource, actualTargetNamespace); + } + + // now go through and record all the imports + Import[] schemaImports = schema.getImportArray(); + for (int i = 0; i < schemaImports.length; i++) + { + queueOfLocators.add(new SchemaLocator(schemaImports[i].getNamespace() == null ? "" : schemaImports[i].getNamespace(), schemaImports[i].getSchemaLocation())); + } + + // and record all the includes too + Include[] schemaIncludes = schema.getIncludeArray(); + for (int i = 0; i < schemaIncludes.length; i++) + { + queueOfLocators.add(new SchemaLocator(null, schemaIncludes[i].getSchemaLocation())); + } + } + } + + private static class SchemaLocator + { + public SchemaLocator(String namespace, String schemaLocation) + { + this.namespace = namespace; + this.schemaLocation = schemaLocation; + } + + public final String namespace; + public final String schemaLocation; + } +} diff --git a/xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/SchemaResourceManager.java b/xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/SchemaResourceManager.java new file mode 100644 index 000000000..bcbc5a365 --- /dev/null +++ b/xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/SchemaResourceManager.java @@ -0,0 +1,308 @@ +/* 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.tool; + +import org.apache.xmlbeans.impl.common.IOUtil; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.FileInputStream; +import java.io.InputStream; +import java.io.FileFilter; +import java.io.OutputStream; +import java.util.List; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.HashSet; +import java.util.Set; + +public class SchemaResourceManager extends BaseSchemaResourceManager +{ + public static void printUsage() + { + System.out.println("Maintains \"xsdownload.xml\", an index of locally downloaded .xsd files"); + System.out.println("usage: sdownload [-dir directory] [-refresh] [-recurse] [-sync] [url/file...]"); + System.out.println(""); + System.out.println("URLs that are specified are downloaded if they aren't already cached."); + System.out.println("In addition:"); + System.out.println(" -dir specifies the directory for the xsdownload.xml file (default .)."); + System.out.println(" -sync synchronizes the index to any local .xsd files in the tree."); + System.out.println(" -recurse recursively downloads imported and included .xsd files."); + System.out.println(" -refresh redownloads all indexed .xsd files."); + System.out.println("If no files or URLs are specified, all indexed files are relevant."); + } + + public static void main(String[] args) throws IOException + { + if (args.length == 0) + { + printUsage(); + System.exit(0); + return; + } + + Set flags = new HashSet(); + flags.add("h"); + flags.add("help"); + flags.add("usage"); + flags.add("license"); + flags.add("version"); + flags.add("sync"); + flags.add("refresh"); + flags.add("recurse"); + + Set opts = new HashSet(); + opts.add("dir"); + CommandLine cl = new CommandLine(args, flags, opts); + if (cl.getOpt("h") != null || cl.getOpt("help") != null || cl.getOpt("usage") != null) + { + printUsage(); + System.exit(0); + return; + } + + String[] badopts = cl.getBadOpts(); + if (badopts.length > 0) + { + for (int i = 0; i < badopts.length; i++) + System.out.println("Unrecognized option: " + badopts[i]); + printUsage(); + System.exit(0); + return; + } + + if (cl.getOpt("license") != null) + { + CommandLine.printLicense(); + System.exit(0); + return; + } + + if (cl.getOpt("version") != null) + { + CommandLine.printVersion(); + System.exit(0); + return; + } + + args = cl.args(); + + boolean sync = (cl.getOpt("sync") != null); + boolean refresh = (cl.getOpt("refresh") != null); + boolean imports = (cl.getOpt("recurse") != null); + String dir = cl.getOpt("dir"); + if (dir == null) + dir = "."; + File directory = new File(dir); + + SchemaResourceManager mgr; + try + { + mgr = new SchemaResourceManager(directory); + } + catch (IllegalStateException e) + { + if (e.getMessage() != null) + System.out.println(e.getMessage()); + else + e.printStackTrace(); + System.exit(1); + return; + } + + List uriList = new ArrayList(); + List fileList = new ArrayList(); + for (int i = 0; i < args.length; i++) + { + if (looksLikeURL(args[i])) + { + uriList.add(args[i]); + } + else + { + fileList.add(new File(directory, args[i])); + } + } + + // deal with files that are not in the proper directory + for (Iterator i = fileList.iterator(); i.hasNext(); ) + { + File file = (File)i.next(); + if (!isInDirectory(file, directory)) + { + System.err.println("File not within directory: " + file); + i.remove(); + } + } + + // deal with directories + fileList = collectXSDFiles((File[])fileList.toArray(new File[0])); + + String[] uris = (String[])uriList.toArray(new String[0]); + File[] files = (File[])fileList.toArray(new File[0]); + String[] filenames = relativeFilenames(files, directory); + + if (uris.length + filenames.length > 0) + { + mgr.process(uris, filenames, sync, refresh, imports); + } + else + { + mgr.processAll(sync, refresh, imports); + } + + mgr.writeCache(); + System.exit(0); + } + + private static boolean looksLikeURL(String str) + { + return str.startsWith("http:") || str.startsWith("https:") || str.startsWith("ftp:") || str.startsWith("file:"); + } + + private static String relativeFilename(File file, File directory) + { + if (file == null || file.equals(directory)) + return "."; + return relativeFilename(file.getParentFile(), directory) + "/" + file.getName(); + } + + private static String[] relativeFilenames(File[] files, File directory) + { + String[] result = new String[files.length]; + for (int i = 0; i < files.length; i++) + { + result[i] = relativeFilename(files[i], directory); + } + return result; + } + + private static boolean isInDirectory(File file, File dir) + { + if (file == null) + return false; + if (file.equals(dir)) + return true; + return isInDirectory(file.getParentFile(), dir); + } + + + + + + public SchemaResourceManager(File directory) + { + _directory = directory; + init(); + } + + private File _directory; + + + // SOME METHODS TO OVERRIDE ============================ + + /** + * Sends messages to System.out. + */ + protected void warning(String msg) + { + System.out.println(msg); + } + + /** + * Returns true if the given filename exists. The filenames + * are of the form "/foo/bar/zee.xsd" and should be construed + * as rooted at the root of the project. + */ + protected boolean fileExists(String filename) + { + return (new File(_directory, filename)).exists(); + } + + /** + * Gets the data in the given filename as an InputStream. + */ + protected InputStream inputStreamForFile(String filename) throws IOException + { + return new FileInputStream(new File(_directory, filename)); + } + + /** + * Writes an entire file in one step. An InputStream is passed and + * copied to the file. + */ + protected void writeInputStreamToFile(InputStream input, String filename) throws IOException + { + File targetFile = new File(_directory, filename); + + File parent = targetFile.getParentFile(); + if (!parent.exists()) + parent.mkdirs(); + OutputStream output = new FileOutputStream(targetFile); + IOUtil.copyCompletely(input, output); + } + + /** + * Deletes a file. Sometimes immediately after writing a new file + * we notice that it's exactly the same as an existing file and + * we delete it. We never delete a file that was given to us + * by the user. + */ + protected void deleteFile(String filename) + { + new File(_directory, filename).delete(); + } + + /** + * Returns a list of all the XSD filesnames in the project. + */ + protected String[] getAllXSDFilenames() + { + File[] allFiles = (File[])collectXSDFiles(new File[] { _directory }).toArray(new File[0]); + return relativeFilenames(allFiles, _directory); + } + + /** + * Simple recursive file filter to do the above. + */ + private static List collectXSDFiles(File[] dirs) + { + List files = new ArrayList(); + for (int i = 0; i < dirs.length; i++) + { + File f = dirs[i]; + if (!f.isDirectory()) + { + files.add(f); + } + else + { + files.addAll(collectXSDFiles( + f.listFiles(new FileFilter() + { + public boolean accept(File file) + { return file.isDirectory() || + file.isFile() && + file.getName().endsWith(".xsd"); } + } + ))); + } + } + return files; + } + +} diff --git a/xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/StreamInstanceValidator.java b/xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/StreamInstanceValidator.java new file mode 100644 index 000000000..e6463f51e --- /dev/null +++ b/xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/StreamInstanceValidator.java @@ -0,0 +1,235 @@ +/* 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.tool; + +import org.apache.xmlbeans.SchemaTypeLoader; +import org.apache.xmlbeans.XmlBeans; +import org.apache.xmlbeans.XmlException; +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.XmlOptions; +import org.apache.xmlbeans.XmlError; +import org.apache.xmlbeans.impl.validator.ValidatingXMLStreamReader; + +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.Location; +import java.io.File; +import java.io.FileInputStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import java.util.HashSet; + +public class StreamInstanceValidator +{ + private static final XMLInputFactory XML_INPUT_FACTORY = XMLInputFactory.newInstance(); + + public static void printUsage() + { + System.out.println("Validates the specified instance against the specified schema."); + System.out.println("A streaming validation useful for validating very large instance "); + System.out.println("documents with less memory. Contrast with the validate tool."); + System.out.println("Usage: svalidate [-dl] [-nopvr] [-noupa] [-license] schema.xsd instance.xml"); + System.out.println("Options:"); + System.out.println(" -dl - permit network downloads for imports and includes (default is off)"); + System.out.println(" -noupa - do not enforce the unique particle attribution rule"); + System.out.println(" -nopvr - do not enforce the particle valid (restriction) rule"); + System.out.println(" -license - prints license information"); + } + + public static void main(String[] args) + { + Set flags = new HashSet(); + flags.add("h"); + flags.add("help"); + flags.add("usage"); + flags.add("license"); + flags.add("version"); + flags.add("dl"); + flags.add("noupr"); + flags.add("noupa"); + + CommandLine cl = new CommandLine(args, flags, Collections.EMPTY_SET); + if (cl.getOpt("h") != null || cl.getOpt("help") != null || cl.getOpt("usage") != null || args.length < 1) + { + printUsage(); + System.exit(0); + return; + } + + String[] badopts = cl.getBadOpts(); + if (badopts.length > 0) + { + for (int i = 0; i < badopts.length; i++) + System.out.println("Unrecognized option: " + badopts[i]); + printUsage(); + System.exit(0); + return; + } + + if (cl.getOpt("license") != null) { + CommandLine.printLicense(); + System.exit(0); + return; + } + + if (cl.getOpt("version") != null) + { + CommandLine.printVersion(); + System.exit(0); + return; + } + + if (cl.args().length == 0) { + printUsage(); + return; + } + + boolean dl = (cl.getOpt("dl") != null); + boolean nopvr = (cl.getOpt("nopvr") != null); + boolean noupa = (cl.getOpt("noupa") != null); + + File[] schemaFiles = cl.filesEndingWith(".xsd"); + File[] instanceFiles = cl.filesEndingWith(".xml"); + File[] jarFiles = cl.filesEndingWith(".jar"); + + List sdocs = new ArrayList(); + + final XmlOptions options = (new XmlOptions()).setLoadLineNumbers(); + for (int i = 0; i < schemaFiles.length; i++) { + try { + sdocs.add( + XmlObject.Factory.parse( + schemaFiles[i], options.setLoadMessageDigest())); + } + catch (Exception e) { + System.err.println(schemaFiles[i] + " not loadable: " + e); + } + } + + XmlObject[] schemas = (XmlObject[])sdocs.toArray(new XmlObject[0]); + + SchemaTypeLoader sLoader = null; + Collection compErrors = new ArrayList(); + XmlOptions schemaOptions = new XmlOptions(); + schemaOptions.setErrorListener(compErrors); + if (dl) + schemaOptions.setCompileDownloadUrls(); + if (nopvr) + schemaOptions.setCompileNoPvrRule(); + if (noupa) + schemaOptions.setCompileNoUpaRule(); + + if (jarFiles != null && jarFiles.length > 0) + sLoader = XmlBeans.typeLoaderForResource(XmlBeans.resourceLoaderForPath(jarFiles)); + + try { + if (schemas != null && schemas.length > 0) + sLoader = XmlBeans.compileXsd(schemas, sLoader, schemaOptions); + } + catch (Exception e) { + if (compErrors.isEmpty() || !(e instanceof XmlException)) { + e.printStackTrace(System.err); + } + System.out.println("Schema invalid"); + for (Iterator i = compErrors.iterator(); i.hasNext();) + System.out.println(i.next()); + return; + } + + validateFiles(instanceFiles, sLoader, options); + + } + + public static void validateFiles(File[] instanceFiles, + SchemaTypeLoader sLoader, + final XmlOptions options) + { + final ValidatingXMLStreamReader vsr = new ValidatingXMLStreamReader(); + final Collection errors = new ArrayList(); + + for (int i = 0; i < instanceFiles.length; i++) { + final File file = instanceFiles[i]; + final String path = file.getPath(); + long time = 0; + + errors.clear(); + + try { + final FileInputStream fis = new FileInputStream(file); + final XMLStreamReader rdr = + XML_INPUT_FACTORY.createXMLStreamReader(path, fis); + + //advance to first start element. + while(!rdr.isStartElement()) { + rdr.next(); + } + + time = System.currentTimeMillis(); + vsr.init(rdr, true, null, sLoader, options, errors); + + while (vsr.hasNext()) { + vsr.next(); + } + + time = (System.currentTimeMillis() - time); + vsr.close(); + fis.close(); + } + catch (XMLStreamException xse) { + final Location loc = xse.getLocation(); + XmlError e = XmlError.forLocation(xse.getMessage(), path, + loc.getLineNumber(), + loc.getColumnNumber(), + loc.getCharacterOffset()); + errors.add(e); + } + catch (Exception e) { + System.err.println("error for file: " + file + ": " + e); + e.printStackTrace(System.err); + continue; + } + + + if (errors.isEmpty()) { + System.out.println(file + " valid. (" + time + " ms)"); + } else { + System.out.println(file + " NOT valid (" + time + " ms):"); + for (Iterator it = errors.iterator(); it.hasNext();) { + XmlError err = (XmlError)it.next(); + System.out.println(stringFromError(err, path)); + } + } + + } + } + + private static String stringFromError(XmlError err, + final String path) + { + String s = XmlError.severityAsString(err.getSeverity()) + + ": " + + //err.getSourceName() + path + + ":" + err.getLine() + ":" + err.getColumn() + " " + + err.getMessage() + " "; + return s; + } +} diff --git a/xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/TypeHierarchyPrinter.java b/xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/TypeHierarchyPrinter.java new file mode 100644 index 000000000..cbca80472 --- /dev/null +++ b/xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/TypeHierarchyPrinter.java @@ -0,0 +1,287 @@ +/* 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.tool; + +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.XmlOptions; +import org.apache.xmlbeans.XmlBeans; +import org.apache.xmlbeans.XmlException; +import org.apache.xmlbeans.SchemaTypeSystem; +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.SchemaTypeLoader; +import org.apache.xmlbeans.impl.common.QNameHelper; + +import java.util.Collections; +import java.util.List; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.HashMap; +import java.util.Map; +import java.util.Arrays; +import java.util.Set; +import java.util.HashSet; +import java.io.File; + +import org.apache.xmlbeans.impl.xb.xsdschema.SchemaDocument; + +public class TypeHierarchyPrinter +{ + public static void printUsage() + { + System.out.println("Prints the inheritance hierarchy of types defined in a schema.\n"); + System.out.println("Usage: xsdtree [-noanon] [-nopvr] [-noupa] [-partial] [-license] schemafile.xsd*"); + System.out.println(" -noanon - Don't include anonymous types in the tree."); + System.out.println(" -noupa - do not enforce the unique particle attribution rule"); + System.out.println(" -nopvr - do not enforce the particle valid (restriction) rule"); + System.out.println(" -partial - Print only part of the hierarchy."); + System.out.println(" -license - prints license information"); + System.out.println(" schemafile.xsd - File containing the schema for which to print a tree."); + System.out.println(); + } + + public static void main(String[] args) throws Exception + { + Set flags = new HashSet(); + flags.add("h"); + flags.add("help"); + flags.add("usage"); + flags.add("license"); + flags.add("version"); + flags.add("noanon"); + flags.add("noupr"); + flags.add("noupa"); + flags.add("partial"); + + CommandLine cl = new CommandLine(args, flags, Collections.EMPTY_SET); + if (cl.getOpt("h") != null || cl.getOpt("help") != null || cl.getOpt("usage") != null) + { + printUsage(); + System.exit(0); + return; + } + + String[] badopts = cl.getBadOpts(); + if (badopts.length > 0) + { + for (int i = 0; i < badopts.length; i++) + System.out.println("Unrecognized option: " + badopts[i]); + printUsage(); + System.exit(0); + return; + } + + if (cl.getOpt("license") != null) + { + CommandLine.printLicense(); + System.exit(0); + return; + } + + if (cl.getOpt("version") != null) + { + CommandLine.printVersion(); + System.exit(0); + return; + } + + if (cl.args().length == 0) + { + printUsage(); + return; + } + + boolean noanon = (cl.getOpt("noanon") != null); + boolean nopvr = (cl.getOpt("nopvr") != null); + boolean noupa = (cl.getOpt("noupa") != null); + boolean partial = (cl.getOpt("partial") != null); + + File[] schemaFiles = cl.filesEndingWith(".xsd"); + File[] jarFiles = cl.filesEndingWith(".jar"); + + // step 1: load all the files + List sdocs = new ArrayList(); + for (int i = 0; i < schemaFiles.length; i++) + { + try + { + sdocs.add( + SchemaDocument.Factory.parse( + schemaFiles[i], (new XmlOptions()).setLoadLineNumbers())); + } + catch (Exception e) + { + System.err.println( schemaFiles[i] + " not loadable: " + e ); + } + } + + + XmlObject[] schemas = (XmlObject[])sdocs.toArray(new XmlObject[0]); + + // step 2: compile all the schemas + SchemaTypeLoader linkTo = null; + SchemaTypeSystem typeSystem; + Collection compErrors = new ArrayList(); + XmlOptions schemaOptions = new XmlOptions(); + schemaOptions.setErrorListener(compErrors); + schemaOptions.setCompileDownloadUrls(); + if (nopvr) + schemaOptions.setCompileNoPvrRule(); + if (noupa) + schemaOptions.setCompileNoUpaRule(); + if (partial) + schemaOptions.put("COMPILE_PARTIAL_TYPESYSTEM"); + + if (jarFiles != null && jarFiles.length > 0) + linkTo = XmlBeans.typeLoaderForResource(XmlBeans.resourceLoaderForPath(jarFiles)); + + try + { + typeSystem = XmlBeans.compileXsd(schemas, linkTo, schemaOptions); + } + catch (XmlException e) + { + System.out.println("Schema invalid:" + (partial ? " couldn't recover from errors" : "")); + if (compErrors.isEmpty()) + System.out.println(e.getMessage()); + else for (Iterator i = compErrors.iterator(); i.hasNext(); ) + System.out.println(i.next()); + return; + } + + // step 2.5: recovered from errors, print out errors + if (partial && !compErrors.isEmpty()) + { + System.out.println("Schema invalid: partial schema type system recovered"); + for (Iterator i = compErrors.iterator(); i.hasNext(); ) + System.out.println(i.next()); + } + + // step 3: go through all the types, and note their base types and namespaces + Map prefixes = new HashMap(); + prefixes.put("http://www.w3.org/XML/1998/namespace", "xml"); + prefixes.put("http://www.w3.org/2001/XMLSchema", "xs"); + System.out.println("xmlns:xs=\"http://www.w3.org/2001/XMLSchema\""); + + // This will be a map of (base SchemaType -> Collection of directly dervied types) + Map childTypes = new HashMap(); + + // breadthfirst traversal of the type containment tree + List allSeenTypes = new ArrayList(); + allSeenTypes.addAll(Arrays.asList(typeSystem.documentTypes())); + allSeenTypes.addAll(Arrays.asList(typeSystem.attributeTypes())); + allSeenTypes.addAll(Arrays.asList(typeSystem.globalTypes())); + + for (int i = 0; i < allSeenTypes.size(); i++) + { + SchemaType sType = (SchemaType)allSeenTypes.get(i); + + // recurse through nested anonymous types as well + if (!noanon) + allSeenTypes.addAll(Arrays.asList(sType.getAnonymousTypes())); + + // we're not interested in document types, attribute types, or chasing the base type of anyType + if (sType.isDocumentType() || sType.isAttributeType() || sType == XmlObject.type) + continue; + + // assign a prefix to the namespace of this type if needed + noteNamespace(prefixes, sType); + + // enter this type in the list of children of its base type + Collection children = (Collection)childTypes.get(sType.getBaseType()); + if (children == null) + { + children = new ArrayList(); + childTypes.put(sType.getBaseType(), children); + + // the first time a builtin type is seen, add it too (to get a complete tree up to anyType) + if (sType.getBaseType().isBuiltinType()) + allSeenTypes.add(sType.getBaseType()); + } + children.add(sType); + } + + // step 4: print the tree, starting from xs:anyType (i.e., XmlObject.type) + List typesToPrint = new ArrayList(); + typesToPrint.add(XmlObject.type); + StringBuffer spaces = new StringBuffer(); + while (!typesToPrint.isEmpty()) + { + SchemaType sType = (SchemaType)typesToPrint.remove(typesToPrint.size() - 1); + if (sType == null) + spaces.setLength(Math.max(0, spaces.length() - 2)); + else + { + System.out.println(spaces + "+-" + QNameHelper.readable(sType, prefixes) + notes(sType)); + Collection children = (Collection)childTypes.get(sType); + if (children != null && children.size() > 0) + { + spaces.append(typesToPrint.size() == 0 || typesToPrint.get(typesToPrint.size() - 1) == null ? " " : "| "); + typesToPrint.add(null); + typesToPrint.addAll(children); + } + } + } + } + + private static String notes(SchemaType sType) + { + if (sType.isBuiltinType()) + return " (builtin)"; + + if (sType.isSimpleType()) + { + switch (sType.getSimpleVariety()) + { + case SchemaType.LIST: + return " (list)"; + case SchemaType.UNION: + return " (union)"; + default: + if (sType.getEnumerationValues() != null) + return " (enumeration)"; + return ""; + } + } + + switch (sType.getContentType()) + { + case SchemaType.MIXED_CONTENT: + return " (mixed)"; + case SchemaType.SIMPLE_CONTENT: + return " (complex)"; + default: + return ""; + } + } + + private static void noteNamespace(Map prefixes, SchemaType sType) + { + String namespace = QNameHelper.namespace(sType); + if (namespace.equals("") || prefixes.containsKey(namespace)) + return; + + String base = QNameHelper.suggestPrefix(namespace); + String result = base; + for (int n = 0; prefixes.containsValue(result); n += 1) + { + result = base + n; + } + + prefixes.put(namespace, result); + System.out.println("xmlns:" + result + "=\"" + namespace + "\""); + } +} diff --git a/xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/XMLBean.java b/xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/XMLBean.java new file mode 100644 index 000000000..325affb50 --- /dev/null +++ b/xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/XMLBean.java @@ -0,0 +1,870 @@ +/* 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.tool; + +import org.apache.tools.ant.types.Path; +import org.apache.tools.ant.types.FileSet; +import org.apache.tools.ant.types.Reference; +import org.apache.tools.ant.taskdefs.MatchingTask; +import org.apache.tools.ant.taskdefs.Javac; +import org.apache.tools.ant.taskdefs.Jar; +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.FileScanner; +import org.apache.tools.ant.Project; + +import java.io.File; +import java.io.StringWriter; +import java.io.PrintWriter; +import java.util.*; +import java.net.URI; + +import org.apache.xmlbeans.XmlError; +import org.apache.xmlbeans.impl.common.IOUtil; + +/** + * Modeled after Ant's javac and zip tasks. + * + * Schema files to process, or directories of schema files, are set with the 'schema' + * attribute, and can be filtered with 'includes' and 'excludes'. + * Alternatively, one or more nested <fileset> elements can specify the + * files and directories to be used to generate this XMLBean. + * The include set can also define .java files that should be built as well. + * See the FileSet documentation at http://jakarta.apache.org/ant/manual/index.html + * for instructions on FileSets if you are unfamiliar with their usage. + */ + +public class XMLBean extends MatchingTask +{ + private ArrayList schemas = new ArrayList(); + + private Set mdefnamespaces; + + private Path classpath; + + private File destfile, + schema, + srcgendir, + classgendir; + + private boolean quiet, + verbose, + debug, + optimize, + download, + srconly, + noupa, + nopvr, + noann, + novdoc, + noext = false, + failonerror = true, + fork = true, + includeAntRuntime = true, + noSrcRegen, + includeJavaRuntime = false; + + private String typesystemname, + forkedExecutable, + compiler, + debugLevel, + memoryInitialSize, + memoryMaximumSize, + catalog, + javasource; + + private List extensions = new ArrayList(); + + private HashMap _extRouter = new HashMap(5); + + private static final String XSD = ".xsd", + WSDL = ".wsdl", + JAVA = ".java", + XSDCONFIG = ".xsdconfig"; + + + public void execute() throws BuildException + { + /* VALIDATION */ + //required + if (schemas.size() == 0 + && schema == null + && fileset.getDir(project) == null) + { + String msg = "The 'schema' or 'dir' attribute or a nested fileset is required."; + if (failonerror) + throw new BuildException(msg); + else + { + log(msg, Project.MSG_ERR); + return; + } + } + + _extRouter.put(XSD, new HashSet()); + _extRouter.put(WSDL, new HashSet()); + _extRouter.put(JAVA, new HashSet()); + _extRouter.put(XSDCONFIG, new HashSet()); + + File theBasedir = schema; + + if (schema != null) + { + if (schema.isDirectory()) + { + FileScanner scanner = getDirectoryScanner(schema); + String[] paths = scanner.getIncludedFiles(); + processPaths(paths, scanner.getBasedir()); + } + else + { + theBasedir = schema.getParentFile(); + processPaths(new String[] { schema.getName() }, theBasedir); + } + } + + if (fileset.getDir(project) != null) + schemas.add(fileset); + + Iterator si = schemas.iterator(); + while (si.hasNext()) + { + FileSet fs = (FileSet) si.next(); + FileScanner scanner = fs.getDirectoryScanner(project); + File basedir = scanner.getBasedir(); + String[] paths = scanner.getIncludedFiles(); + + processPaths(paths, basedir); + } + + Set xsdList = (Set) _extRouter.get(XSD); + Set wsdlList = (Set) _extRouter.get(WSDL); + + if (xsdList.size() + wsdlList.size() == 0) + { + log("Could not find any xsd or wsdl files to process.", Project.MSG_WARN); + return; + } + + //optional + Set javaList = (Set) _extRouter.get(JAVA); + Set xsdconfigList = (Set) _extRouter.get(XSDCONFIG); + + if (srcgendir == null && srconly) + srcgendir = classgendir; + + if (destfile == null && classgendir == null && ! srconly) + destfile = new File("xmltypes.jar"); + + if (verbose) + quiet = false; + + /* EXECUTION */ + + File[] xsdArray = (File[]) xsdList.toArray(new File[xsdList.size()]); + File[] wsdlArray = (File[]) wsdlList.toArray(new File[wsdlList.size()]); + File[] javaArray = (File[]) javaList.toArray(new File[javaList.size()]); + File[] xsdconfigArray = (File[]) xsdconfigList.toArray(new File[xsdconfigList.size()]); + ErrorLogger err = new ErrorLogger(verbose); + + boolean success = false; + + try + { + // create a temp directory + File tmpdir = null; + if (srcgendir == null || classgendir == null) + { + tmpdir = SchemaCodeGenerator.createTempDir(); + } + if (srcgendir == null) + srcgendir = IOUtil.createDir(tmpdir, "src"); + if (classgendir == null) + classgendir = IOUtil.createDir(tmpdir, "classes"); + + // use the system classpath if user didn't provide any + if (classpath == null) + { + classpath = new Path(project); + classpath.concatSystemClasspath(); + } + + // prepend the output directory on the classpath + Path.PathElement pathElement = classpath.createPathElement(); + pathElement.setLocation(classgendir); + + String[] paths = classpath.list(); + File[] cp = new File[paths.length]; + for (int i = 0; i < paths.length; i++) + cp[i] = new File(paths[i]); + + // generate the source + SchemaCompiler.Parameters params = new SchemaCompiler.Parameters(); + params.setBaseDir(theBasedir); + params.setXsdFiles(xsdArray); + params.setWsdlFiles(wsdlArray); + params.setJavaFiles(javaArray); + params.setConfigFiles(xsdconfigArray); + params.setClasspath(cp); + params.setName(typesystemname); + params.setSrcDir(srcgendir); + params.setClassesDir(classgendir); + params.setNojavac(true); // always compile using javac task below + params.setDebug(debug); + params.setVerbose(verbose); + params.setQuiet(quiet); + params.setDownload(download); + params.setExtensions(extensions); + params.setErrorListener(err); + params.setCatalogFile(catalog); + params.setIncrementalSrcGen(noSrcRegen); + params.setMdefNamespaces(mdefnamespaces); + params.setNoUpa(noupa); + params.setNoPvr(nopvr); + params.setNoAnn(noann); + params.setNoVDoc(novdoc); + params.setNoExt(noext); + params.setJavaSource(javasource); + success = SchemaCompiler.compile(params); + + if (success && !srconly) { + long start = System.currentTimeMillis(); + + // compile the source + Javac javac = new Javac(); + javac.setProject(project); + javac.setTaskName(getTaskName()); + javac.setClasspath(classpath); + if (compiler != null) javac.setCompiler(compiler); + javac.setDebug(debug); + if (debugLevel != null) javac.setDebugLevel(debugLevel); + javac.setDestdir(classgendir); + javac.setExecutable(forkedExecutable); + javac.setFailonerror(failonerror); + javac.setFork(fork); + if (javasource != null) + { + javac.setSource(javasource); + javac.setTarget(javasource); + } + else + { + javac.setSource("1.4"); + javac.setTarget("1.4"); + } + javac.setIncludeantruntime(includeAntRuntime); + javac.setIncludejavaruntime(includeJavaRuntime); + javac.setSrcdir(new Path(project, srcgendir.getAbsolutePath())); + if (memoryInitialSize != null) javac.setMemoryInitialSize(memoryInitialSize); + if (memoryMaximumSize != null) javac.setMemoryMaximumSize(memoryMaximumSize); + javac.setOptimize(optimize); + javac.setVerbose(verbose); + javac.execute(); + + long finish = System.currentTimeMillis(); + if (!quiet) + log("Time to compile code: " + ((double)(finish - start) / 1000.0) + " seconds"); + + if (destfile != null) + { + // jar the compiled classes + Jar jar = new Jar(); + jar.setProject(project); + jar.setTaskName(getTaskName()); + jar.setBasedir(classgendir); + jar.setDestFile(destfile); + jar.execute(); + } + } + + if (tmpdir != null) { + SchemaCodeGenerator.tryHardToDelete(tmpdir); + } + } + catch (BuildException e) + { + // re-throw anything thrown from javac or jar task + throw e; + } + catch (Throwable e) + { + //interrupted means cancel + if (e instanceof InterruptedException || failonerror) + throw new BuildException(e); + + log("Exception while building schemas: " + e.getMessage(), Project.MSG_ERR); + StringWriter sw = new StringWriter(); + e.printStackTrace(new PrintWriter(sw)); + log(sw.toString(), Project.MSG_VERBOSE); + } + + if (!success && failonerror) + throw new BuildException(); //stop the build + } + + private void processPaths(String[] paths, File baseDir) + { + for (int i = 0; i < paths.length; i++) + { + int dot = paths[i].lastIndexOf('.'); + if (dot > -1) + { + String path = paths[i]; + String possExt = path.substring(dot).toLowerCase(); + Set set = (Set) _extRouter.get(possExt); + + if (set != null) + set.add(new File(baseDir, path)); + } + } + } + + public void addFileset(FileSet fileset) + { + schemas.add(fileset); + } + + ///////////////////////////// + //Getter/Setters + public File getSchema() + { + return schema; + } + + /** + * A file that points to either an individual schema file or a directory of files. + * It is optional only if one or more <fileset> elements are nested in this + * task. + * @param schema Required, unless a fileset element is nested. + */ + public void setSchema(File schema) + { + this.schema = schema; + } + + /** + * The classpath to use if schemas in the fileset import definitions that are + * supplied by other compiled xml beans JAR files, or if .java files are in the + * schema fileset. + * @param classpath Optional. + */ + public void setClasspath(Path classpath) + { + if (this.classpath != null) + this.classpath.append(classpath); + else + this.classpath = classpath; + } + + /** + * Adds a path to the classpath. + */ + public Path createClasspath() { + if (classpath == null) { + classpath = new Path(project); + } + return classpath.createPath(); + } + + /** + * Adds a reference to a classpath defined elsewhere. + * @param classpathref Optional. + */ + public void setClasspathRef(Reference classpathref) + { + if (classpath == null) + classpath = new Path(project); + + classpath.createPath().setRefid(classpathref); + } + + public Path getClasspath() + { + return classpath; + } + + public File getDestfile() + { + return destfile; + } + + /** + * Define the name of the jar file created. For instance, "myXMLBean.jar" + * will output the results of this task into a jar with the same name. + * Optional, defaults to "xmltypes.jar". + * @param destfile Optional. + */ + public void setDestfile(File destfile) + { + this.destfile = destfile; + } + + public File getSrcgendir() + { + return srcgendir; + } + + /** + * Set a location to generate .java files into. Optional, defaults to + * a temp dir. + * @param srcgendir Optional. + */ + public void setSrcgendir(File srcgendir) + { + this.srcgendir = srcgendir; + } + + public File getClassgendir() + { + return classgendir; + } + + /** + * Set a location to generate .class files into. Optional, defaults to + * a temp dir. + * @param classgendir Optional. + */ + public void setClassgendir(File classgendir) + { + this.classgendir = classgendir; + } + + /** + * Choose the implementation for this particular task. + * + * @since Ant 1.5 + */ + public void setCompiler(String compiler) + { + this.compiler = compiler; + } + + public boolean isDownload() + { + return download; + } + + /** + * Set to true to permit the compiler to download URLs for imports + * and includes. Defaults to false, meaning all imports and includes + * must be copied locally. + * @param download Optional. + */ + public void setDownload(boolean download) + { + this.download = download; + } + + /** + * If true, compiles with optimization enabled. + */ + public void setOptimize(boolean optimize) { + this.optimize = optimize; + } + + /** Gets the optimize flag. */ + public boolean getOptimize() { + return optimize; + } + + public boolean isVerbose() + { + return verbose; + } + + /** + * Controls the amount of output. Defaults to true. + * @param verbose Optional. + */ + public void setVerbose(boolean verbose) + { + this.verbose = verbose; + } + + public boolean isQuiet() + { + return quiet; + } + + /** + * Controls the amount of output. Defaults to false. + * @param quiet Optional. + */ + public void setQuiet(boolean quiet) + { + this.quiet = quiet; + } + + public boolean isDebug() + { + return debug; + } + + /** + * Get the value of debugLevel. + * @return value of debugLevel. + */ + public String getDebugLevel() { + return debugLevel; + } + + /** + * Keyword list to be appended to the -g command-line switch. + * + * This will be ignored by all implementations except modern + * and classic(ver >= 1.2). Legal values are none or a + * comma-separated list of the following keywords: lines, vars, + * and source. If debuglevel is not specified, by default, :none + * will be appended to -g. If debug is not turned on, this attribute + * will be ignored. + * + * @param v Value to assign to debugLevel. + */ + public void setDebugLevel(String v) { + this.debugLevel = v; + } + + /** + * Generate debugging symbols. + * @param debug Optional. + */ + public void setDebug(boolean debug) + { + this.debug = debug; + } + + /** + * If true, forks the javac compiler. + * + * @param f "true|false|on|off|yes|no" + */ + public void setFork(boolean f) { + fork = f; + } + + /** + * Sets the the name of the javac executable. + * + *

    Ignored unless fork is true or extJavac has been specified + * as the compiler.

    + */ + public void setExecutable(String forkExec) { + forkedExecutable = forkExec; + } + + public String getExecutable() { + return forkedExecutable; + } + + public boolean isSrconly() + { + return srconly; + } + + /** + * A value of true means that only source will be generated. Optional, + * default is false. + * @param srconly Optional. + */ + public void setSrconly(boolean srconly) + { + this.srconly = srconly; + } + + public String getTypesystemname() + { + return typesystemname; + } + + /** + * One or more SchemaCompiler extensions can be passed in via the <extension> subelement. + * Schema Compiler extensions must implement the interface com.xbean.too.SchemaCompilerExtension + */ + public Extension createExtension() { + Extension e = new Extension(); + extensions.add(e); + return e; + } + + /** + * One or more namespaces in which duplicate definitions are to be ignored + * can be passed in via the <ignoreDuplicatesInNamespaces> subelement. + */ + public void setIgnoreDuplicatesInNamespaces(String namespaces) { + mdefnamespaces = new HashSet(); + StringTokenizer st = new StringTokenizer(namespaces, ","); + while (st.hasMoreTokens()) + { + String namespace = st.nextToken().trim(); + mdefnamespaces.add(namespace); + } + } + + public String getIgnoreDuplicatesInNamespaces() { + if (mdefnamespaces == null) { + return null; + } + StringBuffer buf = new StringBuffer(); + Iterator i = mdefnamespaces.iterator(); + while (i.hasNext()) { + buf.append((String)i.next()); + if (i.hasNext()) { + buf.append(","); + } + } + return buf.toString(); + } + + /** + * The name of the package that the TypeSystemHolder class should be + * generated in. Normally this should be left unspecified. None of + * the xml beans are generated in this package. + *

    Use .xsdconfig files to modify xml bean package or class names. + * @param typesystemname Optional. + */ + public void setTypesystemname(String typesystemname) + { + this.typesystemname = typesystemname; + } + + public boolean isFailonerror() + { + return failonerror; + } + + /** + * Determines whether or not the ant target will continue if the XMLBean + * creation encounters a build error. Defaults to true. Optional. + * @param failonerror Optional. + */ + public void setFailonerror(boolean failonerror) + { + this.failonerror = failonerror; + } + + public boolean isIncludeAntRuntime() + { + return includeAntRuntime; + } + + public void setIncludeAntRuntime(boolean includeAntRuntime) + { + this.includeAntRuntime = includeAntRuntime; + } + + public boolean isIncludeJavaRuntime() + { + return includeJavaRuntime; + } + + public void setIncludeJavaRuntime(boolean includeJavaRuntime) + { + this.includeJavaRuntime = includeJavaRuntime; + } + + public boolean isNoSrcRegen() + { + return noSrcRegen; + } + + public void setNoSrcRegen(boolean noSrcRegen) + { + this.noSrcRegen = noSrcRegen; + } + + /** + * Set the initial memory size of the underlying javac process. + */ + public String getMemoryInitialSize() + { + return memoryInitialSize; + } + + public void setMemoryInitialSize(String memoryInitialSize) + { + this.memoryInitialSize = memoryInitialSize; + } + + /** + * Set the maximum memory size of the underlying javac process. + */ + public String getMemoryMaximumSize() + { + return memoryMaximumSize; + } + + public void setMemoryMaximumSize(String memoryMaximumSize) + { + this.memoryMaximumSize = memoryMaximumSize; + } + + /** + * Do not enforce the unique particle attribution rule. + */ + public void setNoUpa(boolean noupa) + { + this.noupa = noupa; + } + + public boolean isNoUpa() + { + return noupa; + } + + /** + * Do not enforce the particle valid (restriction) rule. + */ + public void setNoPvr(boolean nopvr) + { + this.nopvr = nopvr; + } + + public boolean isNoPvr() + { + return nopvr; + } + + /** + * Skip over schema <annotation%gt; elements. + */ + public void setNoAnnotations(boolean noann) + { + this.noann = noann; + } + + public boolean isNoAnnotations() + { + return noann; + } + + /** + * Do not validate the contents of schema <documentation> elements. + */ + public void setNoValidateDoc(boolean novdoc) + { + this.novdoc = novdoc; + } + + public boolean isNoValidateDoc() + { + return novdoc; + } + + /** + * Ignore extensions found in .xsdconfig files + * @param novdoc + */ + public void setNoExt(boolean noext) + { + this.noext = noext; + } + + public boolean isNoExt() + { + return noext; + } + + /** + * Generate java source compatible with the given version. Currently, + * only "1.4" or "1.5" are supported and "1.4" is the default. + */ + public void setJavaSource(String javasource) + { + this.javasource = javasource; + } + + public String getJavaSource() + { + return javasource; + } + + //REVIEW this allows people to deal with the case where they drag in + //more files for compilation than they should. not sure if this is + //a good thing or not + private String source = null; + public void setSource(String s) { source = s; } + + /** + * Gets the XML Catalog file for org.apache.xml.resolver.tools.CatalogResolver. (Note: needs resolver.jar from http://xml.apache.org/commons/components/resolver/index.html) + */ + public String getCatalog() + { + return catalog; + } + + /** + * Sets the XML Catalog file for org.apache.xml.resolver.tools.CatalogResolver. (Note: needs resolver.jar from http://xml.apache.org/commons/components/resolver/index.html) + */ + public void setCatalog(String catalog) + { + this.catalog = catalog; + } + + private static URI uriFromFile(File f) + { + if (f == null) + return null; + + try + { + return f.getCanonicalFile().toURI(); + } + catch(java.io.IOException e) + { + // Don't spit out an exception here because on Windows you'll get one + // if the filename is "aux", "lpt1", etc. It's the caller's responsibility + // to deal with those cases correctly, usually by calling FileSvc.invalidPathCheck() + // MessageSvc.get().logException(e); + return f.getAbsoluteFile().toURI(); + } + } + + public class ErrorLogger extends AbstractCollection + { + private boolean _noisy; + private URI _baseURI; + + public ErrorLogger(boolean noisy) + { + _noisy = noisy; + _baseURI = uriFromFile(project.getBaseDir()); + } + + public boolean add(Object o) + { + if (o instanceof XmlError) + { + XmlError err = (XmlError)o; + if (err.getSeverity() == XmlError.SEVERITY_ERROR) + log(err.toString(_baseURI), Project.MSG_ERR); + else if (err.getSeverity() == XmlError.SEVERITY_WARNING) + log(err.toString(_baseURI), Project.MSG_WARN); + else if (_noisy) + log(err.toString(_baseURI), Project.MSG_INFO); + } + return false; + } + + public Iterator iterator() + { + return Collections.EMPTY_LIST.iterator(); + } + + public int size() + { + return 0; + } + } +} diff --git a/xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/XMLBeanXSTCHarness.java b/xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/XMLBeanXSTCHarness.java new file mode 100644 index 000000000..bf87c7216 --- /dev/null +++ b/xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/XMLBeanXSTCHarness.java @@ -0,0 +1,109 @@ +/* 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.tool; + +import org.apache.xmlbeans.SchemaTypeLoader; +import org.apache.xmlbeans.XmlBeans; +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.XmlOptions; +import org.apache.xmlbeans.SchemaTypeSystem; +import org.apache.xmlbeans.XmlException; + +import java.util.Collection; +import java.util.ArrayList; +import java.util.Collections; +import java.io.PrintWriter; +import java.io.StringWriter; + +public class XMLBeanXSTCHarness implements XSTCTester.Harness +{ + public void runTestCase(XSTCTester.TestCaseResult result) + { + XSTCTester.TestCase testCase = result.getTestCase(); + + // System.out.println("Running case " + testCase.getDescription()); + + try + { + Collection errors = new ArrayList(); + boolean schemaValid = true; + boolean instanceValid = true; + + if (testCase.getSchemaFile() == null) + return; + + // step 1, load schema file etc. + SchemaTypeLoader loader = null; + try + { + XmlObject schema = XmlObject.Factory.parse(testCase.getSchemaFile(), new XmlOptions().setErrorListener(errors).setLoadLineNumbers()); + XmlObject schema2 = null; + if (testCase.getResourceFile() != null) + schema2 = XmlObject.Factory.parse(testCase.getResourceFile(), new XmlOptions().setErrorListener(errors).setLoadLineNumbers()); + XmlObject[] schemas = schema2 == null ? new XmlObject[] { schema } : new XmlObject[] { schema, schema2 }; + SchemaTypeSystem system = XmlBeans.compileXsd(schemas, XmlBeans.getBuiltinTypeSystem(), new XmlOptions().setErrorListener(errors)); + loader = XmlBeans.typeLoaderUnion(new SchemaTypeLoader[] { system, XmlBeans.getBuiltinTypeSystem() }); + } + catch (Exception e) + { + schemaValid = false; + if (!(e instanceof XmlException) || errors.isEmpty()) + { + result.setCrash(true); + StringWriter sw = new StringWriter(); + e.printStackTrace(new PrintWriter(sw)); + result.addSvMessages(Collections.singleton(sw.toString())); + } + } + + result.addSvMessages(errors); + result.setSvActual(schemaValid); + errors.clear(); + + if (loader == null) + return; + + if (testCase.getInstanceFile() == null) + return; + + // step 2, load instance file and validate + try + { + XmlObject instance = loader.parse(testCase.getInstanceFile(), null, new XmlOptions().setErrorListener(errors).setLoadLineNumbers()); + if (!instance.validate(new XmlOptions().setErrorListener(errors))) + instanceValid = false; + } + catch (Exception e) + { + instanceValid = false; + if (!(e instanceof XmlException) || errors.isEmpty()) + { + result.setCrash(true); + StringWriter sw = new StringWriter(); + e.printStackTrace(new PrintWriter(sw)); + result.addIvMessages(Collections.singleton(sw.toString())); + } + } + result.addIvMessages(errors); + result.setIvActual(instanceValid); + + } + finally + { + // System.out.println(result.succeeded() ? "Success.": "Failure."); + } + } +} diff --git a/xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/XSTCTester.java b/xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/XSTCTester.java new file mode 100644 index 000000000..f7ea835db --- /dev/null +++ b/xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/XSTCTester.java @@ -0,0 +1,510 @@ +/* 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.tool; + +import org.apache.xmlbeans.SystemProperties; +import org.apache.xmlbeans.impl.xb.ltgfmt.TestsDocument; +import org.apache.xmlbeans.impl.xb.ltgfmt.FileDesc; +import org.apache.xmlbeans.XmlOptions; +import org.apache.xmlbeans.XmlException; +import org.apache.xmlbeans.XmlError; +import org.apache.xmlbeans.XmlCalendar; + +import java.io.File; +import java.io.PrintWriter; +import java.io.FileWriter; +import java.io.IOException; +import java.util.Collection; +import java.util.ArrayList; +import java.util.Set; +import java.util.HashSet; +import java.util.Collections; +import java.util.Iterator; +import java.util.Date; +import java.util.regex.Pattern; +import java.net.URI; + +public class XSTCTester +{ + public static void printUsage() + { + System.out.println("Usage: xstc [-showpass] [-errcode] foo_LTGfmt.xml ..."); + } + + public static void main(String[] args) throws IOException + { + Set flags = new HashSet(); + flags.add("h"); + flags.add("help"); + flags.add("usage"); + flags.add("version"); + flags.add("showpass"); + flags.add("errcode"); + + long start = System.currentTimeMillis(); + + CommandLine cl = new CommandLine(args, flags, Collections.EMPTY_SET); + if (cl.getOpt("h") != null || cl.getOpt("help") != null || cl.getOpt("usage") != null) + { + printUsage(); + System.exit(0); + return; + } + + if (cl.getOpt("version") != null) + { + CommandLine.printVersion(); + System.exit(0); + return; + } + + String[] badopts = cl.getBadOpts(); + if (badopts.length > 0) + { + for (int i = 0; i < badopts.length; i++) + System.out.println("Unrecognized option: " + badopts[i]); + printUsage(); + System.exit(0); + return; + } + + if (cl.args().length == 0) { + printUsage(); + return; + } + + boolean showpass = (cl.getOpt("showpass") != null); + boolean errcode = (cl.getOpt("errcode") != null); + + File[] allFiles = cl.getFiles(); + Collection ltgFiles = new ArrayList(); + Harness harness = new XMLBeanXSTCHarness(); + + for (int i = 0; i < allFiles.length; i++) + { + if (allFiles[i].getName().indexOf("LTG") >= 0) + ltgFiles.add(allFiles[i]); + } + + File resultsFile = new File("out.html"); + PrintWriter writer = new PrintWriter(new FileWriter(resultsFile)); + writer.println(""); + writer.println(""); + writer.println(""); + + writer.println(""); + + writer.println("

    XML Schema Test Collection Results

    "); + writer.println("

    Run on " + (new XmlCalendar(new Date())) + "

    "); + writer.println("

    Values in schema or instance valid columns are results from compiling or validating respectively."); + writer.println("Red or orange background mean the test failed.

    "); + writer.println(""); + writer.println(""); + int failures = 0; + int cases = 0; + for (Iterator i = ltgFiles.iterator(); i.hasNext(); ) + { + File ltgFile = (File)i.next(); + System.out.println("Processing test cases in " + ltgFile); + Collection ltgErrors = new ArrayList(); + TestCase[] testCases = parseLTGFile(ltgFile, ltgErrors); + Collection results = new ArrayList(); + if (testCases != null) for (int j = 0; j < testCases.length; j++) + { + TestCaseResult result = new TestCaseResult(); + result.testCase = testCases[j]; + harness.runTestCase(result); + cases += 1; + if (!result.succeeded(errcode)) + failures += 1; + else if (!showpass) + continue; + results.add(result); + } + writer.println(""); + if (!ltgErrors.isEmpty()) + { + writer.println(""); + } + else + { + if (results.size() == 0) + writer.println(""); + } + if (results == null) + continue; + for (Iterator j = results.iterator(); j.hasNext() ;) + { + summarizeResultAsHTMLTableRows((TestCaseResult)j.next(), writer, errcode); + } + } + writer.println(""); + writer.println("
    idDescriptionsch vins v
    " + ltgFile + "
    Errors within the LTG file:"); + writer.println(""); + for (Iterator j = ltgErrors.iterator(); j.hasNext(); ) + writer.println(j.next()); + writer.println(""); + writer.println("
    Nothing to report
    Summary: " + failures + " failures out of " + cases + " cases run.
    "); + writer.close(); + + long finish = System.currentTimeMillis(); + System.out.println("Time run tests: " + ((double)(finish - start) / 1000.0) + " seconds" ); + + // Launch results + System.out.println("Results output to " + resultsFile); + if (SystemProperties.getProperty("os.name").toLowerCase().indexOf("windows") >= 0) + Runtime.getRuntime().exec("cmd /c start iexplore \"" + resultsFile.getAbsolutePath() + "\""); + else + Runtime.getRuntime().exec("mozilla file://" + resultsFile.getAbsolutePath()); + } + + public static class TestCase + { + private File ltgFile; + private String id; + private String origin; + private String description; + private File schemaFile; + private File instanceFile; + private File resourceFile; + private boolean svExpected; + private boolean ivExpected; + private boolean rvExpected; + private String errorCode; + + public File getLtgFile() + { + return ltgFile; + } + + public String getId() + { + return id; + } + + public String getOrigin() + { + return origin; + } + + public String getDescription() + { + return description; + } + + public File getSchemaFile() + { + return schemaFile; + } + + public File getInstanceFile() + { + return instanceFile; + } + + public File getResourceFile() + { + return resourceFile; + } + + public boolean isSvExpected() + { + return svExpected; + } + + public boolean isIvExpected() + { + return ivExpected; + } + + public boolean isRvExpected() + { + return rvExpected; + } + + public String getErrorCode() + { + return errorCode; + } + + } + + public static class TestCaseResult + { + private TestCase testCase; + private boolean svActual; + private Collection svMessages = new ArrayList(); + private boolean ivActual; + private Collection ivMessages = new ArrayList(); + private boolean crash; + + public TestCase getTestCase() + { + return testCase; + } + + public boolean isSvActual() + { + return svActual; + } + + public void setSvActual(boolean svActual) + { + this.svActual = svActual; + } + + public boolean isIvActual() + { + return ivActual; + } + + public void setIvActual(boolean ivActual) + { + this.ivActual = ivActual; + } + + public Collection getSvMessages() + { + return Collections.unmodifiableCollection(svMessages); + } + + public void addSvMessages(Collection svMessages) + { + this.svMessages.addAll(svMessages); + } + + public Collection getIvMessages() + { + return Collections.unmodifiableCollection(ivMessages); + } + + public void addIvMessages(Collection ivMessages) + { + this.ivMessages.addAll(ivMessages); + } + + public void setCrash(boolean crash) + { + this.crash = crash; + } + + public boolean isCrash() + { + return crash; + } + + public boolean succeeded(boolean errcode) + { + boolean success = !crash && + (isIvActual() == testCase.isIvExpected()) && + (isSvActual() == testCase.isSvExpected()); + if (errcode && testCase.getErrorCode() != null) + success &= errorReported(testCase.getErrorCode(), svMessages) || errorReported(testCase.getErrorCode(), ivMessages); + return success; + } + + } + + public static interface Harness + { + public void runTestCase(TestCaseResult result); + } + + public static String makeHTMLLink(File file, boolean value) + { + if (file == null) + return " "; + URI uri = file.getAbsoluteFile().toURI(); + return "" + Boolean.toString(value) + ""; + } + + private static final Pattern leadingSpace = Pattern.compile("^\\s+", Pattern.MULTILINE); + + public static String makeHTMLDescription(TestCase testCase) + { + StringBuffer sb = new StringBuffer(); + sb.append(""); + sb.append(leadingSpace.matcher(testCase.getDescription()).replaceAll("")); + sb.append(""); + return sb.toString(); + } + + public static void summarizeResultAsHTMLTableRows(TestCaseResult result, PrintWriter out, boolean errcode) + { + TestCase testCase = result.getTestCase(); + + boolean errorRow = errcode && testCase.getErrorCode() != null; + boolean messagesRow = !result.getIvMessages().isEmpty() || !result.getSvMessages().isEmpty(); + + boolean sRight = testCase.getSchemaFile() == null || testCase.isSvExpected() == result.isSvActual(); + boolean iRight = testCase.getInstanceFile() == null || testCase.isIvExpected() == result.isIvActual(); + boolean codeRight = true; + if (errorRow) + codeRight = (errorReported(testCase.getErrorCode(), result.svMessages) || errorReported(testCase.getErrorCode(), result.ivMessages)); + + out.println(result.isCrash() ? "" : ""); + int idRowSpan = 1 + (errorRow ? 1 : 0) + (messagesRow ? 1 : 0); + out.println("" + testCase.getId() + ""); + out.println("" + makeHTMLDescription(testCase) + ""); + String sLinks; + if (testCase.getResourceFile() == null) + sLinks = makeHTMLLink(testCase.getSchemaFile(), result.isSvActual()); + else + sLinks = makeHTMLLink(testCase.getSchemaFile(), result.isSvActual()) + "
    " + makeHTMLLink(testCase.getResourceFile(), result.isSvActual()); + + out.println((sRight ? "" : result.isSvActual() ? "" : "") + sLinks + ""); + out.println((iRight ? "" : result.isIvActual() ? "" : "") + makeHTMLLink(testCase.getInstanceFile(), result.isIvActual()) + ""); + out.println(""); + if (errorRow) + { + out.println(""); + out.println((codeRight ? "" : "") + "expected error: " + testCase.getErrorCode() + ""); + out.println(""); + } + if (messagesRow) + { + if (!result.succeeded(errcode)) + out.println(""); + else + out.println("<tr><td colspan=4><xmp>"); + for (Iterator j = result.getSvMessages().iterator(); j.hasNext(); ) + out.println(j.next()); + for (Iterator j = result.getIvMessages().iterator(); j.hasNext(); ) + out.println(j.next()); + out.println(""); + } + } + + public static TestCase[] parseLTGFile(File ltgFile, Collection outerErrors) + { + Collection errors = new ArrayList(); + try + { + XmlOptions ltgOptions = new XmlOptions(); + ltgOptions.setLoadSubstituteNamespaces(Collections.singletonMap("", "http://www.bea.com/2003/05/xmlbean/ltgfmt")); + ltgOptions.setErrorListener(errors); + ltgOptions.setLoadLineNumbers(); + TestsDocument doc = TestsDocument.Factory.parse(ltgFile, ltgOptions); + if (!doc.validate(ltgOptions)) + throw new Exception("Document " + ltgFile + " not valid."); + + org.apache.xmlbeans.impl.xb.ltgfmt.TestCase[] testCases = doc.getTests().getTestArray(); + + Collection result = new ArrayList(); + for (int i = 0; i < testCases.length; i++) + { + TestCase newCase = new TestCase(); + newCase.ltgFile = ltgFile; + newCase.id = testCases[i].getId(); + newCase.origin = testCases[i].getOrigin(); + newCase.description = testCases[i].getDescription(); + FileDesc[] filedescs = testCases[i].getFiles().getFileArray(); + testCases[i].getOrigin(); + for (int j = 0; j < filedescs.length; j++) + { + String dir = filedescs[j].getFolder(); + String filename = filedescs[j].getFileName(); + File theFile = new File(ltgFile.getParentFile(), dir + "/" + filename); + if (!theFile.exists() || !theFile.isFile() || !theFile.canRead()) + { + outerErrors.add(XmlError.forObject("Can't read file " + theFile, filedescs[j]).toString()); + continue; + } + + switch (filedescs[j].getRole().intValue()) + { + case FileDesc.Role.INT_INSTANCE: + if (newCase.instanceFile != null) + outerErrors.add(XmlError.forObject("More than one instance file speicifed - ignoring all but last", filedescs[j]).toString()); + newCase.instanceFile = theFile; + newCase.ivExpected = filedescs[j].getValidity(); + break; + + case FileDesc.Role.INT_SCHEMA: + if (newCase.schemaFile != null) + outerErrors.add(XmlError.forObject("More than one schema file speicifed - ignoring all but last", filedescs[j]).toString()); + newCase.schemaFile = theFile; + newCase.svExpected = filedescs[j].getValidity(); + break; + + case FileDesc.Role.INT_RESOURCE: + if (newCase.resourceFile != null) + outerErrors.add(XmlError.forObject("More than one resource file speicifed - ignoring all but last", filedescs[j]).toString()); + newCase.resourceFile = theFile; + newCase.rvExpected = filedescs[j].getValidity(); + break; + + default: + throw new XmlException(XmlError.forObject("Unexpected file role", filedescs[j])); + } + + if (filedescs[j].getCode() != null) + newCase.errorCode = filedescs[j].getCode().getID(); + } + result.add(newCase); + } + return (TestCase[])result.toArray(new TestCase[result.size()]); + } + catch (Exception e) + { + if (errors.isEmpty()) + outerErrors.add(e.getMessage()); + else for (Iterator i = errors.iterator(); i.hasNext(); ) + outerErrors.add(i.next().toString()); + return null; + } + } + + public static boolean errorReported(String errorCode, Collection set) + { + if (errorCode == null || set == null || set.size() == 0) + return false; + + for (Iterator i = set.iterator(); i.hasNext(); ) + { + if (errorCode.equals(((XmlError)i.next()).getErrorCode())) + return true; + } + + return false; + } + +} diff --git a/xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/XsbDumper.java b/xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/XsbDumper.java new file mode 100644 index 000000000..d13ce42a9 --- /dev/null +++ b/xmlbeans/src/xmlcomp/org/apache/xmlbeans/impl/tool/XsbDumper.java @@ -0,0 +1,1340 @@ +/* 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.tool; + +import java.util.*; +import java.util.zip.ZipFile; +import java.util.zip.ZipEntry; +import java.io.*; +import java.math.BigInteger; + + +import org.apache.xmlbeans.impl.common.QNameHelper; +import org.apache.xmlbeans.impl.util.HexBin; +import org.apache.xmlbeans.QNameSet; +import org.apache.xmlbeans.SchemaLocalAttribute; +import org.apache.xmlbeans.SchemaParticle; +import org.apache.xmlbeans.SchemaProperty; +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.soap.SOAPArrayType; +import org.apache.xmlbeans.XmlException; +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.XmlOptions; +import javax.xml.namespace.QName; + +public class XsbDumper +{ + public static void printUsage() + { + System.out.println("Prints the contents of an XSB file in human-readable form."); + System.out.println("An XSB file contains schema meta information needed to "); + System.out.println("perform tasks such as binding and validation."); + System.out.println("Usage: dumpxsb myfile.xsb"); + System.out.println(" myfile.xsb - Path to an XSB file."); + System.out.println(); + } + + public static void main(String[] args) + { + if (args.length == 0) { + printUsage(); + System.exit(0); + return; + } + + for (int i = 0; i < args.length; i++) + { + dump(new File(args[i]), true); + } + } + + private static void dump(File file, boolean force) + { + if (file.isDirectory()) + { + File[] files = file.listFiles( + new FileFilter() + { + public boolean accept(File file) + { return file.isDirectory() || file.isFile() && file.getName().endsWith(".xsb"); } + } + ); + for (int i = 0; i < files.length; i++) + { + dump(files[i], false); + } + } + else if (file.getName().endsWith(".jar") || file.getName().endsWith(".zip")) + { + dumpZip(file); + } + else if (force || file.getName().endsWith(".xsb")) + { + try + { + System.out.println(file.toString()); + dump(new FileInputStream(file), " "); + System.out.println(); + } + catch (FileNotFoundException e) + { + System.out.println(e.toString()); + } + } + } + + public static void dumpZip(File file) + { + try + { + ZipFile zipFile = new ZipFile(file); + Enumeration e = zipFile.entries(); + while (e.hasMoreElements()) + { + ZipEntry entry = (ZipEntry)e.nextElement(); + if (entry.getName().endsWith(".xsb")) + { + System.out.println(entry.getName()); + dump(zipFile.getInputStream(entry), " "); + System.out.println(); + } + } + } + catch (IOException e) + { + System.out.println(e.toString()); + } + } + + public static void dump(InputStream input) + { + dump(input, "", System.out); + } + + public static void dump(InputStream input, String indent) + { + dump(input, indent, System.out); + } + + public static void dump(InputStream input, String indent, PrintStream output) + { + XsbDumper dumper = new XsbDumper(input, indent, output); + dumper.dumpAll(); + } + + private XsbDumper(InputStream stream, String indent, PrintStream ostream) + { + _input = new DataInputStream(stream); + _indent = indent; + _out = ostream; + } + + void flush() { _out.flush(); } + void emit(String str) { _out.println(_indent + str); flush(); } + void emit() { _out.println(); flush(); } + void error(Exception e) { _out.println(e.toString()); flush(); IllegalStateException e2 = new IllegalStateException( e.getMessage() ); e2.initCause( e ); throw e2; } + void error(String str) { _out.println(str); flush(); IllegalStateException e2 = new IllegalStateException( str ); throw e2; } + private String _indent; + private PrintStream _out; + void indent() { _indent += " "; } + void outdent() { _indent = _indent.substring(0, _indent.length() - 2); } + + public static final int DATA_BABE = 0xDA7ABABE; + public static final int MAJOR_VERSION = 2; + public static final int MINOR_VERSION = 24; + + 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; + + static String filetypeString(int code) + { + switch (code) + { + case FILETYPE_SCHEMAINDEX: return "FILETYPE_SCHEMAINDEX"; + case FILETYPE_SCHEMATYPE: return "FILETYPE_SCHEMATYPE"; + case FILETYPE_SCHEMAELEMENT: return "FILETYPE_SCHEMAELEMENT"; + case FILETYPE_SCHEMAATTRIBUTE: return "FILETYPE_SCHEMAATTRIBUTE"; + case FILETYPE_SCHEMAPOINTER: return "FILETYPE_SCHEMAPOINTER"; + case FILETYPE_SCHEMAMODELGROUP: return "FILETYPE_SCHEMAMODELGROUP"; + case FILETYPE_SCHEMAATTRIBUTEGROUP: return "FILETYPE_SCHEMAATTRIBUTEGROUP"; + default: + return "Unknown FILETYPE (" + code + ")"; + } + } + + 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; + + static String particleflagsString(int flags) + { + StringBuffer result = new StringBuffer(); + if ((flags & FLAG_PART_SKIPPABLE) != 0) result.append("FLAG_PART_SKIPPABLE | "); + if ((flags & FLAG_PART_FIXED) != 0) result.append("FLAG_PART_FIXED | "); + if ((flags & FLAG_PART_NILLABLE) != 0) result.append("FLAG_PART_NILLABLE | "); + if ((flags & FLAG_PART_BLOCKEXT) != 0) result.append("FLAG_PART_BLOCKEXT | "); + if ((flags & FLAG_PART_BLOCKREST) != 0) result.append("FLAG_PART_BLOCKREST | "); + if ((flags & FLAG_PART_BLOCKSUBST) != 0) result.append("FLAG_PART_BLOCKSUBST | "); + if ((flags & FLAG_PART_ABSTRACT) != 0) result.append("FLAG_PART_ABSTRACT | "); + if ((flags & FLAG_PART_FINALEXT) != 0) result.append("FLAG_PART_FINALEXT | "); + if ((flags & FLAG_PART_FINALREST) != 0) result.append("FLAG_PART_FINALREST | "); + if (result.length() == 0) result.append("0 | "); + return result.substring(0, result.length() - 3); + } + + 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; + + static String propertyflagsString(int flags) + { + StringBuffer result = new StringBuffer(); + if ((flags & FLAG_PROP_ISATTR) != 0) result.append("FLAG_PROP_ISATTR | "); + if ((flags & FLAG_PROP_JAVASINGLETON) != 0) result.append("FLAG_PROP_JAVASINGLETON | "); + if ((flags & FLAG_PROP_JAVAOPTIONAL) != 0) result.append("FLAG_PROP_JAVAOPTIONAL | "); + if ((flags & FLAG_PROP_JAVAARRAY) != 0) result.append("FLAG_PROP_JAVAARRAY | "); + if (result.length() == 0) result.append("0 | "); + return result.substring(0, result.length() - 3); + } + + 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; + + static String containerfieldTypeString(int code) + { + switch (code) + { + case FIELD_NONE: return "FIELD_NONE"; + case FIELD_GLOBAL: return "FIELD_GLOBAL"; + case FIELD_LOCALATTR: return "FIELD_LOCALATTR"; + case FIELD_LOCALELT: return "FIELD_LOCALELT"; + default: + return "Unknown container field type (" + code + ")"; + } + } + + // 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; + + static String typeflagsString(int flags) + { + StringBuffer result = new StringBuffer(); + if ((flags & FLAG_SIMPLE_TYPE) != 0) result.append("FLAG_SIMPLE_TYPE | "); + if ((flags & FLAG_DOCUMENT_TYPE) != 0) result.append("FLAG_DOCUMENT_TYPE | "); + if ((flags & FLAG_ATTRIBUTE_TYPE) != 0) result.append("FLAG_ATTRIBUTE_TYPE | "); + if ((flags & FLAG_ORDERED) != 0) result.append("FLAG_ORDERED | "); + if ((flags & FLAG_BOUNDED) != 0) result.append("FLAG_BOUNDED | "); + if ((flags & FLAG_FINITE) != 0) result.append("FLAG_FINITE | "); + if ((flags & FLAG_NUMERIC) != 0) result.append("FLAG_NUMERIC | "); + if ((flags & FLAG_STRINGENUM) != 0) result.append("FLAG_STRINGENUM | "); + if ((flags & FLAG_UNION_OF_LISTS) != 0) result.append("FLAG_UNION_OF_LISTS | "); + if ((flags & FLAG_HAS_PATTERN) != 0) result.append("FLAG_HAS_PATTERN | "); + if ((flags & FLAG_TOTAL_ORDER) != 0) result.append("FLAG_TOTAL_ORDER | "); + if ((flags & FLAG_COMPILED) != 0) result.append("FLAG_COMPILED | "); + if ((flags & FLAG_BLOCK_EXT) != 0) result.append("FLAG_BLOCK_EXT | "); + if ((flags & FLAG_BLOCK_REST) != 0) result.append("FLAG_BLOCK_REST | "); + if ((flags & FLAG_FINAL_EXT) != 0) result.append("FLAG_FINAL_EXT | "); + if ((flags & FLAG_FINAL_REST) != 0) result.append("FLAG_FINAL_REST | "); + if ((flags & FLAG_FINAL_UNION) != 0) result.append("FLAG_FINAL_UNION | "); + if ((flags & FLAG_FINAL_LIST) != 0) result.append("FLAG_FINAL_LIST | "); + if ((flags & FLAG_ABSTRACT) != 0) result.append("FLAG_ABSTRACT | "); + if (result.length() == 0) result.append("0 | "); + return result.substring(0, result.length() - 3); + } + + void dumpAll() + { + int filetype = dumpHeader(); + switch (filetype) + { + case FILETYPE_SCHEMAINDEX: + dumpIndexData(); + return; + case FILETYPE_SCHEMATYPE: + dumpTypeFileData(); + break; + case FILETYPE_SCHEMAELEMENT: + dumpParticleData(true); + break; + case FILETYPE_SCHEMAATTRIBUTE: + dumpAttributeData(true); + break; + case FILETYPE_SCHEMAPOINTER: + dumpPointerData(); + break; + case FILETYPE_SCHEMAMODELGROUP: + dumpModelGroupData(); + break; + case FILETYPE_SCHEMAATTRIBUTEGROUP: + dumpAttributeGroupData(); + break; + } + readEnd(); + } + + static String hex32String(int i) + { + return Integer.toHexString(i); + } + + protected int dumpHeader() + { + int magic = readInt(); + emit("Magic cookie: " + hex32String(magic)); + + if (magic != DATA_BABE) + { + emit("Wrong magic cookie."); + return 0; + } + + _majorver = readShort(); + _minorver = readShort(); + if (atLeast(2, 18, 0)) + _releaseno = readShort(); + + emit("Major version: " + _majorver); + emit("Minor version: " + _minorver); + emit("Release number: " + _releaseno); + + if (_majorver != MAJOR_VERSION || _minorver > MINOR_VERSION) + { + emit("Incompatible version."); + return 0; + } + + int actualfiletype = readShort(); + emit("Filetype: " + filetypeString(actualfiletype)); + + _stringPool = new StringPool(); + _stringPool.readFrom(_input); + + return actualfiletype; + } + + void dumpPointerData() + { + emit("Type system: " + readString()); + } + + protected void dumpIndexData() + { + // has a handle pool (count, handle/type, handle/type...) + int size = readShort(); + emit("Handle pool (" + size + "):"); + indent(); + for (int i = 0; i < size; i++) + { + String handle = readString(); + int code = readShort(); + emit(handle + " (" + filetypeString(code) + ")"); + } + outdent(); + + dumpQNameMap("Global elements"); + + // qname map of global attributes + dumpQNameMap("Global attributes"); + + // attr groups and model groups + dumpQNameMap("Model groups"); + dumpQNameMap("Attribute groups"); + + dumpQNameMap("Identity constraints"); + + // qname map of global types + dumpQNameMap("Global types"); + + // qname map of document types, by the qname of the contained element + dumpQNameMap("Document types"); + + // qname map of attribute types, by the qname of the contained attribute + dumpQNameMap("Attribute types"); + + // all the types indexed by classname + dumpClassnameIndex("All types by classname"); + + // all the namespaces + dumpStringArray("Defined namespaces"); + + // version 15 stuff for redefines + if (atLeast(2, 15, 0)) + { + dumpQNameMap("Redefined global types"); + dumpQNameMap("Redfined model groups"); + dumpQNameMap("Redfined attribute groups"); + } + + // version 19 annotations + if (atLeast(2, 19, 0)) + dumpAnnotations(); + + readEnd(); + } + + + class StringPool + { + private List intsToStrings = new ArrayList(); + private Map stringsToInts = new HashMap(); + + StringPool() + { + intsToStrings.add(null); + } + + String stringForCode(int code) + { + if (code == 0) + return null; + return (String)intsToStrings.get(code); + } + + 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(); + } + + void readFrom(DataInputStream input) + { + if (intsToStrings.size() != 1 || stringsToInts.size() != 0) + throw new IllegalStateException(); + + try + { + int size = input.readShort(); + emit("String pool (" + size + "):"); + indent(); + for (int i = 1; i < size; i++) + { + String str = input.readUTF(); + int code = codeForString(str); + if (code != i) + throw new IllegalStateException(); + emit(code + " = \"" + str + "\""); + } + outdent(); + } + catch (IOException e) + { + emit(e.toString()); + } + } + } + + // active while loading one type. + DataInputStream _input; + StringPool _stringPool; + + int readShort() + { + try + { + return _input.readUnsignedShort(); + } + catch (IOException e) + { + error(e); + return 0; + } + } + + int readInt() + { + try + { + return _input.readInt(); + } + catch (IOException e) + { + error(e); + return 0; + } + } + + String readString() + { + return _stringPool.stringForCode(readShort()); + } + + QName readQName() + { + String namespace = readString(); + String localname = readString(); + if (localname == null) + return null; + return new QName(namespace, localname); + } + + String readHandle() + { + return readString(); + } + + String readType() + { + return readHandle(); + } + + static String qnameString(QName qname) + { + if (qname == null) + return "(null)"; + if (qname.getNamespaceURI() != null) + return qname.getLocalPart() + "@" + qname.getNamespaceURI(); + else + return qname.getLocalPart(); + } + + static String qnameSetString(QNameSet set) + { + return set.toString(); + } + + void dumpQNameMap(String fieldname) + { + int size = readShort(); + emit(fieldname + " (" + size + "):"); + indent(); + for (int i = 0; i < size; i++) + { + emit(qnameString(readQName()) + " = " + readHandle()); + } + outdent(); + } + + void dumpTypeArray(String fieldname) + { + int size = readShort(); + emit(fieldname + " (" + size + "):"); + indent(); + for (int i = 0; i < size; i++) + { + emit(i + " = " + readType()); + } + outdent(); + } + + void dumpClassnameIndex(String fieldname) + { + int size = readShort(); + emit(fieldname + " (" + size + "):"); + indent(); + for (int i = 0; i < size; i++) + { + emit(readString() + " = " + readType()); + } + outdent(); + } + + void dumpStringArray(String fieldname) + { + int size = readShort(); + emit(fieldname + " (" + size + "):"); + indent(); + for (int i = 0; i < size; i++) + { + emit(readString()); + } + outdent(); + } + + void readEnd() + { + try + { + _input.close(); + } + catch (IOException e) + { + // oh, well. + } + _input = null; + _stringPool = null; + } + + static String particleTypeString(int spt) + { + switch (spt) + { + case SchemaParticle.ALL: return "ALL"; + case SchemaParticle.CHOICE: return "CHOICE"; + case SchemaParticle.ELEMENT: return "ELEMENT"; + case SchemaParticle.SEQUENCE: return "SEQUENCE"; + case SchemaParticle.WILDCARD: return "WILDCARD"; + default: + return "Unknown particle type (" + spt + ")"; + } + } + + static String bigIntegerString(BigInteger bigint) + { + if (bigint == null) + return "(null)"; + return bigint.toString(); + } + + static String wcprocessString(int code) + { + switch (code) + { + case SchemaParticle.STRICT: return "STRICT"; + case SchemaParticle.SKIP: return "SKIP"; + case SchemaParticle.LAX: return "LAX"; + case 0: return "NOT_WILDCARD"; + default: + return "Unknown process type (" + code + ")"; + } + } + + void dumpAnnotation() + { + if (!atLeast(2, 19, 0)) + return; // no annotations in this version of the file + + int n = readInt(); + if (n == -1) + return; // no annotation present + emit("Annotation"); + boolean empty = true; + indent(); + if (n > 0) + { + emit("Attributes (" + n + "):"); + indent(); + for (int i = 0; i < n; i++) + { + if (atLeast(2, 24, 0)) + emit("Name: " + qnameString(readQName()) + + ", Value: " + readString() + + ", ValueURI: " + readString()); + else + emit("Name: " + qnameString(readQName()) + + ", Value: " + readString()); + } + outdent(); + empty = false; + } + + n = readInt(); + if (n > 0) + { + emit("Documentation elements (" + n + "):"); + indent(); + for (int i = 0; i < n; i++) + emit(readString()); + outdent(); + empty = false; + } + + n = readInt(); + if (n > 0) + { + emit("Appinfo elements (" + n + "):"); + indent(); + for (int i = 0; i < n; i++) + emit(readString()); + outdent(); + empty = false; + } + if (empty) + emit(""); + outdent(); + } + + void dumpAnnotations() + { + int n = readInt(); + if (n > 0) + { + emit("Top-level annotations (" + n + "):"); + indent(); + for (int i = 0; i < n; i++) + dumpAnnotation(); + outdent(); + } + } + + void dumpParticleData(boolean global) + { + int particleType = readShort(); + emit(particleTypeString(particleType) + ":"); + indent(); + int particleFlags = readShort(); + emit("Flags: " + particleflagsString(particleFlags)); + + emit("MinOccurs: " + bigIntegerString(readBigInteger())); + emit("MaxOccurs: " + bigIntegerString(readBigInteger())); + + emit("Transition: " + qnameSetString(readQNameSet())); + + switch (particleType) + { + case SchemaParticle.WILDCARD: + emit("Wildcard set: " + qnameSetString(readQNameSet())); + emit("Wildcard process: " + wcprocessString(readShort())); + break; + + case SchemaParticle.ELEMENT: + emit("Name: " + qnameString(readQName())); + emit("Type: " + readType()); + emit("Default: " + readString()); + if (atLeast(2, 16, 0)) + emit("Default value: " + readXmlValueObject()); + emit("WsdlArrayType: " + SOAPArrayTypeString(readSOAPArrayType())); + dumpAnnotation(); + if (global) + { + if (atLeast(2, 17, 0)) + emit("Substitution group ref: " + readHandle()); + int substGroupCount = readShort(); + emit("Substitution group members (" + substGroupCount + ")"); + indent(); + for (int i = 0; i < substGroupCount; i++) + { + emit(qnameString(readQName())); + } + outdent(); + } + int count = readShort(); + emit("Identity constraints (" + count + "):"); + indent(); + for (int i = 0; i < count; i++) + { + emit(readHandle()); + } + outdent(); + if (global) + emit("Filename: " + readString()); + break; + + case SchemaParticle.ALL: + case SchemaParticle.SEQUENCE: + case SchemaParticle.CHOICE: + dumpParticleArray("Particle children"); + break; + + default: + error("Unrecognized schema particle type"); + } + outdent(); + } + + void dumpParticleArray(String fieldname) + { + int count = readShort(); + emit(fieldname + "(" + count + "):"); + indent(); + for (int i = 0; i < count; i++) + dumpParticleData(false); + outdent(); + } + + static String complexVarietyString(int code) + { + switch (code) + { + case SchemaType.EMPTY_CONTENT: return "EMPTY_CONTENT"; + case SchemaType.SIMPLE_CONTENT: return "SIMPLE_CONTENT"; + case SchemaType.ELEMENT_CONTENT: return "ELEMENT_CONTENT"; + case SchemaType.MIXED_CONTENT: return "MIXED_CONTENT"; + default: + return "Unknown complex variety (" + code + ")"; + } + } + + static String simpleVarietyString(int code) + { + switch (code) + { + case SchemaType.ATOMIC: return "ATOMIC"; + case SchemaType.LIST: return "LIST"; + case SchemaType.UNION: return "UNION"; + default: + return "Unknown simple variety (" + code + ")"; + } + } + + String facetCodeString(int code) + { + switch (code) + { + case SchemaType.FACET_LENGTH: return "FACET_LENGTH"; + case SchemaType.FACET_MIN_LENGTH: return "FACET_MIN_LENGTH"; + case SchemaType.FACET_MAX_LENGTH: return "FACET_MAX_LENGTH"; + case SchemaType.FACET_MIN_EXCLUSIVE: return "FACET_MIN_EXCLUSIVE"; + case SchemaType.FACET_MIN_INCLUSIVE: return "FACET_MIN_INCLUSIVE"; + case SchemaType.FACET_MAX_INCLUSIVE: return "FACET_MAX_INCLUSIVE"; + case SchemaType.FACET_MAX_EXCLUSIVE: return "FACET_MAX_EXCLUSIVE"; + case SchemaType.FACET_TOTAL_DIGITS: return "FACET_TOTAL_DIGITS"; + case SchemaType.FACET_FRACTION_DIGITS: return "FACET_FRACTION_DIGITS"; + default: + return "Unknown facet code (" + code + ")"; + } + } + + String whitespaceCodeString(int code) + { + switch (code) + { + case SchemaType.WS_COLLAPSE: return "WS_COLLAPSE"; + case SchemaType.WS_PRESERVE: return "WS_PRESERVE"; + case SchemaType.WS_REPLACE: return "WS_REPLACE"; + case SchemaType.WS_UNSPECIFIED: return "WS_UNSPECIFIED"; + default: + return "Unknown whitespace code (" + code + ")"; + } + } + + String derivationTypeString(int code) + { + switch (code) + { + case SchemaType.DT_NOT_DERIVED: return "DT_NOT_DERIVED"; + case SchemaType.DT_RESTRICTION: return "DT_RESTRICTION"; + case SchemaType.DT_EXTENSION: return "DT_EXTENSION"; + default: + return "Unknown derivation code (" + code + ")"; + } + } + + void dumpTypeFileData() + { + emit("Name: " + qnameString(readQName())); + emit("Outer type: " + readType()); + emit("Depth: " + readShort()); + emit("Base type: " + readType()); + emit("Derivation type: " + derivationTypeString(readShort())); + dumpAnnotation(); + + emit("Container field:"); + indent(); + int containerfieldtype = readShort(); + emit("Reftype: " + containerfieldTypeString(containerfieldtype)); + switch (containerfieldtype) + { + case FIELD_GLOBAL: + emit("Handle: " + readHandle()); + break; + case FIELD_LOCALATTR: + emit("Index: " + readShort()); + break; + case FIELD_LOCALELT: + emit("Index: " + readShort()); + break; + } + outdent(); + emit("Java class name: " + readString()); + emit("Java impl class name: " + readString()); + + dumpTypeArray("Anonymous types"); + + emit("Anonymous union member ordinal: " + readShort()); + + int flags; + flags = readInt(); + emit("Flags: " + typeflagsString(flags)); + boolean isComplexType = ((flags & FLAG_SIMPLE_TYPE) == 0); + + int complexVariety = SchemaType.NOT_COMPLEX_TYPE; + if (isComplexType) + { + complexVariety = readShort(); + emit("Complex variety: " + complexVarietyString(complexVariety)); + + if (atLeast(2, 23, 0)) + emit("Content based on type: " + readType()); + + int attrCount = readShort(); + emit("Attribute model (" + attrCount + "):"); + indent(); + for (int i = 0; i < attrCount; i++) + dumpAttributeData(false); + + emit("Wildcard set: " + qnameSetString(readQNameSet())); + emit("Wildcard process: " + wcprocessString(readShort())); + outdent(); + + // Attribute Property Table + int attrPropCount = readShort(); + emit("Attribute properties (" + attrPropCount + "):"); + indent(); + for (int i = 0; i < attrPropCount; i++) + { + dumpPropertyData(); + } + outdent(); + + if (complexVariety == SchemaType.ELEMENT_CONTENT || complexVariety == SchemaType.MIXED_CONTENT) + { + emit("IsAll: " + readShort()); + + // Content model tree + dumpParticleArray("Content model"); + + // Element Property Table + int elemPropCount = readShort(); + emit("Element properties (" + elemPropCount + "):"); + indent(); + for (int i = 0; i < elemPropCount; i++) + { + dumpPropertyData(); + } + outdent(); + } + } + + if (!isComplexType || complexVariety == SchemaType.SIMPLE_CONTENT) + { + int simpleVariety = readShort(); + emit("Simple type variety: " + simpleVarietyString(simpleVariety)); + + boolean isStringEnum = ((flags & FLAG_STRINGENUM) != 0); + + int facetCount = readShort(); + emit("Facets (" + facetCount + "):"); + indent(); + for (int i = 0; i < facetCount; i++) + { + emit(facetCodeString(readShort())); + emit("Value: " + readXmlValueObject()); + emit("Fixed: " + readShort()); + } + outdent(); + + emit("Whitespace rule: " + whitespaceCodeString(readShort())); + + int patternCount = readShort(); + emit("Patterns (" + patternCount + "):"); + indent(); + for (int i = 0; i < patternCount; i++) + { + emit(readString()); + } + outdent(); + + int enumCount = readShort(); + emit("Enumeration values (" + enumCount + "):"); + indent(); + for (int i = 0; i < enumCount; i++) + { + emit(readXmlValueObject()); + } + outdent(); + + emit("Base enum type: " + readType()); + if (isStringEnum) + { + int seCount = readShort(); + emit("String enum entries (" + seCount + "):"); + indent(); + for (int i = 0; i < seCount; i++) + { + emit("\"" + readString() + "\" -> " + readShort() + " = " + readString()); + } + outdent(); + } + + switch (simpleVariety) + { + case SchemaType.ATOMIC: + emit("Primitive type: " + readType()); + emit("Decimal size: " + readInt()); + break; + + case SchemaType.LIST: + emit("List item type: " + readType()); + break; + + case SchemaType.UNION: + dumpTypeArray("Union members"); + break; + + default: + error("Unknown simple type variety"); + } + } + + emit("Filename: " + readString()); + } + + static String attruseCodeString(int code) + { + switch (code) + { + case SchemaLocalAttribute.OPTIONAL: return "OPTIONAL"; + case SchemaLocalAttribute.REQUIRED: return "REQUIRED"; + case SchemaLocalAttribute.PROHIBITED: return "PROHIBITED"; + default: + return "Unknown use code (" + code + ")"; + } + } + + void dumpAttributeData(boolean global) + { + emit("Name: " + qnameString(readQName())); + emit("Type: " + readType()); + emit("Use: " + attruseCodeString(readShort())); + emit("Default: " + readString()); + if (atLeast(2, 16, 0)) + emit("Default value: " + readXmlValueObject()); + emit("Fixed: " + readShort()); + emit("WsdlArrayType: " + SOAPArrayTypeString(readSOAPArrayType())); + dumpAnnotation(); + if (global) + emit("Filename: " + readString()); + } + + private static final XmlOptions prettyOptions = + new XmlOptions().setSavePrettyPrint(); + + void dumpXml() + { + String xml = readString(); + try + { + emit( XmlObject.Factory.parse( xml ).xmlText( prettyOptions ) ); + } + catch ( XmlException x ) + { + emit( "!!!!!! BAD XML !!!!!" ); + emit( xml ); + } + } + + void dumpModelGroupData() + { + emit("Name: " + qnameString(readQName())); + emit("Target namespace: " + readString()); + emit("Chameleon: " + readShort()); + if (atLeast(2, 22, 0)) + emit("Element form default: " + readString()); + if (atLeast(2, 22, 0)) + emit("Attribute form default: " + readString()); + if (atLeast(2, 15, 0)) + emit("Redefine: " + readShort()); + emit("Model Group Xml: "); + dumpXml(); + dumpAnnotation(); + if (atLeast(2, 21, 0)) + emit("Filename: " + readString()); + } + + void dumpAttributeGroupData() + { + emit("Name: " + qnameString(readQName())); + emit("Target namespace: " + readString()); + emit("Chameleon: " + readShort()); + if (atLeast(2, 22, 0)) + emit("Form default: " + readString()); + if (atLeast(2, 15, 0)) + emit("Redefine: " + readShort()); + emit("Attribute Group Xml: "); + dumpXml(); + dumpAnnotation(); + if (atLeast(2, 21, 0)) + emit("Filename: " + readString()); + } + + static String alwaysString(int code) + { + switch (code) + { + case SchemaProperty.CONSISTENTLY: return "CONSISTENTLY"; + case SchemaProperty.NEVER: return "NEVER"; + case SchemaProperty.VARIABLE: return "VARIABLE"; + default: + return "Unknown frequency code (" + code + ")"; + } + } + + static String jtcString(int code) + { + switch (code) + { + case SchemaProperty.XML_OBJECT: return "XML_OBJECT"; + case SchemaProperty.JAVA_BOOLEAN: return "JAVA_BOOLEAN"; + case SchemaProperty.JAVA_FLOAT: return "JAVA_FLOAT"; + case SchemaProperty.JAVA_DOUBLE: return "JAVA_DOUBLE"; + case SchemaProperty.JAVA_BYTE: return "JAVA_BYTE"; + case SchemaProperty.JAVA_SHORT: return "JAVA_SHORT"; + case SchemaProperty.JAVA_INT: return "JAVA_INT"; + case SchemaProperty.JAVA_LONG: return "JAVA_LONG"; + + case SchemaProperty.JAVA_BIG_DECIMAL: return "JAVA_BIG_DECIMAL"; + case SchemaProperty.JAVA_BIG_INTEGER: return "JAVA_BIG_INTEGER"; + case SchemaProperty.JAVA_STRING: return "JAVA_STRING"; + case SchemaProperty.JAVA_BYTE_ARRAY: return "JAVA_BYTE_ARRAY"; + case SchemaProperty.JAVA_GDATE: return "JAVA_GDATE"; + case SchemaProperty.JAVA_GDURATION: return "JAVA_GDURATION"; + case SchemaProperty.JAVA_DATE: return "JAVA_DATE"; + case SchemaProperty.JAVA_QNAME: return "JAVA_QNAME"; + case SchemaProperty.JAVA_CALENDAR: return "JAVA_CALENDAR"; + case SchemaProperty.JAVA_LIST: return "JAVA_LIST"; + + case SchemaProperty.JAVA_ENUM: return "JAVA_ENUM"; + case SchemaProperty.JAVA_OBJECT: return "JAVA_OBJECT"; + + default: + return "Unknown java type code (" + code + ")"; + } + } + + void dumpPropertyData() + { + emit("Property"); + indent(); + emit("Name: " + qnameString(readQName())); + emit("Type: " + readType()); + int propflags = readShort(); + emit("Flags: " + propertyflagsString(propflags)); + emit("Container type: " + readType()); + emit("Min occurances: " + bigIntegerString(readBigInteger())); + emit("Max occurances: " + bigIntegerString(readBigInteger())); + emit("Nillable: " + alwaysString(readShort())); + emit("Default: " + alwaysString(readShort())); + emit("Fixed: " + alwaysString(readShort())); + emit("Default text: " + readString()); + emit("Java prop name: " + readString()); + emit("Java type code: " + jtcString(readShort())); + emit("Type for java signature: " + readType()); + if (atMost(2, 19, 0)) + emit("Java setter delimiter: " + qnameSetString(readQNameSet())); + if (atLeast(2, 16, 0)) + emit("Default value: " + readXmlValueObject()); + if (((propflags & FLAG_PROP_ISATTR) == 0) && atLeast(2, 17, 0)) + { + int size = readShort(); + emit("Accepted substitutions (" + size + "):"); + for (int i = 0 ; i < size ; i++) + emit(" Accepted name " + readQName()); + } + outdent(); + } + + String readXmlValueObject() + { + String type = readType(); + if (type == null) + return "null"; + + int btc = readShort(); + String value; + switch (btc) + { + default: + assert(false); + case 0: + value = "nil"; + break; + + 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: + value = readString(); + break; + + case SchemaType.BTC_BASE_64_BINARY: + case SchemaType.BTC_HEX_BINARY: + { + value = new String(HexBin.encode(readByteArray())); + if (value.length() > 19) + value = value.subSequence(0, 16) + "..."; + break; + } + + case SchemaType.BTC_QNAME: + case SchemaType.BTC_NOTATION: + value = QNameHelper.pretty(readQName()); + break; + + case SchemaType.BTC_FLOAT: + case SchemaType.BTC_DOUBLE: + value = Double.toString(readDouble()); + break; + } + return value + " (" + type + ": " + btc +")"; + } + + double readDouble() + { + try + { + return _input.readDouble(); + } + catch (IOException e) + { + error(e); + return 0.0; + } + } + + String SOAPArrayTypeString(SOAPArrayType t) + { + if (t == null) + return "null"; + return QNameHelper.pretty(t.getQName()) + t.soap11DimensionString(); + } + + SOAPArrayType readSOAPArrayType() + { + QName qName = readQName(); + String dimensions = readString(); + if (qName == null) + return null; + return new SOAPArrayType(qName, dimensions); + } + + QNameSet readQNameSet() + { + int flag = readShort(); + + Set uriSet = new HashSet(); + int uriCount = readShort(); + for (int i = 0; i < uriCount; i++) + uriSet.add(readString()); + + Set qnameSet1 = new HashSet(); + int qncount1 = readShort(); + for (int i = 0; i < qncount1; i++) + qnameSet1.add(readQName()); + + Set 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); + } + + byte[] readByteArray() + { + try + { + int len = _input.readShort(); + byte[] result = new byte[len]; + _input.readFully(result); + return result; + } + catch (IOException e) + { + error(e); + return null; + } + } + + 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); + } + + static final byte[] SINGLE_ZERO_BYTE = new byte[] { (byte)0 }; + + private int _majorver; + private int _minorver; + private int _releaseno; + + + 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); + } + +} diff --git a/xmlbeans/src/xmlconfig/org/apache/xmlbeans/impl/config/BindingConfigImpl.java b/xmlbeans/src/xmlconfig/org/apache/xmlbeans/impl/config/BindingConfigImpl.java new file mode 100755 index 000000000..956cbed80 --- /dev/null +++ b/xmlbeans/src/xmlconfig/org/apache/xmlbeans/impl/config/BindingConfigImpl.java @@ -0,0 +1,480 @@ +/* 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.config; + +import org.apache.xmlbeans.impl.xb.xmlconfig.ConfigDocument.Config; +import org.apache.xmlbeans.impl.xb.xmlconfig.Extensionconfig; +import org.apache.xmlbeans.impl.xb.xmlconfig.Nsconfig; +import org.apache.xmlbeans.impl.xb.xmlconfig.Qnameconfig; +import org.apache.xmlbeans.impl.xb.xmlconfig.Qnametargetenum; +import org.apache.xmlbeans.impl.xb.xmlconfig.Usertypeconfig; +import org.apache.xmlbeans.BindingConfig; +import org.apache.xmlbeans.UserType; +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.XmlError; +import org.apache.xmlbeans.InterfaceExtension; +import org.apache.xmlbeans.PrePostExtension; +import org.apache.xmlbeans.impl.jam.JamClassLoader; +import org.apache.xmlbeans.impl.jam.JamService; +import org.apache.xmlbeans.impl.jam.JamServiceFactory; +import org.apache.xmlbeans.impl.jam.JamServiceParams; +import org.apache.xmlbeans.impl.schema.StscState; + +import javax.xml.namespace.QName; +import java.io.File; +import java.io.IOException; +import java.util.*; + +/** + * An implementation of BindingConfig + */ +public class BindingConfigImpl extends BindingConfig +{ + private Map _packageMap; + private Map _prefixMap; + private Map _suffixMap; + private Map _packageMapByUriPrefix; // uri prefix -> package + private Map _prefixMapByUriPrefix; // uri prefix -> name prefix + private Map _suffixMapByUriPrefix; // uri prefix -> name suffix + private Map _qnameTypeMap; + private Map _qnameDocTypeMap; + private Map _qnameElemMap; + private Map _qnameAttMap; + + private List _interfaceExtensions; + private List _prePostExtensions; + private Map _userTypes; + + private BindingConfigImpl() + { + _packageMap = Collections.EMPTY_MAP; + _prefixMap = Collections.EMPTY_MAP; + _suffixMap = Collections.EMPTY_MAP; + _packageMapByUriPrefix = Collections.EMPTY_MAP; + _prefixMapByUriPrefix = Collections.EMPTY_MAP; + _suffixMapByUriPrefix = Collections.EMPTY_MAP; + _qnameTypeMap = Collections.EMPTY_MAP; + _qnameDocTypeMap = Collections.EMPTY_MAP; + _qnameElemMap = Collections.EMPTY_MAP; + _qnameAttMap = Collections.EMPTY_MAP; + _interfaceExtensions = new ArrayList(); + _prePostExtensions = new ArrayList(); + _userTypes = Collections.EMPTY_MAP; + } + + public static BindingConfig forConfigDocuments(Config[] configs, File[] javaFiles, File[] classpath) + { + return new BindingConfigImpl(configs, javaFiles, classpath); + } + + private BindingConfigImpl(Config[] configs, File[] javaFiles, File[] classpath) + { + _packageMap = new LinkedHashMap(); + _prefixMap = new LinkedHashMap(); + _suffixMap = new LinkedHashMap(); + _packageMapByUriPrefix = new LinkedHashMap(); + _prefixMapByUriPrefix = new LinkedHashMap(); + _suffixMapByUriPrefix = new LinkedHashMap(); + _qnameTypeMap = new LinkedHashMap(); + _qnameDocTypeMap = new LinkedHashMap(); + _qnameElemMap = new LinkedHashMap(); + _qnameAttMap = new LinkedHashMap(); + _interfaceExtensions = new ArrayList(); + _prePostExtensions = new ArrayList(); + _userTypes = new LinkedHashMap(); + + for (int i = 0; i < configs.length; i++) + { + Config config = configs[i]; + Nsconfig[] nsa = config.getNamespaceArray(); + for (int j = 0; j < nsa.length; j++) + { + recordNamespaceSetting(nsa[j].getUri(), nsa[j].getPackage(), _packageMap); + recordNamespaceSetting(nsa[j].getUri(), nsa[j].getPrefix(), _prefixMap); + recordNamespaceSetting(nsa[j].getUri(), nsa[j].getSuffix(), _suffixMap); + recordNamespacePrefixSetting(nsa[j].getUriprefix(), nsa[j].getPackage(), _packageMapByUriPrefix); + recordNamespacePrefixSetting(nsa[j].getUriprefix(), nsa[j].getPrefix(), _prefixMapByUriPrefix); + recordNamespacePrefixSetting(nsa[j].getUriprefix(), nsa[j].getSuffix(), _suffixMapByUriPrefix); + } + + Qnameconfig[] qnc = config.getQnameArray(); + for (int j = 0; j < qnc.length; j++) + { + List applyto = qnc[j].xgetTarget().xgetListValue(); + QName name = qnc[j].getName(); + String javaname = qnc[j].getJavaname(); + for (int k = 0; k < applyto.size(); k++) + { + Qnametargetenum a = (Qnametargetenum) applyto.get(k); + switch (a.enumValue().intValue()) + { + case Qnametargetenum.INT_TYPE: + _qnameTypeMap.put(name, javaname); + break; + case Qnametargetenum.INT_DOCUMENT_TYPE: + _qnameDocTypeMap.put(name, javaname); + break; + case Qnametargetenum.INT_ACCESSOR_ELEMENT: + _qnameElemMap.put(name, javaname); + break; + case Qnametargetenum.INT_ACCESSOR_ATTRIBUTE: + _qnameAttMap.put(name, javaname); + break; + } + } + } + + Extensionconfig[] ext = config.getExtensionArray(); + for (int j = 0; j < ext.length; j++) + { + recordExtensionSetting(javaFiles, classpath, ext[j]); + } + + Usertypeconfig[] utypes = config.getUsertypeArray(); + for (int j = 0; j < utypes.length; j++) + { + recordUserTypeSetting(javaFiles, classpath, utypes[j]); + } + } + + secondPhaseValidation(); + //todo normalize(); + } + + void addInterfaceExtension(InterfaceExtensionImpl ext) + { + if (ext==null) + return; + + _interfaceExtensions.add(ext); + } + + void addPrePostExtension(PrePostExtensionImpl ext) + { + if (ext==null) + return; + + _prePostExtensions.add(ext); + } + + void secondPhaseValidation() + { + // validate interface methods collisions + Map methodSignatures = new HashMap(); + + for (int i = 0; i < _interfaceExtensions.size(); i++) + { + InterfaceExtensionImpl interfaceExtension = (InterfaceExtensionImpl) _interfaceExtensions.get(i); + + InterfaceExtensionImpl.MethodSignatureImpl[] methods = (InterfaceExtensionImpl.MethodSignatureImpl[])interfaceExtension.getMethods(); + for (int j = 0; j < methods.length; j++) + { + InterfaceExtensionImpl.MethodSignatureImpl ms = methods[j]; + + if (methodSignatures.containsKey(methods[j])) + { + + InterfaceExtensionImpl.MethodSignatureImpl ms2 = (InterfaceExtensionImpl.MethodSignatureImpl) methodSignatures.get(methods[j]); + if (!ms.getReturnType().equals(ms2.getReturnType())) + { + BindingConfigImpl.error("Colliding methods '" + ms.getSignature() + "' in interfaces " + + ms.getInterfaceName() + " and " + ms2.getInterfaceName() + ".", null); + } + + return; + } + + // store it into hashmap + methodSignatures.put(methods[j], methods[j]); + } + } + + // validate that PrePostExtension-s do not intersect + for (int i = 0; i < _prePostExtensions.size() - 1; i++) + { + PrePostExtensionImpl a = (PrePostExtensionImpl) _prePostExtensions.get(i); + for (int j = 1; j < _prePostExtensions.size(); j++) + { + PrePostExtensionImpl b = (PrePostExtensionImpl) _prePostExtensions.get(j); + if (a.hasNameSetIntersection(b)) + BindingConfigImpl.error("The applicable domain for handler '" + a.getHandlerNameForJavaSource() + + "' intersects with the one for '" + b.getHandlerNameForJavaSource() + "'.", null); + } + } + } + + private static void recordNamespaceSetting(Object key, String value, Map result) + { + if (value == null) + return; + else if (key == null) + result.put("", value); + else if (key instanceof String && "##any".equals(key)) + result.put(key, value); + else if (key instanceof List) + { + for (Iterator i = ((List)key).iterator(); i.hasNext(); ) + { + String uri = (String)i.next(); + if ("##local".equals(uri)) + uri = ""; + result.put(uri, value); + } + } + } + + private static void recordNamespacePrefixSetting(List list, String value, Map result) + { + if (value == null) + return; + else if (list == null) + return; + for (Iterator i = list.iterator(); i.hasNext(); ) + { + result.put(i.next(), value); + } + } + + private void recordExtensionSetting(File[] javaFiles, File[] classpath, Extensionconfig ext) + { + NameSet xbeanSet = null; + Object key = ext.getFor(); + + + if (key instanceof String && "*".equals(key)) + xbeanSet = NameSet.EVERYTHING; + else if (key instanceof List) + { + NameSetBuilder xbeanSetBuilder = new NameSetBuilder(); + for (Iterator i = ((List) key).iterator(); i.hasNext();) + { + String xbeanName = (String) i.next(); + xbeanSetBuilder.add(xbeanName); + } + xbeanSet = xbeanSetBuilder.toNameSet(); + } + + if (xbeanSet == null) + error("Invalid value of attribute 'for' : '" + key + "'.", ext); + + Extensionconfig.Interface[] intfXO = ext.getInterfaceArray(); + Extensionconfig.PrePostSet ppXO = ext.getPrePostSet(); + + if (intfXO.length > 0 || ppXO != null) + { + JamClassLoader jamLoader = getJamLoader(javaFiles, classpath); + for (int i = 0; i < intfXO.length; i++) + { + addInterfaceExtension(InterfaceExtensionImpl.newInstance(jamLoader, xbeanSet, intfXO[i])); + } + + addPrePostExtension(PrePostExtensionImpl.newInstance(jamLoader, xbeanSet, ppXO)); + } + } + + private void recordUserTypeSetting(File[] javaFiles, File[] classpath, + Usertypeconfig usertypeconfig) + { + JamClassLoader jamLoader = getJamLoader(javaFiles, classpath); + UserTypeImpl userType = UserTypeImpl.newInstance(jamLoader, usertypeconfig); + _userTypes.put(userType.getName(), userType); + } + + + private String lookup(Map map, Map mapByUriPrefix, String uri) + { + if (uri == null) + uri = ""; + String result = (String)map.get(uri); + if (result != null) + return result; + if (mapByUriPrefix != null) + { + result = lookupByUriPrefix(mapByUriPrefix, uri); + if (result != null) + return result; + } + + return (String)map.get("##any"); + } + + private String lookupByUriPrefix(Map mapByUriPrefix, String uri) + { + if (uri == null) + return null; + if (!mapByUriPrefix.isEmpty()) + { + String uriprefix = null; + Iterator i = mapByUriPrefix.keySet().iterator(); + while (i.hasNext()) + { + String nextprefix = (String)i.next(); + if (uriprefix != null && nextprefix.length() < uriprefix.length()) + continue; + if (uri.startsWith(nextprefix)) + uriprefix = nextprefix; + } + + if (uriprefix != null) + return (String)mapByUriPrefix.get(uriprefix); + } + return null; + } + + //package methods + static void warning(String s, XmlObject xo) + { + StscState.get().error(s, XmlError.SEVERITY_WARNING, xo); + } + + static void error(String s, XmlObject xo) + { + StscState.get().error(s, XmlError.SEVERITY_ERROR, xo); + } + + //public methods + + public String lookupPackageForNamespace(String uri) + { + return lookup(_packageMap, _packageMapByUriPrefix, uri); + } + + public String lookupPrefixForNamespace(String uri) + { + return lookup(_prefixMap, _prefixMapByUriPrefix, uri); + } + + public String lookupSuffixForNamespace(String uri) + { + return lookup(_suffixMap, _suffixMapByUriPrefix, uri); + } + + /** @deprecated replaced with {@link #lookupJavanameForQName(QName, int)} */ + public String lookupJavanameForQName(QName qname) + { + String result = (String)_qnameTypeMap.get(qname); + if (result != null) + return result; + return (String)_qnameDocTypeMap.get(qname); + } + + public String lookupJavanameForQName(QName qname, int kind) + { + switch (kind) + { + case QNAME_TYPE: + return (String)_qnameTypeMap.get(qname); + case QNAME_DOCUMENT_TYPE: + return (String)_qnameDocTypeMap.get(qname); + case QNAME_ACCESSOR_ELEMENT: + return (String)_qnameElemMap.get(qname); + case QNAME_ACCESSOR_ATTRIBUTE: + return (String)_qnameAttMap.get(qname); + } + return null; + } + + public UserType lookupUserTypeForQName(QName qname) + { + if (qname == null) + return null; + + return (UserType) _userTypes.get(qname); + } + + public InterfaceExtension[] getInterfaceExtensions() + { + return (InterfaceExtension[])_interfaceExtensions.toArray(new InterfaceExtension[_interfaceExtensions.size()]); + } + + public InterfaceExtension[] getInterfaceExtensions(String fullJavaName) + { + List result = new ArrayList(); + for (int i = 0; i < _interfaceExtensions.size(); i++) + { + InterfaceExtensionImpl intfExt = (InterfaceExtensionImpl) _interfaceExtensions.get(i); + if (intfExt.contains(fullJavaName)) + result.add(intfExt); + } + + return (InterfaceExtension[])result.toArray(new InterfaceExtension[result.size()]); + } + + public PrePostExtension[] getPrePostExtensions() + { + return (PrePostExtension[])_prePostExtensions.toArray(new PrePostExtension[_prePostExtensions.size()]); + } + + public PrePostExtension getPrePostExtension(String fullJavaName) + { + for (int i = 0; i < _prePostExtensions.size(); i++) + { + PrePostExtensionImpl prePostExt = (PrePostExtensionImpl) _prePostExtensions.get(i); + if (prePostExt.contains(fullJavaName)) + return prePostExt; + } + return null; + } + + private JamClassLoader getJamLoader(File[] javaFiles, File[] classpath) + { + JamServiceFactory jf = JamServiceFactory.getInstance(); + JamServiceParams params = jf.createServiceParams(); + params.set14WarningsEnabled(false); + // BUGBUG(radup) This is here because the above doesn't do the trick + params.setShowWarnings(false); + + // process the included sources + if (javaFiles!=null) + for (int i = 0; i < javaFiles.length; i++) + params.includeSourceFile(javaFiles[i]); + + //params.setVerbose(DirectoryScanner.class); + + // add the sourcepath and classpath, if specified + params.addClassLoader(this.getClass().getClassLoader()); + if (classpath != null) + for (int i = 0; i < classpath.length; i++) + params.addClasspath(classpath[i]); + + // create service, get classes, return compiler + JamService service; + try + { + service = jf.createService(params); + } + catch (IOException ioe) + { + error("Error when accessing .java files.", null); + return null; + } + +// JClass[] cls = service.getAllClasses(); +// for (int i = 0; i < cls.length; i++) +// { +// JClass cl = cls[i]; +// System.out.println("CL: " + cl + " " + cl.getQualifiedName()); +// JMethod[] methods = cl.getMethods(); +// for (int j = 0; j < methods.length; j++) +// { +// JMethod method = methods[j]; +// System.out.println(" " + method.getQualifiedName()); +// } +// } + + return service.getClassLoader(); + } +} diff --git a/xmlbeans/src/xmlconfig/org/apache/xmlbeans/impl/config/InterfaceExtensionImpl.java b/xmlbeans/src/xmlconfig/org/apache/xmlbeans/impl/config/InterfaceExtensionImpl.java new file mode 100755 index 000000000..caefa3324 --- /dev/null +++ b/xmlbeans/src/xmlconfig/org/apache/xmlbeans/impl/config/InterfaceExtensionImpl.java @@ -0,0 +1,411 @@ +/* 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.config; + +import org.apache.xmlbeans.impl.xb.xmlconfig.Extensionconfig; +import org.apache.xmlbeans.InterfaceExtension; +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.impl.jam.JMethod; +import org.apache.xmlbeans.impl.jam.JClass; +import org.apache.xmlbeans.impl.jam.JParameter; +import org.apache.xmlbeans.impl.jam.JamClassLoader; + +public class InterfaceExtensionImpl implements InterfaceExtension +{ + private NameSet _xbeanSet; + private String _interfaceClassName; + private String _delegateToClassName; + private MethodSignatureImpl[] _methods; + + static InterfaceExtensionImpl newInstance(JamClassLoader loader, NameSet xbeanSet, Extensionconfig.Interface intfXO) + { + InterfaceExtensionImpl result = new InterfaceExtensionImpl(); + + result._xbeanSet = xbeanSet; + JClass interfaceJClass = validateInterface(loader, intfXO.getName(), intfXO); + + + if (interfaceJClass == null) + { + BindingConfigImpl.error("Interface '" + intfXO.getStaticHandler() + "' not found.", intfXO); + return null; + } + + result._interfaceClassName = interfaceJClass.getQualifiedName(); + + result._delegateToClassName = intfXO.getStaticHandler(); + JClass delegateJClass = validateClass(loader, result._delegateToClassName, intfXO); + + if (delegateJClass == null) // no HandlerClass + { + BindingConfigImpl.warning("Handler class '" + intfXO.getStaticHandler() + "' not found on classpath, skip validation.", intfXO); + return result; + } + + if (!result.validateMethods(interfaceJClass, delegateJClass, intfXO)) + return null; + + return result; + } + + private static JClass validateInterface(JamClassLoader loader, String intfStr, XmlObject loc) + { + return validateJava(loader, intfStr, true, loc); + } + + static JClass validateClass(JamClassLoader loader, String clsStr, XmlObject loc) + { + return validateJava(loader, clsStr, false, loc); + } + + static JClass validateJava(JamClassLoader loader, String clsStr, boolean isInterface, XmlObject loc) + { + if (loader==null) + return null; + + final String ent = isInterface ? "Interface" : "Class"; + JClass cls = loader.loadClass(clsStr); + + if (cls==null || cls.isUnresolvedType()) + { + BindingConfigImpl.error(ent + " '" + clsStr + "' not found.", loc); + return null; + } + + if ( (isInterface && !cls.isInterface()) || + (!isInterface && cls.isInterface())) + { + BindingConfigImpl.error("'" + clsStr + "' must be " + + (isInterface ? "an interface" : "a class") + ".", loc); + } + + if (!cls.isPublic()) + { + BindingConfigImpl.error(ent + " '" + clsStr + "' is not public.", loc); + } + + return cls; + } + + private boolean validateMethods(JClass interfaceJClass, JClass delegateJClass, XmlObject loc) + { + //assert _delegateToClass != null : "Delegate to class handler expected."; + boolean valid = true; + + JMethod[] interfaceMethods = interfaceJClass.getMethods(); + _methods = new MethodSignatureImpl[interfaceMethods.length]; + + for (int i = 0; i < interfaceMethods.length; i++) + { + JMethod method = validateMethod(interfaceJClass, delegateJClass, interfaceMethods[i], loc); + if (method != null) + _methods[i] = new MethodSignatureImpl(getStaticHandler(), method); + else + valid = false; + } + + + return valid; + } + + private JMethod validateMethod(JClass interfaceJClass, JClass delegateJClass, JMethod method, XmlObject loc) + { + String methodName = method.getSimpleName(); + JParameter[] params = method.getParameters(); + JClass returnType = method.getReturnType(); + + JClass[] delegateParams = new JClass[params.length+1]; + delegateParams[0] = returnType.forName("org.apache.xmlbeans.XmlObject"); + for (int i = 1; i < delegateParams.length; i++) + { + delegateParams[i] = params[i-1].getType(); + } + + JMethod handlerMethod = null; + handlerMethod = getMethod(delegateJClass, methodName, delegateParams); + if (handlerMethod==null) + { + BindingConfigImpl.error("Handler class '" + delegateJClass.getQualifiedName() + "' does not contain method " + methodName + "(" + listTypes(delegateParams) + ")", loc); + return null; + } + + // check for throws exceptions + JClass[] intfExceptions = method.getExceptionTypes(); + JClass[] delegateExceptions = handlerMethod.getExceptionTypes(); + if ( delegateExceptions.length!=intfExceptions.length ) + { + BindingConfigImpl.error("Handler method '" + delegateJClass.getQualifiedName() + "." + methodName + "(" + listTypes(delegateParams) + + ")' must declare the same exceptions as the interface method '" + interfaceJClass.getQualifiedName() + "." + methodName + "(" + listTypes(params), loc); + return null; + } + + for (int i = 0; i < delegateExceptions.length; i++) + { + if ( delegateExceptions[i]!=intfExceptions[i] ) + { + BindingConfigImpl.error("Handler method '" + delegateJClass.getQualifiedName() + "." + methodName + "(" + listTypes(delegateParams) + + ")' must declare the same exceptions as the interface method '" + interfaceJClass.getQualifiedName() + "." + methodName + "(" + listTypes(params), loc); + return null; + } + } + + if (!handlerMethod.isPublic() || !handlerMethod.isStatic()) + { + BindingConfigImpl.error("Method '" + delegateJClass.getQualifiedName() + "." + methodName + "(" + listTypes(delegateParams) + ")' must be declared public and static.", loc); + return null; + } + + if (!returnType.equals(handlerMethod.getReturnType())) + { + BindingConfigImpl.error("Return type for method '" + handlerMethod.getReturnType() + " " + delegateJClass.getQualifiedName() + + "." + methodName + "(" + listTypes(delegateParams) + ")' does not match the return type of the interface method :'" + returnType + "'.", loc); + return null; + } + + return method; + } + + static JMethod getMethod(JClass cls, String name, JClass[] paramTypes) + { + JMethod[] methods = cls.getMethods(); + for (int i = 0; i < methods.length; i++) + { + JMethod method = methods[i]; + if (!name.equals(method.getSimpleName())) + continue; + + JParameter[] mParams = method.getParameters(); + + // can have methods with same name but different # of params + if (mParams.length != paramTypes.length) + continue; + + for (int j = 0; j < mParams.length; j++) + { + JParameter mParam = mParams[j]; + if (!mParam.getType().equals(paramTypes[j])) + continue; + } + + return method; + } + return null; + } + + private static String listTypes(JClass[] types) + { + StringBuffer result = new StringBuffer(); + for (int i = 0; i < types.length; i++) + { + JClass type = types[i]; + if (i>0) + result.append(", "); + result.append(emitType(type)); + } + return result.toString(); + } + + private static String listTypes(JParameter[] params) + { + StringBuffer result = new StringBuffer(); + for (int i = 0; i < params.length; i++) + { + JClass type = params[i].getType(); + if (i>0) + result.append(", "); + result.append(emitType(type)); + } + return result.toString(); + } + + public static String emitType(JClass cls) + { + if (cls.isArrayType()) + return emitType(cls.getArrayComponentType()) + "[]"; + else + return cls.getQualifiedName().replace('$', '.'); + } + + /* public getters */ + public boolean contains(String fullJavaName) + { + return _xbeanSet.contains(fullJavaName); + } + + public String getStaticHandler() + { + return _delegateToClassName; + } + + public String getInterface() + { + return _interfaceClassName; + } + + public InterfaceExtension.MethodSignature[] getMethods() + { + return _methods; + } + + public String toString() + { + StringBuffer buf = new StringBuffer(); + buf.append(" static handler: ").append(_delegateToClassName).append("\n"); + buf.append(" interface: ").append(_interfaceClassName).append("\n"); + buf.append(" name set: ").append(_xbeanSet).append("\n"); + + for (int i = 0; i < _methods.length; i++) + buf.append(" method[").append(i).append("]=").append(_methods[i]).append("\n"); + + return buf.toString(); + } + + // this is used only for detecting method colisions of extending interfaces + static class MethodSignatureImpl implements InterfaceExtension.MethodSignature + { + private String _intfName; + private final int NOTINITIALIZED = -1; + private int _hashCode = NOTINITIALIZED; + private String _signature; + + private String _name; + private String _return; + private String[] _params; + private String[] _exceptions; + + MethodSignatureImpl(String intfName, JMethod method) + { + if (intfName==null || method==null) + throw new IllegalArgumentException("Interface: " + intfName + " method: " + method); + + _intfName = intfName; + _hashCode = NOTINITIALIZED; + _signature = null; + + _name = method.getSimpleName(); + _return = method.getReturnType().getQualifiedName().replace('$', '.'); + + JParameter[] paramTypes = method.getParameters(); + _params = new String[paramTypes.length]; + for (int i = 0; i < paramTypes.length; i++) + _params[i] = paramTypes[i].getType().getQualifiedName().replace('$', '.');; + + JClass[] exceptionTypes = method.getExceptionTypes(); + _exceptions = new String[exceptionTypes.length]; + for (int i = 0; i < exceptionTypes.length; i++) + _exceptions[i] = exceptionTypes[i].getQualifiedName().replace('$', '.'); + } + + String getInterfaceName() + { + return _intfName; + } + + public String getName() + { + return _name; + } + + public String getReturnType() + { + return _return; + } + + public String[] getParameterTypes() + { + return _params; + } + + public String[] getExceptionTypes() + { + return _exceptions; + } + + public boolean equals(Object o) + { + if ( !(o instanceof MethodSignatureImpl)) + return false; + + MethodSignatureImpl ms = (MethodSignatureImpl)o; + + if (!ms.getName().equals(getName()) ) + return false; + + String[] params = getParameterTypes(); + String[] msParams = ms.getParameterTypes(); + + if (msParams.length != params.length ) + return false; + + for (int i = 0; i < params.length; i++) + { + if (!msParams[i].equals(params[i])) + return false; + } + + if (!_intfName.equals(ms._intfName)) + return false; + + return true; + } + + public int hashCode() + { + if (_hashCode!=NOTINITIALIZED) + return _hashCode; + + int hash = getName().hashCode(); + + String[] params = getParameterTypes(); + + for (int i = 0; i < params.length; i++) + { + hash *= 19; + hash += params[i].hashCode(); + } + + hash += 21 * _intfName.hashCode(); + + _hashCode = hash; + return _hashCode; + } + + String getSignature() + { + if (_signature!=null) + return _signature; + + StringBuffer sb = new StringBuffer(60); + sb.append(_name).append("("); + for (int i = 0; i < _params.length; i++) + sb.append((i == 0 ? "" : " ,")).append(_params[i]); + sb.append(")"); + + _signature = sb.toString(); + + return _signature; + } + + public String toString() + { + StringBuffer buf = new StringBuffer(); + + buf.append(getReturnType()).append(" ").append(getSignature()); + + return buf.toString(); + } + } +} diff --git a/xmlbeans/src/xmlconfig/org/apache/xmlbeans/impl/config/NameSet.java b/xmlbeans/src/xmlconfig/org/apache/xmlbeans/impl/config/NameSet.java new file mode 100644 index 000000000..2b0b8d089 --- /dev/null +++ b/xmlbeans/src/xmlconfig/org/apache/xmlbeans/impl/config/NameSet.java @@ -0,0 +1,224 @@ +/* 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. + */ +/** + * Author: Cezar Andrei ( cezar.andrei at bea.com ) + * Date: Apr 25, 2004 + */ +package org.apache.xmlbeans.impl.config; + +import java.util.Set; +import java.util.Collections; +import java.util.HashSet; + +/** + * Reprezents a non finite set of names. + * @see NameSetBuilder + */ +public class NameSet +{ + /** + * An empty NameSet, it doesn't contain any name + */ + public static NameSet EMPTY = new NameSet(true, Collections.EMPTY_SET); + /** + * The NameSet that contains any name + */ + public static NameSet EVERYTHING = new NameSet(false, Collections.EMPTY_SET); + + /* + There are two big cases: + 1) - it reprezents "*", ie all except a finite set of names: _isFinite==false + 2) - if reprezents only a finite set of names: _isFinite==true + */ + private boolean _isFinite; + private Set _finiteSet; + + private NameSet(boolean isFinite, Set finiteSet) + { + _isFinite = isFinite; + _finiteSet = finiteSet; + } + + static NameSet newInstance(boolean isFinite, Set finiteSet) + { + if ( finiteSet.size()==0 ) + if ( isFinite ) + return NameSet.EMPTY; + else + return NameSet.EVERYTHING; + else + { + Set fs = new HashSet(); + fs.addAll(finiteSet); + return new NameSet(isFinite, fs); + } + } + + private static Set intersectFiniteSets(Set a, Set b) + { + Set intersection = new HashSet(); + //compute the intersection of _finiteSet with withSet + while (a.iterator().hasNext()) + { + String name = (String) a.iterator().next(); + if (b.contains(name)) + intersection.add(name); + } + return intersection; + } + + /** + * Returns the union of this NameSet with the 'with' NameSet. + */ + public NameSet union(NameSet with) + { + if (_isFinite) + { + if (with._isFinite) + { + Set union = new HashSet(); + union.addAll(_finiteSet); + union.addAll(with._finiteSet); + return newInstance(true, union); + } + else + { + Set subst = new HashSet(); + subst.addAll(with._finiteSet); + subst.removeAll(_finiteSet); + return newInstance(false, subst); + } + } + else + { + if (with._isFinite) + { + Set subst = new HashSet(); + subst.addAll(_finiteSet); + subst.removeAll(with._finiteSet); + return newInstance(false, subst); + } + else + { + return newInstance(false, intersectFiniteSets(_finiteSet, with._finiteSet)); + } + } + } + + /** + * Returns the intersection of this NameSet with the 'with' NameSet + */ + public NameSet intersect(NameSet with) + { + if (_isFinite) + { + if (with._isFinite) + { + return newInstance(true, intersectFiniteSets(_finiteSet, with._finiteSet)); + } + else + { + Set subst = new HashSet(); + subst.addAll(_finiteSet); + subst.removeAll(with._finiteSet); + return newInstance(false, subst); + } + } + else + { + if (with._isFinite) + { + Set subst = new HashSet(); + subst.addAll(with._finiteSet); + subst.removeAll(_finiteSet); + return newInstance(true, subst); + } + else + { + Set union = new HashSet(); + union.addAll(_finiteSet); + union.addAll(with._finiteSet); + return newInstance(false, union); + } + } + } + + /** + * Returns the result of substracting this NameSet from 'from' NameSet + * @see NameSet#substract + */ + public NameSet substractFrom(NameSet from) + { + return from.substract(this); + } + + /** + * Returns the result of substracting 'what' NameSet from this NameSet + * @see NameSet#substractFrom + */ + public NameSet substract(NameSet what) + { + if (_isFinite) + { + if ( what._isFinite ) + { + // it's the subst of _finiteSet with what._finiteSet + Set subst = new HashSet(); + subst.addAll(_finiteSet); + subst.removeAll(what._finiteSet); + return newInstance(true, subst); + } + else + { + return newInstance(true, intersectFiniteSets(_finiteSet, what._finiteSet)); + } + } + else + { + if ( what._isFinite ) + { + // it's the union of _finiteSet with what._finiteSet + Set union = new HashSet(); + union.addAll(_finiteSet); + union.addAll(what._finiteSet); + return newInstance(false, union); + } + else + { + // what's in thisSet and it's not in whatSet + Set subst = new HashSet(); + subst.addAll(what._finiteSet); + subst.removeAll(_finiteSet); + return newInstance(true, subst); + } + } + } + + /** + * Returns an inversion of this NameSet + */ + public NameSet invert() + { + return newInstance(!_isFinite, _finiteSet); + } + + public boolean contains(String name) + { + if (_isFinite) + return _finiteSet.contains(name); + else + return !_finiteSet.contains(name); + } +} diff --git a/xmlbeans/src/xmlconfig/org/apache/xmlbeans/impl/config/NameSetBuilder.java b/xmlbeans/src/xmlconfig/org/apache/xmlbeans/impl/config/NameSetBuilder.java new file mode 100644 index 000000000..da61a08a7 --- /dev/null +++ b/xmlbeans/src/xmlconfig/org/apache/xmlbeans/impl/config/NameSetBuilder.java @@ -0,0 +1,75 @@ +/* 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. + */ +/** + * Author: Cezar Andrei ( cezar.andrei at bea.com ) + * Date: Apr 25, 2004 + */ +package org.apache.xmlbeans.impl.config; + +import java.util.Set; +import java.util.HashSet; + +/** + * Used to build {@link NameSet NameSets}. + */ +public class NameSetBuilder +{ + private boolean _isFinite; + private Set _finiteSet; + + /** + * Creates an empty builder for a NameSet. + */ + public NameSetBuilder() + { + _isFinite = true; + _finiteSet = new HashSet(); + } + + /** + * Inverts the representing NameSet + */ + public void invert() + { + _isFinite = !_isFinite; + } + + /** + * Adds a name to the representing NameSet + * @param name + */ + public void add(String name) + { + if (_isFinite ) + _finiteSet.add(name); + else + _finiteSet.remove(name); + } + + /** + * Creates a new NameSet with the current state. + * @return created NameSet + */ + public NameSet toNameSet() + { + if ( _finiteSet.size()==0 ) + if ( _isFinite ) + return NameSet.EMPTY; + else + return NameSet.EVERYTHING; + else + return NameSet.newInstance(_isFinite, _finiteSet); + } +} \ No newline at end of file diff --git a/xmlbeans/src/xmlconfig/org/apache/xmlbeans/impl/config/PrePostExtensionImpl.java b/xmlbeans/src/xmlconfig/org/apache/xmlbeans/impl/config/PrePostExtensionImpl.java new file mode 100755 index 000000000..bbf7415ef --- /dev/null +++ b/xmlbeans/src/xmlconfig/org/apache/xmlbeans/impl/config/PrePostExtensionImpl.java @@ -0,0 +1,169 @@ +/* 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.config; + +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.PrePostExtension; +import org.apache.xmlbeans.impl.jam.JamClassLoader; +import org.apache.xmlbeans.impl.jam.JClass; +import org.apache.xmlbeans.impl.jam.JMethod; +import org.apache.xmlbeans.impl.xb.xmlconfig.Extensionconfig; + + +public class PrePostExtensionImpl implements PrePostExtension +{ + + private static JClass[] PARAMTYPES_PREPOST = null; //new JClass[]{int.class, XmlObject.class, QName.class, boolean.class, int.class}; + private static final String[] PARAMTYPES_STRING = new String[] {"int", "org.apache.xmlbeans.XmlObject", + "javax.xml.namespace.QName", "boolean", "int"}; + private static final String SIGNATURE; + static + { + String sig = "("; + for (int i = 0; i < PARAMTYPES_STRING.length; i++) + { + String t = PARAMTYPES_STRING[i]; + if (i!=0) + sig += ", "; + sig += t; + } + SIGNATURE = sig + ")"; + } + + private NameSet _xbeanSet; + private JClass _delegateToClass; + private String _delegateToClassName; + private JMethod _preSet; + private JMethod _postSet; + + static PrePostExtensionImpl newInstance(JamClassLoader jamLoader, NameSet xbeanSet, Extensionconfig.PrePostSet prePostXO) + { + if (prePostXO==null) + return null; + + PrePostExtensionImpl result = new PrePostExtensionImpl(); + + result._xbeanSet = xbeanSet; + result._delegateToClassName = prePostXO.getStaticHandler(); + result._delegateToClass = InterfaceExtensionImpl.validateClass(jamLoader, result._delegateToClassName, prePostXO); + + if ( result._delegateToClass==null ) // no HandlerClass + { + BindingConfigImpl.warning("Handler class '" + prePostXO.getStaticHandler() + "' not found on classpath, skip validation.", prePostXO); + return result; + } + + if (!result.lookAfterPreAndPost(jamLoader, prePostXO)) + return null; + + return result; + } + + private boolean lookAfterPreAndPost(JamClassLoader jamLoader, XmlObject loc) + { + assert _delegateToClass!=null : "Delegate to class handler expected."; + boolean valid = true; + + initParamPrePost(jamLoader); + + _preSet = InterfaceExtensionImpl.getMethod(_delegateToClass, "preSet", PARAMTYPES_PREPOST); + if (_preSet==null) + {} // not available is ok, _preSet will be null + + if (_preSet!=null && !_preSet.getReturnType().equals(jamLoader.loadClass("boolean"))) + { + // just emit an warning and don't remember as a preSet + BindingConfigImpl.warning("Method '" + _delegateToClass.getSimpleName() + + ".preSet" + SIGNATURE + "' " + + "should return boolean to be considered for a preSet handler.", loc); + _preSet = null; + } + + _postSet = InterfaceExtensionImpl.getMethod(_delegateToClass, "postSet", PARAMTYPES_PREPOST); + if (_postSet==null) + {} // not available is ok, _postSet will be null + + if (_preSet==null && _postSet==null) + { + BindingConfigImpl.error("prePostSet handler specified '" + _delegateToClass.getSimpleName() + + "' but no preSet" + SIGNATURE + " or " + + "postSet" + SIGNATURE + " methods found.", loc); + valid = false; + } + + return valid; + } + + private void initParamPrePost(JamClassLoader jamLoader) + { + if (PARAMTYPES_PREPOST==null) + { + PARAMTYPES_PREPOST = new JClass[PARAMTYPES_STRING.length]; + for (int i = 0; i < PARAMTYPES_PREPOST.length; i++) + { + PARAMTYPES_PREPOST[i] = jamLoader.loadClass(PARAMTYPES_STRING[i]); + if (PARAMTYPES_PREPOST[i]==null) + { + throw new IllegalStateException("JAM should have access to the following types " + SIGNATURE); + } + } + } + } + + // public methods + public NameSet getNameSet() + { + return _xbeanSet; + } + + public boolean contains(String fullJavaName) + { + return _xbeanSet.contains(fullJavaName); + } + + public boolean hasPreCall() + { + return _preSet!=null; + } + + public boolean hasPostCall() + { + return _postSet!=null; + } + + public String getStaticHandler() + { + return _delegateToClassName; + } + + /** + * Returns the name of the handler in a form that can be put in a java source. + */ + public String getHandlerNameForJavaSource() + { + // used only in validation + if (_delegateToClass==null) + return null; + + return InterfaceExtensionImpl.emitType(_delegateToClass); + } + + boolean hasNameSetIntersection(PrePostExtensionImpl ext) + { + return !NameSet.EMPTY.equals(_xbeanSet.intersect(ext._xbeanSet)); + } + +} diff --git a/xmlbeans/src/xmlconfig/org/apache/xmlbeans/impl/config/UserTypeImpl.java b/xmlbeans/src/xmlconfig/org/apache/xmlbeans/impl/config/UserTypeImpl.java new file mode 100644 index 000000000..6ef6d39e9 --- /dev/null +++ b/xmlbeans/src/xmlconfig/org/apache/xmlbeans/impl/config/UserTypeImpl.java @@ -0,0 +1,46 @@ +package org.apache.xmlbeans.impl.config; + +import javax.xml.namespace.QName; + +import org.apache.xmlbeans.UserType; +import org.apache.xmlbeans.impl.jam.JamClassLoader; +import org.apache.xmlbeans.impl.xb.xmlconfig.Usertypeconfig; + +public class UserTypeImpl implements UserType +{ + private QName _name; + private String _javaName; + private String _staticHandler; + + + static UserTypeImpl newInstance(JamClassLoader loader, Usertypeconfig cfgXO) + { + UserTypeImpl result = new UserTypeImpl(); + + result._name = cfgXO.getName(); + result._javaName = cfgXO.getJavaname(); + result._staticHandler = cfgXO.getStaticHandler(); + + // We don't validate here because we're just using reflection in + // the implementation. However, in the future we might want to add + // the option of directly using the static handler in generated code + + return result; + } + + + public String getJavaName() + { + return _javaName; + } + + public QName getName() + { + return _name; + } + + public String getStaticHandler() + { + return _staticHandler; + } +} diff --git a/xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/Attribute.java b/xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/Attribute.java new file mode 100755 index 000000000..16da4b643 --- /dev/null +++ b/xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/Attribute.java @@ -0,0 +1,47 @@ +/* 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.xml.stream; + +/** + * An interface that contains information about an attribute + * + * @since Weblogic XML Input Stream 1.0 + * @version 1.0 + * @see org.apache.xmlbeans.xml.stream.XMLName + * @see org.apache.xmlbeans.xml.stream.Attribute + */ +public interface Attribute { + /** + * Get the XMLName of the current attribute. + * @see org.apache.xmlbeans.xml.stream.XMLName + */ + public XMLName getName(); + + /** + * Get the attribute value of the current attribute. + */ + public String getValue(); + + /** + * Get the attribute type of the current attribute + */ + public String getType(); + + /** + * Get the attribute type of the current attribute + */ + public XMLName getSchemaType(); +} diff --git a/xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/AttributeIterator.java b/xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/AttributeIterator.java new file mode 100755 index 000000000..7c9b8f75a --- /dev/null +++ b/xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/AttributeIterator.java @@ -0,0 +1,48 @@ +/* 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.xml.stream; + +/** + * This interface specifies methods for iterating over attributes. + * @since Weblogic XML Input Stream 1.0 + * @version 1.0 + * @see org.apache.xmlbeans.xml.stream.Attribute +*/ + +public interface AttributeIterator { + /** + * Get the next Attribute on the stream + * @see org.apache.xmlbeans.xml.stream.Attribute + */ + public Attribute next(); + + /** + * Check if there are any attributes on the stream + */ + public boolean hasNext(); + + /** + * Return the next element on the stream without shifting it + */ + public Attribute peek(); + + + /** + * Skip the next element on the stream + */ + public void skip(); +} + diff --git a/xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/BufferedXMLInputStream.java b/xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/BufferedXMLInputStream.java new file mode 100755 index 000000000..3b5cc82a5 --- /dev/null +++ b/xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/BufferedXMLInputStream.java @@ -0,0 +1,49 @@ +/* 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.xml.stream; + +import java.io.IOException; +/** + * Extends the XMLInputStream to allow marking and reseting of the stream. + * + * @since XMLInputStream 1.0 + * @version 1.0 + * @see org.apache.xmlbeans.xml.stream.CharacterData + * @see org.apache.xmlbeans.xml.stream.ProcessingInstruction + * @see org.apache.xmlbeans.xml.stream.StartElement + * @see org.apache.xmlbeans.xml.stream.EndElement + * @see org.apache.xmlbeans.xml.stream.CharacterData + * @see org.apache.xmlbeans.xml.stream.XMLName + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ +public interface BufferedXMLInputStream extends XMLInputStream { + /** + * Sets the marks a point to return to in the stream, + * throws an exception if the stream does not support mark. + * This is only supported in BufferedStreams + */ + public void mark() throws XMLStreamException; + /** + * Resets the stream to the previous mark. + * throws an exception if the stream does not support mark; + */ + public void reset() throws XMLStreamException; +} + + + + + diff --git a/xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/ChangePrefixMapping.java b/xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/ChangePrefixMapping.java new file mode 100755 index 000000000..c45687677 --- /dev/null +++ b/xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/ChangePrefixMapping.java @@ -0,0 +1,43 @@ +/* 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.xml.stream; + +/** + * This event signals that a prefix mapping has changed from + * OldNamespaceName to the NewNamespaceName + * + * @since Weblogic XML Input Stream 1.0 + * @version 1.0 + * @see org.apache.xmlbeans.xml.stream.StartPrefixMapping + * @see org.apache.xmlbeans.xml.stream.EndPrefixMapping + */ +public interface ChangePrefixMapping extends XMLEvent { + /* + * returns the uri that the prefix was bound to + * @return String value of the uri + */ + public String getOldNamespaceUri(); + /* + * returns the new uri that the prefix is bound to + * @return String value of the uri + */ + public String getNewNamespaceUri(); + /* + * returns the prefix that is bound + * @return String value of the prefix + */ + public String getPrefix(); +} diff --git a/xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/CharacterData.java b/xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/CharacterData.java new file mode 100755 index 000000000..fcb98ddc8 --- /dev/null +++ b/xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/CharacterData.java @@ -0,0 +1,37 @@ +/* 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.xml.stream; + +/** + * A marker interface for character data + * + * @since Weblogic XML Input Stream 1.0 + * @version 1.0 + * @see org.apache.xmlbeans.xml.stream.XMLEvent +*/ +public interface CharacterData extends XMLEvent { + /** + * Get the content of this element, + * returns null if the element has no content + */ + public String getContent(); + + /** + * Returns true if this element has content and false otherwise + */ + public boolean hasContent(); + +} diff --git a/xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/Comment.java b/xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/Comment.java new file mode 100755 index 000000000..c4541cd2c --- /dev/null +++ b/xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/Comment.java @@ -0,0 +1,30 @@ +/* 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.xml.stream; + +/** + * A marker interface for comment data + * + * @since Weblogic XML Input Stream 1.0 + * @version 1.0 + * @see org.apache.xmlbeans.xml.stream.XMLEvent +*/ + +public interface Comment extends CharacterData { + /** + * No methods are defined in this interface. + */ +} diff --git a/xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/ElementFilter.java b/xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/ElementFilter.java new file mode 100755 index 000000000..d179a5c50 --- /dev/null +++ b/xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/ElementFilter.java @@ -0,0 +1,28 @@ +/* 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.xml.stream; + +/** + * + * This interface defines a filter on elements + */ + +public interface ElementFilter { + /** + * tests whether this event is part of this stream + */ + boolean accept(XMLEvent element); +} diff --git a/xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/EndDocument.java b/xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/EndDocument.java new file mode 100755 index 000000000..ca98a507c --- /dev/null +++ b/xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/EndDocument.java @@ -0,0 +1,29 @@ +/* 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.xml.stream; + +/** + * A marker interface for the end of a document + * + * @since Weblogic XML Input Stream 1.0 + * @version 1.0 + * @see org.apache.xmlbeans.xml.stream.XMLEvent +*/ +public interface EndDocument extends XMLEvent { + /** + * No methods are defined in this interface. + */ +} diff --git a/xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/EndElement.java b/xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/EndElement.java new file mode 100755 index 000000000..e8a69ac40 --- /dev/null +++ b/xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/EndElement.java @@ -0,0 +1,31 @@ +/* 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.xml.stream; + +/** + * A marker interface for the end element event. + * The name is available in the getName method of + * org.apache.xmlbeans.xml.stream.XMLEvent interface. + * + * @since Weblogic XML Input Stream 1.0 + * @version 1.0 + * @see org.apache.xmlbeans.xml.stream.XMLEvent +*/ +public interface EndElement extends XMLEvent { + /** + * No methods are defined in this interface. + */ +} diff --git a/xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/EndPrefixMapping.java b/xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/EndPrefixMapping.java new file mode 100755 index 000000000..fb12fed45 --- /dev/null +++ b/xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/EndPrefixMapping.java @@ -0,0 +1,33 @@ +/* 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.xml.stream; + +/** + * This event signals that a prefix mapping has gone out of scope + * + * @since Weblogic XML Input Stream 1.0 + * @version 1.0 + * @see org.apache.xmlbeans.xml.stream.StartPrefixMapping + * @see org.apache.xmlbeans.xml.stream.ChangePrefixMapping + */ + +public interface EndPrefixMapping extends XMLEvent { + /* + * Returns the prefix that has gone out of scope + * @return String value of the prefix + */ + public String getPrefix(); +} diff --git a/xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/EntityReference.java b/xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/EntityReference.java new file mode 100755 index 000000000..40e4ec213 --- /dev/null +++ b/xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/EntityReference.java @@ -0,0 +1,30 @@ +/* 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.xml.stream; + +/** + * An interface for handling Entity Declarations + * + * @since Weblogic XML Input Stream 1.0 + * @version 1.0 + */ + +public interface EntityReference extends XMLEvent { + /** + * Returns true if this entity was skipped + */ + public boolean skipped(); +} diff --git a/xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/Location.java b/xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/Location.java new file mode 100755 index 000000000..dfd18d0a5 --- /dev/null +++ b/xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/Location.java @@ -0,0 +1,54 @@ +/* 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.xml.stream; + +/** + * Returns the document location of the event. This is not + * required to be exact and is informational only. + * + * @since Weblogic XML Input Stream 1.0 + * @version 1.0 + * + */ +public interface Location { + /* + * returns the current column number + * + * @return integer value of the current column number + */ + public int getColumnNumber(); + /* + * returns the current line + * + * @return integer value of the current line number + */ + public int getLineNumber(); + /* + * returns the String value of the public ID + * + * @return public ID or null if not set + */ + public String getPublicId(); + /* + * returns the String value of the system ID + * + * @return system ID or null if not set + */ + public String getSystemId(); +} + + + diff --git a/xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/ProcessingInstruction.java b/xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/ProcessingInstruction.java new file mode 100755 index 000000000..4bd62563f --- /dev/null +++ b/xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/ProcessingInstruction.java @@ -0,0 +1,38 @@ +/* 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.xml.stream; + +/** + * A marker interface for processing instructions + * + * @since Weblogic XML Input Stream 1.0 + * @version 1.0 + * @see org.apache.xmlbeans.xml.stream.XMLEvent +*/ +public interface ProcessingInstruction extends XMLEvent { + /* + * the target section of the processing instruction + * + * @return the String value of the PI or null + */ + public String getTarget(); + /* + * the data section of the processing instruction + * + * @return the String value of the PI's data or null + */ + public String getData(); +} diff --git a/xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/ReferenceResolver.java b/xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/ReferenceResolver.java new file mode 100755 index 000000000..ac5c88645 --- /dev/null +++ b/xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/ReferenceResolver.java @@ -0,0 +1,39 @@ +/* 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.xml.stream; + +import org.apache.xmlbeans.xml.stream.XMLInputStream; + +/** + * This interface can be implemented to allow resolution of references + * on a stream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ +public interface ReferenceResolver { + /** + * Returns the xml pointed to by this idref as an XMLInputStream + * @param idref + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + XMLInputStream resolve(String idref) + throws XMLStreamException; + + /** + * Returns the id that corresponds to this idref + * @param idref + */ + String getId(String idref); +} diff --git a/xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/Space.java b/xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/Space.java new file mode 100755 index 000000000..df453ce69 --- /dev/null +++ b/xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/Space.java @@ -0,0 +1,30 @@ +/* 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.xml.stream; + +/** + * This element returns whitespace characters to allow separate + * handling by the application + * + * @since Weblogic XML Input Stream 1.0 + * @version 1.0 + */ +public interface Space extends CharacterData { + /** + * Returns true if this is ignorable whitespace + */ + public boolean ignorable(); +} diff --git a/xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/StartDocument.java b/xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/StartDocument.java new file mode 100755 index 000000000..e980bfc45 --- /dev/null +++ b/xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/StartDocument.java @@ -0,0 +1,46 @@ +/* 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.xml.stream; + +/** + * An interface for the start document event + * + * @since Weblogic XML Input Stream 1.0 + * @version 1.0 + * @see org.apache.xmlbeans.xml.stream.XMLEvent +*/ +public interface StartDocument extends XMLEvent { + /* + * Returns the system id of the stream + * @return the system id, defaults to "" + */ + public String getSystemId(); + /* + * Returns the encoding style of this XML stream + * @return the character encoding, defaults to "UTF-8" + */ + public String getCharacterEncodingScheme(); + /* + * Returns if this XML is standalone + * @return the version of XML, defaults to "yes" + */ + public boolean isStandalone(); + /* + * Returns the version of XML of this XML stream + * @return the version of XML, defaults to "1.0" + */ + public String getVersion(); +} diff --git a/xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/StartElement.java b/xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/StartElement.java new file mode 100755 index 000000000..14d904df0 --- /dev/null +++ b/xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/StartElement.java @@ -0,0 +1,56 @@ +/* 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.xml.stream; + +import java.util.Map; +/** + * The StartElement interface provides access to information about + * start elements + * + * @since Weblogic XML Input Stream 1.0 + * @version 1.0 + * @see org.apache.xmlbeans.xml.stream.AttributeIterator + */ + +public interface StartElement extends XMLEvent { + /** + * Returns an AttributeIterator of non-namespace declared attributes + */ + public AttributeIterator getAttributes(); + /** + * Returns an AttributeIterator of namespaces declared in this element + */ + public AttributeIterator getNamespaces(); + /** + * Returns the union of declared attributes and namespaces + */ + public AttributeIterator getAttributesAndNamespaces(); + /** + * Returns the attribute referred to by this name + */ + public Attribute getAttributeByName(XMLName name); + /** + * Gets the value that the prefix is bound to in the + * context of this element. Returns null if + * the prefix is not bound in this context + */ + public String getNamespaceUri(String prefix); + /** + * Gets a java.util.Map from prefixes to URIs in scope for this + * element. + */ + public Map getNamespaceMap(); +} diff --git a/xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/StartPrefixMapping.java b/xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/StartPrefixMapping.java new file mode 100755 index 000000000..c10661a7f --- /dev/null +++ b/xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/StartPrefixMapping.java @@ -0,0 +1,39 @@ +/* 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.xml.stream; + +/** + * This event signals that a prefix mapping has begun scope + * + * @since Weblogic XML Input Stream 1.0 + * @version 1.0 + * @see org.apache.xmlbeans.xml.stream.EndPrefixMapping + * @see org.apache.xmlbeans.xml.stream.ChangePrefixMapping + */ + +public interface StartPrefixMapping extends XMLEvent { + /* + * Returns the uri of the prefix that is in scope for the following + * element + * @return String value of the uri + */ + public String getNamespaceUri(); + /* + * Returns the prefix that is now in scope + * @return String value of the prefix + */ + public String getPrefix(); +} diff --git a/xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/XMLEvent.java b/xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/XMLEvent.java new file mode 100755 index 000000000..a0bfc24f6 --- /dev/null +++ b/xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/XMLEvent.java @@ -0,0 +1,149 @@ +/* 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.xml.stream; + +/** + * This is the base element interface for handling markup events. + * + * @since Weblogic XML Input Stream 1.0 + * @version 1.0 + * @see org.apache.xmlbeans.xml.stream.CharacterData + * @see org.apache.xmlbeans.xml.stream.ProcessingInstruction + * @see org.apache.xmlbeans.xml.stream.StartElement + * @see org.apache.xmlbeans.xml.stream.EndElement + * @see org.apache.xmlbeans.xml.stream.CharacterData + * @see org.apache.xmlbeans.xml.stream.XMLName + * @see org.apache.xmlbeans.xml.stream.StartDocument + */ + +public interface XMLEvent { + /** + * A constant which identifies an XMLEvent + * @see org.apache.xmlbeans.xml.stream.XMLEvent + */ + public static final int XML_EVENT=0x00000001; + /** + * A constant which identifies a StartElement + * @see org.apache.xmlbeans.xml.stream.StartElement + */ + public static final int START_ELEMENT=0x00000002; + /** + * A constant which identifies an EndElement + * @see org.apache.xmlbeans.xml.stream.EndElement + */ + public static final int END_ELEMENT=0x00000004; + /** + * A constant which identifies a ProcessingInstruction + * @see org.apache.xmlbeans.xml.stream.ProcessingInstruction + */ + public static final int PROCESSING_INSTRUCTION=0x00000008; + /** + * A constant which identifies a CharacterData Event + * @see org.apache.xmlbeans.xml.stream.CharacterData + */ + public static final int CHARACTER_DATA=0x00000010; + /** + * A constant which identifies a Comment + * @see org.apache.xmlbeans.xml.stream.Comment + */ + public static final int COMMENT=0x00000020; + /** + * A constant which identifies a Space + * @see org.apache.xmlbeans.xml.stream.Space + */ + public static final int SPACE=0x00000040; + /** + * A constant which identifies a NullElement + */ + public static final int NULL_ELEMENT=0x00000080; + /** + * A constant which identifies a StartDocument + * @see org.apache.xmlbeans.xml.stream.StartDocument + */ + public static final int START_DOCUMENT=0x00000100; + /** + * A constant which identifies an EndDocument + * @see org.apache.xmlbeans.xml.stream.EndDocument + */ + public static final int END_DOCUMENT=0x00000200; + /** + * A constant which identifies a StartPrefixMapping + * @see org.apache.xmlbeans.xml.stream.StartPrefixMapping + */ + public static final int START_PREFIX_MAPPING=0x00000400; + /** + * A constant which identifies a EndPrefixMapping + * @see org.apache.xmlbeans.xml.stream.EndPrefixMapping + */ + public static final int END_PREFIX_MAPPING=0x00000800; + /** + * A constant which identifies a ChangePrefixMapping + * @see org.apache.xmlbeans.xml.stream.ChangePrefixMapping + */ + public static final int CHANGE_PREFIX_MAPPING=0x00001000; + /** + * A constant which identifies an EntityReference + * @see org.apache.xmlbeans.xml.stream.EntityReference + */ + public static final int ENTITY_REFERENCE=0x00002000; + /** + * Get the event type of the current element, + * returns an integer so that switch statements + * can be written on the result + */ + public int getType(); + /** + * Get the event type of the current element, + * returns an integer so that switch statements + * can be written on the result + */ + public XMLName getSchemaType(); + /** + * Get the string value of the type name + */ + public String getTypeAsString(); + /** + * Get the XMLName of the current element + * @see org.apache.xmlbeans.xml.stream.XMLName + */ + public XMLName getName(); + + /** + * Check if this Element has a name + */ + public boolean hasName(); + + /** + * Return the location of this Element + */ + public Location getLocation(); + + /** + * Method access to the elements type + */ + public boolean isStartElement(); + public boolean isEndElement(); + public boolean isEntityReference(); + public boolean isStartPrefixMapping(); + public boolean isEndPrefixMapping(); + public boolean isChangePrefixMapping(); + public boolean isProcessingInstruction(); + public boolean isCharacterData(); + public boolean isSpace(); + public boolean isNull(); + public boolean isStartDocument(); + public boolean isEndDocument(); +} diff --git a/xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/XMLInputStream.java b/xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/XMLInputStream.java new file mode 100755 index 000000000..1d69110d6 --- /dev/null +++ b/xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/XMLInputStream.java @@ -0,0 +1,142 @@ +/* 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.xml.stream; + +/** + * + * This is the top level interface for iterating over XML Events + * in an XML document. + * + *

    Difference from SAX

    + *

    An event stream can be thought of encapsulating SAX + * events. It applies an iterator/pull metaphor to the parser + * allowing procedural, stream-based, handling of input XML rather than + * having to write chained event handlers to handle complex XML + * documents. + *

    Difference from DOM

    + *

    The pull metaphor allows single-pass, stream-based parsing of the document rather + * than tree based manipulation.

    + * + * @since XMLInputStream 1.0 + * @version 1.0 + * @see org.apache.xmlbeans.xml.stream.XMLEvent + * @see org.apache.xmlbeans.xml.stream.CharacterData + * @see org.apache.xmlbeans.xml.stream.ProcessingInstruction + * @see org.apache.xmlbeans.xml.stream.StartElement + * @see org.apache.xmlbeans.xml.stream.EndElement + * @see org.apache.xmlbeans.xml.stream.CharacterData + * @see org.apache.xmlbeans.xml.stream.XMLName + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + +// REVIEW pdapkus@bea.com 2002-Sep-13 -- while I like the convenience +// of many of these methods, it strikes me that many of these methods +// could implemented as static methods in a utility class. the down +// side to having them in this base interface is that it makes the +// contract for implementers unnecessarily steap and results in +// duplicated code in methods that can't extend one of the common base +// classes. + +public interface XMLInputStream { + /** + * Get the next XMLEvent on the stream + * @see org.apache.xmlbeans.xml.stream.XMLEvent + */ + public XMLEvent next() throws XMLStreamException; + /** + * Check if there are more events to pull of the stream + * @see org.apache.xmlbeans.xml.stream.XMLEvent + */ + public boolean hasNext() throws XMLStreamException; + /** + * Skip the next stream event + */ + public void skip() throws XMLStreamException; + /** + * Skips the entire next start tag / end tag pair. + */ + public void skipElement() throws XMLStreamException; + /** + * Check the next XMLEvent without reading it from the stream. + * Returns null if the stream is at EOF or has no more XMLEvents. + * @see org.apache.xmlbeans.xml.stream.XMLEvent + */ + public XMLEvent peek() throws XMLStreamException; + /** + * Position the stream at the next XMLEvent of this type. The method + * returns true if the stream contains another XMLEvent of this type + * and false otherwise. + * @param eventType An integer code that indicates the element type. + * @see org.apache.xmlbeans.xml.stream.XMLEvent + */ + public boolean skip(int eventType) throws XMLStreamException; + /** + * Position the stream at the next element of this name. The method + * returns true if the stream contains another element with this name + * and false otherwise. Skip is a forward operator only. It does + * not look backward in the stream. + * @param name An object that defines an XML name. + * If the XMLName.getNameSpaceName() method on the XMLName argument returns + * null the XMLName will match just the local name. Prefixes are + * not checked for equality. + * @see org.apache.xmlbeans.xml.stream.XMLName + */ + public boolean skip(XMLName name) throws XMLStreamException; + /** + * Position the stream at the next element of this name and this type. + * The method returns true if the stream contains another element + * with this name of this type and false otherwise. + * @param name An object that defines an XML name. + * If the XMLName.getNameSpaceName() method on the XMLName argument returns + * null the XMLName will match just the local name. Prefixes are + * not checked for equality. + * @param eventType An integer code that indicates the element type. + * @see org.apache.xmlbeans.xml.stream.XMLEvent + * @see org.apache.xmlbeans.xml.stream.XMLName + */ + public boolean skip(XMLName name, int eventType) throws XMLStreamException; + /** + * getSubStream() returns a stream which points to the entire next element in the + * current stream. For example: take a document that has a root node A, where the children + * of A are B, C, and D. If the stream is pointing to the start element of A, getSubStream() will return + * A, B, C and D including the start element of A and the end element of A. The position of the parent + * stream is not changed and the events read by the substream are written back to its parent. + */ + public XMLInputStream getSubStream() throws XMLStreamException; + /** + * Closes this input stream and releases any system resources associated with the stream. + */ + public void close() throws XMLStreamException; + + /** + * Returns the reference resolver that was set for this stream, + * returns null if no ReferenceResolver has been set. + * @see org.apache.xmlbeans.xml.stream.ReferenceResolver + */ + public ReferenceResolver getReferenceResolver(); + /** + * Provides a way to set the ReferenceResolver of the stream, + * this is mostly needed for handle references to other parts of the + * document. + * @see org.apache.xmlbeans.xml.stream.ReferenceResolver + */ + public void setReferenceResolver(ReferenceResolver resolver); +} + + + + + diff --git a/xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/XMLName.java b/xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/XMLName.java new file mode 100755 index 000000000..a050b402b --- /dev/null +++ b/xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/XMLName.java @@ -0,0 +1,57 @@ +/* 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.xml.stream; + +/** + * Encapsulates information about the Qualified Name of an XML event. + * + * @since Weblogic XML Input Stream 1.0 + * @version 1.0 + * @see org.apache.xmlbeans.xml.stream.StartElement + * @see org.apache.xmlbeans.xml.stream.XMLEvent + */ + +public interface XMLName { + /* + * returns the uri of the prefix of this name + * + * @return returns the uri, + * empty string if the default namespace is bound to empty string + * or null if the name does not have a namespace + */ + public String getNamespaceUri(); + /* + * returns the localname of the xml name + * + * @return the localname, cannot be null + */ + public String getLocalName(); + /* + * returns the prefix of the xml name + * + * @return the prefix of the xml name or null + */ + public String getPrefix(); + + /* + * returns the prefix of the xml name + ':' + the local name + * if the prefix is not null + * returns the local name otherwise + * + * @return the prefix plus the local name + */ + public String getQualifiedName(); +} diff --git a/xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/XMLStreamException.java b/xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/XMLStreamException.java new file mode 100755 index 000000000..32c6f2562 --- /dev/null +++ b/xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/XMLStreamException.java @@ -0,0 +1,141 @@ +/* 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.xml.stream; + +import java.io.IOException; +import java.io.PrintStream; +import java.io.PrintWriter; + +import org.apache.xmlbeans.xml.stream.utils.NestedThrowable; + +/** + * The base exception for unexpected input during XML handling + * + * @since Weblogic XML Input Stream 1.0 + * @version 1.0 + */ + +public class XMLStreamException + extends IOException + implements NestedThrowable +{ + protected Throwable th; + + public XMLStreamException() {} + + public XMLStreamException(String msg) { + super(msg); + } + + public XMLStreamException(Throwable th) { + this.th = th; + + } + + public XMLStreamException(String msg, Throwable th) { + super(msg); + this.th = th; + } + + /** + * Gets the nested exception. + * + * @return Nested exception + */ + public Throwable getNestedException() { + return getNested(); + } + + //try to do someting useful + public String getMessage() { + String msg = super.getMessage(); + + if (msg == null && th != null) { + return th.getMessage(); + } else { + return msg; + } + } + + + // ================================================================= + // NestedThrowable implementation. + + /** + * Gets the nested Throwable. + * + * @return Nested exception + */ + public Throwable getNested() { + return th; + } + + public String superToString() { + return super.toString(); + } + + public void superPrintStackTrace(PrintStream ps) { + super.printStackTrace(ps); + } + + public void superPrintStackTrace(PrintWriter pw) { + super.printStackTrace(pw); + } + + // End NestedThrowable implementation. + // ================================================================= + + /** + * Prints the exception message and its nested exception message. + * + * @return String representation of the exception + */ + public String toString() { + return NestedThrowable.Util.toString(this); + } + + /** + * Prints the stack trace associated with this exception and + * its nested exception. + * + * @param s PrintStream + */ + public void printStackTrace(PrintStream s) { + NestedThrowable.Util.printStackTrace(this, s); + } + + /** + * Prints the stack trace associated with this exception and + * its nested exception. + * + * @param s PrintStream + */ + public void printStackTrace(PrintWriter w) { + NestedThrowable.Util.printStackTrace(this, w); + } + + /** + * Prints the stack trace associated with this exception and + * its nested exception to System.err. + * + * @param s PrintStream + */ + public void printStackTrace() { + printStackTrace(System.err); + } +} + + diff --git a/xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/events/ElementTypeNames.java b/xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/events/ElementTypeNames.java new file mode 100755 index 000000000..a4655376e --- /dev/null +++ b/xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/events/ElementTypeNames.java @@ -0,0 +1,71 @@ +/* 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.xml.stream.events; + +import org.apache.xmlbeans.xml.stream.XMLEvent; + +public class ElementTypeNames { + public static String getName(int val) { + switch(val) { + case XMLEvent.XML_EVENT: return ("XML_EVENT"); + case XMLEvent.START_ELEMENT: return ("START_ELEMENT"); + case XMLEvent.END_ELEMENT: return ("END_ELEMENT"); + case XMLEvent.PROCESSING_INSTRUCTION: return ("PROCESSING_INSTRUCTION"); + case XMLEvent.CHARACTER_DATA: return ("CHARACTER_DATA"); + case XMLEvent.COMMENT: return ("COMMENT"); + case XMLEvent.SPACE: return ("SPACE"); + case XMLEvent.NULL_ELEMENT: return ("NULL_ELEMENT"); + case XMLEvent.START_DOCUMENT: return ("START_DOCUMENT"); + case XMLEvent.END_DOCUMENT: return ("END_DOCUMENT"); + case XMLEvent.START_PREFIX_MAPPING: return ("START_PREFIX_MAPPING"); + case XMLEvent.CHANGE_PREFIX_MAPPING: return ("CHANGE_PREFIX_MAPPING"); + case XMLEvent.END_PREFIX_MAPPING: return ("END_PREFIX_MAPPING"); + case XMLEvent.ENTITY_REFERENCE: return ("ENTITY_REFERENCE"); + default: return ""; + } + } + public static int getType(String val) { + if (val.equals("XML_EVENT")) + return XMLEvent.XML_EVENT; + if (val.equals ("START_ELEMENT")) return + XMLEvent.START_ELEMENT; + if (val.equals ("END_ELEMENT")) return XMLEvent.END_ELEMENT; + if (val.equals ("PROCESSING_INSTRUCTION")) + return XMLEvent.PROCESSING_INSTRUCTION; + if (val.equals ("CHARACTER_DATA")) + return XMLEvent.CHARACTER_DATA; + if (val.equals ("COMMENT")) + return XMLEvent.COMMENT; + if (val.equals ("SPACE")) + return XMLEvent.SPACE; + if (val.equals ("NULL_ELEMENT")) + return XMLEvent.NULL_ELEMENT; + if (val.equals ("START_DOCUMENT")) + return XMLEvent.START_DOCUMENT; + if (val.equals ("END_DOCUMENT")) + return XMLEvent.END_DOCUMENT; + if (val.equals ("START_PREFIX_MAPPING")) + return XMLEvent.START_PREFIX_MAPPING; + if (val.equals ("CHANGE_PREFIX_MAPPING")) + return XMLEvent.CHANGE_PREFIX_MAPPING; + if (val.equals ("ENTITY_REFERENCE")) + return XMLEvent.ENTITY_REFERENCE; + if (val.equals ("END_PREFIX_MAPPING")) + return XMLEvent.END_PREFIX_MAPPING; + + return XMLEvent.NULL_ELEMENT; + } +} diff --git a/xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/utils/NestedThrowable.java b/xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/utils/NestedThrowable.java new file mode 100755 index 000000000..2ca73d2a2 --- /dev/null +++ b/xmlbeans/src/xmlinputstream/org/apache/xmlbeans/xml/stream/utils/NestedThrowable.java @@ -0,0 +1,105 @@ +/* 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.xml.stream.utils; + +/** + * The interface implemented by NestedException, NestedError, and + * NestedRuntimeException largely so Util can provide a standard + * implementation of toString() and printStackTrace() + * + * @deprecated use JDK 1.4 style nested throwables where possible. + * + */ + +import java.io.PrintWriter; +import java.io.PrintStream; +import java.lang.reflect.InvocationTargetException; + +public interface NestedThrowable { + + /** Get the nested Throwable. */ + Throwable getNested(); + + /** Call super.toString(). [Kludge but necessary.] */ + String superToString(); + + /** Call super.printStackTrace(). [Kludge but necessary.] */ + void superPrintStackTrace(PrintStream ps); + + /** Call super.printStackTrace(). [Kludge but necessary.] */ + void superPrintStackTrace(PrintWriter po); + + static class Util { + + private static String EOL = System.getProperty("line.separator"); + + /** + * Prints the exception message and its nested exception message. + * + * @return String representation of the exception + */ + public static String toString(NestedThrowable nt) { + Throwable nested = nt.getNested(); + if (nested == null) { + return nt.superToString(); + } else { + return nt.superToString() + " - with nested exception:" + + EOL + "[" + nestedToString(nested) + "]"; + } + } + + private static String nestedToString(Throwable nested) { + if (nested instanceof InvocationTargetException) { + InvocationTargetException ite = (InvocationTargetException) nested; + return nested.toString() + " - with target exception:" + + EOL + "[" + ite.getTargetException().toString() + + "]"; + } + return nested.toString(); + } + + /** + * Prints the stack trace associated with this exception and + * its nested exception. + * + * @param s PrintStream + */ + public static void printStackTrace(NestedThrowable nt, PrintStream s) { + Throwable nested = nt.getNested(); + if (nested != null) { + nested.printStackTrace(s); + s.println("--------------- nested within: ------------------"); + } + nt.superPrintStackTrace(s); + } + + /** + * Prints the stack trace associated with this exception and + * its nested exception. + * + * @param w PrintWriter + */ + public static void printStackTrace(NestedThrowable nt, PrintWriter w) { + Throwable nested = nt.getNested(); + if (nested != null) { + nested.printStackTrace(w); + w.println("--------------- nested within: ------------------"); + } + nt.superPrintStackTrace(w); + } + } + +} diff --git a/xmlbeans/src/xmlpublic/javax/xml/namespace/NamespaceContext.java b/xmlbeans/src/xmlpublic/javax/xml/namespace/NamespaceContext.java new file mode 100644 index 000000000..8d24f0744 --- /dev/null +++ b/xmlbeans/src/xmlpublic/javax/xml/namespace/NamespaceContext.java @@ -0,0 +1,25 @@ +/* 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 javax.xml.namespace; + +import java.util.Iterator; + +public interface NamespaceContext { + + public String getNamespaceURI(String prefix); + public String getPrefix(String namespaceURI); + public Iterator getPrefixes(String namespaceURI); +} diff --git a/xmlbeans/src/xmlpublic/javax/xml/namespace/QName.java b/xmlbeans/src/xmlpublic/javax/xml/namespace/QName.java new file mode 100644 index 000000000..4dd943290 --- /dev/null +++ b/xmlbeans/src/xmlpublic/javax/xml/namespace/QName.java @@ -0,0 +1,231 @@ +/* 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 javax.xml.namespace; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.Serializable; + +/** + * QName class represents the value of a qualified name + * as specified in XML + * Schema Part2: Datatypes specification. + *

    + * The value of a QName contains a namespaceURI, a localPart and a prefix. + * The localPart provides the local part of the qualified name. The + * namespaceURI is a URI reference identifying the namespace. + * + * @version 1.1 + */ +public class QName implements Serializable { + + private static final long serialVersionUID = -9120448754896609940L; + + /** comment/shared empty string */ + private static final String emptyString = "".intern(); + + /** Field namespaceURI */ + private String namespaceURI; + + /** Field localPart */ + private String localPart; + + /** Field prefix */ + private String prefix; + + /** + * Constructor for the QName. + * + * @param localPart Local part of the QName + */ + public QName(String localPart) { + this(emptyString, localPart, emptyString); + } + + /** + * Constructor for the QName. + * + * @param namespaceURI Namespace URI for the QName + * @param localPart Local part of the QName. + */ + public QName(String namespaceURI, String localPart) { + this(namespaceURI, localPart, emptyString); + } + + /** + * Constructor for the QName. + * + * @param namespaceURI Namespace URI for the QName + * @param localPart Local part of the QName. + * @param prefix Prefix of the QName. + */ + public QName(String namespaceURI, String localPart, String prefix) { + this.namespaceURI = (namespaceURI == null) + ? emptyString + : namespaceURI.intern(); + if (localPart == null) { + throw new IllegalArgumentException("invalid QName local part"); + } else { + this.localPart = localPart.intern(); + } + + if (prefix == null) { + throw new IllegalArgumentException("invalid QName prefix"); + } else { + this.prefix = prefix.intern(); + } + } + + /** + * Gets the Namespace URI for this QName + * + * @return Namespace URI + */ + public String getNamespaceURI() { + return namespaceURI; + } + + /** + * Gets the Local part for this QName + * + * @return Local part + */ + public String getLocalPart() { + return localPart; + } + + /** + * Gets the Prefix for this QName + * + * @return Prefix + */ + public String getPrefix() { + return prefix; + } + + /** + * Returns a string representation of this QName + * + * @return a string representation of the QName + */ + public String toString() { + + return ((namespaceURI == emptyString) + ? localPart + : '{' + namespaceURI + '}' + localPart); + } + + /** + * Tests this QName for equality with another object. + *

    + * If the given object is not a QName or is null then this method + * returns false. + *

    + * For two QNames to be considered equal requires that both + * localPart and namespaceURI must be equal. This method uses + * String.equals to check equality of localPart + * and namespaceURI. Any class that extends QName is required + * to satisfy this equality contract. + *

    + * This method satisfies the general contract of the Object.equals method. + * + * @param obj the reference object with which to compare + * + * @return true if the given object is identical to this + * QName: false otherwise. + */ + public final boolean equals(Object obj) { + + if (obj == this) { + return true; + } + + if (!(obj instanceof QName)) { + return false; + } + + if ((namespaceURI == ((QName) obj).namespaceURI) + && (localPart == ((QName) obj).localPart)) { + return true; + } + + return false; + } + + /** + * Returns a QName holding the value of the specified String. + *

    + * The string must be in the form returned by the QName.toString() + * method, i.e. "{namespaceURI}localPart", with the "{namespaceURI}" + * part being optional. + *

    + * This method doesn't do a full validation of the resulting QName. + * In particular, it doesn't check that the resulting namespace URI + * is a legal URI (per RFC 2396 and RFC 2732), nor that the resulting + * local part is a legal NCName per the XML Namespaces specification. + * + * @param s the string to be parsed + * @throws java.lang.IllegalArgumentException If the specified String cannot be parsed as a QName + * @return QName corresponding to the given String + */ + public static QName valueOf(String s) { + + if ((s == null) || s.equals("")) { + throw new IllegalArgumentException("invalid QName literal"); + } + + if (s.charAt(0) == '{') { + int i = s.indexOf('}'); + + if (i == -1) { + throw new IllegalArgumentException("invalid QName literal"); + } + + if (i == s.length() - 1) { + throw new IllegalArgumentException("invalid QName literal"); + } else { + return new QName(s.substring(1, i), s.substring(i + 1)); + } + } else { + return new QName(s); + } + } + + /** + * Returns a hash code value for this QName object. The hash code + * is based on both the localPart and namespaceURI parts of the + * QName. This method satisfies the general contract of the + * Object.hashCode method. + * + * @return a hash code value for this Qname object + */ + public final int hashCode() { + return namespaceURI.hashCode() ^ localPart.hashCode(); + } + + /** + * Ensure that deserialization properly interns the results. + * @param in the ObjectInputStream to be read + */ + private void readObject(ObjectInputStream in) throws + IOException, ClassNotFoundException { + in.defaultReadObject(); + + namespaceURI = namespaceURI.intern(); + localPart = localPart.intern(); + prefix = prefix.intern(); + } +} diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/BindingConfig.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/BindingConfig.java new file mode 100755 index 000000000..ea69da5a3 --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/BindingConfig.java @@ -0,0 +1,99 @@ +/* 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; + +import javax.xml.namespace.QName; + +/** + * The BindingConfig class is used during compilation to control the generation of java source files. + * The default BindingConfig does nothing, but sub-classes should provide more interesting behavior. + * + * @see XmlBeans#compileXmlBeans(String, SchemaTypeSystem, XmlObject[], BindingConfig, SchemaTypeLoader, Filer, XmlOptions) XmlBeans.compileXmlBeans() + */ +public class BindingConfig +{ + private static final InterfaceExtension[] EMPTY_INTERFACE_EXT_ARRAY = new InterfaceExtension[0]; + private static final PrePostExtension[] EMPTY_PREPOST_EXT_ARRAY = new PrePostExtension[0]; + private static final UserType[] EMPTY_USER_TYPE_ARRY = new UserType[0]; + + public static final int QNAME_TYPE = 1; + public static final int QNAME_DOCUMENT_TYPE = 2; + public static final int QNAME_ACCESSOR_ELEMENT = 3; + public static final int QNAME_ACCESSOR_ATTRIBUTE = 4; + + /** + * Get the package name for a namespace or null. + */ + public String lookupPackageForNamespace(String uri) { return null; } + + /** + * Get the prefix applied to each java name for a namespace or null. + */ + public String lookupPrefixForNamespace(String uri) { return null; } + + /** + * Get the suffix applied to each java name for a namespace or null. + */ + public String lookupSuffixForNamespace(String uri) { return null; } + + /** + * Get the java name for a QName or null. + * @deprecated replaced with {@link #lookupJavanameForQName(QName, int)} + */ + public String lookupJavanameForQName(QName qname) { return null; } + + /** + * Get the java name for a QName of a specific component kind, or null. + * @see #QNAME_TYPE + * @see #QNAME_TYPE_DOCUMENT + * @see #QNAME_METHOD_ELEMENT + * @see #QNAME_METHOD_ATTRIBUTE + */ + public String lookupJavanameForQName(QName qname, int kind) { return null; } + + /** + * Returns all configured InterfaceExtensions or an empty array. + */ + public InterfaceExtension[] getInterfaceExtensions() { return EMPTY_INTERFACE_EXT_ARRAY; } + + /** + * Returns all InterfaceExtensions defined for the fully qualified java + * type generated from schema compilation or an empty array. + */ + public InterfaceExtension[] getInterfaceExtensions(String fullJavaName) { return EMPTY_INTERFACE_EXT_ARRAY; } + + /** + * Returns all configued PrePostExtensions or an empty array. + */ + public PrePostExtension[] getPrePostExtensions() { return EMPTY_PREPOST_EXT_ARRAY; } + + /** + * Returns the PrePostExtension defined for the fully qualified java + * type generated from schema compilation or null. + */ + public PrePostExtension getPrePostExtension(String fullJavaName) { return null; } + + /** + * Returns all defined user types. + */ + public UserType[] getUserTypes() { return EMPTY_USER_TYPE_ARRY; } + + /** + * Returns a user defined Java type for a given QName. + */ + public UserType lookupUserTypeForQName(QName qname) { return null; } + +} diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/CDataBookmark.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/CDataBookmark.java new file mode 100644 index 000000000..c49283b0f --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/CDataBookmark.java @@ -0,0 +1,58 @@ +/* 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; + +/** + * Represents a CDATA bookmark. + * + *

    When XmlOption UseCDataBookmarks is setted on parse methods, + * the loader will set these CDataBookmarks in the store on the respective + * TEXT fields that were represented as CDATA.

    + * + *

    Users can modify the 'look' of TEXT fields, by annotating them with + * this bookmark, or remove the bookmark.

    + * + *

    Additionaly if setted on save methods, the output will look for these + * bookmarks and will output the text as CDATA. + * Note: The SaveCDataEntityCountThreshold and SaveCDataLengthThreshold + * options and their default values still apply.

    + * + *

    Note: Due to the store representation, a CDATA will not be recognized + * if it is imediately after non CDATA text and all text following it will + * be considered CDATA.
    + * Example:
    + *

    + * <a><![CDATA[cdata text]]></a>               - is considered as: <a><![CDATA[cdata text]]></a>
    + * <b><![CDATA[cdata text]]> regular text</b>  - is considered as: <b><![CDATA[cdata text regular text]]></b>
    + * <c>text <![CDATA[cdata text]]></c>          - is considered as: <c>text cdata text</c>
    + * 
    + *

    + * @see XmlOptions#setUseCDataBookmarks() + * @see org.apache.xmlbeans.XmlObject.Factory#parse(String, XmlOptions) + * @see org.apache.xmlbeans.XmlObject#save(java.io.OutputStream, XmlOptions) + * @see XmlOptions#setSaveCDataEntityCountThreshold(int) + * @see XmlOptions#setSaveCDataLengthThreshold(int) + * @author Cezar Andrei (cezar dot andrei at gmail dot com) + */ +public class CDataBookmark + extends XmlCursor.XmlBookmark +{ + /** + * The actual bookmark object representing CData.
    + * Users must use this bookmark in addition to UseCDataBookmarks + * option to make use of CDATA representation in XML text. + */ + public static CDataBookmark CDATA_BOOKMARK = new CDataBookmark(); +} \ No newline at end of file diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/DelegateXmlObject.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/DelegateXmlObject.java new file mode 100644 index 000000000..e677520c2 --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/DelegateXmlObject.java @@ -0,0 +1,28 @@ +/* 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; + +/** + * See {@link FilterXmlObject} + */ +public interface DelegateXmlObject +{ + /** + * This method is called to obtain the underlying XmlObject. + * Implement this method to supply or compute the wrapped object. + */ + XmlObject underlyingXmlObject(); +} diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/Filer.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/Filer.java new file mode 100755 index 000000000..80b45753d --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/Filer.java @@ -0,0 +1,46 @@ +/* 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; + +import java.io.OutputStream; +import java.io.Writer; +import java.io.IOException; + +/** + * + */ +public interface Filer +{ + + /** + * Creates a new schema binary file (.xsb) and returns a stream for writing to it. + * + * @param typename fully qualified type name + * @return a stream to write the type to + * @throws IOException + */ + public OutputStream createBinaryFile(String typename) throws IOException; + + /** + * Creates a new binding source file (.java) and returns a writer for it. + * + * @param typename fully qualified type name + * @return a stream to write the type to + * @throws IOException + */ + public Writer createSourceFile(String typename) throws IOException; + +} diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/FilterXmlObject.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/FilterXmlObject.java new file mode 100644 index 000000000..7f2b6672b --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/FilterXmlObject.java @@ -0,0 +1,812 @@ +/* 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; + +import org.apache.xmlbeans.xml.stream.XMLInputStream; + +import java.io.InputStream; +import java.io.Reader; +import java.io.File; +import java.io.IOException; +import java.io.OutputStream; +import java.io.Writer; +import java.math.BigInteger; +import java.math.BigDecimal; +import java.util.Calendar; +import java.util.Date; +import java.util.List; + +import org.w3c.dom.Node; +import org.xml.sax.ContentHandler; +import org.xml.sax.SAXException; +import org.xml.sax.ext.LexicalHandler; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamReader; + +/** + * A FilterXmlObject delegates to some other XmlObject, which it can use as + * its basic source of data, possibly transforming the data along the way or + * providing additional functionality. The class FilterXmlObject itself + * simply overrides all methods of XmlObject with versions that pass all + * requests to the underlying XmlObject. Subclasses of FilterXmlObject may + * further override some of these methods and may also provide additional + * methods and fields. + *

    + * Note: it is important that FilterXmlObject has no storage (i.e., no + * non-transient fields), because subclasses may be serializable and + * adding storage would break the serialization format. + */ +public abstract class FilterXmlObject implements XmlObject, SimpleValue, DelegateXmlObject +{ + public SchemaType schemaType() + { + return underlyingXmlObject().schemaType(); + } + + public boolean validate() + { + return underlyingXmlObject().validate(); + } + + public boolean validate(XmlOptions options) + { + return underlyingXmlObject().validate(options); + } + + public XmlObject[] selectPath(String path) + { + return underlyingXmlObject().selectPath(path); + } + + public XmlObject[] selectPath(String path, XmlOptions options) + { + return underlyingXmlObject().selectPath(path, options); + } + + public XmlObject[] execQuery(String query) + { + return underlyingXmlObject().execQuery(query); + } + + public XmlObject[] execQuery(String query, XmlOptions options) + { + return underlyingXmlObject().execQuery(query, options); + } + + public XmlObject changeType(SchemaType newType) + { + return underlyingXmlObject().changeType(newType); + } + + public boolean isNil() + { + return underlyingXmlObject().isNil(); + } + + public void setNil() + { + underlyingXmlObject().setNil(); + } + + public boolean isImmutable() + { + return underlyingXmlObject().isImmutable(); + } + + public XmlObject set(XmlObject srcObj) + { + return underlyingXmlObject().set(srcObj); + } + + public XmlObject copy() + { + return underlyingXmlObject().copy(); + } + + public XmlObject copy(XmlOptions options) + { + return underlyingXmlObject().copy(options); + } + + public boolean valueEquals(XmlObject obj) + { + return underlyingXmlObject().valueEquals(obj); + } + + public int valueHashCode() + { + return underlyingXmlObject().valueHashCode(); + } + + public int compareTo(Object obj) + { + return underlyingXmlObject().compareTo(obj); + } + + public int compareValue(XmlObject obj) + { + return underlyingXmlObject().compareValue(obj); + } + + public Object monitor() + { + return underlyingXmlObject().monitor(); + } + + public XmlDocumentProperties documentProperties() + { + return underlyingXmlObject().documentProperties(); + } + + public XmlCursor newCursor() + { + return underlyingXmlObject().newCursor(); + } + + /** + * @deprecated Deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public XMLInputStream newXMLInputStream() + { + return underlyingXmlObject().newXMLInputStream(); + } + + public XMLStreamReader newXMLStreamReader() + { + return underlyingXmlObject().newXMLStreamReader(); + } + + public String xmlText() + { + return underlyingXmlObject().xmlText(); + } + + public InputStream newInputStream() + { + return underlyingXmlObject().newInputStream(); + } + + public Reader newReader() + { + return underlyingXmlObject().newReader(); + } + + public Node newDomNode() + { + return underlyingXmlObject().newDomNode(); + } + + public Node getDomNode() + { + return underlyingXmlObject().getDomNode(); + } + + public void save(ContentHandler ch, LexicalHandler lh) throws SAXException + { + underlyingXmlObject().save(ch, lh); + } + + public void save(File file) throws IOException + { + underlyingXmlObject().save(file); + } + + public void save(OutputStream os) throws IOException + { + underlyingXmlObject().save(os); + } + + public void save(Writer w) throws IOException + { + underlyingXmlObject().save(w); + } + + /** + * @deprecated Deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public XMLInputStream newXMLInputStream(XmlOptions options) + { + return underlyingXmlObject().newXMLInputStream(options); + } + + public XMLStreamReader newXMLStreamReader(XmlOptions options) + { + return underlyingXmlObject().newXMLStreamReader(options); + } + + public String xmlText(XmlOptions options) + { + return underlyingXmlObject().xmlText(options); + } + + public InputStream newInputStream(XmlOptions options) + { + return underlyingXmlObject().newInputStream(options); + } + + public Reader newReader(XmlOptions options) + { + return underlyingXmlObject().newReader(options); + } + + public Node newDomNode(XmlOptions options) + { + return underlyingXmlObject().newDomNode(options); + } + + public void save(ContentHandler ch, LexicalHandler lh, XmlOptions options) throws SAXException + { + underlyingXmlObject().save(ch, lh, options); + } + + public void save(File file, XmlOptions options) throws IOException + { + underlyingXmlObject().save(file, options); + } + + public void save(OutputStream os, XmlOptions options) throws IOException + { + underlyingXmlObject().save(os, options); + } + + public void save(Writer w, XmlOptions options) throws IOException + { + underlyingXmlObject().save(w, options); + } + + public SchemaType instanceType() + { + return ((SimpleValue)underlyingXmlObject()).instanceType(); + } + + /** + * @deprecated replaced with {@link #getStringValue} + */ + public String stringValue() + { + return ((SimpleValue)underlyingXmlObject()).stringValue(); + } + + /** + * @deprecated replaced with {@link #getBooleanValue} + */ + public boolean booleanValue() + { + return ((SimpleValue)underlyingXmlObject()).booleanValue(); + } + + /** + * @deprecated replaced with {@link #getByteValue} + */ + public byte byteValue() + { + return ((SimpleValue)underlyingXmlObject()).byteValue(); + } + + /** + * @deprecated replaced with {@link #getShortValue} + */ + public short shortValue() + { + return ((SimpleValue)underlyingXmlObject()).shortValue(); + } + + /** + * @deprecated replaced with {@link #getIntValue} + */ + public int intValue() + { + return ((SimpleValue)underlyingXmlObject()).intValue(); + } + + /** + * @deprecated replaced with {@link #getLongValue} + */ + public long longValue() + { + return ((SimpleValue)underlyingXmlObject()).longValue(); + } + + /** + * @deprecated replaced with {@link #getBigIntegerValue} + */ + public BigInteger bigIntegerValue() + { + return ((SimpleValue)underlyingXmlObject()).bigIntegerValue(); + } + + /** + * @deprecated replaced with {@link #getBigDecimalValue} + */ + public BigDecimal bigDecimalValue() + { + return ((SimpleValue)underlyingXmlObject()).bigDecimalValue(); + } + + /** + * @deprecated replaced with {@link #getFloatValue} + */ + public float floatValue() + { + return ((SimpleValue)underlyingXmlObject()).floatValue(); + } + + /** + * @deprecated replaced with {@link #getDoubleValue} + */ + public double doubleValue() + { + return ((SimpleValue)underlyingXmlObject()).doubleValue(); + } + + /** + * @deprecated replaced with {@link #getByteArrayValue} + */ + public byte[] byteArrayValue() + { + return ((SimpleValue)underlyingXmlObject()).byteArrayValue(); + } + + /** + * @deprecated replaced with {@link #getEnumValue} + */ + public StringEnumAbstractBase enumValue() + { + return ((SimpleValue)underlyingXmlObject()).enumValue(); + } + + /** + * @deprecated replaced with {@link #getCalendarValue} + */ + public Calendar calendarValue() + { + return ((SimpleValue)underlyingXmlObject()).calendarValue(); + } + + /** + * @deprecated replaced with {@link #getDateValue} + */ + public Date dateValue() + { + return ((SimpleValue)underlyingXmlObject()).dateValue(); + } + + /** + * @deprecated replaced with {@link #getGDateValue} + */ + public GDate gDateValue() + { + return ((SimpleValue)underlyingXmlObject()).gDateValue(); + } + + /** + * @deprecated replaced with {@link #getGDurationValue} + */ + public GDuration gDurationValue() + { + return ((SimpleValue)underlyingXmlObject()).gDurationValue(); + } + + /** + * @deprecated replaced with {@link #getQNameValue} + */ + public QName qNameValue() + { + return ((SimpleValue)underlyingXmlObject()).qNameValue(); + } + + /** + * @deprecated replaced with {@link #getListValue} + */ + public List listValue() + { + return ((SimpleValue)underlyingXmlObject()).listValue(); + } + + /** + * @deprecated replaced with {@link #getListValue} + */ + public List xlistValue() + { + return ((SimpleValue)underlyingXmlObject()).xlistValue(); + } + + /** + * @deprecated replaced with {@link #getObjectValue} + */ + public Object objectValue() + { + return ((SimpleValue)underlyingXmlObject()).objectValue(); + } + + /** + * @deprecated replaced with {@link #setStringValue} + */ + public void set(String obj) + { + ((SimpleValue)underlyingXmlObject()).set(obj); + } + + /** + * @deprecated replaced with {@link #setBooleanValue} + */ + public void set(boolean v) + { + ((SimpleValue)underlyingXmlObject()).set(v); + } + + /** + * @deprecated replaced with {@link #setByteValue} + */ + public void set(byte v) + { + ((SimpleValue)underlyingXmlObject()).set(v); + } + + /** + * @deprecated replaced with {@link #setShortValue} + */ + public void set(short v) + { + ((SimpleValue)underlyingXmlObject()).set(v); + } + + /** + * @deprecated replaced with {@link #setIntValue} + */ + public void set(int v) + { + ((SimpleValue)underlyingXmlObject()).set(v); + } + + /** + * @deprecated replaced with {@link #setLongValue} + */ + public void set(long v) + { + ((SimpleValue)underlyingXmlObject()).set(v); + } + + /** + * @deprecated replaced with {@link #setBigIntegerValue} + */ + public void set(BigInteger obj) + { + ((SimpleValue)underlyingXmlObject()).set(obj); + } + + /** + * @deprecated replaced with {@link #setBigDecimalValue} + */ + public void set(BigDecimal obj) + { + ((SimpleValue)underlyingXmlObject()).set(obj); + } + + /** + * @deprecated replaced with {@link #setFloatValue} + */ + public void set(float v) + { + ((SimpleValue)underlyingXmlObject()).set(v); + } + + /** + * @deprecated replaced with {@link #setDoubleValue} + */ + public void set(double v) + { + ((SimpleValue)underlyingXmlObject()).set(v); + } + + /** + * @deprecated replaced with {@link #setByteArrayValue} + */ + public void set(byte[] obj) + { + ((SimpleValue)underlyingXmlObject()).set(obj); + } + + /** + * @deprecated replaced with {@link #setEnumValue} + */ + public void set(StringEnumAbstractBase obj) + { + ((SimpleValue)underlyingXmlObject()).set(obj); + } + + /** + * @deprecated replaced with {@link #setCalendarValue} + */ + public void set(Calendar obj) + { + ((SimpleValue)underlyingXmlObject()).set(obj); + } + + /** + * @deprecated replaced with {@link #setDateValue} + */ + public void set(Date obj) + { + ((SimpleValue)underlyingXmlObject()).set(obj); + } + + /** + * @deprecated replaced with {@link #setGDateValue} + */ + public void set(GDateSpecification obj) + { + ((SimpleValue)underlyingXmlObject()).set(obj); + } + + /** + * @deprecated replaced with {@link #setGDurationValue} + */ + public void set(GDurationSpecification obj) + { + ((SimpleValue)underlyingXmlObject()).set(obj); + } + + /** + * @deprecated replaced with {@link #setQNameValue} + */ + public void set(QName obj) + { + ((SimpleValue)underlyingXmlObject()).set(obj); + } + + /** + * @deprecated replaced with {@link #setListValue} + */ + public void set(List obj) + { + ((SimpleValue)underlyingXmlObject()).set(obj); + } + + public String getStringValue() + { + return ((SimpleValue)underlyingXmlObject()).getStringValue(); + } + + public boolean getBooleanValue() + { + return ((SimpleValue)underlyingXmlObject()).getBooleanValue(); + } + + public byte getByteValue() + { + return ((SimpleValue)underlyingXmlObject()).getByteValue(); + } + + public short getShortValue() + { + return ((SimpleValue)underlyingXmlObject()).getShortValue(); + } + + public int getIntValue() + { + return ((SimpleValue)underlyingXmlObject()).getIntValue(); + } + + public long getLongValue() + { + return ((SimpleValue)underlyingXmlObject()).getLongValue(); + } + + public BigInteger getBigIntegerValue() + { + return ((SimpleValue)underlyingXmlObject()).getBigIntegerValue(); + } + + public BigDecimal getBigDecimalValue() + { + return ((SimpleValue)underlyingXmlObject()).getBigDecimalValue(); + } + + public float getFloatValue() + { + return ((SimpleValue)underlyingXmlObject()).getFloatValue(); + } + + public double getDoubleValue() + { + return ((SimpleValue)underlyingXmlObject()).getDoubleValue(); + } + + public byte[] getByteArrayValue() + { + return ((SimpleValue)underlyingXmlObject()).getByteArrayValue(); + } + + public StringEnumAbstractBase getEnumValue() + { + return ((SimpleValue)underlyingXmlObject()).getEnumValue(); + } + + public Calendar getCalendarValue() + { + return ((SimpleValue)underlyingXmlObject()).getCalendarValue(); + } + + public Date getDateValue() + { + return ((SimpleValue)underlyingXmlObject()).getDateValue(); + } + + public GDate getGDateValue() + { + return ((SimpleValue)underlyingXmlObject()).getGDateValue(); + } + + public GDuration getGDurationValue() + { + return ((SimpleValue)underlyingXmlObject()).getGDurationValue(); + } + + public QName getQNameValue() + { + return ((SimpleValue)underlyingXmlObject()).getQNameValue(); + } + + public List getListValue() + { + return ((SimpleValue)underlyingXmlObject()).getListValue(); + } + + public List xgetListValue() + { + return ((SimpleValue)underlyingXmlObject()).xgetListValue(); + } + + public Object getObjectValue() + { + return ((SimpleValue)underlyingXmlObject()).getObjectValue(); + } + + public void setStringValue(String obj) + { + ((SimpleValue)underlyingXmlObject()).setStringValue(obj); + } + + public void setBooleanValue(boolean v) + { + ((SimpleValue)underlyingXmlObject()).setBooleanValue(v); + } + + public void setByteValue(byte v) + { + ((SimpleValue)underlyingXmlObject()).setByteValue(v); + } + + public void setShortValue(short v) + { + ((SimpleValue)underlyingXmlObject()).setShortValue(v); + } + + public void setIntValue(int v) + { + ((SimpleValue)underlyingXmlObject()).setIntValue(v); + } + + public void setLongValue(long v) + { + ((SimpleValue)underlyingXmlObject()).setLongValue(v); + } + + public void setBigIntegerValue(BigInteger obj) + { + ((SimpleValue)underlyingXmlObject()).setBigIntegerValue(obj); + } + + public void setBigDecimalValue(BigDecimal obj) + { + ((SimpleValue)underlyingXmlObject()).setBigDecimalValue(obj); + } + + public void setFloatValue(float v) + { + ((SimpleValue)underlyingXmlObject()).setFloatValue(v); + } + + public void setDoubleValue(double v) + { + ((SimpleValue)underlyingXmlObject()).setDoubleValue(v); + } + + public void setByteArrayValue(byte[] obj) + { + ((SimpleValue)underlyingXmlObject()).setByteArrayValue(obj); + } + + public void setEnumValue(StringEnumAbstractBase obj) + { + ((SimpleValue)underlyingXmlObject()).setEnumValue(obj); + } + + public void setCalendarValue(Calendar obj) + { + ((SimpleValue)underlyingXmlObject()).setCalendarValue(obj); + } + + public void setDateValue(Date obj) + { + ((SimpleValue)underlyingXmlObject()).setDateValue(obj); + } + + public void setGDateValue(GDate obj) + { + ((SimpleValue)underlyingXmlObject()).setGDateValue(obj); + } + + public void setGDurationValue(GDuration obj) + { + ((SimpleValue)underlyingXmlObject()).setGDurationValue(obj); + } + + public void setQNameValue(QName obj) + { + ((SimpleValue)underlyingXmlObject()).setQNameValue(obj); + } + + public void setListValue(List obj) + { + ((SimpleValue)underlyingXmlObject()).setListValue(obj); + } + + public void setObjectValue(Object obj) + { + ((SimpleValue)underlyingXmlObject()).setObjectValue(obj); + } + + /** + * @deprecated replaced with {@link #setObjectValue} + **/ + public void objectSet(Object obj) + { + ((SimpleValue)underlyingXmlObject()).objectSet(obj); + } + + public XmlObject[] selectChildren(QName elementName) + { + return underlyingXmlObject().selectChildren(elementName); + } + + public XmlObject[] selectChildren(String elementUri, String elementLocalName) + { + return underlyingXmlObject().selectChildren(elementUri, elementLocalName); + } + + public XmlObject[] selectChildren(QNameSet elementNameSet) + { + return underlyingXmlObject().selectChildren(elementNameSet); + } + + public XmlObject selectAttribute(QName attributeName) + { + return underlyingXmlObject().selectAttribute(attributeName); + } + + public XmlObject selectAttribute(String attributeUri, String attributeLocalName) + { + return underlyingXmlObject().selectAttribute(attributeUri, attributeLocalName); + } + + public XmlObject[] selectAttributes(QNameSet attributeNameSet) + { + return underlyingXmlObject().selectAttributes(attributeNameSet); + } +} diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/GDate.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/GDate.java new file mode 100644 index 000000000..805967ea5 --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/GDate.java @@ -0,0 +1,1105 @@ +/* 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; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.TimeZone; + +/** + * Represents an XML Schema-compatible Gregorian date. + *

    + * There are many date types in XML Schema, and this type + * represents the natural union of all those types. A GDate + * can hold any subset of date fields (Year, Month, Day, Time, + * Timezone, or some combination). Wherever the specification + * provides guidance, the guidelines in the + * XML Schema 1.0 specification + * (plus published errata) are followed. + *

    + * Instances may separately have values or no values for + * the year, month, day-of-month, and time-of-day. Not all + * operations are meaningful on all combinations. + */ +public final class GDate implements GDateSpecification, java.io.Serializable +{ + private static final long serialVersionUID = 1L; + + // XMLSchema spec requires support only for years 1 to 9999, but XMLBeans covers more up to the following limitations + // to avoid losing precision when transforming to a java.util.Date + static final int MAX_YEAR = 292277265; // is Long.MAX_VALUE ms in years - 1 (for the 11month, 31days, 23h, 59m, 59sec case). + static final int MIN_YEAR = -292275295; // is Long.MIN_VALUE ms in years + 1970 + 1 + + // for fast equality comparison, hashing, and serialization + private transient String _canonicalString; + private transient String _string; + + private int _bits; + private int _CY; + private int _M; + private int _D; + private int _h; + private int _m; + private int _s; + private BigDecimal _fs; + private int _tzsign; + private int _tzh; + private int _tzm; + + + /* package */ static final BigDecimal _zero = BigDecimal.valueOf(0); + /* package */ static final BigDecimal _one = BigDecimal.valueOf(1); + + /** + * Constructs a GDate based on a lexical representation. + */ + public GDate(CharSequence string) + { + // first trim XML whitespace + int len = string.length(); + int start = 0; + while (len > 0 && isSpace(string.charAt(len - 1))) + len -= 1; + while (start < len && isSpace(string.charAt(start))) + start += 1; + + // pick optional timezone off the end + if (len - start >= 1 && string.charAt(len - 1) == 'Z') + { + _bits |= HAS_TIMEZONE; + len -= 1; + } + else if (len - start >= 6) + timezone: { + int tzsign; + int tzhour; + int tzminute; + + if (string.charAt(len - 3) != ':') + break timezone; + + switch (string.charAt(len - 6)) + { + case '-': + tzsign = -1; break; + case '+': + tzsign = 1; break; + default: + break timezone; + } + + tzhour = twoDigit(string, len - 5); + tzminute = twoDigit(string, len - 2); + if (tzhour > 14) + throw new IllegalArgumentException("time zone hour must be two digits between -14 and +14"); + if (tzminute > 59) + throw new IllegalArgumentException("time zone minute must be two digits between 00 and 59"); + _bits |= HAS_TIMEZONE; + _tzsign = tzsign; + _tzh = tzhour; + _tzm = tzminute; + len -= 6; + } + + // pick date fields off the beginning if it doesn't look like a time + if (start < len && (start + 2 >= len || string.charAt(start + 2) != ':')) + scandate: + { + // parse year sign + boolean negyear = false; + if (start < len && string.charAt(start) == '-') + { + negyear = true; + start += 1; + } + + // scan year digits + int value = 0; + int digits = -start; + char ch; + boolean startsWithZero = start < len && digitVal(string.charAt(start))==0; + + for (;;) + { + ch = start < len ? string.charAt(start) : '\0'; + if (!isDigit(ch)) + break; + + if ( startsWithZero && start+digits>=4 ) + throw new IllegalArgumentException("year value starting with zero must be 4 or less digits: " + string); + + value = value * 10 + digitVal(ch); + start += 1; + } + digits += start; + if (digits > 9) + throw new IllegalArgumentException("year too long (up to 9 digits)"); + else if (digits >= 4) + { + _bits |= HAS_YEAR; + _CY = negyear ? -value : value; + if (_CY == 0) throw new IllegalArgumentException("year must not be zero"); + } + else if (digits > 0) + throw new IllegalArgumentException("year must be four digits (may pad with zeroes, e.g., 0560)"); + + if ( _CY > MAX_YEAR ) + throw new IllegalArgumentException("year value not supported: too big, must be less than " + MAX_YEAR); + + if ( _CY < MIN_YEAR ) + throw new IllegalArgumentException("year values not supported: too small, must be bigger than " + MIN_YEAR); + + // hyphen introduces a month + if (ch != '-') + { + if (negyear && !hasYear()) + throw new IllegalArgumentException(); // a single minus + else + break scandate; + } + start += 1; + + // two-digit month + if (len - start >= 2) + { + value = twoDigit(string, start); + if (value >= 1 && value <= 12) + { + _bits |= HAS_MONTH; + _M = value; + start += 2; + } + } + + // hyphen introduces a day + ch = start < len ? string.charAt(start) : '\0'; + if (ch != '-') + { + if (!hasMonth()) + throw new IllegalArgumentException(); // minus after a year + else + break scandate; + } + start += 1; + + // two-digit day + if (len - start >= 2) + { + value = twoDigit(string, start); + if (value >= 1 && value <= 31) + { + _bits |= HAS_DAY; + _D = value; + start += 2; + } + } + + if (!hasDay()) + { + // error in the original schema spec permits an extra '-' here + if (hasMonth() && !hasYear()) + { + ch = start < len ? string.charAt(start) : '\0'; + if (ch == '-') + { + start += 1; + break scandate; + } + } + throw new IllegalArgumentException(); // minus after a month + } + } + + // time + if (start < len) + { + if (hasYear() || hasMonth() || hasDay()) + { + if (string.charAt(start) != 'T') + throw new IllegalArgumentException("date and time must be separated by 'T'"); + start += 1; + } + + if (len < start + 8 || string.charAt(start + 2) != ':' || string.charAt(start + 5) != ':') + throw new IllegalArgumentException(); + + int h = twoDigit(string, start); + if (h > 24) + throw new IllegalArgumentException("hour must be between 00 and 23"); + int m = twoDigit(string, start + 3); + if (m >= 60) + throw new IllegalArgumentException("minute must be between 00 and 59"); + int s = twoDigit(string, start + 6); + if (s >= 60) + throw new IllegalArgumentException("second must be between 00 and 59"); + + start += 8; + + BigDecimal fs = _zero; + if (start < len) + { + if (string.charAt(start) != '.') + throw new IllegalArgumentException(); + if (start + 1 < len) + { + for (int i = start + 1; i < len; i++) + { + if (!isDigit(string.charAt(i))) + throw new IllegalArgumentException(); + } + try + { + fs = new BigDecimal(string.subSequence(start, len).toString()); + } + catch (Throwable e) + { + throw new IllegalArgumentException(); + } + } + } + + _bits |= HAS_TIME; + _h = h; + _m = m; + _s = s; + _fs = fs; + } + + if ( hasTime() && _h == 24 ) + { + if ( _m != 0 || _s != 0 || _fs.compareTo(_zero) != 0 ) + throw new IllegalArgumentException("if hour is 24, minutes, seconds and fraction must be 0"); + else + { // normalize to next day if it has date or at least has day + if ( hasDate() ) + { + GDateBuilder gdb = new GDateBuilder(_CY, _M, _D, _h, _m, _s, _fs, _tzsign, _tzh, _tzm); + gdb.normalize24h(); + + _D = gdb.getDay(); + _M = gdb.getMonth(); + _CY = gdb.getYear(); + _h = 0; + } + else if ( hasDay() ) // if no date only days increment + { + _D++; + _h = 0; + } + } + } + + if (!isValid()) + throw new IllegalArgumentException("invalid date"); + } + + /** + * Constructs a GDate with the specified year, month, day, + * hours, minutes, seconds, and optional fractional seconds, in + * an unspecified timezone. + *

    + * Note that by not specifying the timezone the GDate + * becomes partially unordered with respect to times that + * do have a specified timezone. + */ + public GDate( + int year, + int month, + int day, + int hour, + int minute, + int second, + BigDecimal fraction) + { + _bits = HAS_YEAR | HAS_MONTH | HAS_DAY | HAS_TIME; + + _CY = year; + _M = month; + _D = day; + _h = hour; + _m = minute; + _s = second; + _fs = fraction == null ? _zero : fraction; + + if (!isValid()) + throw new IllegalArgumentException(); + } + + /** + * Constructs an absolute GDate with the specified year, + * month, day, hours, minutes, seconds, and optional fractional + * seconds, and in the timezone specified. + *

    + * If you wish to have a time or date that isn't in a specified timezone, + * then use the constructor that does not include the timezone arguments. + */ + public GDate( + int year, + int month, + int day, + int hour, + int minute, + int second, + BigDecimal fraction, + int tzSign, + int tzHour, + int tzMinute) + { + _bits = HAS_TIMEZONE | HAS_YEAR | HAS_MONTH | HAS_DAY | HAS_TIME; + + _CY = year; + _M = month; + _D = day; + _h = hour; + _m = minute; + _s = second; + _fs = fraction == null ? _zero : fraction; + _tzsign = tzSign; + _tzh = tzHour; + _tzm = tzMinute; + + if (!isValid()) + throw new IllegalArgumentException(); + } + + /** + * Constructs a GDate based on a java.util.Date. + *

    + * The current offset of the default timezone is used as the timezone. + *

    + * For example, if eastern daylight time is in effect at the given + * date, the timezone on the east coast of the united states + * translates to GMT-05:00 (EST) + 1:00 (DT offset) == GMT-04:00. + */ + public GDate(Date date) + { + // requires some date math, so ctor lives on GDateBuilder + this(new GDateBuilder(date)); + } + + /** + * Constructs a GDate based on a java.util.Calendar. + *

    + * If the calendar does not have some fields set, the same absence + * of information is reflected in the GDate. Note that + * java.util.GregorianCalendar fills in all fields as soon as any + * are fetched, so constructing a GDate with the same calendar object + * twice may result in a different GDate because of a changed calendar. + * Note that org.apache.xmlbeans.XmlCalendar is stable if you re-get a set field, + * so it does not have the same problem. + */ + public GDate(Calendar calendar) + { + // we must scrape the "isSet" information out before accessing anything + boolean isSetYear = calendar.isSet(Calendar.YEAR); + boolean isSetEra = calendar.isSet(Calendar.ERA); + boolean isSetMonth = calendar.isSet(Calendar.MONTH); + boolean isSetDay = calendar.isSet(Calendar.DAY_OF_MONTH); + boolean isSetHourOfDay = calendar.isSet(Calendar.HOUR_OF_DAY); + boolean isSetHour = calendar.isSet(Calendar.HOUR); + boolean isSetAmPm = calendar.isSet(Calendar.AM_PM); + boolean isSetMinute = calendar.isSet(Calendar.MINUTE); + boolean isSetSecond = calendar.isSet(Calendar.SECOND); + boolean isSetMillis = calendar.isSet(Calendar.MILLISECOND); + boolean isSetZone = calendar.isSet(Calendar.ZONE_OFFSET); + boolean isSetDst = calendar.isSet(Calendar.DST_OFFSET); + + if (isSetYear) + { + int y = calendar.get(Calendar.YEAR); + if (isSetEra && calendar instanceof GregorianCalendar) + if (calendar.get(Calendar.ERA) == GregorianCalendar.BC) + y = -y; //1 - y; + _bits |= HAS_YEAR; + _CY = y; + } + if (isSetMonth) + { + _bits |= HAS_MONTH; + _M = calendar.get(Calendar.MONTH) + 1; // !!note + } + if (isSetDay) + { + _bits |= HAS_DAY; + _D = calendar.get(Calendar.DAY_OF_MONTH); + } + boolean gotTime = false; + + int h = 0; + int m = 0; + int s = 0; + BigDecimal fs = _zero; + + if (isSetHourOfDay) + { + h = calendar.get(Calendar.HOUR_OF_DAY); + gotTime = true; + } + else if (isSetHour && isSetAmPm) + { + h = calendar.get(Calendar.HOUR) + calendar.get(Calendar.AM_PM) * 12; + gotTime = true; + } + + if (isSetMinute) + { + m = calendar.get(Calendar.MINUTE); + gotTime = true; + } + + if (isSetSecond) + { + s = calendar.get(Calendar.SECOND); + gotTime = true; + } + + if (isSetMillis) + { + fs = BigDecimal.valueOf(calendar.get(Calendar.MILLISECOND), 3); + gotTime = true; + } + + if (gotTime) + { + _bits |= HAS_TIME; + _h = h; + _m = m; + _s = s; + _fs = fs; + } + + if (isSetZone) + { + int zoneOffsetInMilliseconds = calendar.get(Calendar.ZONE_OFFSET); + if (isSetDst) + zoneOffsetInMilliseconds += calendar.get(Calendar.DST_OFFSET); + + _bits |= HAS_TIMEZONE; + if (zoneOffsetInMilliseconds == 0) + { + _tzsign = 0; + _tzh = 0; + _tzm = 0; + TimeZone zone = calendar.getTimeZone(); + String id = zone.getID(); + if (id != null && id.length() > 3) switch (id.charAt(3)) + { + case '+': _tzsign = 1; break; // GMT+00:00 + case '-': _tzsign = -1; break; // GMT-00:00 + } + } + else + { + _tzsign = (zoneOffsetInMilliseconds < 0 ? -1 : +1); + zoneOffsetInMilliseconds = zoneOffsetInMilliseconds * _tzsign; + _tzh = zoneOffsetInMilliseconds / 3600000; + _tzm = (zoneOffsetInMilliseconds - _tzh * 3600000) / 60000; + } + } + } + + /** + * Constructs a GDate based on another GDateSpecification. + */ + public GDate(GDateSpecification gdate) + { + if (gdate.hasTimeZone()) + { + _bits |= HAS_TIMEZONE; + _tzsign = gdate.getTimeZoneSign(); + _tzh = gdate.getTimeZoneHour(); + _tzm = gdate.getTimeZoneMinute(); + } + + if (gdate.hasTime()) + { + _bits |= HAS_TIME; + _h = gdate.getHour(); + _m = gdate.getMinute(); + _s = gdate.getSecond(); + _fs = gdate.getFraction(); + } + + if (gdate.hasDay()) + { + _bits |= HAS_DAY; + _D = gdate.getDay(); + } + + if (gdate.hasMonth()) + { + _bits |= HAS_MONTH; + _M = gdate.getMonth(); + } + + if (gdate.hasYear()) + { + _bits |= HAS_YEAR; + _CY = gdate.getYear(); + } + } + + /* package */ static final boolean isDigit(char ch) + { + return ((char)(ch - '0') <= '9' - '0'); // char is unsigned + } + + /* package */ static final boolean isSpace(char ch) + { + switch (ch) + { + case ' ': + case '\t': + case '\r': + case '\n': + return true; + default: + return false; + } + } + + /* package */ static final int digitVal(char ch) + { + return (ch - '0'); + } + + private static final int twoDigit(CharSequence str, int index) + { + char ch1 = str.charAt(index); + char ch2 = str.charAt(index + 1); + if (!isDigit(ch1) || !isDigit(ch2)) + return 100; // not two digits + return digitVal(ch1) * 10 + digitVal(ch2); + } + + /** + * Returns true: all GDate instances are immutable. + */ + public final boolean isImmutable() + { + return true; + } + + /** + * Returns a combination of flags indicating the information + * contained by this GDate. The five flags are + * HAS_TIMEZONE, HAS_YEAR, HAS_MONTH, HAS_DAY, and HAS_TIME. + */ + public int getFlags() + { + return _bits; + } + + /** + * True if this date/time specification specifies a timezone. + */ + public final boolean hasTimeZone() + { return ((_bits & HAS_TIMEZONE) != 0); } + + /** + * True if this date/time specification specifies a year. + */ + public final boolean hasYear() + { return ((_bits & HAS_YEAR) != 0); } + + /** + * True if this date/time specification specifies a month-of-year. + */ + public final boolean hasMonth() + { return ((_bits & HAS_MONTH) != 0); } + + /** + * True if this date/time specification specifies a day-of-month. + */ + public final boolean hasDay() + { return ((_bits & HAS_DAY) != 0); } + + /** + * True if this date/time specification specifies a time-of-day. + */ + public final boolean hasTime() + { return ((_bits & HAS_TIME) != 0); } + + /** + * True if this date/time specification specifies a full date (year, month, day) + */ + public final boolean hasDate() + { return ((_bits & (HAS_DAY | HAS_MONTH | HAS_YEAR)) == (HAS_DAY | HAS_MONTH | HAS_YEAR)); } + + /** + * Gets the year. Should be a four-digit year specification. + */ + public final int getYear() + { return _CY; } + + /** + * Gets the month-of-year. January is 1. + */ + public final int getMonth() + { return _M; } + + /** + * Gets the day-of-month. The first day of each month is 1. + */ + public final int getDay() + { return _D; } + + /** + * Gets the hour-of-day. Midnight is 0, and 11PM is 23. + */ + public final int getHour() + { return _h; } + + /** + * Gets the minute-of-hour. Range from 0 to 59. + */ + public final int getMinute() + { return _m; } + + /** + * Gets the second-of-minute. Range from 0 to 59. + */ + public final int getSecond() + { return _s; } + + /** + * Gets the fraction-of-second. Range from 0 (inclusive) to 1 (exclusive). + */ + public final BigDecimal getFraction() + { return _fs; } + + /** + * Gets the time zone sign. For time zones east of GMT, + * this is positive; for time zones west, this is negative. + */ + public final int getTimeZoneSign() + { return _tzsign; } + + /** + * Gets the time zone hour. + * + * This is always positive: for the sign, look at + * getTimeZoneSign(). + */ + public final int getTimeZoneHour() + { return _tzh; } + + /** + * Gets the time zone minutes. + * + * This is always positive: for the sign, look at + * getTimeZoneSign(). + */ + public final int getTimeZoneMinute() + { return _tzm; } + + /** + * Gets the rounded millisecond value. Range from 0 to 999 + */ + public int getMillisecond() + { + if (_fs == null) + return 0; + return _fs.setScale(3, BigDecimal.ROUND_DOWN).unscaledValue().intValue(); + } + + /** + * The canonical string representation. Specific moments or + * times-of-day in a specified timezone are normalized to + * UTC time to produce a canonical string form for them. + * Other recurring time specifications keep their timezone + * information. + */ + public String canonicalString() + { + ensureCanonicalString(); + return _canonicalString; + } + + /** + * True if this GDate corresponds to a valid gregorian date value + * in XML schema. + */ + public boolean isValid() + { + return GDateBuilder.isValidGDate(this); + } + + /** + * Returns the Julian date corresponding to this Gregorian date. + * The Julian date (JD) is a continuous count of days from + * 1 January 4713 BC. + */ + public int getJulianDate() + { + return GDateBuilder.julianDateForGDate(this); + } + + /** + * Retrieves the value of the current time as an {@link XmlCalendar}. + *

    + * {@link XmlCalendar} is a subclass of {@link java.util.GregorianCalendar} + * which is slightly customized to match XML schema date rules. + *

    + * The returned {@link XmlCalendar} has only those time and date fields + * set that are reflected in the GDate object. Because of the way the + * {@link java.util.Calendar} contract works, any information in the isSet() vanishes + * as soon as you view any unset field using get() methods. + * This means that if it is important to understand which date fields + * are set, you must call isSet() first before get(). + */ + public XmlCalendar getCalendar() + { + return new XmlCalendar(this); + } + + + /** + * Retrieves the value of the current time as a java.util.Date + * instance. + */ + public Date getDate() + { + return GDateBuilder.dateForGDate(this); + } + + /** + * Comparison to another GDate. + *

      + *
    • Returns -1 if this < date. (less-than) + *
    • Returns 0 if this == date. (equal) + *
    • Returns 1 if this > date. (greater-than) + *
    • Returns 2 if this <> date. (incomparable) + *
    + * Two instances are incomparable if they have different amounts + * of information. + */ + public int compareToGDate(GDateSpecification datespec) + { + return GDateBuilder.compareGDate(this, datespec); + } + + /** + * Returns the builtin type code for the shape of the information + * contained in this instance, or 0 if the + * instance doesn't contain information corresponding to a + * Schema type. + *

    + * Value will be equal to + * {@link SchemaType#BTC_NOT_BUILTIN}, + * {@link SchemaType#BTC_G_YEAR}, + * {@link SchemaType#BTC_G_YEAR_MONTH}, + * {@link SchemaType#BTC_G_MONTH}, + * {@link SchemaType#BTC_G_MONTH_DAY}, + * {@link SchemaType#BTC_G_DAY}, + * {@link SchemaType#BTC_DATE}, + * {@link SchemaType#BTC_DATE_TIME}, or + * {@link SchemaType#BTC_TIME}. + */ + public int getBuiltinTypeCode() + { + return GDateBuilder.btcForFlags(_bits); + } + + /** + * Adds a duration to this GDate, and returns a new GDate. + */ + public GDate add(GDurationSpecification duration) + { + GDateBuilder builder = new GDateBuilder(this); + builder.addGDuration(duration); + return builder.toGDate(); + } + + /** + * Adds a duration to this GDate, and returns a new GDate. + */ + public GDate subtract(GDurationSpecification duration) + { + GDateBuilder builder = new GDateBuilder(this); + builder.subtractGDuration(duration); + return builder.toGDate(); + } + + /** + * GDate is an immutable class, and equality is computed based + * on its canonical value. + */ + public boolean equals(Object obj) + { + if (obj == this) + return true; + if (!(obj instanceof GDate)) + return false; + + ensureCanonicalString(); + return _canonicalString.equals(((GDate)obj).canonicalString()); + } + + /** + * Returns a hash code for this GDate. + */ + public int hashCode() + { + ensureCanonicalString(); + return _canonicalString.hashCode(); + } + + /** + * The canonical string representation. Specific moments or + * times-of-day in a specified timezone are normalized to + * UTC time to produce a canonical string form for them. + * Other recurring time specifications keep their timezone + * information. + */ + private void ensureCanonicalString() + { + if (_canonicalString != null) + return; + + boolean needNormalize = + (hasTimeZone() && getTimeZoneSign() != 0 && hasTime() && + ((hasDay() == hasMonth() && hasDay() == hasYear()))); + + if (!needNormalize && getFraction() != null && getFraction().scale() > 0) + { + BigInteger bi = getFraction().unscaledValue(); + needNormalize = (bi.mod(GDateBuilder.TEN).signum() == 0); + } + + if (!needNormalize) + _canonicalString = toString(); + else + { + GDateBuilder gdb = new GDateBuilder(this); + gdb.normalize(); + _canonicalString = gdb.toString(); + } + } + + /** + * The natural string representation. This represents the information + * that is available, including timezone. For types that correspond + * to defined schema types (schemaBuiltinTypeCode() > 0), + * this provides the natural lexical representation. + *

    + * When both time and timezone are specified, this string is not + * the canonical representation unless the timezone is UTC (Z) + * (since the same moment in time can be expressed in different + * timezones). To get a canonical string, use the canonicalString() + * method. + */ + public String toString() + { + if (_string == null) + _string = formatGDate(this); + return _string; + } + + private final static char[] _tensDigit = + { + '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', + '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', + '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', + '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', + '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', + '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', + '6', '6', '6', '6', '6', '6', '6', '6', '6', '6', + '7', '7', '7', '7', '7', '7', '7', '7', '7', '7', + '8', '8', '8', '8', '8', '8', '8', '8', '8', '8', + '9', '9', '9', '9', '9', '9', '9', '9', '9', '9', + }; + private final static char[] _onesDigit = + { + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + }; + + private static final int _padTwoAppend(char[] b, int i, int n) + { + assert(n >= 0 && n < 100); + b[i] = _tensDigit[n]; + b[i + 1] = _onesDigit[n]; + return i + 2; + } + + private static final int _padFourAppend(char[] b, int i, int n) + { + if (n < 0) + { + b[i++] = '-'; + n = -n; + } + if (n >= 10000) + { + String s = Integer.toString(n); + s.getChars(0, s.length(), b, i); + return i + s.length(); + } + int q = n / 100; + int r = n - q * 100; + b[i] = _tensDigit[q]; + b[i + 1] = _onesDigit[q]; + b[i + 2] = _tensDigit[r]; + b[i + 3] = _onesDigit[r]; + return i + 4; + } + + private static final TimeZone GMTZONE = TimeZone.getTimeZone("GMT"); + private static final TimeZone[] MINUSZONE = + { + TimeZone.getTimeZone("GMT-00:00"), + TimeZone.getTimeZone("GMT-01:00"), + TimeZone.getTimeZone("GMT-02:00"), + TimeZone.getTimeZone("GMT-03:00"), + TimeZone.getTimeZone("GMT-04:00"), + TimeZone.getTimeZone("GMT-05:00"), + TimeZone.getTimeZone("GMT-06:00"), + TimeZone.getTimeZone("GMT-07:00"), + TimeZone.getTimeZone("GMT-08:00"), + TimeZone.getTimeZone("GMT-09:00"), + TimeZone.getTimeZone("GMT-10:00"), + TimeZone.getTimeZone("GMT-11:00"), + TimeZone.getTimeZone("GMT-12:00"), + TimeZone.getTimeZone("GMT-13:00"), + TimeZone.getTimeZone("GMT-14:00"), + }; + private static final TimeZone[] PLUSZONE = + { + TimeZone.getTimeZone("GMT+00:00"), + TimeZone.getTimeZone("GMT+01:00"), + TimeZone.getTimeZone("GMT+02:00"), + TimeZone.getTimeZone("GMT+03:00"), + TimeZone.getTimeZone("GMT+04:00"), + TimeZone.getTimeZone("GMT+05:00"), + TimeZone.getTimeZone("GMT+06:00"), + TimeZone.getTimeZone("GMT+07:00"), + TimeZone.getTimeZone("GMT+08:00"), + TimeZone.getTimeZone("GMT+09:00"), + TimeZone.getTimeZone("GMT+10:00"), + TimeZone.getTimeZone("GMT+11:00"), + TimeZone.getTimeZone("GMT+12:00"), + TimeZone.getTimeZone("GMT+13:00"), + TimeZone.getTimeZone("GMT+14:00"), + }; + + /* package */ static final TimeZone timeZoneForGDate(GDateSpecification date) + { + // use a cached timezone if integral; otherwise make a new one. + if (!date.hasTimeZone()) + return TimeZone.getDefault(); + if (date.getTimeZoneSign() == 0) + return GMTZONE; + if (date.getTimeZoneMinute() == 0 && date.getTimeZoneHour() <= 14 && date.getTimeZoneHour() >= 0) + return date.getTimeZoneSign() < 0 ? MINUSZONE[date.getTimeZoneHour()] : PLUSZONE[date.getTimeZoneHour()]; + + char[] zb = new char[9]; + zb[0] = 'G'; + zb[1] = 'M'; + zb[2] = 'T'; + zb[3] = (date.getTimeZoneSign() < 0) ? '-' : '+'; + GDate._padTwoAppend(zb, 4, date.getTimeZoneHour()); + zb[6] = ':'; + GDate._padTwoAppend(zb, 7, date.getTimeZoneMinute()); + return TimeZone.getTimeZone(new String(zb)); + } + + /* package */ static String formatGDate(GDateSpecification spec) + { + // We've used a char[] rather than a StringBuffer for a 4x speedup + // -YY(10)YY-MM-DDTHH:MM:SS.FFFFFF+ZH:ZM + // 1 + 10 + 3+ 3+ 3+ 3+ 3+1 + s + 3+ 3 = 33 + s + BigDecimal fs = spec.getFraction(); + char[] message = new char[33 + (fs == null ? 0 : fs.scale())]; + int i = 0; + + if (spec.hasYear() || spec.hasMonth() || spec.hasDay()) + { + dmy: { + if (spec.hasYear()) + i = _padFourAppend(message, 0, spec.getYear()); + else + message[i++] = '-'; + + if (!(spec.hasMonth() || spec.hasDay())) + break dmy; + + message[i++] = '-'; + if (spec.hasMonth()) + i = _padTwoAppend(message, i, spec.getMonth()); + + if (!spec.hasDay()) + break dmy; + + message[i++] = '-'; + i = _padTwoAppend(message, i, spec.getDay()); + break dmy; + } + if (spec.hasTime()) + message[i++] = 'T'; + } + + if (spec.hasTime()) + { + i = _padTwoAppend(message, i, spec.getHour()); + message[i++] = ':'; + i = _padTwoAppend(message, i, spec.getMinute()); + message[i++] = ':'; + i = _padTwoAppend(message, i, spec.getSecond()); + if (fs != _zero) // (optimization ~3%) + { + String frac = fs.toString(); + int point = frac.indexOf('.'); + if (point >= 0) + { + frac.getChars(point, frac.length(), message, i); + i += frac.length() - point; + } + } + } + + if (spec.hasTimeZone()) + { + if (spec.getTimeZoneSign() == 0) + { + message[i++] = 'Z'; + } + else + { + message[i++] = spec.getTimeZoneSign() > 0 ? '+' : '-'; + i = _padTwoAppend(message, i, spec.getTimeZoneHour()); + message[i++] = ':'; + i = _padTwoAppend(message, i, spec.getTimeZoneMinute()); + } + } + + // it would be nice to use (0, i, message) ctor instead + return new String(message, 0, i); + } + +} + diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/GDateBuilder.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/GDateBuilder.java new file mode 100644 index 000000000..53fdcbe8d --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/GDateBuilder.java @@ -0,0 +1,1503 @@ +/* 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; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.Calendar; +import java.util.Date; +import java.util.TimeZone; + +/** + * Used to build {@link GDate GDates}. + *

    + * Like GDate, a GDateBuilder represents an Gregorian Date, Time, + * and Timezone, or subset of information (Year, Month, Day, + * Time, Timezone, or some combination). Wherever it provides + * guidance, the XML Schema 1.0 specification (plus published + * errata) is followed. + *

    + * Instances may separately set or clear the year, month, + * day-of-month, and time-of-day. Not all operations are + * meaningful on all combinations. In particular, timezone + * normalization is only possible if there is a time, or + * a time together with a full date. + */ +public final class GDateBuilder implements GDateSpecification, java.io.Serializable +{ + private static final long serialVersionUID = 1L; + + private int _bits; + private int _CY; + private int _M; + private int _D; + private int _h; + private int _m; + private int _s; + private BigDecimal _fs; + private int _tzsign; + private int _tzh; + private int _tzm; + + /** + * Constructs a GDateBuilder specifying no date or time + */ + public GDateBuilder() + { + } + + /** + * Builds another GDateBuilder with the same value + * as this one. + */ + public Object clone() + { + return new GDateBuilder(this); + } + + /** + * Builds a GDate from this GDateBuilder. + */ + public GDate toGDate() + { + return new GDate(this); + } + + /** + * Construts a GDateBuilder by copying another GDateSpecificaiton. + */ + public GDateBuilder(GDateSpecification gdate) + { + if (gdate.hasTimeZone()) + setTimeZone(gdate.getTimeZoneSign(), gdate.getTimeZoneHour(), gdate.getTimeZoneMinute()); + + if (gdate.hasTime()) + setTime(gdate.getHour(), gdate.getMinute(), gdate.getSecond(), gdate.getFraction()); + + if (gdate.hasDay()) + setDay(gdate.getDay()); + + if (gdate.hasMonth()) + setMonth(gdate.getMonth()); + + if (gdate.hasYear()) + setYear(gdate.getYear()); + } + + // Forms: + + // Date part: + // Year: (-?\d{4,}) + // YearMonth: (-?\d{4,})-(\d{2}) + // Date: (-?\d{4,})-(\d{2})-(\d{2}) + // Month: --(\d{2})(--)? //errata R-48 + // MonthDay: --(\d{2})-(\d{2}) + // Day: ---(\d{2}) + + // Time part: + // Time: (\d{2}):(\d{2}):(\d{2})(.\d*)? + + // Timezone part: + // TZ: (Z)|([+-]\d{2}):(\d{2}) + + /** + * Constructs a GDateBuilder from a lexical + * representation. The lexical space contains the + * union of the lexical spaces of all the schema + * date/time types (except for duration). + */ + public GDateBuilder(CharSequence string) + { + this(new GDate(string)); + } + + + public GDateBuilder(Calendar calendar) + { + this(new GDate(calendar)); + } + + /** + * Constructs a GDateBuilder with the specified year, month, day, + * hours, minutes, seconds, and optional fractional seconds, in + * an unspecified timezone. + *

    + * Note that by not specifying the timezone the GDateBuilder + * becomes partially unordered with respect to timesthat do have a + * specified timezone. + * + * @param year The year + * @param month The month, from 1-12 + * @param day The day of month, from 1-31 + * @param hour The hour of day, from 0-23 + * @param minute The minute of hour, from 0-59 + * @param second The second of minute, from 0-59 + * @param fraction The fraction of second, 0.0 to 0.999... (may be null) + */ + public GDateBuilder( + int year, + int month, + int day, + int hour, + int minute, + int second, + BigDecimal fraction) + { + _bits = HAS_YEAR | HAS_MONTH | HAS_DAY | HAS_TIME; + + if (year == 0) + throw new IllegalArgumentException(); + + _CY = (year > 0 ? year : year + 1); + _M = month; + _D = day; + _h = hour; + _m = minute; + _s = second; + _fs = fraction == null ? GDate._zero : fraction; + + if (!isValid()) + throw new IllegalArgumentException(); + } + + /** + * Constructs an absolute GDateBuilder with the specified year, + * month, day, hours, minutes, seconds, and optional fractional + * seconds, and in the timezone specified. + *

    + * Note that you can reexpress the GDateBuilder in any timezone using + * normalizeToTimeZone(). The normalize() method normalizes to UTC. + *

    + * If you wish to have a time or date that isn't in a specified timezone, + * then use the constructor that does not include the timezone arguments. + * + * @param year the year + * @param month the month, from 1-12 + * @param day the day of month, from 1-31 + * @param hour the hour of day, from 0-23 + * @param minute the minute of hour, from 0-59 + * @param second the second of minute, from 0-59 + * @param fraction the fraction of second, 0.0 to 0.999... (may be null) + * @param tzSign the timezone offset sign, either +1, 0, or -1 + * @param tzHour the timezone offset hour + * @param tzMinute the timezone offset minute + */ + public GDateBuilder( + int year, + int month, + int day, + int hour, + int minute, + int second, + BigDecimal fraction, + int tzSign, + int tzHour, + int tzMinute) + { + _bits = HAS_TIMEZONE | HAS_YEAR | HAS_MONTH | HAS_DAY | HAS_TIME; + + if (year == 0) + throw new IllegalArgumentException(); + + _CY = (year > 0 ? year : year + 1); + _M = month; + _D = day; + _h = hour; + _m = minute; + _s = second; + _fs = fraction == null ? GDate._zero : fraction; + _tzsign = tzSign; + _tzh = tzHour; + _tzm = tzMinute; + + if (!isValid()) + throw new IllegalArgumentException(); + } + + /** + * Constructs a GDateBuilder based on a java.util.Date. + *

    + * The current offset of the default timezone is used as the timezone. + *

    + * For example, if eastern daylight time is in effect at the given + * date, the timezone on the east coast of the united states + * translates to GMT-05:00 (EST) + 1:00 (DT offset) == GMT-04:00. + * + * @param date the date object to copy + */ + public GDateBuilder(Date date) + { + setDate(date); + } + + /** + * True if the instance is immutable. + */ + public boolean isImmutable() + { + return false; + } + + /** + * Returns a combination of flags indicating the information + * contained by this GDate. The five flags are + * HAS_TIMEZONE, HAS_YEAR, HAS_MONTH, HAS_DAY, and HAS_TIME. + */ + public int getFlags() + { + return _bits; + } + + /** + * True if this date/time specification specifies a timezone. + */ + public final boolean hasTimeZone() + { return ((_bits & HAS_TIMEZONE) != 0); } + + /** + * True if this date/time specification specifies a year. + */ + public final boolean hasYear() + { return ((_bits & HAS_YEAR) != 0); } + + /** + * True if this date/time specification specifies a month-of-year. + */ + public final boolean hasMonth() + { return ((_bits & HAS_MONTH) != 0); } + + /** + * True if this date/time specification specifies a day-of-month. + */ + public final boolean hasDay() + { return ((_bits & HAS_DAY) != 0); } + + /** + * True if this date/time specification specifies a time-of-day. + */ + public final boolean hasTime() + { return ((_bits & HAS_TIME) != 0); } + + /** + * True if this date/time specification specifies a full date (year, month, day) + */ + public final boolean hasDate() + { return ((_bits & (HAS_DAY | HAS_MONTH | HAS_YEAR)) == (HAS_DAY | HAS_MONTH | HAS_YEAR)); } + + /** + * Gets the year. Should be a four-digit year specification. + */ + public final int getYear() + { return (_CY > 0 ? _CY : _CY - 1); } + + /** + * Gets the month-of-year. January is 1. + */ + public final int getMonth() + { return _M; } + + /** + * Gets the day-of-month. The first day of each month is 1. + */ + public final int getDay() + { return _D; } + + /** + * Gets the hour-of-day. Midnight is 0, and 11PM is 23. + */ + public final int getHour() + { return _h; } + + /** + * Gets the minute-of-hour. Range from 0 to 59. + */ + public final int getMinute() + { return _m; } + + /** + * Gets the second-of-minute. Range from 0 to 59. + */ + public final int getSecond() + { return _s; } + + + /** + * Gets the fraction-of-second. Range from 0 (inclusive) to 1 (exclusive). + */ + public final BigDecimal getFraction() + { return _fs; } + + + /** + * Gets the rounded millisecond value. Range from 0 to 999 + */ + public final int getMillisecond() + { + if (_fs == null || _fs == GDate._zero) + return 0; + return _fs.setScale(3, BigDecimal.ROUND_HALF_UP).unscaledValue().intValue(); + } + + /** + * Gets the time zone sign. For time zones east of GMT, + * this is positive; for time zones west, this is negative. + */ + public final int getTimeZoneSign() + { return _tzsign; } + + /** + * Gets the time zone hour. + * This is always positive: for the sign, look at + * getTimeZoneSign(). + */ + public final int getTimeZoneHour() + { return _tzh; } + + /** + * Gets the time zone minutes. + * This is always positive: for the sign, look at + * getTimeZoneSign(). + */ + public final int getTimeZoneMinute() + { return _tzm; } + + + + /** + * Sets the year. Should be a four-digit year specification. + * @param year the year + */ + public void setYear(int year) + { + if (year < GDate.MIN_YEAR || year > GDate.MAX_YEAR) + throw new IllegalArgumentException("year out of range"); + if (year == 0) + throw new IllegalArgumentException("year cannot be 0"); + _bits |= HAS_YEAR; _CY = (year > 0 ? year : year + 1); + } + + /** + * Sets the month-of-year. January is 1. + * @param month the month, from 1-12 + */ + public void setMonth(int month) + { + if (month < 1 || month > 12) + throw new IllegalArgumentException("month out of range"); + _bits |= HAS_MONTH; _M = month; + } + + /** + * Sets the day-of-month. The first day of each month is 1. + * @param day the day of month, from 1-31 + */ + public void setDay(int day) + { + if (day < 1 || day > 31) + throw new IllegalArgumentException("day out of range"); + _bits |= HAS_DAY; _D = day; + } + + /** + * Sets the time. Hours in the day range from 0 to 23; + * minutes and seconds range from 0 to 59; and fractional + * seconds range from 0 (inclusive) to 1 (exclusive). + * The fraction can be null and is assumed to be zero. + * @param hour the hour of day, from 0-23 or 24 only if min, sec and fraction are 0 + * @param minute the minute of hour, from 0-59 + * @param second the second of minute, from 0-59 + * @param fraction the fraction of second, 0.0 to 0.999... (may be null) + */ + public void setTime(int hour, int minute, int second, BigDecimal fraction) + { + if (hour < 0 || hour > 24 ) + throw new IllegalArgumentException("hour out of range"); + if (minute < 0 || minute > 59) + throw new IllegalArgumentException("minute out of range"); + if (second < 0 || second > 59) + throw new IllegalArgumentException("second out of range"); + if (fraction != null && (fraction.signum() < 0 || fraction.compareTo(GDate._one) > 1)) + throw new IllegalArgumentException("fraction out of range"); + if ( hour == 24 && (minute!=0 || second!=0 || (fraction!=null && (GDate._zero.compareTo(fraction)!=0)) )) + throw new IllegalArgumentException("when hour is 24, min sec and fracton must be 0"); + + _bits |= HAS_TIME; + _h = hour; + _m = minute; + _s = second; + _fs = fraction == null ? GDate._zero : fraction; + } + + /** + * Sets the time zone without changing the other time + * fields. If you with to adjust other time fields to express + * the same actual moment in time in a different time zone, + * use normalizeToTimeZone. + *

    + * Timezones must be between -14:00 and +14:00. Sign + * must be -1 or 1 (or 0 for UTC only), and the offset hours + * and minute arguments must be nonnegative. + * + * @param tzSign the timezone offset sign, either +1, 0, or -1 + * @param tzHour the timezone offset hour + * @param tzMinute the timezone offset minute + */ + public void setTimeZone(int tzSign, int tzHour, int tzMinute) + { + if (!((tzSign == 0 && tzHour == 0 && tzMinute == 0) || + ((tzSign == -1 || tzSign == 1) && + (tzHour >= 0 && tzMinute >= 0) && + (tzHour == 14 && tzMinute == 0 || tzHour < 14 && tzMinute < 60)))) + throw new IllegalArgumentException("time zone out of range (-14:00 to +14:00). (" + + (tzSign<0 ? "-" : "+") + tzHour + ":" + tzMinute + ")"); + + _bits |= HAS_TIMEZONE; + _tzsign = tzSign; + _tzh = tzHour; + _tzm = tzMinute; + } + + /** + * Sets the time zone based on a number of offset minutes rather + * than sign/hour/minute; for example, setTimeZone(-60) is the + * same as setTimeZone(-1, 1, 0). + */ + public void setTimeZone(int tzTotalMinutes) + { + if (tzTotalMinutes < -14 * 60 || tzTotalMinutes > 14 * 60) + throw new IllegalArgumentException("time zone out of range (-840 to 840 minutes). (" + tzTotalMinutes + ")"); + + int tzSign = tzTotalMinutes < 0 ? -1 : tzTotalMinutes > 0 ? 1 : 0; + tzTotalMinutes *= tzSign; + int tzH = tzTotalMinutes / 60; + int tzM = tzTotalMinutes - tzH * 60; + + setTimeZone(tzSign, tzH, tzM); + } + + /** + * Clears the year. After clearing, hasYear returns false and the + * value of getYear is undefined. + */ + public void clearYear() + { _bits &= ~HAS_YEAR; _CY = 0; } + + /** + * Clears the month-of-year. After clearing. hasMonth returns false and + * the value of getMonth is undefined. + */ + public void clearMonth() + { _bits &= ~HAS_MONTH; _M = 0; } + + /** + * Clears the day-of-month. After clearing. hasDay returns false and + * the value of getDay is undefined. + */ + public void clearDay() + { _bits &= ~HAS_DAY; _D = 0; } + + /** + * Clears the time-of-day. + * After clearing. hasTime returns false and + * the value of getTime is undefined. + */ + public void clearTime() + { + _bits &= ~HAS_TIME; + _h = 0; + _m = 0; + _s = 0; + _fs = null; + } + + /** + * Clears the timezone. After clearing. hasTimeZone returns false and + * the value of getTimeZoneHour and getTimeZoneMinute are undefined. + * Does not change the other time fields. + */ + public void clearTimeZone() + { + _bits &= ~HAS_TIMEZONE; + _tzsign = 0; + _tzh = 0; + _tzm = 0; + } + + /** + * True if all date fields lie within their legal ranges. A GDateBuilder + * can be invalid, for example, if you change the month to February + * and the day-of-month is 31. + */ + public boolean isValid() + { + return isValidGDate(this); + } + + /* package */ static final boolean isValidGDate(GDateSpecification date) + { + if (date.hasYear() && date.getYear() == 0) + return false; + + if (date.hasMonth() && (date.getMonth() < 1 || date.getMonth() > 12)) + return false; + + if (date.hasDay() && + (date.getDay() < 1 || date.getDay() > 31 || + date.getDay() > 28 && + date.hasMonth() && + (date.hasYear() ? + date.getDay() > _maxDayInMonthFor((date.getYear() > 0 ? + date.getYear() : + date.getYear() + 1), + date.getMonth()) : + date.getDay() > _maxDayInMonth(date.getMonth())))) + return false; + + if (date.hasTime() && ((date.getHour() < 0 || date.getHour() > 23 || + date.getMinute() < 0 || date.getMinute() > 59 || + date.getSecond() < 0 || date.getSecond() > 59 || + date.getFraction().signum() < 0 || date.getFraction().compareTo(GDate._one) >= 0) ) && + // check for 24:00:00 valid format + !(date.getHour() == 24 && date.getMinute() == 0 && date.getSecond() == 0 && + date.getFraction().compareTo(GDate._zero) == 0 ) ) + return false; + + if (date.hasTimeZone() && + (!((date.getTimeZoneSign() == 0 && date.getTimeZoneHour() == 0 && date.getTimeZoneMinute() == 0) || + ((date.getTimeZoneSign() == -1 || date.getTimeZoneSign() == +1) && + // NB: allow +00:00 and -00:00 + // (date.getTimeZoneHour() == 0 && date.getTimeZoneMinute() > 0 || date.getTimeZoneHour() > 0 && date.getTimeZoneMinute() >= 0) && + (date.getTimeZoneHour() >= 0 && date.getTimeZoneMinute() >= 0) && + (date.getTimeZoneHour() == 14 && date.getTimeZoneMinute() == 0 || date.getTimeZoneHour() < 14 && date.getTimeZoneMinute() < 60))))) + return false; + + // everyting looks kosher + return true; + } + + + /** + * Normalizes the instance, ensuring date and time fields are within + * their normal ranges. + *

    + * If no timezone or no time is specified, or if a partial date is specified, this + * method does nothing, and leaves the timezone information as-is. + *

    + * If a time or time and date is specified, this method normalizes the timezone + * to UTC. + */ + public void normalize() + { + // DateTime or Time, with TimeZone: normalize to UTC. + // In the process all the fields will be normalized. + if (hasDay() == hasMonth() && hasDay() == hasYear() && + hasTimeZone() && hasTime() ) + { + normalizeToTimeZone(0, 0, 0); + } + else + { + // No timezone, or incomplete date. + _normalizeTimeAndDate(); + } + + // remove trailing zeros from fractional seconds + if (hasTime() && _fs != null && _fs.scale() > 0) + { + if (_fs.signum() == 0) + _fs = GDate._zero; + else + { + BigInteger bi = _fs.unscaledValue(); + String str = bi.toString(); + int lastzero; + for (lastzero = str.length(); lastzero > 0; lastzero -= 1) + if (str.charAt(lastzero - 1) != '0') + break; + if (lastzero < str.length()) + _fs = _fs.setScale(_fs.scale() - str.length() + lastzero); + } + } + } + + /** + * Normalizes the instance when hour is 24. If day is present, hour 24 is equivalent to hour 00 next day. + */ + void normalize24h() + { + if ( !hasTime() || getHour()!=24 ) + return; + + _normalizeTimeAndDate(); + } + + + private void _normalizeTimeAndDate() + { + long carry = 0; + + if (hasTime()) + carry = _normalizeTime(); + + if (hasDay()) + _D += carry; + + if (hasDate()) + { + _normalizeDate(); + } + else if (hasMonth()) + { + // with incomplete dates, just months can be normalized: + // days stay denormalized. + if (_M < 1 || _M > 12) + { + int temp = _M; + _M = _modulo(temp, 1, 13); + if (hasYear()) + _CY = _CY + (int)_fQuotient(temp, 1, 13); + } + } + } + + /** + * If the time and timezone are known, this method changes the timezone to the + * specified UTC offset, altering minutes, hours, day, month, and year as + * necessary to ensure that the actual described moment in time is the same. + *

    + * It is an error to operate on instances without a time or timezone, or + * with a partially specified date. + * + * @param tzSign the timezone offset sign, either +1, 0, or -1 + * @param tzHour the timezone offset hour + * @param tzMinute the timezone offset minute + */ + public void normalizeToTimeZone(int tzSign, int tzHour, int tzMinute) + { + if (!((tzSign == 0 && tzHour == 0 && tzMinute == 0) || + ((tzSign == -1 || tzSign == 1) && + (tzHour >= 0 && tzMinute >= 0) && + (tzHour == 14 && tzMinute == 0 || tzHour < 14 && tzMinute < 60)))) + throw new IllegalArgumentException("time zone must be between -14:00 and +14:00"); + + if (!hasTimeZone() || !hasTime()) + throw new IllegalStateException("cannot normalize time zone without both time and timezone"); + + if (!(hasDay() == hasMonth() && hasDay() == hasYear())) + throw new IllegalStateException("cannot do date math without a complete date"); + + int hshift = tzSign * tzHour - _tzsign * _tzh; + int mshift = tzSign * tzMinute - _tzsign * _tzm; + + _tzsign = tzSign; + _tzh = tzHour; + _tzm = tzMinute; + addDuration(1, 0, 0, 0, hshift, mshift, 0, null); + } + + /** + * Normalizes to a time zone specified by a number of offset minutes rather + * than sign/hour/minute; for example, normalizeToTimeZone(-60) is the + * same as normalizeToTimeZone(-1, 1, 0). + */ + public void normalizeToTimeZone(int tzTotalMinutes) + { + if (tzTotalMinutes < -14 * 60 || tzTotalMinutes > 14 * 60) + throw new IllegalArgumentException("time zone out of range (-840 to 840 minutes). (" + tzTotalMinutes + ")"); + + int tzSign = tzTotalMinutes < 0 ? -1 : tzTotalMinutes > 0 ? 1 : 0; + tzTotalMinutes *= tzSign; + int tzH = tzTotalMinutes / 60; + int tzM = tzTotalMinutes - tzH * 60; + + normalizeToTimeZone(tzSign, tzH, tzM); + } + + + /** + * Adds a given duration to the date/time. + * + * @param duration the duration to add + */ + public void addGDuration(GDurationSpecification duration) + { + addDuration(duration.getSign(), duration.getYear(), duration.getMonth(), duration.getDay(), + duration.getHour(), duration.getMinute(), duration.getSecond(), duration.getFraction()); + } + + /** + * Subtracts a given duration from the date/time. + * + * @param duration the duration to subtract + */ + public void subtractGDuration(GDurationSpecification duration) + { + addDuration(-duration.getSign(), duration.getYear(), duration.getMonth(), duration.getDay(), + duration.getHour(), duration.getMinute(), duration.getSecond(), duration.getFraction()); + } + + + /** + * Normalizes the date by carrying over to the year any months outside 1..12 + * and carrying over to the month any days outside 1..(days-in-month). + */ + private void _normalizeDate() + { + if (_M < 1 || _M > 12 || _D < 1 || _D > _maxDayInMonthFor(_CY, _M)) + { + // fix months first + int temp = _M; + _M = _modulo(temp, 1, 13); + _CY = _CY + (int)_fQuotient(temp, 1, 13); + + // then pull days out + int extradays = _D - 1; + _D = 1; + + // then use the julian date function to fix + setJulianDate(getJulianDate() + extradays); + } + } + + /** + * Normalizes time so that fractions are 0..1(exc), seconds/minutes 0..59, + * and hours 0..24. Returns the number of days to carry over from normalizing + * away more than 24 hours. + */ + private long _normalizeTime() + { + long carry = 0; + long temp; + + // fractions + if (_fs != null && (_fs.signum() < 0 || _fs.compareTo(GDate._one) >= 0)) + { + BigDecimal bdcarry = _fs.setScale(0, BigDecimal.ROUND_FLOOR); + _fs = _fs.subtract(bdcarry); + carry = bdcarry.longValue(); + } + + if (carry != 0 || _s < 0 || _s > 59 || _m < 0 || _m > 50 || _h < 0 || _h > 23) + { + // seconds + temp = _s + carry; + carry = _fQuotient(temp, 60); + _s = _mod(temp, 60, carry); + + // minutes + temp = _m + carry; + carry = _fQuotient(temp, 60); + _m = _mod(temp, 60, carry); + + // hours + temp = _h + carry; + carry = _fQuotient(temp, 24); + _h = _mod(temp, 24, carry); + } + + return carry; + } + + /** + * Adds a given duration to the date/time. + * + * @param sign +1 to add, -1 to subtract + * @param year the number of years to add + * @param month the number of months to add + * @param day the number of days to add + * @param hour the number of hours to add + * @param minute the number of minutes to add + * @param second the number of seconds to add + * @param fraction the number of fractional seconds to add (may be null) + */ + public void addDuration(int sign, int year, int month, int day, + int hour, int minute, int second, BigDecimal fraction) + { + boolean timemath = hour != 0 || minute != 0 || second != 0 || fraction != null && fraction.signum() != 0; + if (timemath && !hasTime()) + throw new IllegalStateException("cannot do time math without a complete time"); + boolean datemath = hasDay() && (day != 0 || timemath); + if (datemath && !hasDate()) + throw new IllegalStateException("cannot do date math without a complete date"); + + int temp; + + // months + years are easy + if (month != 0 || year != 0) + { + // Prepare the _D to be pegged before changing month + if (hasDay()) + _normalizeDate(); + + // Add months and years + temp = _M + sign * month; + _M = _modulo(temp, 1, 13); + _CY = _CY + sign * year + (int)_fQuotient(temp, 1, 13); + + // In new month, day may need to be pegged before proceeding + if (hasDay()) + { + assert(_D >= 1); + temp = _maxDayInMonthFor(_CY, _M); + if (_D > temp) + _D = temp; + } + } + + long carry = 0; + + if (timemath) + { + // fractions + if (fraction != null && fraction.signum() != 0) + { + if (_fs.signum() == 0 && sign == 1) + _fs = fraction; + else + _fs = (sign == 1) ? _fs.add(fraction) : _fs.subtract(fraction); + } + + // seconds, minutes, hours + _s += sign * second; + _m += sign * minute; + _h += sign * hour; + + // normalize time + carry = _normalizeTime(); + } + + if (datemath) + { + // days: may require renormalization + _D += sign * day + carry; + _normalizeDate(); + } + } + + /** + * Given {year,month} computes maximum + * number of days for given month + */ + private static int _maxDayInMonthFor(int year, int month) + { + if (month == 4 || month == 6 || month == 9 || month == 11) + return 30; + + if (month == 2) + return (_isLeapYear(year) ? 29 : 28); + + return 31; + } + + /** + * Given {year,month} computes maximum + * number of days for given month + */ + private static int _maxDayInMonth(int month) + { + if (month == 4 || month == 6 || month == 9 || month == 11) + return 30; + + if (month == 2) + return 29; + + return 31; + } + + /** + * Returns the Julian date corresponding to this Gregorian date. + * The Julian date (JD) is a continuous count of days from + * 1 January 4713 BC. + */ + public final int getJulianDate() + { + return julianDateForGDate(this); + } + + + /** + * Sets the Gregorian date based on the given Julian date. + * The Julian date (JD) is a continuous count of days from + * 1 January 4713 BC. + * + * @param julianday the julian day number + */ + public void setJulianDate(int julianday) + { + if (julianday < 0) + throw new IllegalArgumentException("date before year -4713"); + + int temp; + int qepoc; + + // from http://aa.usno.navy.mil/faq/docs/JD_Formula.html + temp = julianday + 68569; + qepoc = 4 * temp / 146097; + temp = temp - (146097 * qepoc + 3) / 4; + _CY = 4000 * (temp + 1) / 1461001; + temp = temp - 1461 * _CY / 4 + 31; + _M = 80 * temp / 2447; + _D = temp - 2447 * _M / 80; + temp = _M / 11; + _M = _M + 2 - 12 * temp; + _CY = 100 * (qepoc - 49) + _CY + temp; + + _bits |= HAS_DAY | HAS_MONTH | HAS_YEAR; + } + + + /** + * Sets the current time and date based on a java.util.Date instance. + *

    + * The timezone offset used is based on the default TimeZone. (The + * default TimeZone is consulted to incorporate daylight savings offsets + * if applicable for the current date as well as the base timezone offset.) + *

    + * If you wish to normalize the timezone, e.g., to UTC, follow this with + * a call to normalizeToTimeZone. + * + * @param date the Date object to copy + */ + public void setDate(Date date) + { + // Default timezone + TimeZone dtz = TimeZone.getDefault(); + int offset = dtz.getOffset(date.getTime()); + int offsetsign = 1; + if (offset < 0) + { + offsetsign = -1; + offset = -offset; + } + int offsetmin = offset / (1000 * 60); + int offsethr = offsetmin / 60; + offsetmin = offsetmin - offsethr * 60; + + setTimeZone(offsetsign, offsethr, offsetmin); + + // paranoia: tz.getOffset can return fractions of minutes, but we must round + int roundedoffset = offsetsign * (offsethr * 60 + offsetmin) * 60 * 1000; + + // midnight + setTime(0, 0, 0, GDate._zero); + + // Set to January 1, 1970. + // setJulianDate(2440588); + _bits |= HAS_DAY | HAS_MONTH | HAS_YEAR; + _CY = 1970; + _M = 1; + _D = 1; + + // Add a duration representing the number of milliseconds + addGDuration(new GDuration(1, 0, 0, 0, 0, 0, 0, + BigDecimal.valueOf(date.getTime() + roundedoffset, 3))); + + // special case: ss.000 -> ss + if (_fs.signum() == 0) + _fs = GDate._zero; + } + + /** + * Copies a GDateSpecification, completely replacing the current + * information in this GDateBuilder. + * + * @param gdate the GDateSpecification to copy + */ + public void setGDate(GDateSpecification gdate) + { + _bits = gdate.getFlags() & (HAS_TIMEZONE | HAS_YEAR | HAS_MONTH | HAS_DAY | HAS_TIME); + int year = gdate.getYear(); + _CY = (year > 0 ? year : year + 1); + _M = gdate.getMonth(); + _D = gdate.getDay(); + _h = gdate.getHour(); + _m = gdate.getMinute(); + _s = gdate.getSecond(); + _fs = gdate.getFraction(); + _tzsign = gdate.getTimeZoneSign(); + _tzh = gdate.getTimeZoneHour(); + _tzm = gdate.getTimeZoneMinute(); + } + + + /** + * Retrieves the value of the current time as an {@link XmlCalendar}. + *

    + * {@link XmlCalendar} is a subclass of {@link java.util.GregorianCalendar} + * which is slightly customized to match XML schema date rules. + *

    + * The returned {@link XmlCalendar} has only those time and date fields + * set that are reflected in the GDate object. Because of the way the + * {@link java.util.Calendar} contract works, any information in the isSet() vanishes + * as soon as you view any unset field using get() methods. + * This means that if it is important to understand which date fields + * are set, you must call isSet() first before get(). + */ + public XmlCalendar getCalendar() + { + return new XmlCalendar(this); + } + + /** + * Retrieves the value of the current time as a java.util.Date + * instance. + */ + public Date getDate() + { + return dateForGDate(this); + } + + /* package */ static int julianDateForGDate(GDateSpecification date) + { + if (!date.hasDate()) + throw new IllegalStateException("cannot do date math without a complete date"); + + // from http://aa.usno.navy.mil/faq/docs/JD_Formula.html + int day = date.getDay(); + int month = date.getMonth(); + int year = date.getYear(); + year = (year > 0 ? year : year + 1); + int result = day-32075+1461*(year+4800+(month-14)/12)/4+ + 367*(month-2-(month-14)/12*12)/12-3*((year+4900+(month-14)/12)/100)/4; + + if (result < 0) + throw new IllegalStateException("date too far in the past (year allowed to -4713)"); + + return result; + } + + /* package */ static Date dateForGDate(GDateSpecification date) + { + long jDate = julianDateForGDate(date); + long to1970Date = jDate - 2440588; + long to1970Ms = 1000 * 60 * 60 * 24 * to1970Date; + + to1970Ms += date.getMillisecond(); + to1970Ms += date.getSecond() * 1000; + to1970Ms += date.getMinute() * 60 * 1000; + to1970Ms += date.getHour() * 60 * 60 * 1000; + if (date.hasTimeZone()) + { + to1970Ms -= (date.getTimeZoneMinute() * date.getTimeZoneSign()) * 60 * 1000; + to1970Ms -= (date.getTimeZoneHour() * date.getTimeZoneSign()) * 60 * 60 * 1000; + } + else + { + TimeZone def = TimeZone.getDefault(); + int offset = def.getOffset(to1970Ms); + to1970Ms -= offset; + } + + return new Date(to1970Ms); + } + + /** + * True for leap years. + */ + private static boolean _isLeapYear(int year) + { + // BUGBUG: Julian calendar? + return ((year % 4 == 0) && ((year % 100 != 0) || (year % 400 == 0))); + } + + /** + * fQuotient(a, b) = the greatest integer less than or equal to a/b + */ + private static final long _fQuotient(long a, int b) + { + if ((a < 0) == (b < 0)) + return a / b; + + return -((b - a - 1) / b); + } + + /** + * modulo(a, b) = a - fQuotient(a,b)*b + */ + private static int _mod(long a, int b, long quotient) + { + return (int)(a - quotient*b) ; + } + + /** + * modulo(a - low, high - low) + low + */ + private static final int _modulo(long temp, int low, int high) + { + long a = temp - low; + int b = high - low; + return (_mod(a, b, _fQuotient(a, b)) + low) ; + } + + /** + * Quotient(a - low, high - low) + */ + private static final long _fQuotient(long temp, int low, int high) + { + return _fQuotient(temp - low, high - low); + } + + /** + * Sets to the first possible moment that matches the given + * specification. + */ + private void _setToFirstMoment() + { + // 1584 was the first leap year during which the Gregorian + // calendar was in use: seems like the most reasonable "first" + // year to use in absence of a year. + + if (!hasYear()) + setYear(1584); + + if (!hasMonth()) + setMonth(1); + + if (!hasDay()) + setDay(1); + + if (!hasTime()) + setTime(0, 0, 0, GDate._zero); + } + + /** + * Comparison to another GDate. + *

      + *
    • Returns -1 if this < date. (less-than) + *
    • Returns 0 if this == date. (equal) + *
    • Returns 1 if this > date. (greater-than) + *
    • Returns 2 if this <> date. (incomparable) + *
    + * Two instances are incomparable if they have different amounts + * of information. + * + * @param datespec the date to compare against + */ + public final int compareToGDate(GDateSpecification datespec) + { + return compareGDate(this, datespec); + } + + + /* package */ static final int compareGDate(GDateSpecification tdate, GDateSpecification datespec) + { + // same amount of information: looks good + int bitdiff = tdate.getFlags() ^ datespec.getFlags(); + + easy: if ((bitdiff & (HAS_YEAR | HAS_MONTH | HAS_DAY | HAS_TIME | HAS_TIMEZONE)) == 0) + { + // If the other date needs to be normalized to + // our timezone, make a clone and do so if possible + if (tdate.hasTimeZone() && + (datespec.getTimeZoneHour() != tdate.getTimeZoneHour() || + datespec.getTimeZoneMinute() != tdate.getTimeZoneMinute() || + datespec.getTimeZoneSign() != tdate.getTimeZoneSign())) + { + datespec = new GDateBuilder(datespec); + + int flags = tdate.getFlags() & (HAS_YEAR | HAS_MONTH | HAS_DAY); + if (flags != 0 && flags != (HAS_YEAR | HAS_MONTH | HAS_DAY) || !tdate.hasTime()) + { + // in these cases we'll need to fill in fields + ((GDateBuilder)datespec)._setToFirstMoment(); + tdate = new GDateBuilder(tdate); + ((GDateBuilder)tdate)._setToFirstMoment(); + } + + ((GDateBuilder)datespec).normalizeToTimeZone(tdate.getTimeZoneSign(), tdate.getTimeZoneHour(), tdate.getTimeZoneMinute()); + } + + // compare by field + return fieldwiseCompare(tdate, datespec); + } + + // different amounts of information (except timezone): not comparable + if ((bitdiff & (HAS_YEAR | HAS_MONTH | HAS_DAY | HAS_TIME)) != 0) + return 2; + + // The schema spec says we should try to compare with-timezone and + // without-timezone specifications... Well, OK, sure, if they say so. + + // We don't have a timezone but the other does: reverse the call + if (!tdate.hasTimeZone()) + { + int result = compareGDate(datespec, tdate); + return result == 2 ? 2 : -result; + } + + // Now tdate is guaranteed to have a timezone and datespec not. + + // To muck with the times, make clones + GDateBuilder pdate = new GDateBuilder(tdate); + + // To cover the one uncovered case: if one date is 02/28 and the + // other date is 03/01, shift days closer by one to simulate being + // the last day of the month within a leap year + if ((tdate.getFlags() & (HAS_YEAR | HAS_MONTH | HAS_DAY)) == (HAS_MONTH | HAS_DAY)) + { + if (tdate.getDay() == 28 && tdate.getMonth() == 2) + { + if (datespec.getDay() == 01 && datespec.getMonth() == 3) + { + pdate.setDay(29); + } + } + else if (datespec.getDay() == 28 && datespec.getMonth() == 2) + { + if (tdate.getDay() == 01 && tdate.getMonth() == 3) + { + pdate.setMonth(02); + pdate.setDay(29); + } + } + } + + // For timespans, compare by first instant of time + // possible. Therefore, fill in Midnight, January 1, 1584 (a leap year) + // in absence of other information. + pdate._setToFirstMoment(); + + // P < Q if P < (Q with time zone +14:00) + GDateBuilder qplusdate = new GDateBuilder(datespec); + qplusdate._setToFirstMoment(); + qplusdate.setTimeZone(1, 14, 0); + qplusdate.normalizeToTimeZone(tdate.getTimeZoneSign(), tdate.getTimeZoneHour(), tdate.getTimeZoneMinute()); + if (fieldwiseCompare(pdate, qplusdate) == -1) + return -1; + + // P > Q if P > (Q with time zone -14:00) + GDateBuilder qminusdate = qplusdate; + qminusdate.setGDate(datespec); + qminusdate._setToFirstMoment(); + qminusdate.setTimeZone(-1, 14, 0); + qminusdate.normalizeToTimeZone(tdate.getTimeZoneSign(), tdate.getTimeZoneHour(), tdate.getTimeZoneMinute()); + if (fieldwiseCompare(pdate, qminusdate) == 1) + return 1; + + // P <> Q otherwise + return 2; + } + + /** + * Does a simple most-significant-digit-first comparison, + * ignoring any timezone or has/doesn't have issues. + * The data must have been digested first. + */ + private static int fieldwiseCompare(GDateSpecification tdate, GDateSpecification date) + { + if (tdate.hasYear()) + { + int CY = date.getYear(); + int TCY = tdate.getYear(); + if (TCY < CY) return -1; + if (TCY > CY) return 1; + } + if (tdate.hasMonth()) + { + int M = date.getMonth(); + int TM = tdate.getMonth(); + if (TM < M) return -1; + if (TM > M) return 1; + } + if (tdate.hasDay()) + { + int D = date.getDay(); + int TD = tdate.getDay(); + if (TD < D) return -1; + if (TD > D) return 1; + } + if (tdate.hasTime()) + { + int h = date.getHour(); + int th = tdate.getHour(); + if (th < h) return -1; + if (th > h) return 1; + int m = date.getMinute(); + int tm = tdate.getMinute(); + if (tm < m) return -1; + if (tm > m) return 1; + int s = date.getSecond(); + int ts = tdate.getSecond(); + if (ts < s) return -1; + if (ts > s) return 1; + BigDecimal fs = date.getFraction(); + BigDecimal tfs = tdate.getFraction(); + if (tfs == null && fs == null) return 0; + return (tfs == null ? GDate._zero : tfs).compareTo(fs == null ? GDate._zero : fs); + } + + return 0; + } + + /** + * Returns the builtin type code for the shape of the information + * contained in this instance, or 0 if the + * instance doesn't contain information corresponding to a + * Schema type. + *

    + * Value will be equal to + * {@link SchemaType#BTC_NOT_BUILTIN}, + * {@link SchemaType#BTC_G_YEAR}, + * {@link SchemaType#BTC_G_YEAR_MONTH}, + * {@link SchemaType#BTC_G_MONTH}, + * {@link SchemaType#BTC_G_MONTH_DAY}, + * {@link SchemaType#BTC_G_DAY}, + * {@link SchemaType#BTC_DATE}, + * {@link SchemaType#BTC_DATE_TIME}, or + * {@link SchemaType#BTC_TIME}. + */ + public final int getBuiltinTypeCode() + { + return btcForFlags(_bits); + } + + /* package */ static int btcForFlags(int flags) + { + switch (flags & (HAS_YEAR | HAS_MONTH | HAS_DAY | HAS_TIME)) + { + case HAS_YEAR: + return SchemaType.BTC_G_YEAR; + case HAS_YEAR | HAS_MONTH: + return SchemaType.BTC_G_YEAR_MONTH; + case HAS_MONTH: + return SchemaType.BTC_G_MONTH; + case HAS_MONTH | HAS_DAY: + return SchemaType.BTC_G_MONTH_DAY; + case HAS_DAY: + return SchemaType.BTC_G_DAY; + case HAS_YEAR | HAS_MONTH | HAS_DAY: + return SchemaType.BTC_DATE; + case HAS_YEAR | HAS_MONTH | HAS_DAY | HAS_TIME: + return SchemaType.BTC_DATE_TIME; + case HAS_TIME: + return SchemaType.BTC_TIME; + default: + return SchemaType.BTC_NOT_BUILTIN; + } + } + + /** + * Clears the fields in this GDateBuilder that are not applicable + * for the given SchemaType date code. The code should be + * {@link SchemaType#BTC_G_YEAR}, + * {@link SchemaType#BTC_G_YEAR_MONTH}, + * {@link SchemaType#BTC_G_MONTH}, + * {@link SchemaType#BTC_G_MONTH_DAY}, + * {@link SchemaType#BTC_G_DAY}, + * {@link SchemaType#BTC_DATE}, + * {@link SchemaType#BTC_DATE_TIME}, or + * {@link SchemaType#BTC_TIME}. + * + * @param typeCode the type code to apply + */ + public void setBuiltinTypeCode(int typeCode) + { + switch (typeCode) + { + case SchemaType.BTC_G_YEAR: + //HAS_YEAR + clearMonth(); + clearDay(); + clearTime(); + return; + case SchemaType.BTC_G_YEAR_MONTH: + //HAS_YEAR | HAS_MONTH + clearDay(); + clearTime(); + return; + case SchemaType.BTC_G_MONTH: + //HAS_MONTH + clearYear(); + clearDay(); + clearTime(); + return; + case SchemaType.BTC_G_MONTH_DAY: + //HAS_MONTH | HAS_DAY + clearYear(); + clearTime(); + return; + case SchemaType.BTC_G_DAY: + //HAS_DAY + clearYear(); + clearMonth(); + clearTime(); + return; + case SchemaType.BTC_DATE: + //HAS_YEAR | HAS_MONTH | HAS_DAY + clearTime(); + return; + case SchemaType.BTC_DATE_TIME: + //HAS_YEAR | HAS_MONTH | HAS_DAY | HAS_TIME + return; + case SchemaType.BTC_TIME: + //HAS_TIME + clearYear(); + clearMonth(); + clearDay(); + return; + default: + throw new IllegalArgumentException("codeType must be one of SchemaType BTC_ DATE TIME related types."); + } + } + + + /* package */ static final BigInteger TEN = BigInteger.valueOf(10); + + /** + * The canonical string representation. Specific moments or + * times-of-day in a specified timezone are normalized to + * UTC time to produce a canonical string form for them. + * Other recurring time specifications keep their timezone + * information. + */ + public String canonicalString() + { + boolean needNormalize = + (hasTimeZone() && getTimeZoneSign() != 0 && hasTime() && + ((hasDay() == hasMonth() && hasDay() == hasYear()))); + + if (!needNormalize && getFraction()!=null && getFraction().scale() > 0) + { + BigInteger bi = getFraction().unscaledValue(); + needNormalize = (bi.mod(TEN).signum() == 0); + } + + if (!needNormalize) + return toString(); + + GDateBuilder cdate = new GDateBuilder(this); + cdate.normalize(); + return cdate.toString(); + } + + /** + * The natural string representation. This represents the information + * that is available, including timezone. For types that correspond + * to defined schema types (schemaBuiltinTypeCode() > 0), + * this provides the natural lexical representation. + *

    + * When both time and timezone are specified, this string is not + * the canonical representation unless the timezone is UTC (Z) + * (since the same moment in time can be expressed in different + * timezones). To get a canonical string, use the canonicalString() + * method. + */ + public final String toString() + { + return GDate.formatGDate(this); + } + +} diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/GDateSpecification.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/GDateSpecification.java new file mode 100644 index 000000000..584c3a6f0 --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/GDateSpecification.java @@ -0,0 +1,239 @@ +/* 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; + +import java.math.BigDecimal; +import java.util.Date; + +/** + * Represents an XML Schema-compatible Gregorian date. + *

    + * Both the immutable GDate and the mutable GDateBuilder are + * GDateSpecifications. Use this interface where you want to + * allow callers to pass any implementation of a GDate. + * + * @see GDate + * @see XmlCalendar + */ +public interface GDateSpecification +{ + /** + * Returns a combination of flags indicating the information + * contained by this GDate. The five flags are + * {@link #HAS_TIMEZONE}, {@link #HAS_YEAR}, {@link #HAS_MONTH}, + * {@link #HAS_DAY}, and {@link #HAS_TIME}. + */ + int getFlags(); + + /** Timezone is specified. See {@link #getFlags}. */ + public final int HAS_TIMEZONE = 1; + /** Year is specified. See {@link #getFlags}. */ + public final int HAS_YEAR = 2; + /** Month of year is specified. See {@link #getFlags}. */ + public final int HAS_MONTH = 4; + /** Day of month is specified. See {@link #getFlags}. */ + public final int HAS_DAY = 8; + /** Time of day is specified. See {@link #getFlags}. */ + public final int HAS_TIME = 16; + + /** + * True if this GDate specification is immutable. GDate returns true, + * and GDateBuilder returns false. + */ + boolean isImmutable(); + + /** + * True if this GDate corresponds to a valid gregorian date value + * in XML schema. + */ + boolean isValid(); + + /** + * True if this date/time specification specifies a timezone. + */ + boolean hasTimeZone(); + + /** + * True if this date/time specification specifies a year. + */ + boolean hasYear(); + + /** + * True if this date/time specification specifies a month-of-year. + */ + boolean hasMonth(); + + /** + * True if this date/time specification specifies a day-of-month. + */ + boolean hasDay(); + + /** + * True if this date/time specification specifies a time-of-day. + */ + boolean hasTime(); + + /** + * True if this date/time specification specifies a full date (year, month, day) + */ + boolean hasDate(); + + /** + * Gets the year. Should be a four-digit year specification. + */ + int getYear(); + + /** + * Gets the month-of-year. January is 1. + */ + int getMonth(); + + /** + * Gets the day-of-month. The first day of each month is 1. + */ + int getDay(); + + /** + * Gets the hour-of-day. Midnight is 0, and 11PM is 23. + */ + int getHour(); + + /** + * Gets the minute-of-hour. Range from 0 to 59. + */ + int getMinute(); + + /** + * Gets the second-of-minute. Range from 0 to 59. + */ + int getSecond(); + + /** + * Gets the time zone sign. For time zones east of GMT, + * this is positive; for time zones west, this is negative. + */ + int getTimeZoneSign(); + + /** + * Gets the time zone hour. + * This is always positive: for the sign, look at + * getTimeZoneSign(). + */ + int getTimeZoneHour(); + + /** + * Gets the time zone minutes. + * This is always positive: for the sign, look at + * getTimeZoneSign(). + */ + int getTimeZoneMinute(); + + /** + * Gets the fraction-of-second. Range from 0 (inclusive) to 1 (exclusive). + */ + BigDecimal getFraction(); + + /** + * Gets the rounded millisecond value. Range from 0 to 999 + */ + int getMillisecond(); + + /** + * Returns the Julian date corresponding to this Gregorian date. + * The Julian date (JD) is a continuous count of days from + * 1 January 4713 BC. + */ + int getJulianDate(); + + /** + * Retrieves the value of the current time as an {@link XmlCalendar}. + *

    + * {@link XmlCalendar} is a subclass of {@link java.util.GregorianCalendar} + * which is slightly customized to match XML schema date rules. + *

    + * The returned {@link XmlCalendar} has only those time and date fields + * set that are reflected in the GDate object. Because of the way the + * {@link java.util.Calendar} contract works, any information in the isSet() vanishes + * as soon as you view any unset field using get() methods. + * This means that if it is important to understand which date fields + * are set, you must call isSet() first before get(). + */ + XmlCalendar getCalendar(); + + /** + * Retrieves the value of the current time as a java.util.Date + * instance. + */ + Date getDate(); + + /** + * Comparison to another GDate. + *

      + *
    • Returns -1 if this < date. (less-than) + *
    • Returns 0 if this == date. (equal) + *
    • Returns 1 if this > date. (greater-than) + *
    • Returns 2 if this <> date. (incomparable) + *
    + * Two instances are incomparable if they have different amounts + * of information. + * + * @param gdatespec the date to compare against. + */ + int compareToGDate(GDateSpecification gdatespec); + + /** + * Returns the builtin type code for the shape of the information + * contained in this instance, or 0 if the + * instance doesn't contain information corresponding to a + * Schema type. + *

    + * Value will be equal to + * {@link SchemaType#BTC_NOT_BUILTIN}, + * {@link SchemaType#BTC_G_YEAR}, + * {@link SchemaType#BTC_G_YEAR_MONTH}, + * {@link SchemaType#BTC_G_MONTH}, + * {@link SchemaType#BTC_G_MONTH_DAY}, + * {@link SchemaType#BTC_G_DAY}, + * {@link SchemaType#BTC_DATE}, + * {@link SchemaType#BTC_DATE_TIME}, or + * {@link SchemaType#BTC_TIME}. + */ + int getBuiltinTypeCode(); + + /** + * The canonical string representation. Specific moments or + * times-of-day in a specified timezone are normalized to + * UTC time to produce a canonical string form for them. + * Other recurring time specifications keep their timezone + * information. + */ + String canonicalString(); + + /** + * The natural string representation. This represents the information + * that is available, including timezone. For types that correspond + * to defined schema types (schemaBuiltinTypeCode() > 0), + * this provides the natural lexical representation. + * + * When both time and timezone are specified, this string is not + * the canonical representation unless the timezone is UTC (Z) + * (since the same moment in time can be expressed in different + * timezones). To get a canonical string, use the canonicalString() + * method. + */ + String toString(); + +} diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/GDuration.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/GDuration.java new file mode 100644 index 000000000..a7f9a95e1 --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/GDuration.java @@ -0,0 +1,421 @@ +/* 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; + +import java.math.BigDecimal; + +/** + * Represents an XML Schema-compatible duration. + *

    + * A duration is made up of a number of years, months, days, hours, + * minutes, seconds, and fractions of seconds. See the + * XML Schema specification + * section on xs:duration + * for details on the rules for + * comparing durations and + * adding durations to dates. + */ +public final class GDuration implements GDurationSpecification, java.io.Serializable +{ + private static final long serialVersionUID = 1L; + + private int _sign; + private int _CY; + private int _M; + private int _D; + private int _h; + private int _m; + private int _s; + private BigDecimal _fs; + + /** + * Constructs an empty GDuration representing zero seconds. + */ + public GDuration() + { + _sign = +1; + _fs = GDate._zero; + } + + private static final int SEEN_NOTHING = 0; + private static final int SEEN_YEAR = 1; + private static final int SEEN_MONTH = 2; + private static final int SEEN_DAY = 3; + private static final int SEEN_HOUR = 4; + private static final int SEEN_MINUTE = 5; + private static final int SEEN_SECOND = 6; + + /** + * Constructs a GDuration from a lexical + * representation. The lexical space contains the + * union of the lexical spaces of all the schema + * date/time types (except for duration). + */ + public GDuration(CharSequence str) + { + // Form: -PnYnMnDTnHnMnS + // (where each n may be unsigned integer, i.e., an integer that conforms to the pattern [0-9]+ + // {was: preceded by a - for us}, and the whole may be -) + + // first trim XML whitespace + int len = str.length(); + int start = 0; + while (len > 0 && GDate.isSpace(str.charAt(len - 1))) + len -= 1; + while (start < len && GDate.isSpace(str.charAt(start))) + start += 1; + + _sign = 1; + boolean tmark = false; + + if (start < len && str.charAt(start) == '-') + { + _sign = -1; + start += 1; + } + + if (start >= len || str.charAt(start) != 'P') + throw new IllegalArgumentException("duration must begin with P"); + + start += 1; + + int seen = SEEN_NOTHING; + _fs = GDate._zero; + + for (;start < len; start += 1) + { + char ch = str.charAt(start); + if (ch == 'T') + { + if (tmark) + throw new IllegalArgumentException("duration must have no more than one T'"); + if (seen > SEEN_DAY) + throw new IllegalArgumentException("T in duration must precede time fields"); + seen = SEEN_DAY; + tmark = true; + start += 1; + if (start >= len) + throw new IllegalArgumentException("illegal duration"); + ch = str.charAt(start); + } + if (!GDate.isDigit(ch)) + throw new IllegalArgumentException("illegal duration at char[" + start + "]: '" + ch + "'"); + int value = GDate.digitVal(ch); + for (;;) + { + start += 1; + ch = (start < len) ? str.charAt(start) : '\0'; + if (!GDate.isDigit(ch)) + break; + value = value * 10 + GDate.digitVal(ch); + } + if (ch == '.') + { + int i = start; + do i += 1; + while (i < len && GDate.isDigit(ch = str.charAt(i))); + _fs = new BigDecimal(str.subSequence(start, i).toString()); + if (i >= len || ch != 'S') + throw new IllegalArgumentException("illegal duration"); + start = i; + } + + switch (seen) + { + case SEEN_NOTHING: + if (ch == 'Y') + { + seen = SEEN_YEAR; + _CY = value; + break; + } // fallthrough + case SEEN_YEAR: + if (ch == 'M') + { + seen = SEEN_MONTH; + _M = value; + break; + } // fallthrough + case SEEN_MONTH: + if (ch == 'D') + { + seen = SEEN_DAY; + _D = value; + break; + } // fallthrough + case SEEN_DAY: + if (ch == 'H') + { + if (!tmark) + throw new IllegalArgumentException("time in duration must follow T"); + seen = SEEN_HOUR; + _h = value; + break; + } // fallthrough + case SEEN_HOUR: + if (ch == 'M') + { + if (!tmark) + throw new IllegalArgumentException("time in duration must follow T"); + seen = SEEN_MINUTE; + _m = value; + break; + } // fallthrough + case SEEN_MINUTE: + if (ch == 'S') + { + if (!tmark) + throw new IllegalArgumentException("time in duration must follow T"); + seen = SEEN_SECOND; + _s = value; + break; + } // fallthrough + default: + throw new IllegalArgumentException("duration must specify Y M D T H M S in order"); + } + } + + if ( seen == SEEN_NOTHING ) + throw new IllegalArgumentException("duration must contain at least one number and its designator: " + str); + } + + /** + * Constructs a GDuration with the specified sign, + * year, month, day, hours, minutes, seconds, and optional + * fractional seconds. + * @param sign +1 for a positive duration, -1 for a negative duration + * @throws java.lang.IllegalArgumentException if the sign is not 1 or -1 + */ + public GDuration( + int sign, + int year, + int month, + int day, + int hour, + int minute, + int second, + BigDecimal fraction) + { + if (sign != 1 && sign != -1) + throw new IllegalArgumentException(); + _sign = sign; + _CY = year; + _M = month; + _D = day; + _h = hour; + _m = minute; + _s = second; + _fs = fraction == null ? GDate._zero : fraction; + } + + /** + * Constructs a GDuration from another GDurationSpecification. + */ + public GDuration(GDurationSpecification gDuration) + { + _sign = gDuration.getSign(); + _CY = gDuration.getYear(); + _M = gDuration.getMonth(); + _D = gDuration.getDay(); + _h = gDuration.getHour(); + _m = gDuration.getMinute(); + _s = gDuration.getSecond(); + _fs = gDuration.getFraction(); + } + + /** + * Builds another GDate with the same value + * as this one. + */ + public Object clone() + { + return new GDuration(this); + } + + /** + * All GDuration instances return true. + */ + public final boolean isImmutable() + { + return true; + } + + /** + * Returns the sign of the duration: +1 is forwards + * and -1 is backwards in time. + */ + public final int getSign() + { return _sign; } + + /** + * Gets the year component. + */ + public final int getYear() + { return _CY; } + + /** + * Gets the month-of-year component. + */ + public final int getMonth() + { return _M; } + + /** + * Gets the day-of-month component. + */ + public final int getDay() + { return _D; } + + /** + * Gets the hour-of-day component. + */ + public final int getHour() + { return _h; } + + /** + * Gets the minute-of-hour component. + */ + public final int getMinute() + { return _m; } + + /** + * Gets the second-of-minute component. + */ + public final int getSecond() + { return _s; } + + + /** + * Gets the fraction-of-second. Range from 0 (inclusive) to 1 (exclusive). + */ + public BigDecimal getFraction() + { return _fs; } + + /** + * Returns true if all of the individual components + * of the duration are nonnegative. + */ + public boolean isValid() + { + return GDurationBuilder.isValidDuration(this); + } + + /** + * Comparison to another GDuration. + *

      + *
    • Returns -1 if this < duration. (less-than) + *
    • Returns 0 if this == duration. (equal) + *
    • Returns 1 if this > duration. (greater-than) + *
    • Returns 2 if this <> duration. (incomparable) + *
    + * Two instances are incomparable if they have different amounts + * of information. + */ + public final int compareToGDuration(GDurationSpecification duration) + { + return GDurationBuilder.compareDurations(this, duration); + } + + /** + * The natural string representation of the duration. + *

    + * Any components that are zero are omitted. Note that if the duration + * is invalid, i.e., it has negative components, those negative + * components are serialized out here. To check for validity, use + * the isValid() method; and to normalize most durations to a valid + * form use the normalize() method. + */ + public String toString() + { + return GDurationBuilder.formatDuration(this); + } + + /** + * Returns a new GDuration which is the sum of this one and the + * supplied duration. Does a fieldwise addition, with no normalization. + */ + public GDuration add(GDurationSpecification duration) + { + int sign = _sign * duration.getSign(); + return _add(duration, sign); + } + + /** + * Returns a new GDuration which is the result of subtracting + * the supplied duration from this one. Does a fieldwise + * subtraction, with no normalization. + */ + public GDuration subtract(GDurationSpecification duration) + { + int sign = -_sign * duration.getSign(); + return _add(duration, sign); + } + + private GDuration _add(GDurationSpecification duration, int sign) + { + GDuration result = new GDuration(this); + result._CY += sign * duration.getYear(); + result._M += sign * duration.getMonth(); + result._D += sign * duration.getDay(); + result._h += sign * duration.getHour(); + result._m += sign * duration.getMinute(); + result._s += sign * duration.getSecond(); + + if (duration.getFraction().signum() == 0) + return result; + + if (result._fs.signum() == 0 && sign == 1) + result._fs = duration.getFraction(); + else + result._fs = sign > 0 ? + result._fs.add(duration.getFraction()) : + result._fs.subtract(duration.getFraction()); + return result; + } + + /** + * Two GDurations are equal if all their fields are equal. + * The equals function does not apply normalizatin. + */ + public boolean equals(Object obj) + { + if (obj == this) + return true; + if (!(obj instanceof GDuration)) + return false; + + GDuration duration = (GDuration)obj; + return (_sign == duration.getSign() && + _CY == duration.getYear() && + _M == duration.getMonth() && + _D == duration.getDay() && + _h == duration.getHour() && + _m == duration.getMinute() && + _s == duration.getSecond() && + _fs.equals(duration.getFraction())); + } + + public int hashCode() + { + return (_s + + _m * (60 + 7) + + _h * (60 * 60 + 7) + + _D * (60 * 60 * 24 + 7) + + _M * (60 * 60 * 24 * 31 + 7) + + _CY *(60 * 60 * 24 * 372 + 7) + + _sign * 11917049); + } + +} diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/GDurationBuilder.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/GDurationBuilder.java new file mode 100644 index 000000000..23b8caf68 --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/GDurationBuilder.java @@ -0,0 +1,668 @@ +/* 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; + +import java.math.BigDecimal; +import java.math.BigInteger; + +/** + * Used to build {@link GDuration GDurations}. + */ +public class GDurationBuilder implements GDurationSpecification, java.io.Serializable +{ + private static final long serialVersionUID = 1L; + + private int _sign; + private int _CY; + private int _M; + private int _D; + private int _h; + private int _m; + private int _s; + private BigDecimal _fs; + + /** + * Constructs an empty GDurationBuilder representing zero seconds. + */ + public GDurationBuilder() + { + _sign = +1; + _fs = GDate._zero; + } + + /** + * Constructs a GDuration from a lexical + * representation. + */ + public GDurationBuilder(String s) + { + this(new GDuration(s)); + } + + /** + * Constructs a GDurationBuilder with the specified sign, + * year, month, day, hours, minutes, seconds, and optional + * fractional seconds. + * @param sign +1 for a positive duration, -1 for a negative duration + * @throws java.lang.IllegalArgumentException if the sign is not 1 or -1 + */ + public GDurationBuilder( + int sign, + int year, + int month, + int day, + int hour, + int minute, + int second, + BigDecimal fraction) + { + if (sign != 1 && sign != -1) + throw new IllegalArgumentException(); + _sign = sign; + _CY = year; + _M = month; + _D = day; + _h = hour; + _m = minute; + _s = second; + _fs = fraction == null ? GDate._zero : fraction; + } + + /** + * Constructs a GDurationBuilder from another GDurationBuilderSpecification. + */ + public GDurationBuilder(GDurationSpecification gDuration) + { + _sign = gDuration.getSign(); + _CY = gDuration.getYear(); + _M = gDuration.getMonth(); + _D = gDuration.getDay(); + _h = gDuration.getHour(); + _m = gDuration.getMinute(); + _s = gDuration.getSecond(); + _fs = gDuration.getFraction(); + } + + /** + * Builds another GDurationBuilder with the same value + * as this one. + */ + public Object clone() + { + return new GDurationBuilder(this); + } + + /** + * Builds a GDuration from this GDurationBuilder. + */ + public GDuration toGDuration() + { + return new GDuration(this); + } + + /** + * Adds to this duration. Does a fieldwise add, with no + * normalization. + */ + public void addGDuration(GDurationSpecification duration) + { + int sign = _sign * duration.getSign(); + _add(duration, sign); + } + + /** + * Subtracts from this duration. Does a fieldwise subtraction, + * with no normalization. + */ + public void subtractGDuration(GDurationSpecification duration) + { + int sign = -_sign * duration.getSign(); + _add(duration, sign); + } + + private void _add(GDurationSpecification duration, int sign) + { + _CY += sign * duration.getYear(); + _M += sign * duration.getMonth(); + _D += sign * duration.getDay(); + _h += sign * duration.getHour(); + _m += sign * duration.getMinute(); + _s += sign * duration.getSecond(); + + if (duration.getFraction().signum() == 0) + return; + + if (_fs.signum() == 0 && sign == 1) + _fs = duration.getFraction(); + else + _fs = sign > 0 ? + _fs.add(duration.getFraction()) : + _fs.subtract(duration.getFraction()); + } + + /** + * Sets the sign. + */ + public final void setSign(int sign) + { + if (sign != 1 && sign != -1) + throw new IllegalArgumentException(); + _sign = sign; + } + + /** + * Sets the year component. + */ + public void setYear(int year) + { _CY = year; } + + /** + * Sets the month component. + */ + public void setMonth(int month) + { _M = month; } + + /** + * Sets the day component. + */ + public void setDay(int day) + { _D = day; } + + /** + * Sets the hour component. + */ + public void setHour(int hour) + { _h = hour; } + + /** + * Sets the minute component. + */ + public void setMinute(int minute) + { _m = minute; } + + /** + * Sets the second component. + */ + public void setSecond(int second) + { _s = second; } + + /** + * Sets the fraction-of-second component. + */ + public void setFraction(BigDecimal fraction) + { _fs = fraction == null ? GDate._zero : fraction; } + + /** + * All GDuration instances return true. + */ + public final boolean isImmutable() + { + return true; + } + + /** + * Returns the sign of the duration: +1 is forwards + * and -1 is backwards in time. + * This value does not necessarily reflect the + * true direction of the duration if the duration + * is not normalized or not normalizable. + */ + public final int getSign() + { return _sign; } + + /** + * Gets the year component. + */ + public final int getYear() + { return _CY; } + + /** + * Gets the month-of-year component. + */ + public final int getMonth() + { return _M; } + + /** + * Gets the day-of-month component. + */ + public final int getDay() + { return _D; } + + /** + * Gets the hour-of-day component. + */ + public final int getHour() + { return _h; } + + /** + * Gets the minute-of-hour component. + */ + public final int getMinute() + { return _m; } + + /** + * Gets the second-of-minute component. + */ + public final int getSecond() + { return _s; } + + + /** + * Gets the fraction-of-second. Range from 0 (inclusive) to 1 (exclusive). + */ + public BigDecimal getFraction() + { return _fs; } + + /** + * Returns true if all of the individual components + * of the duration are nonnegative. + */ + public boolean isValid() + { + return GDurationBuilder.isValidDuration(this); + } + + + /** + * Normalize a duration value. This ensures that months, + * hours, minutes, seconds, and fractions are positive and + * within the ranges 0..11, 0..23, 0..59, etc. Negative + * durations are indicated by a negative sign rather + * than negative components. + *

    + * Most duration specifications can be normalized to + * valid durations with all positive components, but + * not all of them can. + *

    + * The only situations which cannot be normalized are + * where the year/month and the day/hour/minute/second + * offsets are of opposite sign. Days cannot be carried + * into months since the length of a Gregorian month is + * variable depending on when the duration is applied. + * In these cases, this method normalizes the components + * so that "day" is the only negative component. + */ + public void normalize() + { + _normalizeImpl(true); + } + + /** + * fQuotient(a, b) = the greatest integer less than or equal to a/b + */ + private static final long _fQuotient(long a, int b) + { + if ((a < 0) == (b < 0)) + return a / b; + + return -((b - a - 1) / b); + } + + /** + * modulo(a, b) = a - fQuotient(a,b)*b + */ + private static final int _mod(long a, int b, long quotient) + { + return (int)(a - quotient*b) ; + } + + + /** + * Private implemenation of normalize. The flag is + * to facilitate this method calling itself without + * danger of infinite recursion. + */ + private void _normalizeImpl(boolean adjustSign) + { + long temp; + + // months to years + if (_M < 0 || _M > 11) + { + temp = _M; + long ycarry = _fQuotient(temp, 12); + _M = _mod(temp, 12, ycarry); + _CY += ycarry; + } + + long carry = 0; + + // fractions to seconds + if (_fs != null && (_fs.signum() < 0 || _fs.compareTo(GDate._one) >= 0)) + { + BigDecimal bdcarry = _fs.setScale(0, BigDecimal.ROUND_FLOOR); + _fs = _fs.subtract(bdcarry); + carry = bdcarry.intValue(); + } + + if (carry != 0 || _s < 0 || _s > 59 || _m < 0 || _m > 50 || _h < 0 || _h > 23) + { + // seconds + temp = _s + carry; + carry = _fQuotient(temp, 60); + _s = _mod(temp, 60, carry); + + // minutes + temp = _m + carry; + carry = _fQuotient(temp, 60); + _m = _mod(temp, 60, carry); + + // hours + temp = _h + carry; + carry = _fQuotient(temp, 24); + _h = _mod(temp, 24, carry); + _D += carry; + } + + if (_CY == 0 && _M == 0 && _D == 0 && _h == 0 && _m == 0 && _s == 0 && (_fs == null || _fs.signum() == 0)) + _sign = 1; + + if (adjustSign && (_D < 0 || _CY < 0)) + { + int sign = (_D <= 0 && (_CY < 0 || _CY == 0 && _M == 0)) ? -_sign : _getTotalSignSlowly(); + if (sign == 2) + sign = (_CY < 0) ? -_sign : _sign; + if (sign == 0) + sign = 1; + if (sign != _sign) + { + _sign = sign; + _CY = -_CY; + _M = -_M; + _D = -_D; + _h = -_h; + _m = -_m; + _s = -_s; + if (_fs != null) + _fs = _fs.negate(); + } + _normalizeImpl(false); + } + } + + + /* package */ static boolean isValidDuration(GDurationSpecification spec) + { + if (!(spec.getSign() == 1 || spec.getSign() == -1)) + return false; + + return (spec.getYear() >= 0 && spec.getMonth() >= 0 && spec.getDay() >= 0 && + spec.getHour() >= 0 && spec.getMinute() >= 0 && spec.getSecond() >= 0 && + spec.getFraction().signum() >= 0); + } + + /** + * Comparison to another GDuration. + *

      + *
    • Returns -1 if this < duration. (less-than) + *
    • Returns 0 if this == duration. (equal) + *
    • Returns 1 if this > duration. (greater-than) + *
    • Returns 2 if this <> duration. (incomparable) + *
    + * Two instances are incomparable if they have different amounts + * of information. + */ + public final int compareToGDuration(GDurationSpecification duration) + { + return GDurationBuilder.compareDurations(this, duration); + } + + /** + * The natural string representation of the duration. + *

    + * Any components that are zero are omitted. Note that if the duration + * is invalid, i.e., it has negative components, those negative + * components are serialized out here. To check for validity, use + * the isValid() method; and to normalize most durations to a valid + * form use the normalize() method. + */ + public String toString() + { + return GDurationBuilder.formatDuration(this); + } + + /* package */ static int compareDurations(GDurationSpecification d1, GDurationSpecification d2) + { + // first do an all-fields check + if (d1.getFraction().signum() == 0 && d2.getFraction().signum() == 0) + { + int s1 = d1.getSign(); + int s2 = d2.getSign(); + long month1 = s1 * ((long)d1.getYear() * 12 + d1.getMonth()); + long month2 = s2 * ((long)d2.getYear() * 12 + d2.getMonth()); + long sec1 = s1 * ((((long)d1.getDay() * 24 + d1.getHour()) * 60 + d1.getMinute()) * 60 + d1.getSecond()); + long sec2 = s2 * ((((long)d2.getDay() * 24 + d2.getHour()) * 60 + d2.getMinute()) * 60 + d2.getSecond()); + if (month1 == month2) + { + if (sec1 == sec2) + return 0; + if (sec1 < sec2) + return -1; + if (sec1 > sec2) + return 1; + } + if (month1 < month2 && sec1 - sec2 < 28 * 24 * 60 * 60) + return -1; + if (month1 > month2 && sec2 - sec1 < 28 * 24 * 60 * 60) + return 1; + } + + // the answer isn't obvious, so then do a total-sign check + GDurationBuilder diff = new GDurationBuilder(d1); + diff.subtractGDuration(d2); + return diff._getTotalSignSlowly(); + } + + /** + * Per schema spec, comparison of durations is simply done + * by calculating adding the duration to these four dates and + * comparing the results. If the results are ambiguous, the + * answer is "incomparable". + */ + private static final GDate[] _compDate = new GDate[] + { + new GDate(1696, 9, 1, 0, 0, 0, null, 0, 0, 0), + new GDate(1697, 2, 1, 0, 0, 0, null, 0, 0, 0), + new GDate(1903, 3, 1, 0, 0, 0, null, 0, 0, 0), + new GDate(1903, 7, 1, 0, 0, 0, null, 0, 0, 0) + }; + + + /** + * This returns the total sign of the duration, +1 + * if the duration moves forward in time, -1 if the + * duration moves backwards in time, 0 if the duration + * is zero-length, and 2 if the duration may be positive + * or negative depending on the date. + * + * (For example, one month minus 30 days is indeterminate). + */ + private int _getTotalSignSlowly() + { + int pos = 0; + int neg = 0; + int zer = 0; + + GDateBuilder enddate = new GDateBuilder(); + for (int i = 0; i < _compDate.length; i++) + { + enddate.setGDate(_compDate[i]); + enddate.addGDuration(this); + switch (enddate.compareToGDate(_compDate[i])) + { + case -1: + neg++; break; + case 0: + zer++; break; + case 1: + pos++; break; + } + } + + if (pos == _compDate.length) + return +1; + if (neg == _compDate.length) + return -1; + if (zer == _compDate.length) + return 0; + return 2; + } + + /* package */ static String formatDuration(GDurationSpecification duration) + { + // Sign+P: (-)?P + // Year: (?:(\d+)Y)? + // Month: (?:(\d+)M)? + // Day: (?:(\d+)D)? + // Time: (?:(T) + // Hours: (?:(\d+)H)? + // Minutes: (?:(\d+)M)? + // Seconds: (?:(\d+(?:\.\d*)?|(?:.\d+)S)? + + StringBuffer message = new StringBuffer(30); + + if (duration.getSign() < 0) + message.append('-'); + + message.append('P'); + + if (duration.getYear() != 0) + { + message.append(duration.getYear()); + message.append('Y'); + } + + if (duration.getMonth() != 0) + { + message.append(duration.getMonth()); + message.append('M'); + } + + if (duration.getDay() != 0) + { + message.append(duration.getDay()); + message.append('D'); + } + + if (duration.getHour() != 0 || duration.getMinute() != 0 || duration.getSecond() != 0 || + (duration.getFraction().signum() != 0)) + { + message.append('T'); + } + + if (duration.getHour() != 0) + { + message.append(duration.getHour()); + message.append('H'); + } + + if (duration.getMinute() != 0) + { + message.append(duration.getMinute()); + message.append('M'); + } + + if (duration.getFraction().signum() != 0) + { + BigDecimal s = duration.getFraction(); + if (duration.getSecond() != 0) + s = s.add(BigDecimal.valueOf(duration.getSecond())); + // todo when upgrade to 1.5 message.append(s.stripTrailingZeros().toPlainString()); + message.append(stripTrailingZeros(toPlainString(s))); + message.append('S'); + } + else if (duration.getSecond() != 0) + { + message.append(duration.getSecond()); + message.append('S'); + } + else if (message.length() <= 2) + // Specify zero seconds if everything was 0 + message.append("T0S"); + + return message.toString(); + } + + public static String toPlainString(BigDecimal bd) + { + BigInteger intVal = bd.unscaledValue(); + int scale = bd.scale(); + String intValStr = intVal.toString(); + if (scale == 0) + return intValStr; + + boolean isNegative = (intValStr.charAt(0) == '-'); + + int point = intValStr.length() - scale - (isNegative ? 1 : 0); + + StringBuffer sb = new StringBuffer(intValStr.length() + 2 + (point <= 0 ? (-point + 1) : 0)); + if (point <= 0) + { + // prepend zeros and a decimal point. + if (isNegative) sb.append('-'); + sb.append('0').append('.'); + while (point < 0) + { + sb.append('0'); + point++; + } + sb.append(intValStr.substring(isNegative ? 1 : 0)); + } + else if (point < intValStr.length()) + { + // No zeros needed + sb.append(intValStr); + sb.insert(point + (isNegative ? 1 : 0), '.'); + } + else + { + // append zeros if not 0 + sb.append(intValStr); + if (!intVal.equals(BigInteger.ZERO)) + for (int i = intValStr.length(); i < point; i++) + sb.append('0'); + } + return sb.toString(); + } + + public static String stripTrailingZeros(String s) + { + boolean seenDot = false; + int i = s.length() - 1; + int zeroIndex = i; + + while(i>=0) + { + if (s.charAt(i)!='0') + break; + i--; + zeroIndex--; + } + while(i>=0) + { + if (s.charAt(i)=='E') + return s; + if (s.charAt(i)=='.') + { + seenDot = true; + break; + } + i--; + } + + return seenDot? s.substring(0, zeroIndex+1) : s; + } +} diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/GDurationSpecification.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/GDurationSpecification.java new file mode 100644 index 000000000..8064ae254 --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/GDurationSpecification.java @@ -0,0 +1,95 @@ +/* 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; + +import java.math.BigDecimal; + +/** + * Represents an XML Schema-compatible duration. + *

    + * Both the immutable GDuration and the mutable GDurationBuilder are + * GDurationSpecifications. Use this interface where you want to + * allow callers to pass any implementation of a GDuration. + * + * @see GDuration + */ +public interface GDurationSpecification +{ + /** + * True if this instance is immutable. + */ + boolean isImmutable(); + + /** + * Returns the sign of the duration: +1 is forwards + * and -1 is backwards in time. + */ + int getSign(); + + /** + * Gets the year component. + */ + int getYear(); + + /** + * Gets the month-of-year component. + */ + int getMonth(); + + /** + * Gets the day-of-month component. + */ + int getDay(); + + /** + * Gets the hour-of-day component. + */ + int getHour(); + + /** + * Gets the minute-of-hour component. + */ + int getMinute(); + + /** + * Gets the second-of-minute component. + */ + int getSecond(); + + /** + * Gets the fraction-of-second. Range from 0 (inclusive) to 1 (exclusive). + */ + BigDecimal getFraction(); + + /** + * Returns true if all of the individual components + * of the duration are nonnegative. + */ + boolean isValid(); + + /** + * Comparison to another GDuration. + *

      + *
    • Returns -1 if this < duration. (less-than) + *
    • Returns 0 if this == duration. (equal) + *
    • Returns 1 if this > duration. (greater-than) + *
    • Returns 2 if this <> duration. (incomparable) + *
    + * Two instances are incomparable if they have different amounts + * of information. + */ + int compareToGDuration(GDurationSpecification duration); +} diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/InterfaceExtension.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/InterfaceExtension.java new file mode 100755 index 000000000..9effea47e --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/InterfaceExtension.java @@ -0,0 +1,50 @@ +/* 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; + +public interface InterfaceExtension +{ + /** + * Get the fully qualified interface name. + */ + String getInterface(); + + /** + * Get the fully qualified static handler class name. + */ + String getStaticHandler(); + + /** + * Returns an array of MethodSignature declared in the interface class. + * Possibly null if there is an error in the configuration. + */ + MethodSignature[] getMethods(); + + public interface MethodSignature + { + /** Returns the name of the method. */ + String getName(); + + /** Returns the fully qualified type name of the return value or 'void' for no return value. */ + String getReturnType(); + + /** Returns the fully qualified type name of the parameter types in order. */ + String[] getParameterTypes(); + + /** Returns the fully qualified type name of the exception types. */ + String[] getExceptionTypes(); + } +} diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/ObjectFactory.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/ObjectFactory.java new file mode 100644 index 000000000..c978aad6e --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/ObjectFactory.java @@ -0,0 +1,31 @@ +/* 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; + +/** + * generic interface to abstract creation of an object + */ +public interface ObjectFactory +{ + /** + * Given the type, create an object of that type. Note that the return object + * might be a subclass of type, but should always be an instanceof type. + * + * @param type type of object to create + * @return instance + */ + Object createObject(Class type); +} diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/PrePostExtension.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/PrePostExtension.java new file mode 100755 index 000000000..478080bc5 --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/PrePostExtension.java @@ -0,0 +1,50 @@ +/* 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; + +public interface PrePostExtension +{ + /** Operation code for setting a property. */ + int OPERATION_SET = 1; + + /** Operation code for inserting a property. */ + int OPERATION_INSERT = 2; + + /** Operation code for removing a property. */ + int OPERATION_REMOVE = 3; + + /** + * Get the fully qualified static handler class name. + */ + String getStaticHandler(); + + /** + * Returns true if the static handler class has a preSet() method + * with the following signature: + *
    + * public static boolean preSet(int, org.apache.xmlbeans.XmlObject, javax.xml.namespace.QName, boolean, int}; + */ + boolean hasPreCall(); + + /** + * Returns true if the static handler class has a preSet() method + * with the following signature: + *
    + * public static void postSet(int, org.apache.xmlbeans.XmlObject, javax.xml.namespace.QName, boolean, int}; + */ + boolean hasPostCall(); + +} diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/QNameCache.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/QNameCache.java new file mode 100644 index 000000000..4bf785f31 --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/QNameCache.java @@ -0,0 +1,150 @@ +/* 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; + +import javax.xml.namespace.QName; + +/** + * A cache that can be used to pool QName instances. Each thread has one. + */ +public final class QNameCache +{ + private static final float DEFAULT_LOAD = 0.70f; + private final float loadFactor; + private int numEntries = 0; + private int threshold; + private int hashmask; + private QName[] table; + + /** + * Creates a QNameCache with the given initialCapacity and loadFactor. + * + * @param initialCapacity the number of entries to initially make space for + * @param loadFactor a number to control the density of the hashtable + */ + public QNameCache(int initialCapacity, float loadFactor) + { + assert initialCapacity > 0; + assert loadFactor > 0 && loadFactor < 1; + + // Find a power of 2 >= initialCapacity + int capacity = 16; + while (capacity < initialCapacity) + capacity <<= 1; + + this.loadFactor = loadFactor; + this.hashmask = capacity - 1; + threshold = (int)(capacity * loadFactor); + table = new QName[capacity]; + } + + /** + * Creates a QNameCache with the given initialCapacity. + * + * @param initialCapacity the number of entries to initially make space for + */ + public QNameCache(int initialCapacity) + { + this(initialCapacity, DEFAULT_LOAD); + } + + public QName getName(String uri, String localName) + { + return getName( uri, localName, "" ); + } + + /** + * Fetches a QName with the given namespace and localname. + * Creates one if one is not found in the cache. + * + * @param uri the namespace + * @param localName the localname + * @param prefix the prefix + * @return the cached QName + */ + public QName getName(String uri, String localName, String prefix) + { + /* + return new QName(uri, localName, prefix); + */ + assert localName != null; + + if (uri == null) uri = ""; + if (prefix == null) prefix = ""; + + int index = hash(uri, localName, prefix) & hashmask; + while (true) { + QName q = table[index]; + if (q == null) + { + numEntries++; + if (numEntries >= threshold) + rehash(); + + return table[index] = new QName(uri, localName, prefix); + } + else if (equals(q, uri, localName, prefix)) + return q; + else + index = (index-1) & hashmask; + } + } + + private void rehash() + { + int newLength = table.length * 2; + QName[] newTable = new QName[newLength]; + int newHashmask = newLength - 1; + + for (int i = 0 ; i < table.length ; i++) + { + QName q = table[i]; + if (q != null) + { + int newIndex = + hash( q.getNamespaceURI(), q.getLocalPart(), q.getPrefix() ) & newHashmask; + + while (newTable[newIndex] != null) + newIndex = (newIndex - 1) & newHashmask; + + newTable[newIndex] = q; + } + } + + table = newTable; + hashmask = newHashmask; + threshold = (int) (newLength * loadFactor); + } + + private static int hash(String uri, String localName, String prefix) + { + int h = 0; + + h += prefix.hashCode() << 10; + h += uri.hashCode() << 5; + h += localName.hashCode(); + + return h; + } + + private static boolean equals(QName q, String uri, String localName, String prefix) + { + return + q.getLocalPart().equals(localName) && + q.getNamespaceURI().equals(uri) && + q.getPrefix().equals(prefix); + } +} diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/QNameSet.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/QNameSet.java new file mode 100644 index 000000000..246e8748e --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/QNameSet.java @@ -0,0 +1,447 @@ +/* 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; + +import javax.xml.namespace.QName; + +import java.util.Set; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Collections; +import java.util.Arrays; + +/** + * This interface represents a lattice of finite and infinite sets of QNames. + * The lattice the minimal one that is closed under union, intersection, and + * inverse, and contains individual QNames as well as entire namespaces. + * Here is a summary of the two kinds of QNameSets: + *
      + *
    • A QNameSet can cover a finite set of namespaces, additionally including a finite + * set of QNames outside those namespaces, and with the exception of + * a finite set of QNames excluded from those namespaes: + *
        + *
      • excludedQNamesInIncludedURIs == the set of excluded QNames from coveredURIs namespaces + *
      • excludedURIs == null + *
      • includedURIs == the set of covered namespace URIs + *
      • includedQNamesInExcludedURIs == set of additional QNames outside coveredURIs namespaces + *
      + *
    • + *
    • A QNameSet can cover all namespaces except for a finite number of excluded ones, + * additionally including a finite set of QNames within the excluded namespaces, + * and with the exception of a finite set of QNames outside the excluded namespaces: + *
        + *
      • excludedQNamesInIncludedURIs == the set of excluded QNames outside uncoveredURIs namespaces + *
      • excludedURIs == the set of uncovered namespace URIs + *
      • includedURIs == null + *
      • includedQNamesInExcludedURIs == set of additional QNames from uncoveredURIs namespaces + *
      + *
    • + *
    + *

    + * Notice that a finite set of QNames is a degenerate case of the first + * category outlined above: + *

      + *
    • A QnameSet can contain a finite number of QNames: + *
        + *
      • excludedQNamesInIncludedURIs == empty set + *
      • excludedURIs == null + *
      • includedURIs == empty set + *
      • includedQNamesInExcludedURIs == set of included QNames + *
      + *
    • + *
    + * + * @see QNameSetBuilder + */ +public final class QNameSet implements QNameSetSpecification, java.io.Serializable +{ + private static final long serialVersionUID = 1L; + + private final boolean _inverted; + private final Set _includedURIs; + private final Set _excludedQNames; + private final Set _includedQNames; + + /** + * The empty QNameSet. + */ + public static final QNameSet EMPTY = new QNameSet(null, Collections.EMPTY_SET, Collections.EMPTY_SET, Collections.EMPTY_SET); + + /** + * The QNameSet containing all QNames. + */ + public static final QNameSet ALL = new QNameSet(Collections.EMPTY_SET, null, Collections.EMPTY_SET, Collections.EMPTY_SET); + + /** + * The QNameSet containing all QNames in the local (no-)namespace. + */ + public static final QNameSet LOCAL = new QNameSet(null, Collections.singleton(""), Collections.EMPTY_SET, Collections.EMPTY_SET); + + /** + * The QNameSet containing all QNames except for those in the local (no-)namespace. + */ + public static final QNameSet NONLOCAL = new QNameSet(Collections.singleton(""), null, Collections.EMPTY_SET, Collections.EMPTY_SET); + + /** + * Private function to minimize object creation when copying sets. + */ + private static Set minSetCopy(Set original) + { + if (original == null) + return null; + if (original.isEmpty()) + return Collections.EMPTY_SET; + if (original.size() == 1) + return Collections.singleton(original.iterator().next()); + return new HashSet(original); + } + + /** + * Returns a QNameSet based on the given sets of excluded URIs, + * included URIs, excluded QNames in included namespaces, and included + * QNames in excluded namespaces. + * + * @param excludedURIs the finite set of namespace URI strings to exclude from the set, or null if this set is infinite + * @param includedURIs the finite set of namespace URI strings to include in the set, or null if this set is infinite + * @param excludedQNamesInIncludedURIs the finite set of exceptional QNames to exclude from the included namespaces + * @param excludedQNamesInIncludedURIs the finite set of exceptional QNames to include that are in the excluded namespaces + * + * @return the constructed QNameSet + */ + public static QNameSet forSets(Set excludedURIs, Set includedURIs, Set excludedQNamesInIncludedURIs, Set includedQNamesInExcludedURIs) + { + if ((excludedURIs != null) == (includedURIs != null)) + throw new IllegalArgumentException("Exactly one of excludedURIs and includedURIs must be null"); + + if (excludedURIs == null && includedURIs.isEmpty() && includedQNamesInExcludedURIs.isEmpty()) + return EMPTY; + if (includedURIs == null && excludedURIs.isEmpty() && excludedQNamesInIncludedURIs.isEmpty()) + return ALL; + if (excludedURIs == null && includedURIs.size() == 1 && includedURIs.contains("") && + includedQNamesInExcludedURIs.isEmpty() && excludedQNamesInIncludedURIs.isEmpty()) + return LOCAL; + if (includedURIs == null && excludedURIs.size() == 1 && excludedURIs.contains("") && + excludedQNamesInIncludedURIs.isEmpty() && includedQNamesInExcludedURIs.isEmpty()) + return NONLOCAL; + + return new QNameSet( + minSetCopy(excludedURIs), + minSetCopy(includedURIs), + minSetCopy(excludedQNamesInIncludedURIs), + minSetCopy(includedQNamesInExcludedURIs)); + } + + /** + * Returns a QNameSet based on the given array of included QNames + * + * @param includedQNames the array of included QNames + */ + public static QNameSet forArray(QName[] includedQNames) + { + if (includedQNames == null) + throw new IllegalArgumentException("includedQNames cannot be null"); + + return new QNameSet(null, Collections.EMPTY_SET, Collections.EMPTY_SET, new HashSet(Arrays.asList(includedQNames))); + } + + /** + * Returns a QNameSet with the same contents as the given + * QNameSetSpecification. + * @return the copied QNameSet + */ + public static QNameSet forSpecification(QNameSetSpecification spec) + { + if (spec instanceof QNameSet) + return (QNameSet)spec; + return QNameSet.forSets(spec.excludedURIs(), spec.includedURIs(), spec.excludedQNamesInIncludedURIs(), spec.includedQNamesInExcludedURIs()); + } + + /** + * Returns a QNameSet corresponding to the given wildcard namespace string. + * This is a space-separated list of URIs, plus special tokens as specified + * in the XML Schema specification (##any, ##other, ##targetNamespace, ##local). + * @return the constructed QNameSet + */ + public static QNameSet forWildcardNamespaceString(String wildcard, String targetURI) + { + return QNameSet.forSpecification(new QNameSetBuilder(wildcard, targetURI)); + } + + /** + * Returns a QNameSet containing only the given QName. + * @return the constructed QNameSet + */ + public static QNameSet singleton(QName name) + { + return new QNameSet(null, Collections.EMPTY_SET, Collections.EMPTY_SET, Collections.singleton(name)); + } + + /** + * Constructs a QNameSetBuilder whose contents are given by + * the four sets. + * + * This constuctor is PRIVATE because it uses the given + * sets directly, and it trusts its callers to set only immutable values. + * This constructor is is only called by the static builder methods on + * QNameSet: those methods are all careful assign only unchanging sets. + */ + private QNameSet(Set excludedURIs, Set includedURIs, Set excludedQNamesInIncludedURIs, Set includedQNamesInExcludedURIs) + { + if (includedURIs != null && excludedURIs == null) + { + _inverted = false; + _includedURIs = includedURIs; + _excludedQNames = excludedQNamesInIncludedURIs; + _includedQNames = includedQNamesInExcludedURIs; + } + else if (excludedURIs != null && includedURIs == null) + { + _inverted = true; + _includedURIs = excludedURIs; + _excludedQNames = includedQNamesInExcludedURIs; + _includedQNames = excludedQNamesInIncludedURIs; + } + else + throw new IllegalArgumentException("Exactly one of excludedURIs and includedURIs must be null"); + } + + /** + * Local xml names are hased using "" as the namespace. + */ + private static String nsFromName(QName xmlName) + { + String ns = xmlName.getNamespaceURI(); + return ns == null ? "" : ns; + } + + /** + * True if this ModelTransitionSet contains the given qname. + */ + public boolean contains(QName name) + { + boolean in = _includedURIs.contains(nsFromName(name)) ? + !_excludedQNames.contains(name) : + _includedQNames.contains(name); + return _inverted ^ in; + } + + /** + * True if this ModelTransitionSet contains all QNames. + */ + public boolean isAll() + { + return _inverted && _includedURIs.isEmpty() && _includedQNames.isEmpty(); + } + + /** + * True if this ModelTransitionSet contains no QNames. + */ + public boolean isEmpty() + { + return !_inverted && _includedURIs.isEmpty() && _includedQNames.isEmpty(); + } + + /** + * Returns a new QNameSet that is the intersection of this one and another. + * @param set the set to insersect with + * @return the intersection + */ + public QNameSet intersect(QNameSetSpecification set) + { + QNameSetBuilder result = new QNameSetBuilder(this); + result.restrict(set); + return result.toQNameSet(); + } + + /** + * Returns a new QNameSet that is the union of this one and another. + * @param set the set to union with + * @return the union + */ + public QNameSet union(QNameSetSpecification set) + { + QNameSetBuilder result = new QNameSetBuilder(this); + result.addAll(set); + return result.toQNameSet(); + } + + /** + * Returns a new QNameSet that is the inverse of this one. + */ + public QNameSet inverse() + { + if (this == EMPTY) + return ALL; + if (this == ALL) + return EMPTY; + if (this == LOCAL) + return NONLOCAL; + if (this == NONLOCAL) + return LOCAL; + return new QNameSet(includedURIs(), excludedURIs(), includedQNamesInExcludedURIs(), excludedQNamesInIncludedURIs()); + } + + /** + * True if the given set is a subset of this one. + * @param set the set to test + * @return true if this contains all QNames contained by the given set + */ + public boolean containsAll(QNameSetSpecification set) + { + // a.contains(b) == a.inverse.isDisjoint(b) + if (!_inverted && set.excludedURIs() != null) + return false; + + return inverse().isDisjoint(set); + } + + /** + * True if the given set is disjoint from this one. + * @param set the set to test + * @return true if the set is disjoint from this set + */ + public boolean isDisjoint(QNameSetSpecification set) + { + if (_inverted && set.excludedURIs() != null) + return false; + + if (_inverted) + return isDisjointImpl(set, this); + else + return isDisjointImpl(this, set); + } + + private boolean isDisjointImpl(QNameSetSpecification set1, QNameSetSpecification set2) + { + Set includeURIs = set1.includedURIs(); + Set otherIncludeURIs = set2.includedURIs(); + if (otherIncludeURIs != null) + { + for (Iterator i = includeURIs.iterator(); i.hasNext(); ) + { + if (otherIncludeURIs.contains(i.next())) + return false; + } + } + else + { + Set otherExcludeURIs = set2.excludedURIs(); + for (Iterator i = includeURIs.iterator(); i.hasNext(); ) + { + if (!otherExcludeURIs.contains(i.next())) + return false; + } + } + + for (Iterator i = set1.includedQNamesInExcludedURIs().iterator(); i.hasNext(); ) + { + if (set2.contains((QName)i.next())) + return false; + } + + if (includeURIs.size() > 0) + for (Iterator i = set2.includedQNamesInExcludedURIs().iterator(); i.hasNext(); ) + { + if (set1.contains((QName)i.next())) + return false; + } + + return true; + } + + + /** + * Namespaces that are fully excluded from the set except for a finite + * number of individual QName exceptions. Returns null if this set is infinite. + * @return the set of excluded namespace URI strings + */ + public Set excludedURIs() + { + if (_inverted) return Collections.unmodifiableSet(_includedURIs); + return null; + } + + /** + * Namespaces that are fully included in set except for a finite + * number of individual QName exceptions. Returns null if this set is infinite. + * @return the set of included namespace URI strings + */ + public Set includedURIs() + { + if (!_inverted) return _includedURIs; + return null; + } + + /** + * The set of QNames excluded from the set even though they are within + * a namespace that is otherwise fully included in the set. + * @return the set of excluded QNames from within includedURI namespaces + */ + public Set excludedQNamesInIncludedURIs() + { + return Collections.unmodifiableSet(_inverted ? _includedQNames : _excludedQNames); + } + + /** + * The set of QNames included in the set even though they are within + * a namespace that is otherwise fully included in the set. + * @return the set of included QNames from within excludedURI namespaces + */ + public Set includedQNamesInExcludedURIs() + { + return Collections.unmodifiableSet(_inverted ? _excludedQNames : _includedQNames); + } + + private String prettyQName(QName name) + { + if (name.getNamespaceURI() == null) + return name.getLocalPart(); + return name.getLocalPart() + "@" + name.getNamespaceURI(); + } + + /** + * Returns a string representation useful for debugging, subject to change. + */ + public String toString() + { + StringBuffer sb = new StringBuffer(); + sb.append("QNameSet"); + sb.append(_inverted ? "-(" : "+("); + for (Iterator i = _includedURIs.iterator(); i.hasNext(); ) + { + sb.append("+*@"); + sb.append(i.next()); + sb.append(", "); + } + for (Iterator i = _excludedQNames.iterator(); i.hasNext(); ) + { + sb.append("-"); + sb.append(prettyQName((QName)i.next())); + sb.append(", "); + } + for (Iterator i = _includedQNames.iterator(); i.hasNext(); ) + { + sb.append("+"); + sb.append(prettyQName((QName)i.next())); + sb.append(", "); + } + int index = sb.lastIndexOf(", "); + if (index > 0) + sb.setLength(index); + sb.append(')'); + return sb.toString(); + } +} diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/QNameSetBuilder.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/QNameSetBuilder.java new file mode 100644 index 000000000..25945617c --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/QNameSetBuilder.java @@ -0,0 +1,721 @@ +/* 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; + +import javax.xml.namespace.QName; + +import java.util.Set; +import java.util.HashSet; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.ArrayList; + +/** + * Used to build {@link QNameSet QNameSets}. + */ +public class QNameSetBuilder implements QNameSetSpecification, java.io.Serializable +{ + private static final long serialVersionUID = 1L; + + private boolean _inverted; + private Set _includedURIs; + private Set _excludedQNames; + private Set _includedQNames; + + /** + * Constructs an empty QNameSetBuilder. + */ + public QNameSetBuilder() + { + _inverted = false; + _includedURIs = new HashSet(); + _excludedQNames = new HashSet(); + _includedQNames = new HashSet(); + } + + /** + * Constructs a QNameSetBuilder whose initial contents are given by + * another QNameSetSpecification. + * @param set the QNameSetSpecificaiton to copy + */ + public QNameSetBuilder(QNameSetSpecification set) + { + Set includedURIs = set.includedURIs(); + if (includedURIs != null) + { + _inverted = false; + _includedURIs = new HashSet(includedURIs); + _excludedQNames = new HashSet(set.excludedQNamesInIncludedURIs()); + _includedQNames = new HashSet(set.includedQNamesInExcludedURIs()); + } + else + { + _inverted = true; + _includedURIs = new HashSet(set.excludedURIs()); + _excludedQNames = new HashSet(set.includedQNamesInExcludedURIs()); + _includedQNames = new HashSet(set.excludedQNamesInIncludedURIs()); + } + } + + /** + * Constructs a QNameSetBuilder whose inital contents are given by + * the four sets. Exactly one of either excludedURIs or includedURIs must + * be non-null. + * + * @param excludedURIs the finite set of namespace URI strings to exclude from the set, or null if this set is infinite + * @param includedURIs the finite set of namespace URI strings to include in the set, or null if this set is infinite + * @param excludedQNamesInIncludedURIs the finite set of exceptional QNames to exclude from the included namespaces + * @param excludedQNamesInIncludedURIs the finite set of exceptional QNames to include that are in the excluded namespaces + */ + public QNameSetBuilder(Set excludedURIs, Set includedURIs, Set excludedQNamesInIncludedURIs, Set includedQNamesInExcludedURIs) + { + if (includedURIs != null && excludedURIs == null) + { + _inverted = false; + _includedURIs = new HashSet(includedURIs); + _excludedQNames = new HashSet(excludedQNamesInIncludedURIs); + _includedQNames = new HashSet(includedQNamesInExcludedURIs); + } + else if (excludedURIs != null && includedURIs == null) + { + _inverted = true; + _includedURIs = new HashSet(excludedURIs); + _excludedQNames = new HashSet(includedQNamesInExcludedURIs); + _includedQNames = new HashSet(excludedQNamesInIncludedURIs); + } + else + throw new IllegalArgumentException("Exactly one of excludedURIs and includedURIs must be null"); + } + + + /** + * Constructs a QNameSetBuilder whose initial contents are given + * as a list of namespace URIs, using the same format used by wildcards + * in XSD files. + * + * @param str a wildcard namespace specification string such as "##any", + * "##other", "##local", "##targetNamespace", or a space-separated + * list of URIs. + * @param targetURI the current targetNamespace + */ + public QNameSetBuilder(String str, String targetURI) + { + this(); + + if (str == null) + str = "##any"; + + String[] uri = splitList(str); + for (int i = 0; i < uri.length; i++) + { + String adduri = uri[i]; + if (adduri.startsWith("##")) + { + if (adduri.equals("##other")) + { + if (targetURI == null) + throw new IllegalArgumentException(); + QNameSetBuilder temp = new QNameSetBuilder(); + temp.addNamespace(targetURI); + temp.addNamespace(""); + temp.invert(); + addAll(temp); + continue; + } + else if (adduri.equals("##any")) + { + clear(); + invert(); + continue; + } + else if (uri[i].equals("##targetNamespace")) + { + if (targetURI == null) + throw new IllegalArgumentException(); + adduri = targetURI; + } + else if (uri[i].equals("##local")) + { + adduri = ""; + } + } + addNamespace(adduri); + } + } + + /** + * Local xml names are hased using "" as the namespace. + */ + private static String nsFromName(QName QName) + { + String ns = QName.getNamespaceURI(); + return ns == null ? "" : ns; + } + + private static final String[] EMPTY_STRINGARRAY = new String[0]; + + private static boolean isSpace(char ch) + { + switch (ch) + { + case ' ': + case '\t': + case '\r': + case '\n': + return true; + default: + return false; + } + } + + private static String[] splitList(String s) + { + if (s.length() == 0) + return EMPTY_STRINGARRAY; + + List result = new ArrayList(); + int i = 0; + int start = 0; + for (;;) + { + while (i < s.length() && isSpace(s.charAt(i))) + i += 1; + if (i >= s.length()) + return (String[])result.toArray(EMPTY_STRINGARRAY); + start = i; + while (i < s.length() && !isSpace(s.charAt(i))) + i += 1; + result.add(s.substring(start, i)); + } + } + + /** + * Remove all xml names from qnameset whose namespace matches the uri. + */ + private static void removeAllMatchingNs(String uri, Set qnameset) + { + for (Iterator i = qnameset.iterator(); i.hasNext(); ) + { + if (uri.equals(nsFromName((QName)i.next()))) + i.remove(); + } + } + + /** + * Remove all xml names from qnameset whose namespace is in the + * first set of uris but not the second. + */ + private static void removeAllMatchingFirstOnly(Set setFirst, Set setSecond, Set qnameset) + { + for (Iterator i = qnameset.iterator(); i.hasNext(); ) + { + String ns = nsFromName((QName)i.next()); + if (setFirst.contains(ns) && !setSecond.contains(ns)) + i.remove(); + } + } + + /** + * Remove all xml names from qnameset whose namespace is in both + * sets of uris. + */ + private static void removeAllMatchingBoth(Set setFirst, Set setSecond, Set qnameset) + { + for (Iterator i = qnameset.iterator(); i.hasNext(); ) + { + String ns = nsFromName((QName)i.next()); + if (setFirst.contains(ns) && setSecond.contains(ns)) + i.remove(); + } + } + + /** + * Remove all xml names from qnameset whose namespace is in neither + * set of uris. + */ + private static void removeAllMatchingNeither(Set setFirst, Set setSecond, Set qnameset) + { + for (Iterator i = qnameset.iterator(); i.hasNext(); ) + { + String ns = nsFromName((QName)i.next()); + if (!setFirst.contains(ns) && !setSecond.contains(ns)) + i.remove(); + } + } + + /** + * True if this ModelTransitionSet contains the given qname. + */ + public boolean contains(QName name) + { + boolean in = _includedURIs.contains(nsFromName(name)) ? + !_excludedQNames.contains(name) : + _includedQNames.contains(name); + return _inverted ^ in; + } + + /** + * True if this ModelTransitionSet contains all QNames. + */ + public boolean isAll() + { + return _inverted && _includedURIs.size() == 0 && _includedQNames.size() == 0; + } + + /** + * True if this ModelTransitionSet contains no QNames. + */ + public boolean isEmpty() + { + return !_inverted && _includedURIs.size() == 0 && _includedQNames.size() == 0; + } + + /** + * Returns a new QNameSet that is the intersection of this one and another. + */ + public QNameSet intersect(QNameSetSpecification set) + { + QNameSetBuilder result = new QNameSetBuilder(this); + result.restrict(set); + return result.toQNameSet(); + } + + /** + * Returns a new QNameSet that is the union of this one and another. + */ + public QNameSet union(QNameSetSpecification set) + { + QNameSetBuilder result = new QNameSetBuilder(this); + result.addAll(set); + return result.toQNameSet(); + } + + /** + * Returns a new QNameSet that is the inverse of this one. + */ + public QNameSet inverse() + { + return QNameSet.forSets(includedURIs(), excludedURIs(), includedQNamesInExcludedURIs(), excludedQNamesInIncludedURIs()); + } + + /** + * True if the parameter is a subset of this set. + */ + public boolean containsAll(QNameSetSpecification set) + { + if (!_inverted && set.excludedURIs() != null) + return false; + + return inverse().isDisjoint(set); + } + + /** + * True if the given set is disjoint from this one. + */ + public boolean isDisjoint(QNameSetSpecification set) + { + if (_inverted && set.excludedURIs() != null) + return false; + + if (_inverted) + return isDisjointImpl(set, this); + else + return isDisjointImpl(this, set); + } + + private boolean isDisjointImpl(QNameSetSpecification set1, QNameSetSpecification set2) + { + Set includeURIs = set1.includedURIs(); + Set otherIncludeURIs = set2.includedURIs(); + if (otherIncludeURIs != null) + { + for (Iterator i = includeURIs.iterator(); i.hasNext(); ) + { + if (otherIncludeURIs.contains(i.next())) + return false; + } + } + else + { + Set otherExcludeURIs = set2.excludedURIs(); + for (Iterator i = includeURIs.iterator(); i.hasNext(); ) + { + if (!otherExcludeURIs.contains(i.next())) + return false; + } + } + + for (Iterator i = set1.includedQNamesInExcludedURIs().iterator(); i.hasNext(); ) + { + if (set2.contains((QName)i.next())) + return false; + } + + if (includeURIs.size() > 0) + for (Iterator i = set2.includedQNamesInExcludedURIs().iterator(); i.hasNext(); ) + { + if (set1.contains((QName)i.next())) + return false; + } + + return true; + } + + + /** + * Clears this QNameSetBuilder + */ + public void clear() + { + _inverted = false; + _includedURIs.clear(); + _excludedQNames.clear(); + _includedQNames.clear(); + } + + /** + * Inverts this QNameSetBuilder. + */ + public void invert() + { + _inverted = !_inverted; + } + + /** + * Adds a single QName to this QNameSetBuilder. + */ + public void add(QName qname) + { + if (!_inverted) + addImpl(qname); + else + removeImpl(qname); + } + + /** + * Adds an entire namespace URI of QNames to this QNameSetBuilder. + * The empty string is used to signifiy the (local) no-namespace. + */ + public void addNamespace(String uri) + { + if (!_inverted) + addNamespaceImpl(uri); + else + removeNamespaceImpl(uri); + } + + /** + * Adds the contents of another QNameSet to this QNameSetBuilder. + */ + public void addAll(QNameSetSpecification set) + { + if (_inverted) + removeAllImpl(set.includedURIs(), set.excludedURIs(), set.includedQNamesInExcludedURIs(), set.excludedQNamesInIncludedURIs()); + else + addAllImpl(set.includedURIs(), set.excludedURIs(), set.includedQNamesInExcludedURIs(), set.excludedQNamesInIncludedURIs()); + } + + /** + * Removes the given qname from this QNameSetBuilder. + */ + public void remove(QName qname) + { + if (_inverted) + addImpl(qname); + else + removeImpl(qname); + } + + /** + * Removes an entire namespace URI from this QNameSetBuilder. + */ + public void removeNamespace(String uri) + { + if (_inverted) + addNamespaceImpl(uri); + else + removeNamespaceImpl(uri); + } + + /** + * Removes all contents of a given QNameSet from this QNameSetBuilder. + */ + public void removeAll(QNameSetSpecification set) + { + if (_inverted) + addAllImpl(set.includedURIs(), set.excludedURIs(), set.includedQNamesInExcludedURIs(), set.excludedQNamesInIncludedURIs()); + else + removeAllImpl(set.includedURIs(), set.excludedURIs(), set.includedQNamesInExcludedURIs(), set.excludedQNamesInIncludedURIs()); + } + + /** + * Restricts the contents of this QNameSetBuilder to be a subset of the + * given QNameSet. In other words, computes an intersection. + */ + public void restrict(QNameSetSpecification set) + { + if (_inverted) + addAllImpl(set.excludedURIs(), set.includedURIs(), set.excludedQNamesInIncludedURIs(), set.includedQNamesInExcludedURIs()); + else + removeAllImpl(set.excludedURIs(), set.includedURIs(), set.excludedQNamesInIncludedURIs(), set.includedQNamesInExcludedURIs()); + } + + /** + * Implementation of add(qname) that ignores inversion. + */ + private void addImpl(QName qname) + { + if (_includedURIs.contains(nsFromName(qname))) + _excludedQNames.remove(qname); + else + _includedQNames.add(qname); + } + + /** + * Implementation of add(ns) that ignores inversion. + */ + private void addNamespaceImpl(String uri) + { + if (_includedURIs.contains(uri)) + { + removeAllMatchingNs(uri, _excludedQNames); + } + else + { + removeAllMatchingNs(uri, _includedQNames); + _includedURIs.add(uri); + } + } + + /** + * Implementation of add(set) that ignores inversion. + */ + private void addAllImpl(Set includedURIs, Set excludedURIs, Set includedQNames, Set excludedQNames) + { + boolean exclude = (excludedURIs != null); + Set specialURIs = exclude ? excludedURIs : includedURIs; + + for (Iterator i = _excludedQNames.iterator(); i.hasNext(); ) + { + QName name = (QName)i.next(); + String uri = nsFromName(name); + if ((exclude ^ specialURIs.contains(uri)) && !excludedQNames.contains(name)) + i.remove(); + } + + for (Iterator i = excludedQNames.iterator(); i.hasNext(); ) + { + QName name = (QName)i.next(); + String uri = nsFromName(name); + if (!_includedURIs.contains(uri) && !_includedQNames.contains(name)) + _excludedQNames.add(name); + } + + for (Iterator i = includedQNames.iterator(); i.hasNext(); ) + { + QName name = (QName)i.next(); + String uri = nsFromName(name); + if (!_includedURIs.contains(uri)) + _includedQNames.add(name); + else + _excludedQNames.remove(name); + } + + if (!exclude) + { + removeAllMatchingFirstOnly(includedURIs, _includedURIs, _includedQNames); + _includedURIs.addAll(includedURIs); + } + else + { + removeAllMatchingNeither(excludedURIs, _includedURIs, _includedQNames); + for (Iterator i = _includedURIs.iterator(); i.hasNext(); ) + { + String uri = (String)i.next(); + if (!excludedURIs.contains(uri)) + i.remove(); + } + + for (Iterator i = excludedURIs.iterator(); i.hasNext(); ) + { + String uri = (String)i.next(); + if (!_includedURIs.contains(uri)) + _includedURIs.add(uri); + else + _includedURIs.remove(uri); + } + Set temp = _excludedQNames; + _excludedQNames = _includedQNames; + _includedQNames = temp; + _inverted = !_inverted; + } + } + + /** + * Implementation of remove(qname) that ignores inversion. + */ + private void removeImpl(QName qname) + { + if (_includedURIs.contains(nsFromName(qname))) + _excludedQNames.add(qname); + else + _includedQNames.remove(qname); + } + + /** + * Implementation of remove(ns) that ignores inversion. + */ + private void removeNamespaceImpl(String uri) + { + if (_includedURIs.contains(uri)) + { + removeAllMatchingNs(uri, _excludedQNames); + _includedURIs.remove(uri); + } + else + { + removeAllMatchingNs(uri, _includedQNames); + } + } + + /** + * Implementation of remove(set) that ignores inversion. + */ + private void removeAllImpl(Set includedURIs, Set excludedURIs, Set includedQNames, Set excludedQNames) + { + boolean exclude = (excludedURIs != null); + Set specialURIs = exclude ? excludedURIs : includedURIs; + + for (Iterator i = _includedQNames.iterator(); i.hasNext(); ) + { + QName name = (QName)i.next(); + String uri = nsFromName(name); + if (exclude ^ specialURIs.contains(uri)) + { + if (!excludedQNames.contains(name)) + i.remove(); + } + else + { + if (includedQNames.contains(name)) + i.remove(); + } + } + + for (Iterator i = includedQNames.iterator(); i.hasNext(); ) + { + QName name = (QName)i.next(); + String uri = nsFromName(name); + if (_includedURIs.contains(uri)) + _excludedQNames.add(name); + } + + for (Iterator i = excludedQNames.iterator(); i.hasNext(); ) + { + QName name = (QName)i.next(); + String uri = nsFromName(name); + if (_includedURIs.contains(uri) && !_excludedQNames.contains(name)) + _includedQNames.add(name); + } + + if (exclude) + { + removeAllMatchingFirstOnly(_includedURIs, excludedURIs, _excludedQNames); + } + else + { + removeAllMatchingBoth(_includedURIs, includedURIs, _excludedQNames); + } + + for (Iterator i = _includedURIs.iterator(); i.hasNext(); ) + { + if (exclude ^ specialURIs.contains(i.next())) + i.remove(); + } + } + + public Set excludedURIs() + { + if (_inverted) return Collections.unmodifiableSet(_includedURIs); + return null; + } + + public Set includedURIs() + { + if (!_inverted) return _includedURIs; + return null; + } + + public Set excludedQNamesInIncludedURIs() + { + return Collections.unmodifiableSet(_inverted ? _includedQNames : _excludedQNames); + } + + public Set includedQNamesInExcludedURIs() + { + return Collections.unmodifiableSet(_inverted ? _excludedQNames : _includedQNames); + } + + private String prettyQName(QName name) + { + if (name.getNamespaceURI() == null) + return name.getLocalPart(); + return name.getLocalPart() + "@" + name.getNamespaceURI(); + } + + /** + * Returns a string representation useful for debugging, subject to change. + */ + public String toString() + { + StringBuffer sb = new StringBuffer(); + sb.append("QNameSetBuilder"); + sb.append(_inverted ? "-(" : "+("); + for (Iterator i = _includedURIs.iterator(); i.hasNext(); ) + { + sb.append("+*@"); + sb.append(i.next()); + sb.append(", "); + } + for (Iterator i = _excludedQNames.iterator(); i.hasNext(); ) + { + sb.append("-"); + sb.append(prettyQName((QName)i.next())); + sb.append(", "); + } + for (Iterator i = _includedQNames.iterator(); i.hasNext(); ) + { + sb.append("+"); + sb.append(prettyQName((QName)i.next())); + sb.append(", "); + } + int index = sb.lastIndexOf(", "); + if (index > 0) + sb.setLength(index); + sb.append(')'); + return sb.toString(); + } + + /** + * Returns a {@link QNameSet} equivalent to the current state of this + * QNameSetBuilder. + */ + public QNameSet toQNameSet() + { + return QNameSet.forSpecification(this); + } +} diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/QNameSetSpecification.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/QNameSetSpecification.java new file mode 100644 index 000000000..49d2f101e --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/QNameSetSpecification.java @@ -0,0 +1,129 @@ +/* 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; + +import javax.xml.namespace.QName; + +import java.util.Set; + +/** + * Represents a lattice of finite and infinite sets of QNames. + * + * @see QNameSet + */ +public interface QNameSetSpecification +{ + /** + * True if the set contains the given QName. + * + * Roughly equivalent to: + * (includedURIs() == null ? + * excludedURIs().contains(namespace) : + * includedURIs().contains(namespace) + * ) ? + * !excludedQNamesInIncludedURIs().contains(name) : + * includedQNamesInExcludedURIs().contains(name) + */ + boolean contains(QName name); + + /** + * True if the set is the set of all QNames. + */ + boolean isAll(); + + /** + * True if the set is empty. + */ + boolean isEmpty(); + + /** + * True if the parameter is a subset of this set. + */ + boolean containsAll(QNameSetSpecification set); + + /** + * True if is disjoint from the specified set. + */ + boolean isDisjoint(QNameSetSpecification set); + + /** + * Returns the intersection with another QNameSet. + */ + QNameSet intersect(QNameSetSpecification set); + + /** + * Returns the union with another QNameSet. + */ + QNameSet union(QNameSetSpecification set); + + /** + * Return the inverse of this QNameSet. That is the QNameSet which + * contains all the QNames not contained in this set. In other words + * for which set.contains(name) != set.inverse().contains(name) for + * all names. + */ + QNameSet inverse(); + + /** + * The finite set of namespace URIs that are almost completely excluded from + * the set (that is, each namespace URI that included in the set with with + * a finite number of QName exceptions). Null if the set of namespaceURIs + * that are almost completely included is infinite. + *

    + * Null (meaning almost all URIs excluded) if includedURIs() is non-null; + * non-null otherwise. + *

    + * The same set as inverse().includedURIs(). + */ + Set excludedURIs(); + + /** + * The finite set of namespace URIs that are almost completely included in + * the set (that is, each namespace URI that included in the set with with + * a finite number of QName exceptions). Null if the set of namespaceURIs + * that are almost completely included is infinite. + *

    + * Null (meaning almost all URIs included) if excludedURIs() is non-null; + * non-null otherwise. + *

    + * The same as inverse.excludedURIs(). + */ + Set includedURIs(); + + /** + * The finite set of QNames that are excluded from the set within namespaces + * that are otherwise included. Should only contain QNames within namespace + * that are within the set includedURIs() (or any URI, if includedURIs() + * is null, which means that all URIs are almost completely included). + *

    + * Never null. + *

    + * The same set as inverse().includedQNames(). + */ + Set excludedQNamesInIncludedURIs(); + + /** + * The finite set of QNames that are included in the set within namespaces + * that are otherwise excluded. Should only contain QNames within namespace + * that are within the set excludedURIs() (or any URI, if excludedURIs() + * is null, which means that all URIs are almost completely excluded). + *

    + * Never null. + *

    + * The same as inverse().excludedQNames(). + */ + Set includedQNamesInExcludedURIs(); +} diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/ResourceLoader.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/ResourceLoader.java new file mode 100644 index 000000000..7c580a331 --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/ResourceLoader.java @@ -0,0 +1,24 @@ +/* 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; + +import java.io.InputStream; + +public interface ResourceLoader +{ + InputStream getResourceAsStream(String resourceName); + void close(); +} diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaAnnotated.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaAnnotated.java new file mode 100755 index 000000000..72302b7d3 --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaAnnotated.java @@ -0,0 +1,27 @@ +/* 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; + +/** + * Marker interface denoting that an annotation can be present + */ +public interface SchemaAnnotated +{ + /** + * Returns the Schema annotation object or null if none present + */ + SchemaAnnotation getAnnotation(); +} diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaAnnotation.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaAnnotation.java new file mode 100755 index 000000000..7d3d503cd --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaAnnotation.java @@ -0,0 +1,63 @@ +/* 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; + +import javax.xml.namespace.QName; + +/** + * Represents a Schema annotation. + */ +public interface SchemaAnnotation extends SchemaComponent +{ + /** + * Retrieves all application information items from this annotation + */ + public XmlObject[] getApplicationInformation(); + + /** + * Retrieves all document information items from this annotation + */ + public XmlObject[] getUserInformation(); + + /** + * Retrieves all attributes that are is a namespace other than + * http://www.w3.org/2001/XMLSchema + * from the annotation element and from the enclosing Schema component + */ + public Attribute[] getAttributes(); + + /** + * Represents an attribute instance + */ + public static interface Attribute + { + /** + * Returns the name of the attribute + */ + QName getName(); + + /** + * Returns the value of the attribute + */ + String getValue(); + + /** + * In case the value of this attribute is a QName, + * returns the URI to which the prefix in the value is bound + */ + String getValueUri(); + } +} diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaAttributeGroup.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaAttributeGroup.java new file mode 100644 index 000000000..edb2810f7 --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaAttributeGroup.java @@ -0,0 +1,70 @@ +/* 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; + +import javax.xml.namespace.QName; + +/** + * Represents an attribute group. + *

    + * An attribute group is a syntactic construct, not a part + * of the logical model. For example, types declared within an + * attribute group become local to the type that uses the group - + * they're not local to the attribute group itself. Therefore + * in the logical model of a schema type system, an attribute + * group doesn't represent anything. Its contents are merged + * into the logical model at parse time. + * + * @see SchemaTypeLoader#findAttributeGroup + */ +public interface SchemaAttributeGroup extends SchemaComponent, SchemaAnnotated +{ + /** + * Returns SchemaComponent.ATTRIBUTE_GROUP. + */ + int getComponentType(); + + /** + * The name of the model group. + */ + QName getName(); + + /** + * Used to allow on-demand loading of attribute groups. + * + * @exclude + */ + public final static class Ref extends SchemaComponent.Ref + { + public Ref(SchemaAttributeGroup attributeGroup) + { super(attributeGroup); } + + public Ref(SchemaTypeSystem system, String handle) + { super(system, handle); } + + public final int getComponentType() + { return SchemaComponent.ATTRIBUTE_GROUP; } + + public final SchemaAttributeGroup get() + { return (SchemaAttributeGroup)getComponent(); } + } + + /** + * Returns user-specific information. + * @see SchemaBookmark + */ + Object getUserData(); +} diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaAttributeModel.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaAttributeModel.java new file mode 100644 index 000000000..94fc61fca --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaAttributeModel.java @@ -0,0 +1,56 @@ +/* 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; + +import javax.xml.namespace.QName; + +/** + * Represents the attribute structure allowed on a complex type. + * + * @see SchemaType#getAttributeModel + */ +public interface SchemaAttributeModel +{ + /** + * Returns an array containing all the attributes in the model. + */ + SchemaLocalAttribute[] getAttributes(); + + /** + * Returns the attribute with the given name. + */ + SchemaLocalAttribute getAttribute(QName name); + + /** + * QNameSet representing the attribute wildcard specification. + */ + QNameSet getWildcardSet(); + + /** + * Returns the processing code ({@link #STRICT}, {@link #LAX}, {@link #SKIP}). + * Returns 0 ({@link #NONE}) if no wildcard specified. + */ + int getWildcardProcess(); + + /** See {@link #getWildcardProcess} */ + static final int NONE = 0; + /** Strict wildcard processing. See {@link #getWildcardProcess} */ + static final int STRICT = 1; + /** Lax wildcard processing. See {@link #getWildcardProcess} */ + static final int LAX = 2; + /** Skip wildcard processing. See {@link #getWildcardProcess} */ + static final int SKIP = 3; +} diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaBookmark.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaBookmark.java new file mode 100644 index 000000000..32e52a06a --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaBookmark.java @@ -0,0 +1,42 @@ +/* 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; + +/** + * Represents a Schema bookmark. The XMLSchema compiler will copy the value + * returned by {@link #getValue} when this bookmark is found in the XMLStore + * to the corresponding Schema* objects, and the value will be accessible using + * the getUserInfo method on these objects. + * + * @see SchemaType + * @see SchemaField + * @see SchemaAttributeGroup + * @see SchemaModelGroup + * @see SchemaIdentityConstraint + */ +public class SchemaBookmark extends XmlCursor.XmlBookmark +{ + private Object _value; + + public SchemaBookmark(Object value) + { _value = value; } + + /** + * Getter. Called during the Schema compilation process. + */ + public Object getValue() + { return _value; } +} diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaCodePrinter.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaCodePrinter.java new file mode 100755 index 000000000..8b65366d6 --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaCodePrinter.java @@ -0,0 +1,40 @@ +/* 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; + +import java.io.Writer; +import java.io.IOException; + +/** + * This class is used to provide alternate implementations of the + * schema Java code generation. + */ + +public interface SchemaCodePrinter +{ + public void printTypeImpl(Writer writer, SchemaType sType) + throws IOException; + + public void printType(Writer writer, SchemaType sType) + throws IOException; + + /** + * @deprecated Obsoleted by functionality in {@link SchemaTypeSystem.save()} + */ + public void printLoader(Writer writer, SchemaTypeSystem system) + throws IOException; +} + diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaComponent.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaComponent.java new file mode 100644 index 000000000..f62de93e2 --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaComponent.java @@ -0,0 +1,127 @@ +/* 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; + +import javax.xml.namespace.QName; + +/** + * Represents a global Schema Component. That is, a type, element, attribute, + * model group, attribute group, or identity constraint. + *

    + * Note that not all types, elements, and attributes are global; local + * types, element, and attributes do not appear in the global lookup table. + * Also note that other information items such as particles, facets, and + * so on are not globally indexed, so are not SchemaComponents. + * + * @see SchemaType + * @see SchemaGlobalElement + * @see SchemaGlobalAttribute + * @see SchemaAttributeGroup + * @see SchemaModelGroup + * @see SchemaIdentityConstraint + */ +public interface SchemaComponent +{ + /** A type definition. See {@link #getComponentType} */ + static final int TYPE = 0; + /** An element definition. See {@link #getComponentType} */ + static final int ELEMENT = 1; + /** An attribute definition. See {@link #getComponentType} */ + static final int ATTRIBUTE = 3; + /** An attribute group definition. See {@link #getComponentType} */ + static final int ATTRIBUTE_GROUP = 4; + /** An identity constraint definition. See {@link #getComponentType} */ + static final int IDENTITY_CONSTRAINT = 5; + /** A model group definition. See {@link #getComponentType} */ + static final int MODEL_GROUP = 6; + /** A notation definition. See {@link #getComponentType} */ + static final int NOTATION = 7; + /** An annotation. See {@link #getComponentType} */ + static final int ANNOTATION = 8; + + /** + * Returns the type code for the schema object, either {@link #TYPE}, + * {@link #ELEMENT}, {@link #ATTRIBUTE}, {@link #ATTRIBUTE_GROUP}, + * {@link #MODEL_GROUP}, {@link #IDENTITY_CONSTRAINT}, or {@link #NOTATION}. + */ + int getComponentType(); + + /** + * Returns the typesystem within which this component definition resides + */ + SchemaTypeSystem getTypeSystem(); + + /** + * The name of the schema component + */ + QName getName(); + + /** + * The name of resource that represends the source .xsd in which this component was defined (if known) + *
    See: {@link org.apache.xmlbeans.SchemaTypeLoader#getSourceAsStream(String)} + *

    Example:

    +     *   SchemaType schemaType = ..;
    +     *   InputStream is = schemaType.getTypeSystem().getSourceAsStream(schemaType.getSourceName());
    +     * 
    + */ + String getSourceName(); + + /** + * A lazy reference to a component. Used by SchemaTypeLoaders to + * avoid loading components until they are actually needed. + * + * @exclude + */ + public static abstract class Ref + { + protected Ref(SchemaComponent schemaComponent) + { _schemaComponent = schemaComponent; } + + protected Ref(SchemaTypeSystem schemaTypeSystem, String handle) + { assert(handle != null); _schemaTypeSystem = schemaTypeSystem; _handle = handle; } + + private volatile SchemaComponent _schemaComponent; + private SchemaTypeSystem _schemaTypeSystem; + public String _handle; + + public abstract int getComponentType(); + + public final SchemaTypeSystem getTypeSystem() + { return _schemaTypeSystem; } + + public final SchemaComponent getComponent() + { + if (_schemaComponent == null && _handle != null) + { + synchronized (this) + { + if (_schemaComponent == null && _handle != null) + { + _schemaComponent = _schemaTypeSystem.resolveHandle(_handle); + _schemaTypeSystem = null; + } + } + } + + return _schemaComponent; + } + } + + /** + * Used for on-demand loading of schema components. + */ + public Ref getComponentRef(); +} diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaField.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaField.java new file mode 100644 index 000000000..04a8b5816 --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaField.java @@ -0,0 +1,89 @@ +/* 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; + +import javax.xml.namespace.QName; + +import java.math.BigInteger; + +/** + * Represents an element or an attribute declaration. + * + * @see SchemaType#getContainerField + * @see SchemaLocalElement + * @see SchemaLocalAttribute + */ +public interface SchemaField +{ + /** + * Returns the form-unqualified-or-qualified name. + */ + QName getName(); + + /** + * True if this use is an attribute + */ + boolean isAttribute(); + + /** + * True if nillable; always false for attributes. + */ + boolean isNillable(); + + /** + * Returns the type of this use. + */ + SchemaType getType(); + + /** + * Returns the minOccurs value for this particle. + * If it is not specified explicitly, this defaults to BigInteger.ONE. + */ + BigInteger getMinOccurs(); + + /** + * Returns the maxOccurs value for this particle, or null if it + * is unbounded. + * If it is not specified explicitly, this defaults to BigInteger.ONE. + */ + BigInteger getMaxOccurs(); + + /** + * The default value as plain text. See {@link #isDefault} and {@link #isFixed}. + */ + String getDefaultText(); + + /** + * The default value as a strongly-typed value. See {@link #isDefault} and {@link #isFixed}. + */ + XmlAnySimpleType getDefaultValue(); + + /** + * True if a default is supplied. If {@link #isFixed}, then isDefault is always true. + */ + boolean isDefault(); + + /** + * True if the value is fixed. + */ + boolean isFixed(); + + /** + * Returns user-specific information. + * @see SchemaBookmark + */ + Object getUserData(); +} diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaGlobalAttribute.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaGlobalAttribute.java new file mode 100644 index 000000000..81040819a --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaGlobalAttribute.java @@ -0,0 +1,50 @@ +/* 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; + +/** + * Represents a global attribute definition + * + * @see SchemaTypeLoader#findAttribute + */ +public interface SchemaGlobalAttribute extends SchemaLocalAttribute, SchemaComponent +{ + /** + * Used to allow on-demand loading of elements. + * + * @exclude + */ + public final static class Ref extends SchemaComponent.Ref + { + public Ref(SchemaGlobalAttribute element) + { super(element); } + + public Ref(SchemaTypeSystem system, String handle) + { super(system, handle); } + + public final int getComponentType() + { return SchemaComponent.ATTRIBUTE; } + + public final SchemaGlobalAttribute get() + { return (SchemaGlobalAttribute)getComponent(); } + } + + /** + * Retruns a SchemaGlobalElement.Ref pointing to this element itself. + */ + public Ref getRef(); + +} diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaGlobalElement.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaGlobalElement.java new file mode 100644 index 000000000..ee38086b3 --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaGlobalElement.java @@ -0,0 +1,85 @@ +/* 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; + +import javax.xml.namespace.QName; + +/** + * Represents a global element definition. + * + * @see SchemaTypeLoader#findElement + */ +public interface SchemaGlobalElement extends SchemaLocalElement, SchemaComponent +{ + /** + * Set of QNames for elements that are the members of the + * substitution group for which this element is the head, + * not including this element. + */ + QName[] substitutionGroupMembers(); + + /** + * The element that is the head of this element's substitution + * group, or null if this element is not a member + * of a substitution group. + */ + SchemaGlobalElement substitutionGroup(); + + /** + * True if using this element as the head of a substitution + * group for a substitution via type extension is prohibited. + * If both finalExtension and finalRestriction are true, this + * element cannot be head of a substitution group. + * Sensible only for global elements. + */ + public boolean finalExtension(); + + /** + * True if using this element as the head of a substitution + * group for a substitution via type restriction is prohibited. + * If both finalExtension and finalRestriction are true, this + * element cannot be head of a substitution group. + * Sensible only for global elements. + */ + public boolean finalRestriction(); + + /** + * Used to allow on-demand loading of elements. + * + * @exclude + */ + public final static class Ref extends SchemaComponent.Ref + { + public Ref(SchemaGlobalElement element) + { super(element); } + + public Ref(SchemaTypeSystem system, String handle) + { super(system, handle); } + + public final int getComponentType() + { return SchemaComponent.ELEMENT; } + + public final SchemaGlobalElement get() + { return (SchemaGlobalElement)getComponent(); } + } + + /** + * Retruns a SchemaGlobalElement.Ref pointing to this element itself. + */ + public Ref getRef(); + + +} diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaIdentityConstraint.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaIdentityConstraint.java new file mode 100644 index 000000000..cf5933a7d --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaIdentityConstraint.java @@ -0,0 +1,97 @@ +/* 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; + +import javax.xml.namespace.QName; +import java.util.Map; + +/** + * Represents an identity constraint definition. + */ +public interface SchemaIdentityConstraint extends SchemaComponent, SchemaAnnotated +{ + /** + * Return the selector xpath as a string. + */ + String getSelector(); + + /** + * Return a compiled xpath object for the selector. + */ + Object getSelectorPath(); + + /** + * Return (a copy of) the xpaths for all the fields. + */ + String[] getFields(); + + /** + * Return a compiled xpath object for the field. + */ + Object getFieldPath(int index); + + /** + * Return a read-only copy of the namespace map. This is the + * set of prefix to URI mappings that were in scope in the + * schema at the point at which this constraint was declared + */ + Map getNSMap(); + + /** A xs:key constraint. See {@link #getConstraintCategory}. */ + public static final int CC_KEY = 1; + /** A xs:keyRef constraint. See {@link #getConstraintCategory}. */ + public static final int CC_KEYREF = 2; + /** A xs:unique constraint. See {@link #getConstraintCategory}. */ + public static final int CC_UNIQUE = 3; + + /** + * Return the constraint category. Either {@link #CC_KEY}, {@link #CC_KEYREF}, + * or {@link #CC_UNIQUE}. + */ + int getConstraintCategory(); + + /** + * Returns the key that a key ref refers to. Only valid for + * keyrefs. + */ + SchemaIdentityConstraint getReferencedKey(); + + /** + * Used to allow on-demand loading of identity constraints. + * + * @exclude + */ + public static final class Ref extends SchemaComponent.Ref + { + public Ref(SchemaIdentityConstraint idc) + { super(idc); } + + public Ref(SchemaTypeSystem system, String handle) + { super(system, handle); } + + public final int getComponentType() + { return SchemaComponent.IDENTITY_CONSTRAINT; } + + public final SchemaIdentityConstraint get() + { return (SchemaIdentityConstraint)getComponent(); } + } + + /** + * Returns user-specific information. + * @see SchemaBookmark + */ + Object getUserData(); +} diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaLocalAttribute.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaLocalAttribute.java new file mode 100644 index 000000000..cda208847 --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaLocalAttribute.java @@ -0,0 +1,38 @@ +/* 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; + +/** + * Represents a local or global attribute definition. + */ +public interface SchemaLocalAttribute extends SchemaField, SchemaAnnotated +{ + /** + * Returns {@link #PROHIBITED}, {@link #OPTIONAL}, or {@link #REQUIRED}. + * (Actually, never returns PROHIBITED because the schema specificaion + * states that a prohibited attribute is equivalent to no attribute + * at all, so a prohibited attribute will never be present in the compiled + * model.) + */ + int getUse(); + + /** A prohibited attribute. See {@link #getUse}. */ + static final int PROHIBITED = 1; + /** An optional attribute. See {@link #getUse}. */ + static final int OPTIONAL = 2; + /** A required attribute. See {@link #getUse}. */ + static final int REQUIRED = 3; +} diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaLocalElement.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaLocalElement.java new file mode 100644 index 000000000..704d5d2de --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaLocalElement.java @@ -0,0 +1,53 @@ +/* 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; + +/** + * Represents a local or global element definition. + */ +public interface SchemaLocalElement extends SchemaField, SchemaAnnotated +{ + /** + * True if extension is blocked. + */ + boolean blockExtension(); + /** + * True if restriction is blocked. + */ + boolean blockRestriction(); + /** + * True if element substitution is blocked. + */ + boolean blockSubstitution(); + + /** + * True if this element is prohibited in content. Only + * sensible if this is the head of a substitution group; + * then only substitution group members can appear.

    + * + * Although local elements cannot be abstract, if an element + * use is a ref to a global element, then the flag from the + * global element is copied in to the local element where the + * use occurs. + */ + boolean isAbstract(); + + /** + * Returns all the Key, KeyRef, and Unique constraints + * on this element. + */ + SchemaIdentityConstraint[] getIdentityConstraints(); +} diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaModelGroup.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaModelGroup.java new file mode 100644 index 000000000..34a0ce400 --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaModelGroup.java @@ -0,0 +1,68 @@ +/* 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; + +import javax.xml.namespace.QName; + +/** + * Represents a model group. + *

    + * A model group is a syntactic construct, not a part of + * the logical model. For example, types declared within a + * model group become local to the type that uses the group - + * they're not local to the model group itself. Therefore in + * the logical model of a schema type system, a model group + * doesn't represent anything. Its contents are merged into + * the logical model at parse time. + */ +public interface SchemaModelGroup extends SchemaComponent, SchemaAnnotated +{ + /** + * Returns SchemaComponent.GROUP. + */ + int getComponentType(); + + /** + * The name of the model group. + */ + QName getName(); + + /** + * Used to allow on-demand loading of model groups. + * + * @exclude + */ + public final static class Ref extends SchemaComponent.Ref + { + public Ref(SchemaModelGroup modelGroup) + { super(modelGroup); } + + public Ref(SchemaTypeSystem system, String handle) + { super(system, handle); } + + public final int getComponentType() + { return SchemaComponent.MODEL_GROUP; } + + public final SchemaModelGroup get() + { return (SchemaModelGroup)getComponent(); } + } + + /** + * Returns user-specific information. + * @see SchemaBookmark + */ + Object getUserData(); +} diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaParticle.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaParticle.java new file mode 100644 index 000000000..22dbd215c --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaParticle.java @@ -0,0 +1,197 @@ +/* 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; + +import java.math.BigInteger; + +import javax.xml.namespace.QName; + +/** + * Represents a Schema particle definition. + *

    + * The content model of a complex type is a tree of particles. Each + * particle is either an {@link #ALL}, {@link #CHOICE}, {@link #SEQUENCE}, + * {@link #ELEMENT}, or {@link #WILDCARD}. + * All, choice and sequence particles are groups that can have child + * particles; elements and wildcards are always leaves of the particle tree. + *

    + * The tree of particles available on a schema type is minimized, that + * is, it already has removed "pointless" particles such as empty + * sequences, nonrepeating sequences with only one item, and so on. + * (Pointless particles + * are defined precisely in the XML Schema specification.) + * + * @see SchemaType#getContentModel + */ +public interface SchemaParticle +{ + /** + * Returns the particle type ({@link #ALL}, {@link #CHOICE}, + * {@link #SEQUENCE}, {@link #ELEMENT}, or {@link #WILDCARD}). + */ + int getParticleType(); + + /** + * An xs:all group. + * See {@link #getParticleType}. + */ + static final int ALL = 1; + /** + * A xs:choice group. + * See {@link #getParticleType}. + */ + static final int CHOICE = 2; + /** + * A xs:sequence group. + * See {@link #getParticleType}. + */ + static final int SEQUENCE = 3; + /** + * An xs:element particle. + * This code means the particle can be coerced to {@link SchemaLocalElement}. + * See {@link #getParticleType}. + */ + static final int ELEMENT = 4; + /** + * An xs:any particle, + * also known as an element wildcard. + * See {@link #getParticleType}. + */ + static final int WILDCARD = 5; + + /** + * Returns the minOccurs value for this particle. + * If it's not specified explicitly, this returns BigInteger.ONE. + */ + BigInteger getMinOccurs(); + + /** + * Returns the maxOccurs value for this particle, or null if it + * is unbounded. + * If it's not specified explicitly, this returns BigInteger.ONE. + */ + BigInteger getMaxOccurs(); + + /** + * Returns the minOccurs value, pegged to a 32-bit int for + * convenience of a validating state machine that doesn't count + * higher than MAX_INT anyway. + */ + public int getIntMinOccurs(); + + /** + * Returns the maxOccurs value, pegged to a 32-bit int for + * convenience of a validating state machine that doesn't count + * higher than MAX_INT anyway. Unbounded is given as MAX_INT. + */ + public int getIntMaxOccurs(); + + + /** + * One if minOccurs == maxOccurs == 1. + */ + boolean isSingleton(); + + /** + * Applies to sequence, choice, and all particles only: returns an array + * of all the particle children in order. + */ + SchemaParticle[] getParticleChildren(); + + /** + * Another way to access the particle children. + */ + SchemaParticle getParticleChild(int i); + + /** + * The number of children. + */ + int countOfParticleChild(); + + /** + * True if this particle can start with the given element + * (taking into account the structure of all child particles + * of course). + */ + boolean canStartWithElement(QName name); + + /** + * Returns the QNameSet of element names that can be + * accepted at the beginning of this particle. + */ + QNameSet acceptedStartNames(); + + /** + * True if this particle can be skipped (taking into account + * both the minOcurs as well as the structure of all the + * child particles) + */ + boolean isSkippable(); + + /** + * For wildcards, returns a QNameSet representing the wildcard. + */ + QNameSet getWildcardSet(); + + /** + * For wildcards, returns the processing code ({@link #STRICT}, {@link #LAX}, {@link #SKIP}). + */ + int getWildcardProcess(); + + /** Strict wildcard processing. See {@link #getWildcardProcess} */ + static final int STRICT = 1; + /** Lax wildcard processing. See {@link #getWildcardProcess} */ + static final int LAX = 2; + /** Skip wildcard processing. See {@link #getWildcardProcess} */ + static final int SKIP = 3; + + /** + * For elements only: the QName for the element use. + * May be unqualified version of referenced element's name. + */ + QName getName(); + + /** + * For elements only: returns the type of the element. + */ + SchemaType getType(); + + /** + * For elements only: true if nillable. + */ + boolean isNillable(); + + /** + * For elements only: returns the default (or fixed) text value + */ + String getDefaultText(); + + /** + * For elements only: returns the default (or fixed) strongly-typed value + */ + XmlAnySimpleType getDefaultValue(); + + /** + * For elements only: True if has default. If isFixed, then isDefault is always true. + */ + boolean isDefault(); + + /** + * For elements only: true if is fixed value. + */ + boolean isFixed(); + +} diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaProperty.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaProperty.java new file mode 100644 index 000000000..e99301203 --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaProperty.java @@ -0,0 +1,232 @@ +/* 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; + +import java.math.BigInteger; + +import javax.xml.namespace.QName; + +/** + * Represents a summary of similar SchemaFields in a complex type. + *

    + * In a schema type, every element with the same name must have the + * same type. Therefore, all together, elements with the same name + * form a coherent collection of similar elements. Similarly, attributes + * can only be defined once, so each attribute obviously is a coherent + * group on its own. + *

    + * A SchemaProperty represents a summary of the the elements with a + * given name or the attribute with a given name. It represents the + * summary cardinality of the fields, the summary default and fixed + * values, and so on. When inferring information about an element + * or attribute, it is typically easier to consult then SchemaProperty + * than to hunt for the exact SchemaField in the particle tree or + * attribute model. + * + * @see SchemaType#getProperties + * @see SchemaType#getAttributeProperties + * @see SchemaType#getElementProperties + * @see SchemaType#getAttributeProperty + * @see SchemaType#getElementProperty + */ +public interface SchemaProperty +{ + /** + * The type within which this property appears + */ + SchemaType getContainerType(); + + /** + * The name of this element or attribute + */ + QName getName(); + + /** + * For element properties the set of names that are accepted for this property + * if this element is the head of a substitution group. This will always + * have at least one element, ie, the property's name. + */ + QName[] acceptedNames(); + + /** + * The Java name for this property. For example, if the method to + * access this property is called getFirstName, then this method + * returns the string "FirstName". May be null if the schema type + * has not been compiled to Java. + */ + String getJavaPropertyName(); + + /** + * True for read-only properties. + */ + boolean isReadOnly(); + + /** + * True for attributes. + */ + boolean isAttribute(); + + /** + * The schema type for the property. + */ + SchemaType getType(); + + // note that in the inheritance hierarchy, if the array getter shows up first, + // then the singelton getter is never allowed to show up. + + /** + * The schema type returned from the Java getter for this property. + * Applies only to types that have been code generated to Java; may + * be a base type of getType(). + */ + public SchemaType javaBasedOnType(); // Java property type based on this base type + + /** + * True if there is a Java getter that returns a singleton. + */ + boolean extendsJavaSingleton(); // has singleton getter + + /** + * True if there is an Java isSet method that tests for presence. + */ + boolean extendsJavaOption(); // has isSet tester + + /** + * True if there is a Java getter that returns an array. + */ + boolean extendsJavaArray(); // has array getter (called -Array, if singleton is present) + + /** + * Returns the natural Java type for this property. Returns either + * XML_OBJECT (for complex types) or one of the JAVA_* constants described + * in this interface. + */ + int getJavaTypeCode(); + + /** + * Returns the set of element names which should appear strictly after all + * occurences of the elements described by this property. For element properties only. + */ + QNameSet getJavaSetterDelimiter(); + + /** + * Returns a summarized minimum occurrance number. + * For example, a sequence containing a nonoptional singleton element repeated twice will + * result in a property getMinOccurs() of 2. + */ + BigInteger getMinOccurs(); + + /** + * Returns a summarized minimum occurrance number. + * For example, a sequence containing a nonoptional singleton element repeated twice will + * result in a property getMaxOccurs() of 2. + */ + BigInteger getMaxOccurs(); + + /** + * Returns {@link #NEVER}, {@link #VARIABLE}, or {@link #CONSISTENTLY} nillable, depending on the + * nillability of the elements in this property. + */ + int hasNillable(); + + /** + * Returns {@link #NEVER}, {@link #VARIABLE}, or {@link #CONSISTENTLY} defaulted, depending on the + * defaults present in the elements in this property. + */ + int hasDefault(); + + /** + * Returns {@link #NEVER}, {@link #VARIABLE}, or {@link #CONSISTENTLY} fixed, depending on the + * fixed constraints present in the elements in this property. + */ + int hasFixed(); + + /** Applies to no elements for this property. See {@link #hasNillable}, {@link #hasDefault}, {@link #hasFixed} */ + static final int NEVER = 0; + /** Applies to some, but not other elements for this property. See {@link #hasNillable}, {@link #hasDefault}, {@link #hasFixed} */ + static final int VARIABLE = 1; + /** Applies to all elements for this property. See {@link #hasNillable}, {@link #hasDefault}, {@link #hasFixed} */ + static final int CONSISTENTLY = 2; + + /** An XML Bean type that inherits from {@link XmlObject}. See {@link #getJavaTypeCode}. */ + static final int XML_OBJECT = 0; + + /** Java primitive type codes (for non-nullable Java types) are between JAVA_FIRST_PRIMITIVE and JAVA_LAST_PRIMITIVE, inclusive. */ + static final int JAVA_FIRST_PRIMITIVE = 1; + + /** A Java boolean. See {@link #getJavaTypeCode}. */ + static final int JAVA_BOOLEAN = 1; + /** A Java float. See {@link #getJavaTypeCode}. */ + static final int JAVA_FLOAT = 2; + /** A Java double. See {@link #getJavaTypeCode}. */ + static final int JAVA_DOUBLE = 3; + /** A Java byte. See {@link #getJavaTypeCode}. */ + static final int JAVA_BYTE = 4; + /** A Java short. See {@link #getJavaTypeCode}. */ + static final int JAVA_SHORT = 5; + /** A Java int. See {@link #getJavaTypeCode}. */ + static final int JAVA_INT = 6; + /** A Java long. See {@link #getJavaTypeCode}. */ + static final int JAVA_LONG = 7; + + /** Java primitive type codes (for non-nullable Java types) are between JAVA_FIRST_PRIMITIVE and JAVA_LAST_PRIMITIVE, inclusive. */ + static final int JAVA_LAST_PRIMITIVE = 7; + + /** A {@link java.math.BigDecimal}. See {@link #getJavaTypeCode}. */ + static final int JAVA_BIG_DECIMAL = 8; + /** A {@link java.math.BigInteger}. See {@link #getJavaTypeCode}. */ + static final int JAVA_BIG_INTEGER = 9; + /** A {@link String}. See {@link #getJavaTypeCode}. */ + static final int JAVA_STRING = 10; + /** A byte[]. See {@link #getJavaTypeCode}. */ + static final int JAVA_BYTE_ARRAY = 11; + /** A {@link GDate}. See {@link #getJavaTypeCode}. */ + static final int JAVA_GDATE = 12; + /** A {@link GDuration}. See {@link #getJavaTypeCode}. */ + static final int JAVA_GDURATION = 13; + /** A {@link java.util.Date}. See {@link #getJavaTypeCode}. */ + static final int JAVA_DATE = 14; + /** A {@link javax.xml.namespace.QName}. See {@link #getJavaTypeCode}. */ + static final int JAVA_QNAME = 15; + /** A {@link java.util.List}. See {@link #getJavaTypeCode}. */ + static final int JAVA_LIST = 16; + /** A {@link java.util.Calendar}. See {@link #getJavaTypeCode}. */ + static final int JAVA_CALENDAR = 17; + + /** A generated {@link StringEnumAbstractBase} subclass. See {@link #getJavaTypeCode}. */ + static final int JAVA_ENUM = 18; + /** A {@link java.lang.Object}, used for some simple type unions. See {@link #getJavaTypeCode}. */ + static final int JAVA_OBJECT = 19; // for some unions + + /** A user specified type. */ + static final int JAVA_USER = 20; + + /** + * Returns the default or fixed value, + * if it is consistent. If it is not consistent, + * then returns null. + * See {@link #hasDefault} and {@link #hasFixed}. + */ + String getDefaultText(); + + /** + * Returns the default or fixed value as a strongly-typed value, + * if it is consistent. If it is not consistent, + * then returns null. + * See {@link #hasDefault} and {@link #hasFixed}. + */ + XmlAnySimpleType getDefaultValue(); +} diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaStringEnumEntry.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaStringEnumEntry.java new file mode 100644 index 000000000..710ff5651 --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaStringEnumEntry.java @@ -0,0 +1,39 @@ +/* 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; + +/** + * Describes a code-generated string enumeration + * + * @see SchemaType#getStringEnumEntries + */ +public interface SchemaStringEnumEntry +{ + /** + * The enumerated string value + */ + public String getString(); + + /** + * An integer to represent this choice in the enumeration + */ + public int getIntValue(); + + /** + * A capitalized name to use for the enumeration constant name + */ + public String getEnumName(); +} diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaType.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaType.java new file mode 100644 index 000000000..fc10375b5 --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaType.java @@ -0,0 +1,908 @@ +/* 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; + +import javax.xml.namespace.QName; + +/** + * Represents a schema type. + *

    + * SchemaType is the metadata "type" class for {@link XmlObject}, and it plays the + * analogous role for {@link XmlObject} that {@link java.lang.Class} plays for + * {@link java.lang.Object}. + *

    + * Every XML Bean class corresponds to a singleton SchemaType object + * obtainable by ClassName.type (e.g., {@link XmlNonPositiveInteger#type}), and + * every XML Bean instance has an actual SchemaType, obtainable by + * {@link XmlObject#schemaType}. The ClassName.type and schemaType() mechanisms are + * analogous to the ordinary Java ClassName.class and obj.getClass() mechanisms. + *

    + * All schema types are represented by a SchemaType, this includes all types + * regardless of whether they are built-in or user-defined, compiled or + * uncompiled, simple or complex. + *

    + * In addition, a compiled XML Bean type system includes special "document" schema types + * each representing a document containing nothing but a single element for each + * global element, and special "attribute" schema types each representing + * a fragment containing nothing but a single global attribute for global + * attribute. + *

    + * Do not confuse Schema Types with other types of Schema Components such as + * {@link SchemaGlobalElement Global Elements}, {@link SchemaGlobalAttribute Global Attributes}, + * {@link SchemaModelGroup Named Model Groups}, or {@link SchemaAttributeGroup Attribute Groups}. + * SchemaType represents a Type component, not any of the other kinds of components. + * There are different kinds of metadata objects for the different Schema components. + *

    + * The space of SchemaTypes is divided as follows: + * + *

      + *
    • First, there is the universal base type and the universal + * subtype. These are {@link XmlObject#type} + * (corresponding to xs:anyType) and {@link XmlBeans#NO_TYPE}, + * respectively. The first type is a base type of all other + * types. The other type indicates the absence of type information + * and, at least in set-theoretic terms, is a subtype of all other types. + *
    • There is another universal base type that is the base type + * for all simple types. This is the {@link XmlAnySimpleType#type}, + * corresponding to xs:anySimpleType. Only XmlObject.type and + * XmlAnySimpleType.type return true for {@link #isURType}, and + * only XmlBeans.NO_TYPE returns true for {@link #isNoType}. + *
    • The two "special" kinds of types that are generated that + * do not formally exist in the actual Schema specification are + * document types and global attribute types (corresponding to + * documents that contain a global element, or fragments that + * contain a global attribute). They can be detected using + * {@link #isDocumentType} and {@link #isAttributeType}. Other + * than their anonymity (lack of a type name) and their appearance + * only at the root of an instance, they are otherwise just like + * ordinary complex types. + *
    • Simple types can be detected using {@link #isSimpleType}. + * Complex types are consdered to be all the types that are + * not simple. + *
    • Simple types are divided into three varieties: atomic types, + * list types, and union types. Which variety of simple type + * you have can be discoverd using {@link #getSimpleVariety}. + * It will return either {@link #ATOMIC}, {@link #LIST}, or + * {@link #UNION}. + *
    • An {@link #ATOMIC} simple type is always based on one of the + * 20 built-in primitive schema types. You can determine + * the underlying primitive type for an atomic simple type + * by calling {@link #getPrimitiveType}. An atomic type + * may add facet restrictions on top of the primitive type, + * and these facets can be explored using {@link #getFacet}, + * {@link #getWhiteSpaceRule}, {@link #matchPatternFacet}, + * {@link #getEnumerationValues}, and related methods. + *
    • A {@link #LIST} simple type is always based on another non-list + * simple type. The underlying list item type can be obtained + * by using {@link #getListItemType}. + *
    • A {@link #UNION} simple type is always composed out of a number of + * other simple types. The direct members of the union can + * be obtained by {@link #getUnionMemberTypes}. When unions + * consist of other unions, it is useful to know useful to know + * the "leaves of the union tree", so the + * set of non-union types making up the union can be obtained + * by {@link #getUnionConstituentTypes}. The closure of the + * entire "union tree" is {@link #getUnionSubTypes} (this includes + * the type itself). For + * simple unions that do not consist of other unions, all three + * of these sets are the same. + *
    • Complex types have nested structure. They are divided into + * four content types: empty content, simple content, element-only + * content, and mixed content. All kinds of complex types may + * have attributes. The content type for a complex type can + * be dermined using {@link #getContentType}. This will return + * {@link #EMPTY_CONTENT}, {@link #SIMPLE_CONTENT}, + * {@link #ELEMENT_CONTENT}, or {@link #MIXED_CONTENT}. + *
    • If a complex type has {@link #EMPTY_CONTENT}, the content model will be null. + *
    • If a complex type has {@link #SIMPLE_CONTENT}, then it will extend the + * simple type that describes the content. In addition, the type + * may impose additional simple type facet restrictions; these can + * be determined in the same way they are for a simple type. + *
    • If a complex type has {@link #ELEMENT_CONTENT} or {@link #MIXED_CONTENT}, then + * the detailed content model can be determined by examining + * the particle tree (which may be null for MIXED_CONTENT). + * The particle tree can be obtained via {@link #getContentModel}. + *
    • When working with a complex type, most users will find it + * sufficient to discover the summarized shape of the content model + * and attribute model using {@link #getElementProperties}, + * {@link #getAttributeProperties}, and related methods rather than + * examining the particle tree and attribute model directly. + *
    + * + * @see SchemaTypeLoader + * @see XmlObject#schemaType + * @see SimpleValue#instanceType + */ +public interface SchemaType extends SchemaComponent, SchemaAnnotated +{ + /** + * The name used to describe the type in the schema. + * Null if the type is anonymous (nested), or if it is a document type. + */ + public abstract QName getName(); + + /** + * The parent schema element. + * Null for top-level (named) types and document types. + */ + public abstract SchemaField getContainerField(); + + /** + * True if this is a document type. + *

    + * Document types are generated for every global element. A document + * type is an unnamed complex type that contains exactly one element: + * we define these types, because they are the types of the "documents" + * which contain the defined global elements, and they all turn into + * Java types. (Named ElementnameDocument.) + */ + public boolean isDocumentType(); + + /** + * True if this is a attribute type. + *

    + * Attribute types are generated for every global attribute. An attribute + * type is an unnamed complex type that contains exactly one attribute: + * we define these types, because they are the types of the "attribute documents" + * which contain the defined global attribute, and they all turn into + * Java types. (Named AttributenameAttribute.) + */ + public boolean isAttributeType(); + + + /** + * Returns the document element name if this is a document type, + * or null otherwise. + */ + public QName getDocumentElementName(); + + /** + * Returns the attribute qname if this is a attribute type, + * or null otherwise. + */ + public QName getAttributeTypeAttributeName(); + + /** + * The outer schema type. + * Null for top-level (named) types. + */ + public abstract SchemaType getOuterType(); + + /** + * True if this anonymous type has no corresponding Java type. True for + * anonymous types nested within simple type restrictions. + */ + public abstract boolean isSkippedAnonymousType(); + + /** + * True if this schema type was compiled to have a corresponding + * Java class. + */ + public abstract boolean isCompiled(); + + /** + * The fully-qualified Java type name of the class. + */ + public abstract String getFullJavaName(); + + /** + * The short unqualfiied Java name for the class. + */ + public abstract String getShortJavaName(); + + /** + * The fully-qualified Java type name of the implementation class. + */ + public abstract String getFullJavaImplName(); + + /** + * The short unqualfiied Java name for the implementation class. + */ + public abstract String getShortJavaImplName(); + + /** + * The Java class corresponding to this schema type. + */ + public abstract Class getJavaClass(); + + /** + * The Java class corresponding to the enumeration type for this schema type, + * if applicable (or null if not an enumeration). + */ + public abstract Class getEnumJavaClass(); + + /** + * Returns user-specific information. + * @see SchemaBookmark + */ + public Object getUserData(); + + /** + * True if the Xsd type is anonymous (i.e., not top-level). + */ + public abstract boolean isAnonymousType(); + + /** + * True for any of the 40+ built-in types. + */ + public abstract boolean isBuiltinType(); + + /** + * True for the anySimpleType and any restrictions/unions/lists. + */ + public abstract boolean isSimpleType(); + + /** + * Returns base restriction or extension type. Unions and lists + * return the anySimpleType. + */ + public abstract SchemaType getBaseType(); + + /** + * Returns common base type with the given type. The returned + * type is the most specific declared base type of both types. + */ + public abstract SchemaType getCommonBaseType(SchemaType type); + + /** + * True if the specified type derives from this type (or if + * it is the same type). + * + * Note that XmlObject.type (the anyType) is assignable + * from all type, and the XmlBeans.noType (the absence of + * a type) is assignable to all types. + */ + public abstract boolean isAssignableFrom(SchemaType type); + + /** + * Returns an integer for the derivation type, either + * {@link #DT_EXTENSION}, {@link #DT_RESTRICTION}, {@link #DT_NOT_DERIVED}. + */ + public int getDerivationType(); + + /** Not derived. True for XmlObject.type only. See {@link #getDerivationType}. */ + public static final int DT_NOT_DERIVED = 0; + /** Derived by restriction. See {@link #getDerivationType}. */ + public static final int DT_RESTRICTION = 1; + /** Derived by extension. See {@link #getDerivationType}. */ + public static final int DT_EXTENSION = 2; + + /** + * Returns an integer for builtin types that can be used + * for quick comparison. + */ + public abstract int getBuiltinTypeCode(); + + /** Not a builtin type */ + public static final int BTC_NOT_BUILTIN = 0; + /** xs:anyType, aka {@link XmlObject#type} */ + public static final int BTC_ANY_TYPE = 1; + + /** The primitive types have codes between BTC_FIRST_PRIMITIVE and BTC_LAST_PRIMITIVE inclusive */ + public static final int BTC_FIRST_PRIMITIVE = 2; + + /** xs:anySimpleType, aka {@link XmlAnySimpleType#type} */ + public static final int BTC_ANY_SIMPLE = 2; + + /** xs:boolean, aka {@link XmlBoolean#type} */ + public static final int BTC_BOOLEAN = 3; + /** xs:base64Binary, aka {@link XmlBase64Binary#type} */ + public static final int BTC_BASE_64_BINARY = 4; + /** xs:hexBinary, aka {@link XmlBase64Binary#type} */ + public static final int BTC_HEX_BINARY = 5; + /** xs:anyURI, aka {@link XmlAnyURI#type} */ + public static final int BTC_ANY_URI = 6; + /** xs:QName, aka {@link XmlQName#type} */ + public static final int BTC_QNAME = 7; + /** xs:NOTATION, aka {@link XmlNOTATION#type} */ + public static final int BTC_NOTATION = 8; + /** xs:float, aka {@link XmlFloat#type} */ + public static final int BTC_FLOAT = 9; + /** xs:double, aka {@link XmlDouble#type} */ + public static final int BTC_DOUBLE = 10; + /** xs:decimal, aka {@link XmlDecimal#type} */ + public static final int BTC_DECIMAL = 11; + /** xs:string, aka {@link XmlString#type} */ + public static final int BTC_STRING = 12; + + /** xs:duration, aka {@link XmlDuration#type} */ + public static final int BTC_DURATION = 13; + /** xs:dateTime, aka {@link XmlDateTime#type} */ + public static final int BTC_DATE_TIME = 14; + /** xs:time, aka {@link XmlTime#type} */ + public static final int BTC_TIME = 15; + /** xs:date, aka {@link XmlDate#type} */ + public static final int BTC_DATE = 16; + /** xs:gYearMonth, aka {@link XmlGYearMonth#type} */ + public static final int BTC_G_YEAR_MONTH = 17; + /** xs:gYear, aka {@link XmlGYear#type} */ + public static final int BTC_G_YEAR = 18; + /** xs:gMonthDay, aka {@link XmlGMonthDay#type} */ + public static final int BTC_G_MONTH_DAY = 19; + /** xs:gDay, aka {@link XmlGDay#type} */ + public static final int BTC_G_DAY = 20; + /** xs:gMonth, aka {@link XmlGMonth#type} */ + public static final int BTC_G_MONTH = 21; + + /** The primitive types have codes between BTC_FIRST_PRIMITIVE and BTC_LAST_PRIMITIVE inclusive */ + public static final int BTC_LAST_PRIMITIVE = 21; + + // derived numerics + /** xs:integer, aka {@link XmlInteger#type} */ + public static final int BTC_INTEGER = 22; + /** xs:long, aka {@link XmlLong#type} */ + public static final int BTC_LONG = 23; + /** xs:int, aka {@link XmlInt#type} */ + public static final int BTC_INT = 24; + /** xs:short, aka {@link XmlShort#type} */ + public static final int BTC_SHORT = 25; + /** xs:byte, aka {@link XmlByte#type} */ + public static final int BTC_BYTE = 26; + /** xs:nonPositiveInteger, aka {@link XmlNonPositiveInteger#type} */ + public static final int BTC_NON_POSITIVE_INTEGER = 27; + /** xs:NegativeInteger, aka {@link XmlNegativeInteger#type} */ + public static final int BTC_NEGATIVE_INTEGER = 28; + /** xs:nonNegativeInteger, aka {@link XmlNonNegativeInteger#type} */ + public static final int BTC_NON_NEGATIVE_INTEGER = 29; + /** xs:positiveInteger, aka {@link XmlPositiveInteger#type} */ + public static final int BTC_POSITIVE_INTEGER = 30; + /** xs:unsignedLong, aka {@link XmlUnsignedLong#type} */ + public static final int BTC_UNSIGNED_LONG = 31; + /** xs:unsignedInt, aka {@link XmlUnsignedInt#type} */ + public static final int BTC_UNSIGNED_INT = 32; + /** xs:unsignedShort, aka {@link XmlUnsignedShort#type} */ + public static final int BTC_UNSIGNED_SHORT = 33; + /** xs:unsignedByte, aka {@link XmlUnsignedByte#type} */ + public static final int BTC_UNSIGNED_BYTE = 34; + + // derived strings + /** xs:normalizedString, aka {@link XmlNormalizedString#type} */ + public static final int BTC_NORMALIZED_STRING = 35; + /** xs:token, aka {@link XmlToken#type} */ + public static final int BTC_TOKEN = 36; + /** xs:Name, aka {@link XmlName#type} */ + public static final int BTC_NAME = 37; + /** xs:NCName, aka {@link XmlNCName#type} */ + public static final int BTC_NCNAME = 38; + /** xs:language, aka {@link XmlLanguage#type} */ + public static final int BTC_LANGUAGE = 39; + /** xs:ID, aka {@link XmlID#type} */ + public static final int BTC_ID = 40; + /** xs:IDREF, aka {@link XmlIDREF#type} */ + public static final int BTC_IDREF = 41; + /** xs:IDREFS, aka {@link XmlIDREFS#type} */ + public static final int BTC_IDREFS = 42; + /** xs:ENTITY, aka {@link XmlENTITY#type} */ + public static final int BTC_ENTITY = 43; + /** xs:ENTITIES, aka {@link XmlENTITIES#type} */ + public static final int BTC_ENTITIES = 44; + /** xs:NMTOKEN, aka {@link XmlNMTOKEN#type} */ + public static final int BTC_NMTOKEN = 45; + /** xs:NMTOKENS, aka {@link XmlNMTOKENS#type} */ + public static final int BTC_NMTOKENS = 46; + + public static final int BTC_LAST_BUILTIN = 46; + + /** + * True for anyType and anySimpleType. + */ + public boolean isURType(); + + /** + * True for the type object that represents a the absence of a determined type. + * XML Objects whose type isNoType() are never valid. + */ + public boolean isNoType(); + + /** + * Returns the SchemaTypeLoader in which this type was defined. + * Complex types are defined and used in exactly one schema type + * system, but simple types are defined in one type system and can + * be used in any number of type systems. The most common case is + * the builtin types, which are defined in the builtin type system + * and used elsewhere. + */ + public SchemaTypeSystem getTypeSystem(); + + /** True if this type cannot be used directly in instances */ + public boolean isAbstract(); + + /** True if other types cannot extend this type (only for complex types) */ + public boolean finalExtension(); + + /** True if other types cannot restrict this type */ + public boolean finalRestriction(); + + /** True if list derivation of this type is prohibited (only for simple types) */ + public boolean finalList(); + + /** True if union derivation of this type is prohibited (only for simple types) */ + public boolean finalUnion(); + + /** True if extensions of this type cannot be substituted for this type */ + public boolean blockExtension(); + + /** True if restrictions of this type cannot be substituted for this type */ + public boolean blockRestriction(); + + /** + * Returns {@link #EMPTY_CONTENT}, {@link #SIMPLE_CONTENT}, {@link #ELEMENT_CONTENT}, or + * {@link #MIXED_CONTENT} for complex types. For noncomplex types, returns + * {@link #NOT_COMPLEX_TYPE}. + */ + public abstract int getContentType(); + + /** Not a complex type. See {@link #getContentType()}. */ + public static final int NOT_COMPLEX_TYPE = 0; + /** Empty content. See {@link #getContentType()}. */ + public static final int EMPTY_CONTENT = 1; + /** Simple content. See {@link #getContentType()}. */ + public static final int SIMPLE_CONTENT = 2; + /** Element-only content. See {@link #getContentType()}. */ + public static final int ELEMENT_CONTENT = 3; + /** Mixed content. See {@link #getContentType()}. */ + public static final int MIXED_CONTENT = 4; + + + /** + * For complex types with simple content returns the base type for this + * type's content. In most cases, this is the same as the base type, but + * it can also be an anonymous type. + */ + SchemaType getContentBasedOnType(); + + /** + * Returns a {@link SchemaTypeElementSequencer} object, which can then + * be used to validate complex content inside this element. This is useful + * for example for trying out different names and see which one would be + * valid as a child of this element. + */ + SchemaTypeElementSequencer getElementSequencer(); + + /** + * The array of inner (anonymous) types defined + * within this type. + */ + public abstract SchemaType[] getAnonymousTypes(); + + /** + * Returns a SchemaProperty corresponding to an element within this + * complex type by looking up the element name. + */ + public abstract SchemaProperty getElementProperty(QName eltName); + + /** + * Returns all the SchemaProperties corresponding to elements. + */ + public abstract SchemaProperty[] getElementProperties(); + + /** + * Returns a SchemaProperty corresponding to an attribute within this + * complex type by looking up the attribute name. + */ + public abstract SchemaProperty getAttributeProperty(QName attrName); + + /** + * Returns all the SchemaProperties corresponding to attributes. + */ + public abstract SchemaProperty[] getAttributeProperties(); + + /** + * Returns all the SchemaProperties within this complex type, + * elements followed by attributes. + */ + public abstract SchemaProperty[] getProperties(); + + /** + * Returns the SchemaProperties defined by this complex type, + * exclusive of the base type (if any). + */ + SchemaProperty[] getDerivedProperties(); + + /** + * Returns the attribute model for this complex type (with simple or complex content). + */ + public abstract SchemaAttributeModel getAttributeModel(); + + /** + * True if this type permits wildcard attributes. See the attribute model for + * more information about which wildcards are allowed. + */ + public abstract boolean hasAttributeWildcards(); + + /** + * Returns the complex content model for this complex type (with complex content). + */ + public abstract SchemaParticle getContentModel(); + + /** + * True if this type permits element wildcards. See the content model for + * more information about which wildcards are allowed, and where. + */ + public abstract boolean hasElementWildcards(); + + /** + * For document types, true if the given name can be substituted for the + * document element name. + */ + public boolean isValidSubstitution(QName name); + + /** + * True if the complex content model for this complex type is an "all" group. + */ + public abstract boolean hasAllContent(); + + /** + * True if particles have same defaults, nillability, etc, that are + * invariant when order changes. Computed only for Javaized types. + */ + public abstract boolean isOrderSensitive(); + + /** + * Returns the type of a child element based on the element name and + * an xsi:type attribute (and the type system within which names are + * resolved). + */ + public abstract SchemaType getElementType(QName eltName, QName xsiType, SchemaTypeLoader wildcardTypeLoader); + + /** + * Returns the type of an attribute based on the attribute name and + * the type system within which (wildcard) names are resolved. + */ + public abstract SchemaType getAttributeType(QName eltName, SchemaTypeLoader wildcardTypeLoader); + + /*************************************************************/ + /* SIMPLE TYPE MODEL BELOW */ + /*************************************************************/ + + /** xs:length facet */ + public static final int FACET_LENGTH = 0; + /** xs:minLength facet */ + public static final int FACET_MIN_LENGTH = 1; + /** xs:maxLength facet */ + public static final int FACET_MAX_LENGTH = 2; + /** xs:minExclusive facet */ + public static final int FACET_MIN_EXCLUSIVE = 3; + /** xs:minInclusive facet */ + public static final int FACET_MIN_INCLUSIVE = 4; + /** xs:maxInclusive facet */ + public static final int FACET_MAX_INCLUSIVE = 5; + /** xs:maxExclusive facet */ + public static final int FACET_MAX_EXCLUSIVE = 6; + /** xs:totalDigits facet */ + public static final int FACET_TOTAL_DIGITS = 7; + /** xs:fractionDigits facet */ + public static final int FACET_FRACTION_DIGITS = 8; + + public static final int LAST_BASIC_FACET = 8; + + /** xs:whiteSpace facet - use {@link #getWhiteSpaceRule} instead */ + public static final int FACET_WHITE_SPACE = 9; + /** xs:pattern facet - use {@link #matchPatternFacet} instead */ + public static final int FACET_PATTERN = 10; + /** xs:enumeration facet - use {@link #getEnumerationValues} instead */ + public static final int FACET_ENUMERATION = 11; + + /** The last ordinary facet code */ + public static final int LAST_FACET = 11; + + /** @see #ordered */ + public static final int PROPERTY_ORDERED = 12; + /** @see #isBounded */ + public static final int PROPERTY_BOUNDED = 13; + /** @see #isFinite */ + public static final int PROPERTY_CARDINALITY = 14; + /** @see #isNumeric */ + public static final int PROPERTY_NUMERIC = 15; + + /** The last property code */ + public static final int LAST_PROPERTY = 15; + + + /** + * Returns the value of the given facet, or null if + * none is set. + */ + public abstract XmlAnySimpleType getFacet(int facetCode); + + /** + * True if the given facet is fixed. + */ + public abstract boolean isFacetFixed(int facetCode); + + /** + * True if ordered. Returns either {@link #UNORDERED}, + * {@link #PARTIAL_ORDER}, or {@link #TOTAL_ORDER}. + */ + public abstract int ordered(); + + /** Unordered. See {@link #ordered}. */ + public static int UNORDERED = 0; + /** Partially ordered. See {@link #ordered}. */ + public static int PARTIAL_ORDER = 1; + /** Totally ordered. See {@link #ordered}. */ + public static int TOTAL_ORDER = 2; + + /** + * True if bounded. + */ + public abstract boolean isBounded(); + + /** + * True if finite. + */ + public abstract boolean isFinite(); + + /** + * True if numeric. + */ + public abstract boolean isNumeric(); + + /** + * True if there are regex pattern facents + */ + public abstract boolean hasPatternFacet(); + + /** + * True + */ + public abstract String[] getPatterns(); + + /** + * True if the given string matches the pattern facets. + * Always true if there are no pattern facets. + */ + public abstract boolean matchPatternFacet(String s); + + /** + * Returns the array of valid objects from the + * enumeration facet, null if no enumeration defined. + */ + public abstract XmlAnySimpleType[] getEnumerationValues(); + + /** + * True if this is a string enum where an integer + * is assigned to each enumerated value. + */ + public abstract boolean hasStringEnumValues(); + + /** + * If this is a string enumeration, returns the most basic base schema + * type that this enuemration is based on. Otherwise returns null. + */ + public abstract SchemaType getBaseEnumType(); + + /** + * Returns the array of SchemaStringEnumEntries for this type: this + * array includes information about the java constant names used for + * each string enum entry. + */ + public SchemaStringEnumEntry[] getStringEnumEntries(); + + /** + * Returns the string enum entry corresponding to the given enumerated + * string, or null if there is no match or this type is not + * a string enumeration. + */ + public SchemaStringEnumEntry enumEntryForString(String s); + + /** + * Returns the string enum value corresponding to the given enumerated + * string, or null if there is no match or this type is not + * a string enumeration. + */ + public abstract StringEnumAbstractBase enumForString(String s); + + /** + * Returns the string enum value corresponding to the given enumerated + * string, or null if there is no match or this type is not + * a string enumeration. + */ + public abstract StringEnumAbstractBase enumForInt(int i); + + /** + * True for any of the 20 primitive types (plus anySimpleType) + */ + public abstract boolean isPrimitiveType(); + + /** + * Returns whether the simple type is ATOMIC, UNION, or LIST. + * Returns {@link #NOT_SIMPLE}, {@link #ATOMIC}, {@link #UNION}, + * or {@link #LIST}. + */ + public abstract int getSimpleVariety(); + + /** Not a simple type or simple content. See {@link #getSimpleVariety}. */ + public static final int NOT_SIMPLE = 0; + /** Atomic type. See {@link #getSimpleVariety} */ + public static final int ATOMIC = 1; + /** Union type. See {@link #getSimpleVariety} */ + public static final int UNION = 2; + /** Simple list type. See {@link #getSimpleVariety} */ + public static final int LIST = 3; + + + /** + * For atomic types only: get the primitive type underlying this one. + *

    + * Returns null if this is not an atomic type. + */ + public abstract SchemaType getPrimitiveType(); + + /** + * For atomic numeric restrictions of decimal only: the + * numeric size category. Takes into account min and max + * restrictions as well as totalDigits and fractionDigits + * facets. + *

    + * Returns either {@link #NOT_DECIMAL}, + * {@link #SIZE_BYTE}, {@link #SIZE_SHORT}, {@link #SIZE_INT}, + * {@link #SIZE_LONG}, {@link #SIZE_BIG_INTEGER}, or + * {@link #SIZE_BIG_DECIMAL}. + */ + public abstract int getDecimalSize(); + + /** Not a decimal restriction. See {@link #getDecimalSize}. */ + public static final int NOT_DECIMAL = 0; + /** Fits in a byte. See {@link #getDecimalSize}. */ + public static final int SIZE_BYTE = 8; + /** Fits in a short. See {@link #getDecimalSize}. */ + public static final int SIZE_SHORT = 16; + /** Fits in an int. See {@link #getDecimalSize}. */ + public static final int SIZE_INT = 32; + /** Fits in a long. See {@link #getDecimalSize}. */ + public static final int SIZE_LONG = 64; + /** Fits in a {@link java.math.BigInteger}. See {@link #getDecimalSize}. */ + public static final int SIZE_BIG_INTEGER = 1000000; // "millions" + /** Fits in a {@link java.math.BigDecimal}. See {@link #getDecimalSize}. */ + public static final int SIZE_BIG_DECIMAL = 1000001; // "even more" + + /** + * For union types only: get the shallow member types. This + * returns the declared member types of the union, so, for + * example if the type contains another union, the nested + * members of that union are NOT returned here. + *

    + * Returns null if this type is not a union. + */ + public abstract SchemaType[] getUnionMemberTypes(); + + /** + * For union types only: gets the full tree of member types. + * This computes the closure of the set returned by + * getUnionMemberTypes(), so, for example, it returns + * all the types nested within unions of unions as well + * as the top-level members; the set also includes the + * type itself. If you are seeking only the basic + * non-union consituents, use getUnionConstituentTypes. + *

    + * Returns null if this type is not a union. + */ + public abstract SchemaType[] getUnionSubTypes(); + + /** + * For union types only: get the constituent member types. This + * returns only non-union types, so, for example, for unions of + * unions, this returns the flattened list of individual member + * types within the innermost unions. + *

    + * Returns null if this type is not a union. + */ + public abstract SchemaType[] getUnionConstituentTypes(); + + /** + * For union types only: get the most specific common base + * type of the constituent member types. May return a UR type. + *

    + * Returns null if this type is not a union. + */ + public abstract SchemaType getUnionCommonBaseType(); + + /** + * For anonymous types defined inside a union only: gets + * the integer indicating the declaration order of this + * type within the outer union type, or zero if this is + * not applicable. The first anonymous union member within + * a union type is numbered "1". Used to differentiate + * between different anonymous types. + */ + public abstract int getAnonymousUnionMemberOrdinal(); + + /** + * For list types only: get the item type. This is the atomic + * or union type that is the type of every entry in the list. + *

    + * Returns null if this type is not a list. + */ + public abstract SchemaType getListItemType(); + + /** + * For nonunion simple types: get the whitespace rule. This is + * either {@link #WS_PRESERVE}, {@link #WS_REPLACE}, or + * {@link #WS_COLLAPSE}. Returns {@link #WS_UNSPECIFIED} + * for unions and complex types. + */ + public abstract int getWhiteSpaceRule(); + + /** Whitespace rule unspecified. See {@link #getWhiteSpaceRule}. */ + public static final int WS_UNSPECIFIED = 0; + /** Whitespace preserved. See {@link #getWhiteSpaceRule}. */ + public static final int WS_PRESERVE = 1; + /** Whitespace replaced by ordinary space. See {@link #getWhiteSpaceRule}. */ + public static final int WS_REPLACE = 2; + /** Whitespace collapsed and trimmed. See {@link #getWhiteSpaceRule}. */ + public static final int WS_COLLAPSE = 3; + + /** + * Creates an immutable simple type value that does not reside in a tree. + */ + public abstract XmlAnySimpleType newValue(Object v); + + + /** + * Used to allow on-demand loading of types. + * + * @exclude + */ + public final static class Ref extends SchemaComponent.Ref + { + public Ref(SchemaType type) + { super(type); } + + public Ref(SchemaTypeSystem system, String handle) + { super(system, handle); } + + public final int getComponentType() + { return SchemaComponent.TYPE; } + + public final SchemaType get() + { return (SchemaType)getComponent(); } + } + + /** + * Retruns a SchemaType.Ref pointing to this schema type itself. + */ + public Ref getRef(); + + /** + * Returns a QNameSet of elements that may exist in wildcard + * buchets and are not explicitly defined in this schema type. + * Note: In this example: + * + * + * + * + * + * + * the returned QNameSet will not contain the qname of 'someElement'. + * @return the constructed QNameSet + */ + public QNameSet qnameSetForWildcardElements(); + + /** + * Returns a QNameSet of attributes that may exist in wildcard + * buchets and are not explicitly defined in this schema type. + * Note: In this example: + * + * ... + * + * + * + * the returned QNameSet will not contain the qname of 'someAttribute'. + * @return the constructed QNameSet + */ + public QNameSet qnameSetForWildcardAttributes(); +} diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaTypeElementSequencer.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaTypeElementSequencer.java new file mode 100644 index 000000000..6e1934701 --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaTypeElementSequencer.java @@ -0,0 +1,43 @@ +/* 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; + +import javax.xml.namespace.QName; + +/** + * This class is used to programatically validate the contents of an + * XML element.Call to both {@link #next} and {@link #peek} + * will return true if the element + * with the provided name is allowed at the current position in the element + * content, the difference being that {@link #next} will advance + * the current position, while {@link #peek} won't. + * + * @see SchemaType#getElementSequencer + */ +public interface SchemaTypeElementSequencer +{ + /** + * Returns true if the element with the given name is valid at the + * current position. Advances the current position. + */ + boolean next(QName elementName); + + /** + * Return true if the element with the given name is valid at the + * current position. Does not advance the current position. + */ + boolean peek(QName elementName); +} diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaTypeLoader.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaTypeLoader.java new file mode 100644 index 000000000..abd2ae69f --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaTypeLoader.java @@ -0,0 +1,165 @@ +/* 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; + +import javax.xml.namespace.QName; +import org.apache.xmlbeans.xml.stream.XMLInputStream; +import org.apache.xmlbeans.xml.stream.XMLStreamException; + +import java.io.File; +import java.io.InputStream; +import java.io.IOException; +import java.io.Reader; +import java.net.URL; + +import javax.xml.stream.XMLStreamReader; + +import org.w3c.dom.Node; +import org.w3c.dom.DOMImplementation; + +/** + * Represents a searchable set of XML Schema component definitions. + *

    + * SchemaTypeLoader is somewhat analogous to {@link java.lang.ClassLoader}, + * because it is responsible for finding {@link SchemaComponent} definitions + * by name, yet it is not responsible for being able to enumerate all the + * component definitons available. (If you wish to enumerate component + * definitions, see {@link SchemaTypeSystem}.) There are some ways in which + * SchemaTypeSystems are dissimilar from ClassLoaders, however. + * Since XML Schema has a number of instance-oriented typing mechanisms + * (such as wildcards) that do not exist in Java, a SchemaTypeLoader is + * not associated with a type; instead, a SchemaTypeLoader is associated + * with each XML instance. + *

    + * Every XML instance is loaded within the context of a SchemaTypeLoader; + * the SchemaTypeLoader for an instance is used to resolve all type definitions + * within the instance and for applying type-sensitive methods such as + * {@link XmlObject#validate}. + *

    + * Normally the SchemaTypeLoader being used for all instances is the + * context type loader (that is, the SchemaTypeLoader returned from + * {@link XmlBeans#getContextTypeLoader()}). The context type loader + * consults the thread's context ClassLoader (see {@link Thread#getContextClassLoader()}) + * to find schema type defintions that are available on the classpath. + * The net result is that you can use schema types simply by putting + * their compiled schema JARs on your classpath. + * If you wish to load instances using a different SchemaTypeLoader, then you must + * call {@link #parse} methods on the SchemaTypeLoader instance explicitly + * rather than using the normal convenient Factory methods. + *

    + * A SchemaTypeLoader can be obtained by dynamically loading XSD files + * using {@link XmlBeans#loadXsd}, or by assembling other SchemaTypeLoaders + * or SchemaTypeSystems on a path using {@link XmlBeans#typeLoaderUnion}. + * + * @see XmlBeans#loadXsd + * @see XmlBeans#getContextTypeLoader + * @see XmlBeans#typeLoaderUnion + * @see SchemaTypeSystem + */ +public interface SchemaTypeLoader +{ + /** Returns the type with the given name, or null if none. */ + public SchemaType findType(QName name); + + /** Returns the document type rooted at the given element name, or null if none. */ + public SchemaType findDocumentType(QName name); + + /** Returns the attribute type containing the given attribute name, or null if none. */ + public SchemaType findAttributeType(QName name); + + /** Returns the global element defintion with the given name, or null if none. */ + public SchemaGlobalElement findElement(QName name); + + /** Returns the global attribute defintion with the given name, or null if none. */ + public SchemaGlobalAttribute findAttribute(QName name); + + /** Returns the model group defintion with the given name, or null if none. */ + public SchemaModelGroup findModelGroup(QName name); + + /** Returns the attribute group defintion with the given name, or null if none. */ + public SchemaAttributeGroup findAttributeGroup(QName name); + + /** True if the typeloader contains any definitions in the given namespace. */ + public boolean isNamespaceDefined(String namespace); + + /** Used for on-demand loading. */ + public SchemaType.Ref findTypeRef(QName name); + + /** Used for on-demand loading. */ + public SchemaType.Ref findDocumentTypeRef(QName name); + + /** Used for on-demand loading. */ + public SchemaType.Ref findAttributeTypeRef(QName name); + + /** Used for on-demand loading. */ + public SchemaGlobalElement.Ref findElementRef(QName name); + + /** Used for on-demand loading. */ + public SchemaGlobalAttribute.Ref findAttributeRef(QName name); + + /** Used for on-demand loading. */ + public SchemaModelGroup.Ref findModelGroupRef(QName name); + + /** Used for on-demand loading. */ + public SchemaAttributeGroup.Ref findAttributeGroupRef(QName name); + + /** Used for on-demand loading. */ + public SchemaIdentityConstraint.Ref findIdentityConstraintRef(QName name); + + /** Finds a type for a given signature string */ + public SchemaType typeForSignature(String signature); + + /** Finds a type for a given fully-qualified XML Bean classname */ + public SchemaType typeForClassname(String classname); + + /** Loads original XSD source as a stream. See {@link SchemaType#getSourceName}. */ + public InputStream getSourceAsStream(String sourceName); + + /** Compiles an XPath */ + public String compilePath(String pathExpr, XmlOptions options) throws XmlException; + + /** Compiles an XQuery */ + public String compileQuery(String queryExpr, XmlOptions options) throws XmlException; + + /** Creates an instance of the given type. */ + public XmlObject newInstance ( SchemaType type, XmlOptions options ); + /** Parses an instance of the given type. */ + public XmlObject parse ( String xmlText, SchemaType type, XmlOptions options ) throws XmlException; + /** Parses an instance of the given type. */ + public XmlObject parse ( File file, SchemaType type, XmlOptions options ) throws XmlException, IOException; + /** Parses an instance of the given type. */ + public XmlObject parse ( URL file, SchemaType type, XmlOptions options ) throws XmlException, IOException; + /** Parses an instance of the given type. */ + public XmlObject parse ( InputStream jiois, SchemaType type, XmlOptions options ) throws XmlException, IOException; + /** Parses an instance of the given type. */ + public XmlObject parse ( XMLStreamReader xsr, SchemaType type, XmlOptions options ) throws XmlException; + /** Parses an instance of the given type. */ + public XmlObject parse ( Reader jior, SchemaType type, XmlOptions options ) throws XmlException, IOException; + /** Parses an instance of the given type. */ + public XmlObject parse ( Node node, SchemaType type, XmlOptions options ) throws XmlException; + /** Parses an instance of the given type. + * @deprecated Deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public XmlObject parse ( XMLInputStream xis, SchemaType type, XmlOptions options ) throws XmlException, XMLStreamException; + /** Returns an XmlSaxHandler that can parse an instance of the given type. */ + public XmlSaxHandler newXmlSaxHandler ( SchemaType type, XmlOptions options ); + /** Returns a DOMImplementation. */ + public DOMImplementation newDomImplementation ( XmlOptions options ); + /** Returns a validating XMLInputStream that will throw an exception if the XML is not valid + * @deprecated Deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public XMLInputStream newValidatingXMLInputStream ( XMLInputStream xis, SchemaType type, XmlOptions options ) throws XmlException, XMLStreamException; +} diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaTypeLoaderException.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaTypeLoaderException.java new file mode 100644 index 000000000..0cb6e3e45 --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaTypeLoaderException.java @@ -0,0 +1,78 @@ +/* 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; + +/** + * An exception that is thrown if there is corruption or a version mismatch + * in a compiled schema type system. + */ +public class SchemaTypeLoaderException extends XmlRuntimeException +{ + private int _code; + + /** Constructs an exception with the given message, filename, extension, and code */ + public SchemaTypeLoaderException(String message, String name, String handle, int code) + { + super(message + " (" + name + "." + handle + ") - code " + code); + _code = code; + } + + /** Constructs an exception with the given message, filename, extension, code, and cause */ + public SchemaTypeLoaderException(String message, String name, String handle, int code, Exception cause) + { + super(message + " (" + name + "." + handle + ") - code " + code); + _code = code; + initCause(cause); + } + + /** Returns the reason for the failure, given by one of the numeric constants in this class */ + public int getCode() + { + return _code; + } + + /* See {@link #getCode}. */ + public static final int NO_RESOURCE = 0; + /* See {@link #getCode}. */ + public static final int WRONG_MAGIC_COOKIE = 1; + /* See {@link #getCode}. */ + public static final int WRONG_MAJOR_VERSION = 2; + /* See {@link #getCode}. */ + public static final int WRONG_MINOR_VERSION = 3; + /* See {@link #getCode}. */ + public static final int WRONG_FILE_TYPE = 4; + /* See {@link #getCode}. */ + public static final int UNRECOGNIZED_INDEX_ENTRY = 5; + /* See {@link #getCode}. */ + public static final int WRONG_PROPERTY_TYPE = 6; + /* See {@link #getCode}. */ + public static final int MALFORMED_CONTENT_MODEL = 7; + /* See {@link #getCode}. */ + public static final int WRONG_SIMPLE_VARIETY = 8; + /* See {@link #getCode}. */ + public static final int IO_EXCEPTION = 9; + /* See {@link #getCode}. */ + public static final int INT_TOO_LARGE = 10; + /* See {@link #getCode}. */ + public static final int BAD_PARTICLE_TYPE = 11; + /* See {@link #getCode}. */ + public static final int NOT_WRITEABLE = 12; + /* See {@link #getCode}. */ + public static final int BAD_HANDLE = 13; + /* See {@link #getCode}. */ + public static final int NESTED_EXCEPTION = 14; +} + diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaTypeSystem.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaTypeSystem.java new file mode 100644 index 000000000..824056019 --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/SchemaTypeSystem.java @@ -0,0 +1,208 @@ +/* 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; + +import java.io.File; + +/** + * A finite set of XML Schema component definitions. + *

    + * Every {@link SchemaComponent} such as a {@link SchemaType}, + * {@link SchemaGlobalElement}, {@link SchemaGlobalAttribute}, + * {@link SchemaModelGroup}, {@link SchemaAttributeGroup}, or + * {@link SchemaIdentityConstraint}, is defined in exactly one + * SchemaTypeSystem. (See {@link SchemaComponent#getTypeSystem()}.) + * A single SchemaTypeSystem can include definitions + * from any number of namespaces; one SchemaTypeSystem consists simply + * of a set of component definitions that were compiled together. + *

    + * Since every component is defined in a single SchemaTypeSystem, no + * SchemaTypeSystem other than {@link XmlBeans#getBuiltinTypeSystem()} + * includes any of the the built-in types. That means + * you cannot ordinarily load instances using a single + * SchemaTypeSystem by itself. Instead, you will want to combine a path of + * SchemaTypeSystems together using {@link XmlBeans#typeLoaderUnion} + * to form a SchemaTypeLoader that can be used for loading instances. + *

    + * For example, the following code compiles the schema in myXSDFile + * in the presence of only the minimal builtin type system. + * The resulting SchemaTypeSystem sts contains only the definitions + * from myXSD file. In order to load and validate an instance within + * the context of those types, we must next construct a + * {@link SchemaTypeLoader} stl that contains both + * the builtin type system and the types defined within the myXSD file. + *

    + * SchemaTypeSystem sts = XmlBeans.compileXsd(new XmlObject[]
    + *    { XmlObject.Factory.parse(myXSDFile) },
    + *    XmlBeans.getBuiltinTypeSystem(),
    + *    null);
    + * SchemaTypeLoader stl = XmlBeans.typeLoaderUnion(new SchemaTypeLoader[]
    + *    { sts, XmlBeans.getBuiltinTypeSystem() });
    + * XmlObject mydoc = stl.parse(instanceFile, null, null);
    + * System.out.println("Document valid: " + mydoc.validate());
    + * 
    + *

    + * As you can see, for working with instances, you typically want to + * work with a SchemaTypeLoader constructed from a path rather than + * a solitary SchemaTypeSystem. See {@link XmlBeans#loadXsd} for + * a convenient alternative to {@link XmlBeans#compileXsd}. + *

    + * A SchemaTypeSystem is useful when you need to enumerate the exact set + * of component definitions derived from a set of XSD files, for example, + * when you are analyzing the contents of the XSD files themselves. + * Here is how to use a SchemaTypeSystem to inspect a set of schema + * definitions: + *

      + *
    1. First, use {@link XmlBeans#compileXsd} to compile any number + * of schema files. If the schema files are valid, result will + * be a SchemaTypeSystem that contains all the component definitions + * from those files. It will contain no other component definitions. + *
    2. Alternatively, call {@link SchemaComponent#getTypeSystem} on + * a precompiled schema component to discover the SchemaTypeSystem + * within which that component was originally compiled. + *
    3. Once you have a SchemaTypeSystem, call: + *
        + *
      • {@link #globalTypes()} for all the global type definitions. + *
      • {@link #globalElements()} for all the global element definitions. + *
      • {@link #globalAttributes()} for all the global attribute definitions. + *
      • {@link #modelGroups()} for all the named model group definitions. + *
      • {@link #attributeGroups()} for all the attribute group definitions. + *
      + *
    4. In addition, there are special types generated for XML Beans thare + * are not formally part of the Schema specification: + *
        + *
      • {@link #documentTypes()} returns all the document types. + *
      • {@link #attributeTypes()} returns all the attribute types. + *
      + *
    + * + *

    + * A document type is a type that contains a single global element; there + * is one document type for each global element definition in a + * SchemaTypeSystem. In an instance document, only the root XmlObject + * can have a document type as its type. + *

    + * Similarly, an attribute type is a type that contains a single global + * attribute, and there is one attribute type for each global attribute + * definition in a SchemaTypeSystem. It is possible to have a root + * XmlObject representing a fragment whose type is an attribute type, + * but attribute types are present mainly for symmetry and to simplify + * code such as the type-tree-walking code below. + *

    + * The global component methods above only provide a view of the top-level + * components of a SchemaTypeSystem and do not include any nested + * definitions. To view all the nested definitions, you will want to + * traverse the entire tree of {@link SchemaType} defintions within a + * SchemaTypeSystem by examining the {@link SchemaType#getAnonymousTypes()} + * within each {@link SchemaType} recursively. + *

    The following code is a standard treewalk that visits every + * {@link SchemaType} in the SchemaTypeSystem once, including nested + * definitions. + *

    + * List allSeenTypes = new ArrayList();
    + * allSeenTypes.addAll(Arrays.asList(typeSystem.documentTypes()));
    + * allSeenTypes.addAll(Arrays.asList(typeSystem.attributeTypes()));
    + * allSeenTypes.addAll(Arrays.asList(typeSystem.globalTypes()));
    + * for (int i = 0; i < allSeenTypes.size(); i++)
    + * {
    + *     SchemaType sType = (SchemaType)allSeenTypes.get(i);
    + *     System.out.prinlnt("Visiting " + sType.toString());
    + *     allSeenTypes.addAll(Arrays.asList(sType.getAnonymousTypes()));
    + * }
    + * 
    + * + * @see SchemaType + * @see SchemaTypeLoader + * @see XmlBeans#compileXsd + * @see XmlBeans#typeLoaderUnion + * @see XmlBeans#getBuiltinTypeSystem + */ +public interface SchemaTypeSystem extends SchemaTypeLoader +{ + /** + * Returns the name of this loader. + */ + public String getName(); + + /** + * Returns the global types defined in this loader. + */ + public org.apache.xmlbeans.SchemaType[] globalTypes(); + + /** + * Returns the document types defined in this loader. + */ + public org.apache.xmlbeans.SchemaType[] documentTypes(); + + /** + * Returns the attribute types defined in this loader. + */ + public org.apache.xmlbeans.SchemaType[] attributeTypes(); + + /** + * Returns the global elements defined in this loader. + */ + public SchemaGlobalElement[] globalElements(); + + /** + * Returns the global attributes defined in this loader. + */ + public SchemaGlobalAttribute[] globalAttributes(); + + /** + * Returns the model groups defined in this loader. + */ + public SchemaModelGroup[] modelGroups(); + + /** + * Returns the attribute groups defined in this loader. + */ + public SchemaAttributeGroup[] attributeGroups(); + + /** + * Returns the top-level annotations */ + public SchemaAnnotation[] annotations(); + + /** + * Initializes a type system (resolves all handles within the type system). + */ + public void resolve(); + + /** + * Locates a type, element, or attribute using the handle. + */ + public SchemaComponent resolveHandle(String handle); + + /** + * Locates a type, element, or attribute using the handle. + */ + public SchemaType typeForHandle(String handle); + + /** + * Returns the classloader used by this loader for resolving types. + */ + public ClassLoader getClassLoader(); + + /** + * Saves this type system to a directory. + */ + public void saveToDirectory(File classDir); + + /** + * Saves this type system using a Filer + */ + public void save(Filer filer); +} diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/SimpleValue.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/SimpleValue.java new file mode 100644 index 000000000..3d86aac34 --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/SimpleValue.java @@ -0,0 +1,333 @@ +/* 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; + +import javax.xml.namespace.QName; +import java.util.List; +import java.util.Date; +import java.util.Calendar; +import java.math.BigInteger; +import java.math.BigDecimal; + +/** + * All XmlObject implementations can be coerced to SimpleValue. + * For any given schema type, only a subset of the conversion + * methods will work. Others will throw an exception. + *

    + * SimpleValue is useful for declaring variables which can hold + * more than one similar schema type that may not happen to + * have a common XML base type, for example, two list types, + * or two unrelated integer restrictions that happen to fit + * into an int. + */ +public interface SimpleValue extends XmlObject +{ + /** + * The same as getSchemaType unless this is a union instance + * or nil value. + *

    + * For unions, this returns the non-union consituent type of + * this instance. This type may change if setters are called + * that cause the instance to change to another constituent + * type of the union. + *

    + * For nil values, this returns null. + */ + SchemaType instanceType(); + + /** Returns the value as a {@link String}. */ + String getStringValue(); + /** Returns the value as a boolean. */ + boolean getBooleanValue(); + /** Returns the value as a byte. */ + public byte getByteValue(); + /** Returns the value as a short. */ + public short getShortValue(); + /** Returns the value as an int. */ + public int getIntValue(); + /** Returns the value as a long. */ + public long getLongValue(); + /** Returns the value as a {@link BigInteger}. */ + public BigInteger getBigIntegerValue(); + /** Returns the value as a {@link BigDecimal}. */ + public BigDecimal getBigDecimalValue(); + /** Returns the value as a float. */ + public float getFloatValue(); + /** Returns the value as a double. */ + public double getDoubleValue(); + /** Returns the value as a byte array. */ + byte[] getByteArrayValue(); + /** Returns the value as a {@link StringEnumAbstractBase}. */ + StringEnumAbstractBase getEnumValue(); + /** Returns the value as a {@link Calendar}. */ + Calendar getCalendarValue(); + /** Returns the value as a {@link Date}. */ + Date getDateValue(); + /** Returns the value as a {@link GDate}. */ + GDate getGDateValue(); + /** Returns the value as a {@link GDuration}. */ + GDuration getGDurationValue(); + /** Returns the value as a {@link QName}. */ + QName getQNameValue(); + /** Returns the value as a {@link List} of friendly Java objects (String, Integer, Byte, Short, Long, BigInteger, Decimal, Float, Double, byte[], Calendar, GDuration). */ + List getListValue(); + /** Returns the value as a {@link List} of XmlAnySimpleType objects. */ + List xgetListValue(); + + /** Returns a union value as a its natural friendly Java object (String, Integer, Byte, Short, Long, BigInteger, Decimal, Float, Double, byte[], Calendar, GDuration). */ + Object getObjectValue(); + + // following are simple type value setters + + /** Sets the value as a {@link String}. */ + void setStringValue(String obj); + /** Sets the value as a boolean. */ + void setBooleanValue(boolean v); + /** Sets the value as a byte. */ + void setByteValue(byte v); + /** Sets the value as a short. */ + void setShortValue(short v); + /** Sets the value as an int. */ + void setIntValue(int v); + /** Sets the value as a long. */ + void setLongValue(long v); + /** Sets the value as a {@link BigInteger}. */ + void setBigIntegerValue(BigInteger obj); + /** Sets the value as a {@link BigDecimal}. */ + void setBigDecimalValue(BigDecimal obj); + /** Sets the value as a float. */ + void setFloatValue(float v); + /** Sets the value as a double. */ + void setDoubleValue(double v); + /** Sets the value as a byte array. */ + void setByteArrayValue(byte[] obj); + /** Sets the value as a {@link StringEnumAbstractBase}. */ + void setEnumValue(StringEnumAbstractBase obj); + /** Sets the value as a {@link Calendar}. */ + void setCalendarValue(Calendar obj); + /** Sets the value as a {@link Date}. */ + void setDateValue(Date obj); + /** Sets the value as a {@link GDate}. */ + void setGDateValue(GDate obj); + /** Sets the value as a {@link GDuration}. */ + void setGDurationValue(GDuration obj); + /** Sets the value as a {@link QName}. */ + void setQNameValue(QName obj); + /** Sets the value as a {@link List}. */ + void setListValue(List obj); + /** Sets the value as an arbitrary {@link Object}. */ + void setObjectValue(Object obj); + + /** + * Returns the value as a {@link String}. * + * @deprecated replaced with {@link #getStringValue} + */ + String stringValue(); + /** + * Returns the value as a boolean. * + * @deprecated replaced with {@link #getBooleanValue} + */ + boolean booleanValue(); + /** + * Returns the value as a byte. * + * @deprecated replaced with {@link #getByteValue} + */ + public byte byteValue(); + /** + * Returns the value as a short. * + * @deprecated replaced with {@link #getShortValue} + */ + public short shortValue(); + /** + * Returns the value as an int. * + * @deprecated replaced with {@link #getIntValue} + */ + public int intValue(); + /** + * Returns the value as a long. * + * @deprecated replaced with {@link #getLongValue} + */ + public long longValue(); + /** + * Returns the value as a {@link BigInteger}. * + * @deprecated replaced with {@link #getBigIntegerValue} + */ + public BigInteger bigIntegerValue(); + /** + * Returns the value as a {@link BigDecimal}. * + * @deprecated replaced with {@link #getBigDecimalValue} + */ + public BigDecimal bigDecimalValue(); + /** + * Returns the value as a float. * + * @deprecated replaced with {@link #getFloatValue} + */ + public float floatValue(); + /** + * Returns the value as a double. * + * @deprecated replaced with {@link #getDoubleValue} + */ + public double doubleValue(); + /** + * Returns the value as a byte array. * + * @deprecated replaced with {@link #getByteArrayValue} + */ + byte[] byteArrayValue(); + /** + * Returns the value as a {@link StringEnumAbstractBase}. * + * @deprecated replaced with {@link #getEnumValue} + */ + StringEnumAbstractBase enumValue(); + /** + * Returns the value as a {@link Calendar}. * + * @deprecated replaced with {@link #getCalendarValue} + */ + Calendar calendarValue(); + /** + * Returns the value as a {@link Date}. * + * @deprecated replaced with {@link #getDateValue} + */ + Date dateValue(); + /** + * Returns the value as a {@link GDate}. * + * @deprecated replaced with {@link #getGDateValue} + */ + GDate gDateValue(); + /** + * Returns the value as a {@link GDuration}. * + * @deprecated replaced with {@link #getGDurationValue} + */ + GDuration gDurationValue(); + /** + * Returns the value as a {@link QName}. * + * @deprecated replaced with {@link #getQNameValue} + */ + QName qNameValue(); + /** + * Returns the value as a {@link List} of friendly Java objects (String, Integer, Byte, Short, Long, BigInteger, Decimal, Float, Double, byte[], Calendar, GDuration). * + * @deprecated replaced with {@link #getListValue} + */ + List listValue(); + /** + * Returns the value as a {@link List} of XmlAnySimpleType objects. * + * @deprecated replaced with {@link #xgetListValue} + */ + List xlistValue(); + + /** + * Returns a union value as a its natural friendly Java object (String, Integer, Byte, Short, Long, BigInteger, Decimal, Float, Double, byte[], Calendar, GDuration). * + * @deprecated replaced with {@link #getObjectValue} + */ + Object objectValue(); + + // following are simple type value setters + + /** + * Sets the value as a {@link String}. * + * @deprecated replaced with {@link #setStringValue} + */ + void set(String obj); + /** + * Sets the value as a boolean. * + * @deprecated replaced with {@link #setBooleanValue} + */ + void set(boolean v); + /** + * Sets the value as a byte. + * @deprecated replaced with {@link #setByteValue} + **/ + void set(byte v); + /** + * Sets the value as a short. + * @deprecated replaced with {@link #setShortValue} + **/ + void set(short v); + /** + * Sets the value as an int. + * @deprecated replaced with {@link #setIntValue} + **/ + void set(int v); + /** + * Sets the value as a long. + * @deprecated replaced with {@link #setLongValue} + **/ + void set(long v); + /** + * Sets the value as a {@link BigInteger}. + * @deprecated replaced with {@link #setBigIntegerValue} + **/ + void set(BigInteger obj); + /** + * Sets the value as a {@link BigDecimal} + * @deprecated replaced with {@link #setBigDecimalValue} + **/ + void set(BigDecimal obj); + /** + * Sets the value as a float. + * @deprecated replaced with {@link #setFloatValue} + **/ + void set(float v); + /** + * Sets the value as a double. + * @deprecated replaced with {@link #setDoubleValue} + **/ + void set(double v); + /** + * Sets the value as a byte array. + * @deprecated replaced with {@link #setByteArrayValue} + **/ + void set(byte[] obj); + /** + * Sets the value as a {@link StringEnumAbstractBase}. + * @deprecated replaced with {@link #setEnumValue} + **/ + void set(StringEnumAbstractBase obj); + /** + * Sets the value as a {@link Calendar}. + * @deprecated replaced with {@link #setCalendarValue} + **/ + void set(Calendar obj); + /** + * Sets the value as a {@link Date}. + * @deprecated replaced with {@link #setDateValue} + **/ + void set(Date obj); + /** + * Sets the value as a {@link GDate}. + * @deprecated replaced with {@link #setGDateValue} + **/ + void set(GDateSpecification obj); + /** + * Sets the value as a {@link GDuration}. + * @deprecated replaced with {@link #setGDurationValue} + **/ + void set(GDurationSpecification obj); + /** + * Sets the value as a {@link QName}. + * @deprecated replaced with {@link #setQNameValue} + **/ + void set(QName obj); + /** + * Sets the value as a {@link List}. + * @deprecated replaced with {@link #setListValue} + **/ + void set(List obj); + /** + * Sets the value as an arbitrary {@link Object}. + * @deprecated replaced with {@link #setObjectValue} + **/ + void objectSet(Object obj); +} diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/StringEnumAbstractBase.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/StringEnumAbstractBase.java new file mode 100644 index 000000000..f3bad8b61 --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/StringEnumAbstractBase.java @@ -0,0 +1,99 @@ +/* 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; + +import java.util.HashMap; +import java.util.Map; +import java.util.List; +import java.util.ArrayList; + +/** + * The base class for code-generated string enumeration value classes. + *

    + * Subclasses are intended to be final types with a finite set of + * singleton instances. Each instance has a string value, which + * it returns via {@link #toString}, and an int value for the purpose + * of switching in case statements, returned via {@link #intValue}. + *

    + * Each subclass manages an instance of {@link StringEnumAbstractBase.Table}, + * which holds all the singleton instances for the subclass. A Table + * can return a singleton instance given a String or an integer code. + */ +public class StringEnumAbstractBase implements java.io.Serializable +{ + private static final long serialVersionUID = 1L; + + private String _string; + private int _int; + + /** + * Singleton instances should only be created by subclasses. + */ + protected StringEnumAbstractBase(String s, int i) + { _string = s; _int = i; } + + /** Returns the underlying string value */ + public final String toString() + { return _string; } + /** Returns an int code that can be used for switch statements */ + public final int intValue() + { return _int; } + /** Returns the hash code of the underlying string */ + public final int hashCode() + { return _string.hashCode(); } + + /** + * Used to manage singleton instances of enumerations. + * Each subclass of StringEnumAbstractBase has an instance + * of a table to hold the singleton instances. + */ + public static final class Table + { + private Map _map; + private List _list; + public Table(StringEnumAbstractBase[] array) + { + _map = new HashMap(array.length); + _list = new ArrayList(array.length + 1); + for (int i = 0; i < array.length; i++) + { + _map.put(array[i].toString(), array[i]); + int j = array[i].intValue(); + while (_list.size() <= j) + _list.add(null); + _list.set(j, array[i]); + } + } + + /** Returns the singleton for a {@link String}, or null if none. */ + public StringEnumAbstractBase forString(String s) + { + return (StringEnumAbstractBase)_map.get(s); + } + /** Returns the singleton for an int code, or null if none. */ + public StringEnumAbstractBase forInt(int i) + { + if (i < 0 || i > _list.size()) + return null; + return (StringEnumAbstractBase)_list.get(i); + } + /** Returns the last valid int code (the first is 1; zero is not used). */ + public int lastInt() + { + return _list.size() - 1; + } + } +} diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/SystemProperties.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/SystemProperties.java new file mode 100644 index 000000000..785227974 --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/SystemProperties.java @@ -0,0 +1,50 @@ +/* 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; + +import java.util.Hashtable; + + +public class SystemProperties +{ + + protected static Hashtable propertyH; + + public static String getProperty(String key) { + if (propertyH == null) { + try { + propertyH = System.getProperties(); + } catch(SecurityException ex) { + propertyH = new Hashtable(); + return null; + } + } + return (String)propertyH.get(key); + } + + public static String getProperty(String key, String defaultValue) { + String result = getProperty(key); + if (result == null) + return defaultValue; + return result; + } + + public static void setPropertyH(Hashtable aPropertyH) { + propertyH = aPropertyH; + } + +} + diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/UserType.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/UserType.java new file mode 100644 index 000000000..3d1b4fc54 --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/UserType.java @@ -0,0 +1,27 @@ +package org.apache.xmlbeans; + +import javax.xml.namespace.QName; + +/** + * The UserType class represents a mapping between an XML Schema QName and + * a custom Java class type. It is used during code generation to determine + * how to convert user-defined simple types to user defined Java classes. + */ +public interface UserType +{ + /** + * The QName of the simple value that will be converted to a Java class. + */ + QName getName(); + + /** + * The class name the simple value will be converted to. + */ + String getJavaName(); + + /** + * A class which provides public static methods to convert {@link SimpleValue} + * objects to and from the Java type specified by {@link #getJavaName()}. + */ + String getStaticHandler(); +} diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XMLStreamValidationException.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XMLStreamValidationException.java new file mode 100644 index 000000000..9ec0b0e34 --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XMLStreamValidationException.java @@ -0,0 +1,41 @@ +/* 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; + +import org.apache.xmlbeans.xml.stream.XMLStreamException; + +/** + * An exception thrown from a validating XMLInputStream. + * + * @see XmlObject.Factory#newValidatingXMLInputStream + * @see SchemaTypeLoader#newValidatingXMLInputStream + */ +public class XMLStreamValidationException extends XMLStreamException +{ + public XMLStreamValidationException ( XmlError xmlError ) + { + super( xmlError.toString() ); + + _xmlError = xmlError; + } + + public XmlError getXmlError ( ) + { + return _xmlError; + } + + private XmlError _xmlError; +} \ No newline at end of file diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlAnySimpleType.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlAnySimpleType.java new file mode 100644 index 000000000..acc6fd6d2 --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlAnySimpleType.java @@ -0,0 +1,154 @@ +/* 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; + +import javax.xml.stream.XMLStreamReader; + + +/** + * Corresponds to the XML Schema + * xs:anySimpleType type. + *

    + * All simple types are convertible to {@link String}. + */ +public interface XmlAnySimpleType extends XmlObject +{ + /** The constant {@link SchemaType} object representing this schema type. */ + public static final SchemaType type = XmlBeans.getBuiltinTypeSystem().typeForHandle("_BI_anySimpleType"); + + /** + * Returns the value as a {@link String} + * @deprecated replaced by {@link #getStringValue} + **/ + String stringValue(); + /** + * Sets the value as a {@link String} + * @deprecated replaced by {@link #setStringValue} + **/ + void set(String s); + + /** + * Returns the value as a {@link String} + **/ + String getStringValue(); + + /** + * Sets the value as a {@link String} + **/ + void setStringValue(String s); + + /** + * A class with methods for creating instances + * of {@link XmlAnySimpleType}. + */ + public static final class Factory + { + /** Creates an empty instance of {@link XmlAnySimpleType} */ + public static XmlAnySimpleType newInstance() { + return (XmlAnySimpleType) XmlBeans.getContextTypeLoader().newInstance( type, null ); } + + /** Creates an empty instance of {@link XmlAnySimpleType} */ + public static XmlAnySimpleType newInstance(org.apache.xmlbeans.XmlOptions options) { + return (XmlAnySimpleType) XmlBeans.getContextTypeLoader().newInstance( type, options ); } + + /** Creates an immutable {@link XmlAnySimpleType} value */ + public static XmlAnySimpleType newValue(Object obj) { + return type.newValue( obj ); } + + /** Parses a {@link XmlAnySimpleType} fragment from a String. For example: "<xml-fragment>anything</xml-fragment>". */ + public static XmlAnySimpleType parse(java.lang.String s) throws org.apache.xmlbeans.XmlException { + return (XmlAnySimpleType) XmlBeans.getContextTypeLoader().parse( s, type, null ); } + + /** Parses a {@link XmlAnySimpleType} fragment from a String. For example: "<xml-fragment>anything</xml-fragment>". */ + public static XmlAnySimpleType parse(java.lang.String s, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (XmlAnySimpleType) XmlBeans.getContextTypeLoader().parse( s, type, options ); } + + /** Parses a {@link XmlAnySimpleType} fragment from a File. */ + public static XmlAnySimpleType parse(java.io.File f) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlAnySimpleType) XmlBeans.getContextTypeLoader().parse( f, type, null ); } + + /** Parses a {@link XmlAnySimpleType} fragment from a File. */ + public static XmlAnySimpleType parse(java.io.File f, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlAnySimpleType) XmlBeans.getContextTypeLoader().parse( f, type, options ); } + + /** Parses a {@link XmlAnySimpleType} fragment from a URL. */ + public static XmlAnySimpleType parse(java.net.URL u) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlAnySimpleType) XmlBeans.getContextTypeLoader().parse( u, type, null ); } + + /** Parses a {@link XmlAnySimpleType} fragment from a URL. */ + public static XmlAnySimpleType parse(java.net.URL u, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlAnySimpleType) XmlBeans.getContextTypeLoader().parse( u, type, options ); } + + /** Parses a {@link XmlAnySimpleType} fragment from an InputStream. */ + public static XmlAnySimpleType parse(java.io.InputStream is) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlAnySimpleType) XmlBeans.getContextTypeLoader().parse( is, type, null ); } + + /** Parses a {@link XmlAnySimpleType} fragment from an InputStream. */ + public static XmlAnySimpleType parse(java.io.InputStream is, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlAnySimpleType) XmlBeans.getContextTypeLoader().parse( is, type, options ); } + + /** Parses a {@link XmlAnySimpleType} fragment from a Reader. */ + public static XmlAnySimpleType parse(java.io.Reader r) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlAnySimpleType) XmlBeans.getContextTypeLoader().parse( r, type, null ); } + + /** Parses a {@link XmlAnySimpleType} fragment from a Reader. */ + public static XmlAnySimpleType parse(java.io.Reader r, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlAnySimpleType) XmlBeans.getContextTypeLoader().parse( r, type, options ); } + + /** Parses a {@link XmlAnySimpleType} fragment from a DOM Node. */ + public static XmlAnySimpleType parse(org.w3c.dom.Node node) throws org.apache.xmlbeans.XmlException { + return (XmlAnySimpleType) XmlBeans.getContextTypeLoader().parse( node, type, null ); } + + /** Parses a {@link XmlAnySimpleType} fragment from a DOM Node. */ + public static XmlAnySimpleType parse(org.w3c.dom.Node node, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (XmlAnySimpleType) XmlBeans.getContextTypeLoader().parse( node, type, options ); } + + /** Parses a {@link XmlAnySimpleType} fragment from an XMLInputStream. + * @deprecated Deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XmlAnySimpleType parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (XmlAnySimpleType) XmlBeans.getContextTypeLoader().parse( xis, type, null ); } + + /** Parses a {@link XmlAnySimpleType} fragment from an XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XmlAnySimpleType parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (XmlAnySimpleType) XmlBeans.getContextTypeLoader().parse( xis, type, options ); } + + /** Parses a {@link XmlAnySimpleType} fragment from an XMLStreamReader. */ + public static XmlAnySimpleType parse(javax.xml.stream.XMLStreamReader xsr) throws org.apache.xmlbeans.XmlException { + return (XmlAnySimpleType) XmlBeans.getContextTypeLoader().parse( xsr, type, null ); } + + /** Parses a {@link XmlAnySimpleType} fragment from an XMLStreamReader. */ + public static XmlAnySimpleType parse(javax.xml.stream.XMLStreamReader xsr, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException{ + return (XmlAnySimpleType) XmlBeans.getContextTypeLoader().parse( xsr, type, options ); } + + /** Returns a validating XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, null ); } + + /** Returns a validating XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, options ); } + + private Factory() { } // No instance of this class allowed + } +} + diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlAnyURI.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlAnyURI.java new file mode 100644 index 000000000..4246e7295 --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlAnyURI.java @@ -0,0 +1,133 @@ +/* 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; + +import javax.xml.stream.XMLStreamReader; + + +/** + * Corresponds to the XML Schema + * xs:anyURI type. + *

    + * Convertible to {@link String}. + */ +public interface XmlAnyURI extends XmlAnySimpleType +{ + /** The constant {@link SchemaType} object representing this schema type. */ + public static final SchemaType type = XmlBeans.getBuiltinTypeSystem().typeForHandle("_BI_anyURI"); + + /** + * A class with methods for creating instances + * of {@link XmlAnyURI}. + */ + public static final class Factory + { + /** Creates an empty instance of {@link XmlAnyURI} */ + public static XmlAnyURI newInstance() { + return (XmlAnyURI) XmlBeans.getContextTypeLoader().newInstance( type, null ); } + + /** Creates an empty instance of {@link XmlAnyURI} */ + public static XmlAnyURI newInstance(org.apache.xmlbeans.XmlOptions options) { + return (XmlAnyURI) XmlBeans.getContextTypeLoader().newInstance( type, options ); } + + /** Creates an immutable {@link XmlAnyURI} value */ + public static XmlAnyURI newValue(Object obj) { + return (XmlAnyURI) type.newValue( obj ); } + + /** Parses a {@link XmlAnyURI} fragment from a String. For example: "<xml-fragment>http://www.w3.org/</xml-fragment>". */ + public static XmlAnyURI parse(java.lang.String s) throws org.apache.xmlbeans.XmlException { + return (XmlAnyURI) XmlBeans.getContextTypeLoader().parse( s, type, null ); } + + /** Parses a {@link XmlAnyURI} fragment from a String. For example: "<xml-fragment>http://www.w3.org/</xml-fragment>". */ + public static XmlAnyURI parse(java.lang.String s, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (XmlAnyURI) XmlBeans.getContextTypeLoader().parse( s, type, options ); } + + /** Parses a {@link XmlAnyURI} fragment from a File. */ + public static XmlAnyURI parse(java.io.File f) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlAnyURI) XmlBeans.getContextTypeLoader().parse( f, type, null ); } + + /** Parses a {@link XmlAnyURI} fragment from a File. */ + public static XmlAnyURI parse(java.io.File f, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlAnyURI) XmlBeans.getContextTypeLoader().parse( f, type, options ); } + + /** Parses a {@link XmlAnyURI} fragment from a URL. */ + public static XmlAnyURI parse(java.net.URL u) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlAnyURI) XmlBeans.getContextTypeLoader().parse( u, type, null ); } + + /** Parses a {@link XmlAnyURI} fragment from a URL. */ + public static XmlAnyURI parse(java.net.URL u, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlAnyURI) XmlBeans.getContextTypeLoader().parse( u, type, options ); } + + /** Parses a {@link XmlAnyURI} fragment from an InputStream. */ + public static XmlAnyURI parse(java.io.InputStream is) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlAnyURI) XmlBeans.getContextTypeLoader().parse( is, type, null ); } + + /** Parses a {@link XmlAnyURI} fragment from an InputStream. */ + public static XmlAnyURI parse(java.io.InputStream is, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlAnyURI) XmlBeans.getContextTypeLoader().parse( is, type, options ); } + + /** Parses a {@link XmlAnyURI} fragment from a Reader. */ + public static XmlAnyURI parse(java.io.Reader r) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlAnyURI) XmlBeans.getContextTypeLoader().parse( r, type, null ); } + + /** Parses a {@link XmlAnyURI} fragment from a Reader. */ + public static XmlAnyURI parse(java.io.Reader r, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlAnyURI) XmlBeans.getContextTypeLoader().parse( r, type, options ); } + + /** Parses a {@link XmlAnyURI} fragment from a DOM Node. */ + public static XmlAnyURI parse(org.w3c.dom.Node node) throws org.apache.xmlbeans.XmlException { + return (XmlAnyURI) XmlBeans.getContextTypeLoader().parse( node, type, null ); } + + /** Parses a {@link XmlAnyURI} fragment from a DOM Node. */ + public static XmlAnyURI parse(org.w3c.dom.Node node, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (XmlAnyURI) XmlBeans.getContextTypeLoader().parse( node, type, options ); } + + /** Parses a {@link XmlAnyURI} fragment from an XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XmlAnyURI parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (XmlAnyURI) XmlBeans.getContextTypeLoader().parse( xis, type, null ); } + + /** Parses a {@link XmlAnyURI} fragment from an XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XmlAnyURI parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (XmlAnyURI) XmlBeans.getContextTypeLoader().parse( xis, type, options ); } + + /** Parses a {@link XmlAnyURI} fragment from an XMLStreamReader. */ + public static XmlAnyURI parse(javax.xml.stream.XMLStreamReader xsr) throws org.apache.xmlbeans.XmlException { + return (XmlAnyURI) XmlBeans.getContextTypeLoader().parse( xsr, type, null ); } + + /** Parses a {@link XmlAnyURI} fragment from an XMLStreamReader. */ + public static XmlAnyURI parse(javax.xml.stream.XMLStreamReader xsr, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException{ + return (XmlAnyURI) XmlBeans.getContextTypeLoader().parse( xsr, type, options ); } + + /** Returns a validating XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, null ); } + + /** Returns a validating XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, options ); } + + private Factory() { } // No instance of this class allowed + } +} + diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlBase64Binary.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlBase64Binary.java new file mode 100644 index 000000000..ba8bbd682 --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlBase64Binary.java @@ -0,0 +1,151 @@ +/* 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; + +import javax.xml.stream.XMLStreamReader; + + +/** + * Corresponds to the XML Schema + * xs:base64Binary type. + *

    + * Convertible to a byte array. + */ +public interface XmlBase64Binary extends XmlAnySimpleType +{ + /** The constant {@link SchemaType} object representing this schema type. */ + public static final SchemaType type = XmlBeans.getBuiltinTypeSystem().typeForHandle("_BI_base64Binary"); + + /** + * Returns this value as a byte array. + * @deprecated replaced by {@link #getByteArrayValue} + **/ + byte[] byteArrayValue(); + + /** + * Sets this value as a byte array. + * @deprecated replaced by {@link #setByteArrayValue} + **/ + void set(byte[] ba); + + /** Returns this value as a byte array. **/ + byte[] getByteArrayValue(); + /** Sets this value as a byte array. */ + void setByteArrayValue(byte[] ba); + + + /** + * A class with methods for creating instances + * of {@link XmlBase64Binary}. + */ + public static final class Factory + { + /** Creates an empty instance of {@link XmlBase64Binary} */ + public static XmlBase64Binary newInstance() { + return (XmlBase64Binary) XmlBeans.getContextTypeLoader().newInstance( type, null ); } + + /** Creates an empty instance of {@link XmlBase64Binary} */ + public static XmlBase64Binary newInstance(org.apache.xmlbeans.XmlOptions options) { + return (XmlBase64Binary) XmlBeans.getContextTypeLoader().newInstance( type, options ); } + + /** Creates an immutable {@link XmlBase64Binary} value */ + public static XmlBase64Binary newValue(Object obj) { + return (XmlBase64Binary) type.newValue( obj ); } + + /** Parses a {@link XmlBase64Binary} fragment from a String. For example: "<xml-fragment>VGhpcyBzdHJp</xml-fragment>". */ + public static XmlBase64Binary parse(java.lang.String s) throws org.apache.xmlbeans.XmlException { + return (XmlBase64Binary) XmlBeans.getContextTypeLoader().parse( s, type, null ); } + + /** Parses a {@link XmlBase64Binary} fragment from a String. For example: "<xml-fragment>VGhpcyBzdHJp</xml-fragment>". */ + public static XmlBase64Binary parse(java.lang.String s, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (XmlBase64Binary) XmlBeans.getContextTypeLoader().parse( s, type, options ); } + + /** Parses a {@link XmlBase64Binary} fragment from a File. */ + public static XmlBase64Binary parse(java.io.File f) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlBase64Binary) XmlBeans.getContextTypeLoader().parse( f, type, null ); } + + /** Parses a {@link XmlBase64Binary} fragment from a File. */ + public static XmlBase64Binary parse(java.io.File f, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlBase64Binary) XmlBeans.getContextTypeLoader().parse( f, type, options ); } + + /** Parses a {@link XmlBase64Binary} fragment from a URL. */ + public static XmlBase64Binary parse(java.net.URL u) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlBase64Binary) XmlBeans.getContextTypeLoader().parse( u, type, null ); } + + /** Parses a {@link XmlBase64Binary} fragment from a URL. */ + public static XmlBase64Binary parse(java.net.URL u, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlBase64Binary) XmlBeans.getContextTypeLoader().parse( u, type, options ); } + + /** Parses a {@link XmlBase64Binary} fragment from an InputStream. */ + public static XmlBase64Binary parse(java.io.InputStream is) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlBase64Binary) XmlBeans.getContextTypeLoader().parse( is, type, null ); } + + /** Parses a {@link XmlBase64Binary} fragment from an InputStream. */ + public static XmlBase64Binary parse(java.io.InputStream is, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlBase64Binary) XmlBeans.getContextTypeLoader().parse( is, type, options ); } + + /** Parses a {@link XmlBase64Binary} fragment from a Reader. */ + public static XmlBase64Binary parse(java.io.Reader r) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlBase64Binary) XmlBeans.getContextTypeLoader().parse( r, type, null ); } + + /** Parses a {@link XmlBase64Binary} fragment from a Reader. */ + public static XmlBase64Binary parse(java.io.Reader r, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlBase64Binary) XmlBeans.getContextTypeLoader().parse( r, type, options ); } + + /** Parses a {@link XmlBase64Binary} fragment from a DOM Node. */ + public static XmlBase64Binary parse(org.w3c.dom.Node node) throws org.apache.xmlbeans.XmlException { + return (XmlBase64Binary) XmlBeans.getContextTypeLoader().parse( node, type, null ); } + + /** Parses a {@link XmlBase64Binary} fragment from a DOM Node. */ + public static XmlBase64Binary parse(org.w3c.dom.Node node, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (XmlBase64Binary) XmlBeans.getContextTypeLoader().parse( node, type, options ); } + + /** Parses a {@link XmlBase64Binary} fragment from an XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XmlBase64Binary parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (XmlBase64Binary) XmlBeans.getContextTypeLoader().parse( xis, type, null ); } + + /** Parses a {@link XmlBase64Binary} fragment from an XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XmlBase64Binary parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (XmlBase64Binary) XmlBeans.getContextTypeLoader().parse( xis, type, options ); } + + /** Parses a {@link XmlBase64Binary} fragment from an XMLStreamReader. */ + public static XmlBase64Binary parse(javax.xml.stream.XMLStreamReader xsr) throws org.apache.xmlbeans.XmlException { + return (XmlBase64Binary) XmlBeans.getContextTypeLoader().parse( xsr, type, null ); } + + /** Parses a {@link XmlBase64Binary} fragment from an XMLStreamReader. */ + public static XmlBase64Binary parse(javax.xml.stream.XMLStreamReader xsr, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException{ + return (XmlBase64Binary) XmlBeans.getContextTypeLoader().parse( xsr, type, options ); } + + /** Returns a validating XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, null ); } + + /** Returns a validating XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, options ); } + + private Factory() { } // No instance of this class allowed + } +} + diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlBeans.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlBeans.java new file mode 100644 index 000000000..9445957ce --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlBeans.java @@ -0,0 +1,884 @@ +/* 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; + +import javax.xml.namespace.QName; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Constructor; +import java.lang.ref.SoftReference; +import java.io.File; + +import javax.xml.stream.XMLStreamReader; + +import org.w3c.dom.Node; + +/** + * Provides an assortment of utilities + * for managing XML Bean types, type systems, QNames, paths, + * and queries. + */ +public final class XmlBeans +{ + private static String XMLBEANS_TITLE = "org.apache.xmlbeans"; + private static String XMLBEANS_VERSION = "2.6.0"; + private static String XMLBEANS_VENDOR = "Apache Software Foundation"; + + static + { + Package pkg = XmlBeans.class.getPackage(); + if (pkg != null) + { + XMLBEANS_TITLE = pkg.getImplementationTitle(); + XMLBEANS_VERSION = pkg.getImplementationVersion(); + XMLBEANS_VENDOR = pkg.getImplementationVendor(); + } + } + + /** + * Returns the XmlBeans Package title, "org.apache.xmlbeans", + * the value of + * {@link Package#getImplementationTitle() XmlBeans.class.getPackage().getImplementationTitle()}. + */ + public static final String getTitle() + { + return XMLBEANS_TITLE; + } + + /** + * Returns the XmlBeans vendor, "Apache Software Foundation", + * the value of + * {@link Package#getImplementationVendor() XmlBeans.class.getPackage().getImplementationVendor()}. + */ + public static final String getVendor() + { + return XMLBEANS_VENDOR; + } + + /** + * Returns the XmlBeans version, + * the value of + * {@link Package#getImplementationVersion() XmlBeans.class.getPackage().getImplementationVersion()}. + */ + public static final String getVersion() + { + return XMLBEANS_VERSION; + } + + /** + * Thread local QName cache for general use + */ + private static final ThreadLocal _threadLocalLoaderQNameCache = + new ThreadLocal() + { + protected Object initialValue() + { + return new SoftReference(new QNameCache( 32 )); + } + }; + + /** + * Returns a thread local QNameCache + */ + public static QNameCache getQNameCache ( ) + { + SoftReference softRef = (SoftReference)_threadLocalLoaderQNameCache.get(); + QNameCache qnameCache = (QNameCache) (softRef).get(); + if (qnameCache==null) + { + qnameCache = new QNameCache( 32 ); + _threadLocalLoaderQNameCache.set(new SoftReference(qnameCache)); + } + return qnameCache; + } + + /** + * Obtains a name from the thread local QNameCache + */ + public static QName getQName ( String localPart ) + { + return getQNameCache().getName( "", localPart ); + } + + /** + * Obtains a name from the thread local QNameCache + */ + + public static QName getQName ( String namespaceUri, String localPart ) + { + return getQNameCache().getName( namespaceUri, localPart ); + } + + private static final Method _getContextTypeLoaderMethod = buildGetContextTypeLoaderMethod(); + private static final Method _getBuiltinSchemaTypeSystemMethod = buildGetBuiltinSchemaTypeSystemMethod(); + private static final Method _getNoTypeMethod = buildGetNoTypeMethod(); + private static final Method _typeLoaderBuilderMethod = buildTypeLoaderBuilderMethod(); + private static final Method _compilationMethod = buildCompilationMethod(); + private static final Method _nodeToCursorMethod = buildNodeToCursorMethod(); + private static final Method _nodeToXmlObjectMethod = buildNodeToXmlObjectMethod(); + private static final Method _nodeToXmlStreamMethod = buildNodeToXmlStreamMethod(); + private static final Method _streamToNodeMethod = buildStreamToNodeMethod(); + private static final Constructor _pathResourceLoaderConstructor = buildPathResourceLoaderConstructor(); + + private static RuntimeException causedException ( RuntimeException e, Throwable cause ) + { + e.initCause( cause ); + + return e; + } + + private static XmlException wrappedException(Throwable e) + { + if (e instanceof XmlException) + return (XmlException) e; + + return new XmlException( e.getMessage(), e ); + } + + private static final Constructor buildConstructor ( String className, Class[] args ) + { + try + { + return + Class.forName( + className, false, XmlBeans.class.getClassLoader() ). + getConstructor( args ); + } + catch ( Exception e ) + { + throw causedException( + new IllegalStateException( + "Cannot load constructor for " + className + + ": verify that xbean.jar is on the classpath" ), e ); + } + } + + private static final Method buildMethod ( String className, String methodName, Class[] args ) + { + try + { + return + Class.forName( + className, false, XmlBeans.class.getClassLoader() ). + getMethod( methodName, args ); + } + catch ( Exception e ) + { + throw causedException( + new IllegalStateException( + "Cannot load " + methodName + + ": verify that xbean.jar is on the classpath" ), e ); + } + } + + private static final Method buildNoArgMethod ( String className, String methodName ) + { + return buildMethod( className, methodName, new Class[ 0 ] ); + } + + private static final Method buildNodeMethod ( String className, String methodName ) + { + return buildMethod( className, methodName, new Class[] { Node.class } ); + } + + private static Method buildGetContextTypeLoaderMethod() + { + return buildNoArgMethod( "org.apache.xmlbeans.impl.schema.SchemaTypeLoaderImpl", "getContextTypeLoader" ); + } + + + private static final Method buildGetBuiltinSchemaTypeSystemMethod() + { + return buildNoArgMethod( "org.apache.xmlbeans.impl.schema.BuiltinSchemaTypeSystem", "get" ); + } + + private static final Method buildGetNoTypeMethod() + { + return buildNoArgMethod( "org.apache.xmlbeans.impl.schema.BuiltinSchemaTypeSystem", "getNoType" ); + } + + private static final Method buildTypeLoaderBuilderMethod ( ) + { + return + buildMethod( + "org.apache.xmlbeans.impl.schema.SchemaTypeLoaderImpl", "build", + new Class[] { SchemaTypeLoader[].class, ResourceLoader.class, ClassLoader.class } ); + } + + private static final Method buildCompilationMethod() + { + return + buildMethod( + "org.apache.xmlbeans.impl.schema.SchemaTypeSystemCompiler", "compile", + new Class[] { String.class, SchemaTypeSystem.class, XmlObject[].class, BindingConfig.class, SchemaTypeLoader.class, Filer.class, XmlOptions.class } ); + } + + private static final Method buildNodeToCursorMethod() + { + return buildNodeMethod( "org.apache.xmlbeans.impl.store.Locale", "nodeToCursor" ); + } + + private static final Method buildNodeToXmlObjectMethod() + { + return buildNodeMethod( "org.apache.xmlbeans.impl.store.Locale", "nodeToXmlObject" ); + } + + private static final Method buildNodeToXmlStreamMethod() + { + return buildNodeMethod( "org.apache.xmlbeans.impl.store.Locale", "nodeToXmlStream" ); + } + + private static final Method buildStreamToNodeMethod() + { + return + buildMethod( + "org.apache.xmlbeans.impl.store.Locale", "streamToNode", + new Class[] { XMLStreamReader.class } ); + } + + private static final Constructor buildPathResourceLoaderConstructor() + { + return + buildConstructor( + "org.apache.xmlbeans.impl.schema.PathResourceLoader", + new Class[] { File[].class } ); + } + + /** + * Compiles an XPath, returning a String equal to that which was passed, + * but whose identity is that of one which has been precompiled and cached. + */ + public static String compilePath ( String pathExpr ) throws XmlException + { + return compilePath( pathExpr, null ); + } + + /** + * Compiles an XPath, returning a String equal to that which was passed, + * but whose identity is that of one which has been precompiled and cached; + * takes an option for specifying text that indicates the name of context node. + * The default is "this", as in "$this". + * + * @param options Options for the path. For example, you can call + * the {@link XmlOptions#setXqueryCurrentNodeVar(String) XmlOptions.setXqueryCurrentNodeVar(String)} + * method to specify a particular name for the expression + * variable that indicates the context node. + */ + public static String compilePath ( String pathExpr, XmlOptions options ) + throws XmlException + { + return getContextTypeLoader().compilePath( pathExpr, options ); + } + + /** + * Compiles an XQuery, returning a String equal to that which was passed, + * but whose identity is that of one which has been precompiled and cached. + */ + public static String compileQuery ( String queryExpr ) throws XmlException + { + return compileQuery( queryExpr, null ); + } + + /** + * Compiles an XQuery, returning a String equal to that which was passed, + * but whose identity is that of one which has been precompiled and cached; + * takes an option for specifying text that indicates the context node. + * + * @param options Options for the query. For example, you can call + * the {@link XmlOptions#setXqueryCurrentNodeVar(String) XmlOptions.setXqueryCurrentNodeVar(String)} + * method to specify a particular name for the expression + * variable that indicates the context node and the + * {@link XmlOptions#setXqueryVariables(java.util.Map) XmlOptions.setXqueryVariables(Map)} + * method to map external variable names to values. + */ + public static String compileQuery ( String queryExpr, XmlOptions options ) + throws XmlException + { + return getContextTypeLoader().compileQuery( queryExpr, options ); + } + + /** + * Gets the SchemaTypeLoader based on the current thread's context + * ClassLoader. This is the SchemaTypeLoader that is used to assign + * schema types to XML documents by default. The SchemaTypeLoader is + * also consulted to resolve wildcards and xsi:type attributes. + *

    + * The "parse" methods of XmlBeans all delegate to the + * "parseInstance" methods of the context type loader. + */ + public static SchemaTypeLoader getContextTypeLoader() + { + try + { + return (SchemaTypeLoader)_getContextTypeLoaderMethod.invoke(null, null); + } + catch (IllegalAccessException e) + { + throw causedException(new IllegalStateException("No access to SchemaTypeLoaderImpl.getContextTypeLoader(): verify that version of xbean.jar is correct"), e); + } + catch (InvocationTargetException e) + { + Throwable t = e.getCause(); + IllegalStateException ise = new IllegalStateException(t.getMessage()); + ise.initCause(t); // use initCause() to support Java 1.4 + throw ise; + } + } + + /** + * Returns the builtin type system. This SchemaTypeSystem contains + * only the 46 builtin types defined by the XML Schema specification. + */ + public static SchemaTypeSystem getBuiltinTypeSystem() + { + try + { + return (SchemaTypeSystem)_getBuiltinSchemaTypeSystemMethod.invoke(null, null); + } + catch (IllegalAccessException e) + { + throw causedException(new IllegalStateException("No access to BuiltinSchemaTypeSystem.get(): verify that version of xbean.jar is correct"), e); + } + catch (InvocationTargetException e) + { + Throwable t = e.getCause(); + IllegalStateException ise = new IllegalStateException(t.getMessage()); + ise.initCause(t); // use initCause() to support Java 1.4 + throw ise; + } + } + + /** + * Creates an XmlCursor for a DOM node which is implemented by XmlBwans + */ + public static XmlCursor nodeToCursor ( Node n ) + { + try + { + return (XmlCursor) _nodeToCursorMethod.invoke( null, new Object[] { n } ); + } + catch ( IllegalAccessException e ) + { + throw causedException( + new IllegalStateException( + "No access to nodeToCursor verify that version of xbean.jar is correct" ), e ); + } + catch ( InvocationTargetException e ) + { + Throwable t = e.getCause(); + IllegalStateException ise = new IllegalStateException(t.getMessage()); + ise.initCause(t); // use initCause() to support Java 1.4 + throw ise; + } + } + + /** + * Creates an XmlObject for a DOM node which is implemented by XmlBwans + */ + public static XmlObject nodeToXmlObject ( Node n ) + { + try + { + return (XmlObject) _nodeToXmlObjectMethod.invoke( null, new Object[] { n } ); + } + catch ( IllegalAccessException e ) + { + throw causedException( + new IllegalStateException( + "No access to nodeToXmlObject verify that version of xbean.jar is correct" ), e ); + } + catch ( InvocationTargetException e ) + { + Throwable t = e.getCause(); + IllegalStateException ise = new IllegalStateException(t.getMessage()); + ise.initCause(t); // use initCause() to support Java 1.4 + throw ise; + } + } + + /** + * Creates an XmlObject for a DOM node which is implemented by XmlBwans + */ + public static XMLStreamReader nodeToXmlStreamReader ( Node n ) + { + try + { + return (XMLStreamReader) _nodeToXmlStreamMethod.invoke( null, new Object[] { n } ); + } + catch ( IllegalAccessException e ) + { + throw causedException( + new IllegalStateException( + "No access to nodeToXmlStreamReader verify that version of xbean.jar is correct" ), e ); + } + catch ( InvocationTargetException e ) + { + Throwable t = e.getCause(); + IllegalStateException ise = new IllegalStateException(t.getMessage()); + ise.initCause(t); // use initCause() to support Java 1.4 + throw ise; + } + } + + /** + * Returns the XmlObject for a DOM node which is implemented by XmlBwans + */ + public static Node streamToNode ( XMLStreamReader xs ) + { + try + { + return (Node) _streamToNodeMethod.invoke( null, new Object[] { xs } ); + } + catch ( IllegalAccessException e ) + { + throw causedException( + new IllegalStateException( + "No access to streamToNode verify that version of xbean.jar is correct" ), e ); + } + catch ( InvocationTargetException e ) + { + Throwable t = e.getCause(); + IllegalStateException ise = new IllegalStateException(t.getMessage()); + ise.initCause(t); // use initCause() to support Java 1.4 + throw ise; + } + } + + /** + * Returns the SchemaTypeSystem that results from compiling the XML + * schema definitions passed. + *

    + * Just like compileXsd, but uses the context type loader for + * linking, and returns a unioned typeloader that is suitable for + * creating instances. + */ + public static SchemaTypeLoader loadXsd(XmlObject[] schemas) throws XmlException + { + return loadXsd(schemas, null); + } + + /** + *

    Returns the SchemaTypeSystem that results from compiling the XML + * schema definitions passed in schemas.

    + * + *

    This is just like compileXsd, but uses the context type loader for + * linking, and returns a unioned typeloader that is suitable for + * creating instances.

    + * + *

    Use the options parameter to specify one or both of the following:

    + * + *
      + *
    • A collection instance that should be used as an error listener during + * compilation, as described in {@link XmlOptions#setErrorListener}.
    • + *
    • Whether validation should not be done when building the SchemaTypeSystem, + * as described in {@link XmlOptions#setCompileNoValidation}.
    • + *
    + * + * @param schemas The schema definitions from which to build the schema type system. + * @param options Options specifying an error listener and/or validation behavior. + */ + public static SchemaTypeLoader loadXsd(XmlObject[] schemas, XmlOptions options) throws XmlException + { + try + { + SchemaTypeSystem sts = + (SchemaTypeSystem) + _compilationMethod.invoke( + null, new Object[] { null, null, schemas, null, getContextTypeLoader(), null, options }); + + if (sts == null) + return null; + + return + typeLoaderUnion( + new SchemaTypeLoader[] { sts, getContextTypeLoader() } ); + } + catch (IllegalAccessException e) + { + throw causedException(new IllegalStateException("No access to SchemaTypeLoaderImpl.forSchemaXml(): verify that version of xbean.jar is correct"), e); + } + catch (InvocationTargetException e) + { + throw wrappedException(e.getCause()); + } + } + + /** + *

    Returns the SchemaTypeSystem that results from compiling the XML + * schema definitions passed.

    + * + *

    The XmlObjects passed in should be w3c <schema> elements whose type + * is org.w3c.x2001.xmlSchema.Schema. (That is, schema elements in + * the XML namespace http://www.w3c.org/2001/XMLSchema.) Also + * org.w3c.x2001.xmlSchema.SchemaDocument is permitted.

    + * + *

    The optional second argument is a SchemaTypeLoader which will be + * consulted for already-compiled schema types which may be linked + * while processing the given schemas.

    + * + *

    The SchemaTypeSystem that is returned should be combined + * (via {@link #typeLoaderUnion}) with the typepath typeloader in order + * to create a typeloader that can be used for creating and validating + * instances.

    + * + *

    Use the options parameter to specify the following:

    + * + *
      + *
    • A collection instance that should be used as an error listener during + * compilation, as described in {@link XmlOptions#setErrorListener}.
    • + *
    • Whether validation should not be done when building the SchemaTypeSystem, + * as described in {@link XmlOptions#setCompileNoValidation}.
    • + *
    + * + * @param schemas The schema definitions from which to build the schema type system. + * @param typepath The path to already-compiled schema types for linking while processing. + * @param options Options specifying an error listener and/or validation behavior. + */ + public static SchemaTypeSystem compileXsd(XmlObject[] schemas, SchemaTypeLoader typepath, XmlOptions options) throws XmlException + { + return compileXmlBeans(null, null, schemas, null, typepath, null, options); + } + + /** + *

    Returns the SchemaTypeSystem that results from augumenting the + * SchemaTypeSystem passed in by incrementally adding the given XML + * schema definitions.

    + * + *

    These could be new definitions (if the Schema document is not recorded into + * the existing SchemaTypeSystem), modifications to the already existing + * definitions (if the Schema document is already recorded in the existing + * SchemaTypeSystem), or deletions (if the Schema document is already recorded + * in the existing SchemaTypeSystem and the new definitions are empty). + * The identity of documents is established using + * {@link XmlDocumentProperties#getSourceName}, so if the caller choses to + * construct the Schema definitions using other methods than parsing an + * XML document, they should make sure that the names returned by that + * method are consistent with the caller's intent (add/modify).

    + * + *

    The XmlObjects passed in should be w3c <schema> elements whose type + * is org.w3c.x2001.xmlSchema.Schema. (That is, schema elements in + * the XML namespace http://www.w3c.org/2001/XMLSchema.) Also + * org.w3c.x2001.xmlSchema.SchemaDocument is permitted.

    + * + *

    The optional second argument is a SchemaTypeLoader which will be + * consulted for already-compiled schema types which may be linked + * while processing the given schemas.

    + * + *

    The SchemaTypeSystem that is returned should be combined + * (via {@link #typeLoaderUnion}) with the typepath typeloader in order + * to create a typeloader that can be used for creating and validating + * instances.

    + * + *

    Use the options parameter to specify the following:

    + * + *
      + *
    • A collection instance that should be used as an error listener during + * compilation, as described in {@link XmlOptions#setErrorListener}.
    • + *
    • Whether validation should not be done when building the SchemaTypeSystem, + * as described in {@link XmlOptions#setCompileNoValidation}.
    • + *
    + * + * @param schemas The schema definitions from which to build the schema type system. + * @param typepath The path to already-compiled schema types for linking while processing. + * @param options Options specifying an error listener and/or validation behavior. + */ + public static SchemaTypeSystem compileXsd(SchemaTypeSystem system, XmlObject[] schemas, SchemaTypeLoader typepath, XmlOptions options) throws XmlException + { + return compileXmlBeans(null, system, schemas, null, typepath, null, options); + } + + /** + *

    Returns the SchemaTypeSystem that results from augumenting the + * SchemaTypeSystem passed in by incrementally adding the given XML + * schema definitions.

    + * + *

    These could be new definitions (if the Schema document is not recorded into + * the existing SchemaTypeSystem), modifications to the already existing + * definitions (if the Schema document is already recorded in the existing + * SchemaTypeSystem), or deletions (if the Schema document is already recorded + * in the existing SchemaTypeSystem and the new definitions are empty). + * The identity of documents is established using + * {@link XmlDocumentProperties#getSourceName}, so if the caller choses to + * construct the Schema definitions using other methods than parsing an + * XML document, they should make sure that the names returned by that + * method are consistent with the caller's intent (add/modify).

    + * + *

    The XmlObjects passed in should be w3c <schema> elements whose type + * is org.w3c.x2001.xmlSchema.Schema. (That is, schema elements in + * the XML namespace http://www.w3c.org/2001/XMLSchema.) Also + * org.w3c.x2001.xmlSchema.SchemaDocument is permitted.

    + * + *

    The optional name argument is used to name the compiled schema type system. + * A randomly generated name will be used if the name is null.

    + * + *

    The optional {@link BindingConfig} argument is used to control the shape + * of the generated code. A BindingConfig isn't used if Filer + * is null.

    + * + *

    The optional SchemaTypeLoader argument will be + * consulted for already-compiled schema types which may be linked + * while processing the given schemas. If not specified, the context + * typeloader (as returned by {@link #getContextTypeLoader}) will be used.

    + * + *

    The optional {@link Filer} argument is used to create new binary or source + * files which are the product of the compilation. If the Filer is null, the + * schema binaries (.xsb) files and source files won't be generated.

    + * + *

    The SchemaTypeSystem that is returned should be combined + * (via {@link #typeLoaderUnion}) with the typepath typeloader in order + * to create a typeloader that can be used for creating and validating + * instances.

    + * + *

    Use the options parameter to specify the following:

    + * + *
      + *
    • A collection instance that should be used as an error listener during + * compilation, as described in {@link XmlOptions#setErrorListener}.
    • + *
    • Whether validation should not be done when building the SchemaTypeSystem, + * as described in {@link XmlOptions#setCompileNoValidation}.
    • + *
    + * + * @param name The type system name or null to use a randomly generated name. + * @param system A pre-existing SchemaTypeSystem used in incremental compilation. + * @param schemas The schema definitions from which to build the schema type system. + * @param config The configuration controls the code generation shape. + * @param typepath The path to already-compiled schema types for linking while processing. + * @param filer The Filer instance used to create binary binding files and source text files. + * @param options Options specifying an error listener and/or validation behavior. + */ + public static SchemaTypeSystem compileXmlBeans(String name, SchemaTypeSystem system, XmlObject[] schemas, BindingConfig config, SchemaTypeLoader typepath, Filer filer, XmlOptions options) throws XmlException + { + try + { + return (SchemaTypeSystem)_compilationMethod.invoke(null, new Object[] { name, system, schemas, config, typepath != null ? typepath : getContextTypeLoader(), filer, options }); + } + catch (IllegalAccessException e) + { + throw new IllegalStateException("No access to SchemaTypeLoaderImpl.forSchemaXml(): verify that version of xbean.jar is correct"); + } + catch (InvocationTargetException e) + { + throw wrappedException(e.getCause()); + } + } + + + /** + * Returns the union of a list of typeLoaders. The returned + * SchemaTypeLoader searches the given list of SchemaTypeLoaders + * in order from first to last. + */ + public static SchemaTypeLoader typeLoaderUnion(SchemaTypeLoader[] typeLoaders) + { + try + { + if (typeLoaders.length == 1) + return typeLoaders[0]; + + return (SchemaTypeLoader)_typeLoaderBuilderMethod.invoke(null, new Object[] {typeLoaders, null, null}); + } + catch (IllegalAccessException e) + { + throw causedException(new IllegalStateException("No access to SchemaTypeLoaderImpl: verify that version of xbean.jar is correct"), e); + } + catch (InvocationTargetException e) + { + Throwable t = e.getCause(); + IllegalStateException ise = new IllegalStateException(t.getMessage()); + ise.initCause(t); // use initCause() to support Java 1.4 + throw ise; + } + } + + /** + * Returns a SchemaTypeLoader that searches for compiled schema types + * in the given ClassLoader. + */ + public static SchemaTypeLoader typeLoaderForClassLoader(ClassLoader loader) + { + try + { + return (SchemaTypeLoader)_typeLoaderBuilderMethod.invoke(null, new Object[] {null, null, loader}); + } + catch (IllegalAccessException e) + { + throw causedException(new IllegalStateException("No access to SchemaTypeLoaderImpl: verify that version of xbean.jar is correct"), e); + } + catch (InvocationTargetException e) + { + Throwable t = e.getCause(); + IllegalStateException ise = new IllegalStateException(t.getMessage()); + ise.initCause(t); // use initCause() to support Java 1.4 + throw ise; + } + } + + /** + * Returns a SchemaTypeLoader that searches for compiled schema types + * in the given ResourceLoader. + * + * @see XmlBeans#resourceLoaderForPath(File[]) + */ + public static SchemaTypeLoader typeLoaderForResource(ResourceLoader resourceLoader) + { + try + { + return (SchemaTypeLoader)_typeLoaderBuilderMethod.invoke(null, new Object[] {null, resourceLoader, null}); + } + catch (IllegalAccessException e) + { + throw causedException(new IllegalStateException("No access to SchemaTypeLoaderImpl: verify that version of xbean.jar is correct"), e); + } + catch (InvocationTargetException e) + { + Throwable t = e.getCause(); + IllegalStateException ise = new IllegalStateException(t.getMessage()); + ise.initCause(t); // use initCause() to support Java 1.4 + throw ise; + } + } + + private static final String HOLDER_CLASS_NAME = "TypeSystemHolder"; + private static final String TYPE_SYSTEM_FIELD = "typeSystem"; + + /** + * Returns the SchemaTypeSystem of the given name (as returned by + * {@link SchemaTypeSystem#getName}) for the given ClassLoader. + *

    + * Note: you will almost always need typeLoaderForClassLoader() + * instead (see {@link XmlBeans#typeLoaderForClassLoader}). + */ + public static SchemaTypeSystem typeSystemForClassLoader(ClassLoader loader, String stsName) + { + try + { + Class clazz = loader.loadClass(stsName + "." + HOLDER_CLASS_NAME); + SchemaTypeSystem sts = (SchemaTypeSystem) + (clazz.getDeclaredField(TYPE_SYSTEM_FIELD).get(null)); + if (sts == null) + { + throw new RuntimeException("SchemaTypeSystem is null for field " + + TYPE_SYSTEM_FIELD + " on class with name " + stsName + + "." + HOLDER_CLASS_NAME + + ". Please verify the version of xbean.jar is correct."); + } + return sts; + } + catch (ClassNotFoundException e) + { + throw causedException(new RuntimeException("Cannot load SchemaTypeSystem. " + + "Unable to load class with name " + stsName + "." + HOLDER_CLASS_NAME + + ". Make sure the generated binary files are on the classpath."), e); + } + catch (NoSuchFieldException e) + { + throw causedException(new RuntimeException("Cannot find field " + + TYPE_SYSTEM_FIELD + " on class " + stsName + "." + HOLDER_CLASS_NAME + + ". Please verify the version of xbean.jar is correct."), e); + } + catch (IllegalAccessException e) + { + throw causedException(new RuntimeException("Field " + + TYPE_SYSTEM_FIELD + " on class " + stsName + "." + HOLDER_CLASS_NAME + + "is not accessible. Please verify the version of xbean.jar is correct."), e); + } + } + + /** + * Returns a new ResourceLoader for a search path where each component of + * the path is either a directory or a compiled xbean jar. + */ + public static ResourceLoader resourceLoaderForPath(File[] path) + { + try + { + return (ResourceLoader)_pathResourceLoaderConstructor.newInstance(new Object[] {path}); + } + catch (IllegalAccessException e) + { + throw causedException(new IllegalStateException("No access to SchemaTypeLoaderImpl: verify that version of xbean.jar is correct"), e); + } + catch (InstantiationException e) + { + throw causedException(new IllegalStateException(e.getMessage()), e); + } + catch (InvocationTargetException e) + { + Throwable t = e.getCause(); + IllegalStateException ise = new IllegalStateException(t.getMessage()); + ise.initCause(t); // use initCause() to support Java 1.4 + throw ise; + } + } + + /** + * Returns the SchemaType from a corresponding XmlObject subclass, + * or null if none. + */ + public static SchemaType typeForClass(Class c) + { + if (c == null || !XmlObject.class.isAssignableFrom(c)) + return null; + + try + { + Field typeField = c.getField("type"); + + if (typeField == null) + return null; + + return (SchemaType)typeField.get(null); + } + catch (Exception e) + { + return null; + } + } + + private static SchemaType getNoType() + { + try + { + return (SchemaType)_getNoTypeMethod.invoke(null, null); + } + catch (IllegalAccessException e) + { + throw causedException(new IllegalStateException("No access to SchemaTypeLoaderImpl.getContextTypeLoader(): verify that version of xbean.jar is correct"), e); + } + catch (InvocationTargetException e) + { + Throwable t = e.getCause(); + IllegalStateException ise = new IllegalStateException(t.getMessage()); + ise.initCause(t); // use initCause() to support Java 1.4 + throw ise; + } + } + + /** + * The SchemaType object given to an XmlObject instance when + * no type can be determined. + *

    + * The NO_TYPE is the universal derived type. That is, it is + * derived from all other schema types, and no instances of the + * NO_TYPE are valid. (It is not to be confused with the anyType, + * which is the universal base type from which all other types + * can be derived, and of which all instances are valid.) + */ + public static SchemaType NO_TYPE = getNoType(); + + private XmlBeans ( ) { } +} diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlBoolean.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlBoolean.java new file mode 100644 index 000000000..579b38dca --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlBoolean.java @@ -0,0 +1,149 @@ +/* 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; + +import javax.xml.stream.XMLStreamReader; + + +/** + * Corresponds to the XML Schema + * xs:boolean type. + *

    + * Naturally, convertible to Java boolean. + */ +public interface XmlBoolean extends XmlAnySimpleType +{ + /** The constant {@link SchemaType} object representing this schema type. */ + public static final SchemaType type = XmlBeans.getBuiltinTypeSystem().typeForHandle("_BI_boolean"); + + /** + * Returns this value as a boolean + * @deprecated replaced by {@link #getBooleanValue} + **/ + boolean booleanValue(); + /** + * Sets this value as a boolean + * @deprecated replaced by {@link #setBooleanValue} + **/ + void set(boolean v); + + /** Returns this value as a boolean */ + boolean getBooleanValue(); + /** Sets this value as a boolean */ + void setBooleanValue(boolean v); + + /** + * A class with methods for creating instances + * of {@link XmlBoolean}. + */ + public static final class Factory + { + /** Creates an empty instance of {@link XmlBoolean} */ + public static XmlBoolean newInstance() { + return (XmlBoolean) XmlBeans.getContextTypeLoader().newInstance( type, null ); } + + /** Creates an empty instance of {@link XmlBoolean} */ + public static XmlBoolean newInstance(org.apache.xmlbeans.XmlOptions options) { + return (XmlBoolean) XmlBeans.getContextTypeLoader().newInstance( type, options ); } + + /** Creates an immutable {@link XmlBoolean} value */ + public static XmlBoolean newValue(Object obj) { + return (XmlBoolean) type.newValue( obj ); } + + /** Parses a {@link XmlBoolean} fragment from a String. For example: "<xml-fragment>true</xml-fragment>". */ + public static XmlBoolean parse(java.lang.String s) throws org.apache.xmlbeans.XmlException { + return (XmlBoolean) XmlBeans.getContextTypeLoader().parse( s, type, null ); } + + /** Parses a {@link XmlBoolean} fragment from a String. For example: "<xml-fragment>true</xml-fragment>". */ + public static XmlBoolean parse(java.lang.String s, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (XmlBoolean) XmlBeans.getContextTypeLoader().parse( s, type, options ); } + + /** Parses a {@link XmlBoolean} fragment from a File. */ + public static XmlBoolean parse(java.io.File f) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlBoolean) XmlBeans.getContextTypeLoader().parse( f, type, null ); } + + /** Parses a {@link XmlBoolean} fragment from a File. */ + public static XmlBoolean parse(java.io.File f, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlBoolean) XmlBeans.getContextTypeLoader().parse( f, type, options ); } + + /** Parses a {@link XmlBoolean} fragment from a URL. */ + public static XmlBoolean parse(java.net.URL u) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlBoolean) XmlBeans.getContextTypeLoader().parse( u, type, null ); } + + /** Parses a {@link XmlBoolean} fragment from a URL. */ + public static XmlBoolean parse(java.net.URL u, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlBoolean) XmlBeans.getContextTypeLoader().parse( u, type, options ); } + + /** Parses a {@link XmlBoolean} fragment from an InputStream. */ + public static XmlBoolean parse(java.io.InputStream is) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlBoolean) XmlBeans.getContextTypeLoader().parse( is, type, null ); } + + /** Parses a {@link XmlBoolean} fragment from an InputStream. */ + public static XmlBoolean parse(java.io.InputStream is, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlBoolean) XmlBeans.getContextTypeLoader().parse( is, type, options ); } + + /** Parses a {@link XmlBoolean} fragment from a Reader. */ + public static XmlBoolean parse(java.io.Reader r) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlBoolean) XmlBeans.getContextTypeLoader().parse( r, type, null ); } + + /** Parses a {@link XmlBoolean} fragment from a Reader. */ + public static XmlBoolean parse(java.io.Reader r, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlBoolean) XmlBeans.getContextTypeLoader().parse( r, type, options ); } + + /** Parses a {@link XmlBoolean} fragment from a DOM Node. */ + public static XmlBoolean parse(org.w3c.dom.Node node) throws org.apache.xmlbeans.XmlException { + return (XmlBoolean) XmlBeans.getContextTypeLoader().parse( node, type, null ); } + + /** Parses a {@link XmlBoolean} fragment from a DOM Node. */ + public static XmlBoolean parse(org.w3c.dom.Node node, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (XmlBoolean) XmlBeans.getContextTypeLoader().parse( node, type, options ); } + + /** Parses a {@link XmlBoolean} fragment from an XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XmlBoolean parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (XmlBoolean) XmlBeans.getContextTypeLoader().parse( xis, type, null ); } + + /** Parses a {@link XmlBoolean} fragment from an XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XmlBoolean parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (XmlBoolean) XmlBeans.getContextTypeLoader().parse( xis, type, options ); } + + /** Parses a {@link XmlBoolean} fragment from an XMLStreamReader. */ + public static XmlBoolean parse(javax.xml.stream.XMLStreamReader xsr) throws org.apache.xmlbeans.XmlException { + return (XmlBoolean) XmlBeans.getContextTypeLoader().parse( xsr, type, null ); } + + /** Parses a {@link XmlBoolean} fragment from an XMLStreamReader. */ + public static XmlBoolean parse(javax.xml.stream.XMLStreamReader xsr, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException{ + return (XmlBoolean) XmlBeans.getContextTypeLoader().parse( xsr, type, options ); } + + /** Returns a validating XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, null ); } + + /** Returns a validating XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, options ); } + + private Factory() { } // No instance of this class allowed + } +} + diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlByte.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlByte.java new file mode 100644 index 000000000..b59d3ee1c --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlByte.java @@ -0,0 +1,149 @@ +/* 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; + +import javax.xml.stream.XMLStreamReader; + + +/** + * Corresponds to the XML Schema + * xs:byte type. + *

    + * Naturally, convertible to Java byte. + */ +public interface XmlByte extends XmlShort +{ + /** The constant {@link SchemaType} object representing this schema type. */ + public static final SchemaType type = XmlBeans.getBuiltinTypeSystem().typeForHandle("_BI_byte"); + + /** + * Returns this value as a byte + * @deprecated replaced by {@link #getByteValue} + **/ + public byte byteValue(); + /** + * Sets this value as a byte + * @deprecated replaced by {@link #setByteValue} + **/ + public void set(byte s); + + /** Returns this value as a byte */ + public byte getByteValue(); + /** Sets this value as a byte */ + public void setByteValue(byte s); + + /** + * A class with methods for creating instances + * of {@link XmlByte}. + */ + public static final class Factory + { + /** Creates an empty instance of {@link XmlByte} */ + public static XmlByte newInstance() { + return (XmlByte) XmlBeans.getContextTypeLoader().newInstance( type, null ); } + + /** Creates an empty instance of {@link XmlByte} */ + public static XmlByte newInstance(org.apache.xmlbeans.XmlOptions options) { + return (XmlByte) XmlBeans.getContextTypeLoader().newInstance( type, options ); } + + /** Creates an immutable {@link XmlByte} value */ + public static XmlByte newValue(Object obj) { + return (XmlByte) type.newValue( obj ); } + + /** Parses a {@link XmlByte} fragment from a String. For example: "<xml-fragment>123</xml-fragment>". */ + public static XmlByte parse(java.lang.String s) throws org.apache.xmlbeans.XmlException { + return (XmlByte) XmlBeans.getContextTypeLoader().parse( s, type, null ); } + + /** Parses a {@link XmlByte} fragment from a String. For example: "<xml-fragment>123</xml-fragment>". */ + public static XmlByte parse(java.lang.String s, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (XmlByte) XmlBeans.getContextTypeLoader().parse( s, type, options ); } + + /** Parses a {@link XmlByte} fragment from a File. */ + public static XmlByte parse(java.io.File f) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlByte) XmlBeans.getContextTypeLoader().parse( f, type, null ); } + + /** Parses a {@link XmlByte} fragment from a File. */ + public static XmlByte parse(java.io.File f, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlByte) XmlBeans.getContextTypeLoader().parse( f, type, options ); } + + /** Parses a {@link XmlByte} fragment from a URL. */ + public static XmlByte parse(java.net.URL u) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlByte) XmlBeans.getContextTypeLoader().parse( u, type, null ); } + + /** Parses a {@link XmlByte} fragment from a URL. */ + public static XmlByte parse(java.net.URL u, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlByte) XmlBeans.getContextTypeLoader().parse( u, type, options ); } + + /** Parses a {@link XmlByte} fragment from an InputStream. */ + public static XmlByte parse(java.io.InputStream is) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlByte) XmlBeans.getContextTypeLoader().parse( is, type, null ); } + + /** Parses a {@link XmlByte} fragment from an InputStream. */ + public static XmlByte parse(java.io.InputStream is, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlByte) XmlBeans.getContextTypeLoader().parse( is, type, options ); } + + /** Parses a {@link XmlByte} fragment from a Reader. */ + public static XmlByte parse(java.io.Reader r) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlByte) XmlBeans.getContextTypeLoader().parse( r, type, null ); } + + /** Parses a {@link XmlByte} fragment from a Reader. */ + public static XmlByte parse(java.io.Reader r, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlByte) XmlBeans.getContextTypeLoader().parse( r, type, options ); } + + /** Parses a {@link XmlByte} fragment from a DOM Node. */ + public static XmlByte parse(org.w3c.dom.Node node) throws org.apache.xmlbeans.XmlException { + return (XmlByte) XmlBeans.getContextTypeLoader().parse( node, type, null ); } + + /** Parses a {@link XmlByte} fragment from a DOM Node. */ + public static XmlByte parse(org.w3c.dom.Node node, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (XmlByte) XmlBeans.getContextTypeLoader().parse( node, type, options ); } + + /** Parses a {@link XmlByte} fragment from an XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XmlByte parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (XmlByte) XmlBeans.getContextTypeLoader().parse( xis, type, null ); } + + /** Parses a {@link XmlByte} fragment from an XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XmlByte parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (XmlByte) XmlBeans.getContextTypeLoader().parse( xis, type, options ); } + + /** Parses a {@link XmlByte} fragment from an XMLStreamReader. */ + public static XmlByte parse(javax.xml.stream.XMLStreamReader xsr) throws org.apache.xmlbeans.XmlException { + return (XmlByte) XmlBeans.getContextTypeLoader().parse( xsr, type, null ); } + + /** Parses a {@link XmlByte} fragment from an XMLStreamReader. */ + public static XmlByte parse(javax.xml.stream.XMLStreamReader xsr, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException{ + return (XmlByte) XmlBeans.getContextTypeLoader().parse( xsr, type, options ); } + + /** Returns a validating XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, null ); } + + /** Returns a validating XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, options ); } + + private Factory() { } // No instance of this class allowed + } +} + diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlCalendar.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlCalendar.java new file mode 100644 index 000000000..b450ba5fb --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlCalendar.java @@ -0,0 +1,317 @@ +/* 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; + +import java.util.GregorianCalendar; +import java.util.Calendar; +import java.util.Date; +import java.util.TimeZone; +import java.math.BigDecimal; + +/** + * An XML Schema compatible subclass of {@link java.util.GregorianCalendar GregorianCalendar}. + * XmlCalendar modifies several key details in the behavior of + * GregorianCalendar to make it more useful when dealing with XML dates. + *

    + * It is easy to convert between XmlCalendar and {@link GDate}, or to + * parse or emit an XmlCalendar using a standard XML Schema + * lexical representation. + *

      + *
    1. + * To match XML Schema dates, this XmlCalendar is a fully proleptic + * Gregorian calendar by default, which means that Gregorian calendar + * rules are applied backwards in time as if they had always been in + * effect, actual historical circumstances concerning the observance + * of the 1582 decree of Pope Gregory XIII notwithstanding. + *
    2. + *
    3. + * In order to better support partially-specified dates for XML Schema, + * this implementation provides a stable get(field) method + * that does not modify the instance if you are acessing a field right + * after it was explicitly set: a set followed by a get will always + * return the same thing and will not fill in any other fields. However, + * if you get a field that was not explicitly set, then all the fields + * are still automatically filled and normalized for you, just like a + * regular GregorianCalendar. If you wish to force the completion and + * defaulting of all the fields (without hunting to get one that happens + * to be unset), you can always do so by calling getTime(). + *
    4. + *
    5. + * When a year is unspecified and needs to be filled in automatically + * (for example when using a .get or .getTime method as discussed above), + * the year is defaulted to year 0 (also known as 1 BC). This is different + * from {@link GregorianCalendar}, which chooses 1970. The reason 0 is preferable + * is that it is a leap year and so it permits the date --2-29 to be specified + * stably. A different default year can be chosen via the static method + * {@link #setDefaultYear(int) XmlCalendar.setDefaultYear()}, or by setting the + * system property "user.defaultyear". If you do change this value, you should + * pick another leap year such as 2000 and avoid non-leap years such as 1900. + *
    6. + *
    7. + * When constructing an XmlCalendar from an XML Schema + * formatted date or time string or GDate object, the timezone + * for the calendar is taken from the string if it is present, or + * taken to be {@link java.util.TimeZone#getDefault() TimeZone.getDefault()} if not. + *

      + * For example, the XML timezone "Z" is translated to "GMT"; + * the XML timezone "+05:00" is translated to "GMT+05:00". + *

      + *
    8. + *
    9. + * Finally, this implementation provides a String constructor and a + * toString() method that comply with the XML Schema conventions + * for formatting a date. If only a subset of fields have been + * explicitly set, toString() produces a string with the proper subset + * of information. + *
    10. + *
    + */ +public class XmlCalendar extends GregorianCalendar +{ + /** + * Constructs an XmlCalendar for a standard XML + * schema formatted date string. + * + * The parser accepts any of the following formats: + * + * YYYY-MM-DDThh:mm:ss - dateTime + * YYYY-MM-DD - date + * hh:mm:ss - time + * YYYY - gYear + * --MM - gMonth + * ---DD - gDay + * + * The parser actually accepts all 16 combinations of subsets of + * fields (Y, M, D, T) using the same scheme, even for combinations + * that are not defined as types in the schema spec, such as + * year, day, and time: + * + * YYYY--DDThh:mm:ss - [everything but month specified] + * + * In the string, each field must be padded to its full width, for + * example, January must be --01, not just --1. + * + * In particular, a year must be padded to at least four digits, so + * "98" is not a valid year, although "1998" and "0098" are both valid + * years, unambiguously 19 centuries separated from each other. A year + * may also be preceded by a minus symbol: -0001 is 1 BC and -0002 is + * 2 BC. + * + * Finally a timezone is always allowed (yet optional) at the end. + * Timezones must be either "Z" (UTC, which we translate to GMT), + * or simple offsets from UTC in the range "-14:00" to "+14:00", + * for example: "14:30:00-05:00" specifies 2:30 PM in the + * afternoon at UTC-05:00, which is the same as EST. + * + * If a timezone is not specified, the default TimeZone is used. + */ + public XmlCalendar(String xmlSchemaDateString) + { + this(new GDate(xmlSchemaDateString)); // use GDate to parse + } + + /** + * Constructs an XmlCalendar from a GDate. + * + * If the instance is not completed, you can round-trip to an + * equivalent GDate by writing "new GDate(new XmlCalendar(gdate))". + * However, if you access any of the unset fields of the calendar, all + * the fields will be automatically filled in, so partial dates + * without timezones or other fields will not round-trip after access. + */ + public XmlCalendar(GDateSpecification date) + { + this(GDate.timeZoneForGDate(date), date); + } + + private XmlCalendar(TimeZone tz, GDateSpecification date) + { + super(tz); + setGregorianChange(_beginningOfTime); // proleptic + clear(); + + if (date.hasYear()) + { + int y = date.getYear(); // is never 0 + if (y > 0) + { + set(Calendar.ERA, GregorianCalendar.AD); + } + else // y < 0 + { + set(Calendar.ERA, GregorianCalendar.BC); + //y = 1 - y; + y = -y; // no need to add 1 + } + set(Calendar.YEAR, y); + } + if (date.hasMonth()) + set(Calendar.MONTH, date.getMonth() - 1); // note!! + if (date.hasDay()) + set(Calendar.DAY_OF_MONTH, date.getDay()); + if (date.hasTime()) + { + set(Calendar.HOUR_OF_DAY, date.getHour()); + set(Calendar.MINUTE, date.getMinute()); + set(Calendar.SECOND, date.getSecond()); + if (date.getFraction().scale() > 0) + set(Calendar.MILLISECOND, date.getMillisecond()); + } + if (date.hasTimeZone()) + { + set(Calendar.ZONE_OFFSET, date.getTimeZoneSign() * 1000 * 60 * (date.getTimeZoneHour() * 60 + date.getTimeZoneMinute())); + set(Calendar.DST_OFFSET, 0); // note!! if we don't do this, then GregorianCalendar will pick up DST from the time zone + } + } + + /** + * Constructs an XmlCalendar from a Date. + * + * The default TimeZone is used for computing the various fields. + */ + public XmlCalendar(Date date) + { + this(TimeZone.getDefault(), new GDate(date)); + complete(); + } + + /** + * Constructs an XmlCalendar with the specified year, month, day, + * hours, minutes, seconds, and optional fractional seconds, in + * the default timezone. + */ + public XmlCalendar( + int year, + int month, + int day, + int hour, + int minute, + int second, + BigDecimal fraction) + { + this(TimeZone.getDefault(), new GDate(year, month, day, hour, minute, second, fraction)); + } + + /** + * Constructs an XmlCalendar with the specified year, month, day, + * hours, minutes, seconds, and optional fractional seconds, in + * the specified timezone. + */ + public XmlCalendar( + int year, + int month, + int day, + int hour, + int minute, + int second, + BigDecimal fraction, + int tzSign, + int tzHour, + int tzMinute) + { + this(new GDate(year, month, day, hour, minute, second, fraction, tzSign, tzHour, tzMinute)); + } + + + /** + * Gets the value for a given time field. + * + * Unlike the GregorianCalendar implementation, the get() does not + * force a complete of all fields. If you wish to force a completion + * of all the fields, call getTime() first. + */ + public int get(int field) + { + if (!isSet(field) || isTimeSet) + return super.get(field); // forces a complete + else + return internalGet(field); // does not force a complete. + } + + /** + * Constructs an empty instance with no fields set. + */ + public XmlCalendar() + { + setGregorianChange(_beginningOfTime); // proleptic + clear(); + } + + private static int defaultYear = Integer.MIN_VALUE; + private static final int DEFAULT_DEFAULT_YEAR = 0; + + /** + * Returns the default year that is used when no year is specified. + */ + public static int getDefaultYear() + { + if (defaultYear == Integer.MIN_VALUE) + { + try + { + String yearstring = SystemProperties.getProperty("user.defaultyear"); + if (yearstring != null) + defaultYear = Integer.parseInt(yearstring); + else + defaultYear = DEFAULT_DEFAULT_YEAR; + } + catch (Throwable t) + { + defaultYear = DEFAULT_DEFAULT_YEAR; + } + } + return defaultYear; + } + + /** + * Sets the default year to be used when no year is specified. + */ + public static void setDefaultYear(int year) + { + defaultYear = year; + } + + /** + * Overrides GregorianCalendar.computeTime to apply a different + * default year. (It must be a leap year.) + */ + protected void computeTime() + { + boolean unsetYear = !isSet(YEAR); + if (unsetYear) + set(YEAR, getDefaultYear()); + try + { + super.computeTime(); + } + finally + { + if (unsetYear) + clear(YEAR); + } + } + + private static Date _beginningOfTime = new Date(Long.MIN_VALUE); + + /** + * Prints the XmlCalendar using a standard XML Schema + * format, as described in XmlCalendar(String s). + */ + public String toString() + { + return (new GDate(this)).toString(); // use GDate to print + } +} diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlCursor.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlCursor.java new file mode 100644 index 000000000..6f9f65cae --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlCursor.java @@ -0,0 +1,1813 @@ +/* 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; + +import java.lang.ref.Reference; +import java.lang.ref.WeakReference; +import java.util.Collection; +import java.util.Map; +import javax.xml.namespace.QName; + +/** + * Represents a position between two logical tokens in an XML document. + * + * The tokens themselves are not exposed as objects, but their type and properties + * are discoverable through methods on the cursor. In particular, the general + * category of token is represented by a {@link XmlCursor.TokenType TokenType}.

    + * + * You use an XmlCursor instance to navigate through and manipulate an XML + * instance document. + * Once you obtain an XML document, you can create a cursor to represent + * a specific place in the XML. Because you can use a cursor with or + * without a schema corresponding to the XML, cursors are an ideal + * way to handle XML without a schema. You can create a new cursor by + * calling the {@link XmlTokenSource#newCursor() newCursor} method + * exposed by an object representing + * the XML, whether it was parsed into a strong type compiled from + * schema or an {@link XmlObject XmlObject} (as in the no-schema case).

    + * + * With an XmlCursor, you can also:

    + * + *
      + *
    • Execute XQuery and XPath expressions against the XML with the + * execQuery and selectPath methods.
    • + * + *
    • Edit and reshape the document by inserting, moving, copying, and removing + * XML.
    • + * + *
    • Insert bookmarks that "stick" to the XML at the cursor's + * position even if the cursor or XML moves.
    • + + *
    • Get and set values for containers (elements and whole documents), + * attributes, processing instructions, and comments.
    • + *
    + * + * A cursor moves through XML by moving past tokens. A + * token represents a category of XML markup, such as the start of an element, + * its end, an attribute, comment, and so on. XmlCursor methods such as + * toNextToken, toNextSibling, toParent, and so on move the cursor + * among tokens. Each token's category is of a particular type, represented + * by one of the nine types defined by the {@link XmlCursor.TokenType TokenType} class.

    + * + * When you get a new cursor for a whole instance document, the cursor is + * intially located before the STARTDOC token. This token, which has no analogy + * in the XML specification, is present in this logical model of XML + * so that you may distinguish between the document as a whole + * and the content of the document. Terminating the document is an ENDDOC + * token. This token is also not part of the XML specification. A cursor + * located immediately before this token is at the very end of the document. + * It is not possible to position the cursor after the ENDDOC token. + * Thus, the STARTDOC and ENDDOC tokens are effectively "bookends" for the content of + * the document.

    + * + * For example, for the following XML, if you were the navigate a cursor + * through the XML document using toNextToken(), the list of token types that + * follows represents the token sequence you would encounter.

    + * + *
    + * <sample x='y'>
    + *     <value>foo</value>
    + * </sample>
    + * 
    + * + * STARTDOC
    + * START (sample)
    + * ATTR (x='y')
    + * TEXT ("\n ")
    + * START (value)
    + * TEXT ("foo")
    + * END (value)
    + * TEXT ("\n")
    + * END (sample)
    + * ENDDOC

    + * + * When there are no more tokens available, hasNextToken() returns + * false and toNextToken() returns the special token type NONE and does not move + * the cursor. + *

    + * + * The {@link #currentTokenType() currentTokenType()} method + * will return the type of the token that is immediately after the cursor. + * You can also use a number of convenience methods that test for a particular + * token type. These include the methods isStart(), + * isStartdoc(), isText(), isAttr(), and so on. Each returns a boolean + * value indicating whether the token that follows the cursor is the type + * in question. + *

    + * + * A few other methods determine whether the token is of a kind that may include + * multiple token types. The isAnyAttr() method, for example, returns true if + * the token immediately following the cursor is any kind of attribute, + * including those of the ATTR token type and xmlns attributes. + *

    + * + * Legitimate sequences of tokens for an XML document are described + * by the following Backus-Naur Form (BNF):
    + * + *
    + * <doc> ::= STARTDOC <attributes> <content> ENDDOC
    + * <element> ::= START <attributes> <content> END
    + * <attributes> ::= ( ATTR | NAMESPACE ) *
    + * <content> ::= ( COMMENT | PROCINST | TEXT | <element> ) *
    + * 
    + * + * Note that a legitimate sequence is STARTDOC ENDDOC, the result of + * creating a brand new instance of an empty document. Also note that + * attributes may only follow container tokens (STARTDOC or START) + */ +public interface XmlCursor extends XmlTokenSource +{ + /** + * An enumeration that identifies the type of an XML token. + */ + public static final class TokenType + { + public String toString ( ) { return _name; } + + /** + * Returns one of the INT_ values defined in this class. + */ + public int intValue ( ) { return _value; } + + /** No token. See {@link #intValue}. */ + public static final int INT_NONE = 0; + /** The start-document token. See {@link #intValue}. */ + public static final int INT_STARTDOC = 1; + /** The end-document token. See {@link #intValue}. */ + public static final int INT_ENDDOC = 2; + /** The start-element token. See {@link #intValue}. */ + public static final int INT_START = 3; + /** The end-element token. See {@link #intValue}. */ + public static final int INT_END = 4; + /** The text token. See {@link #intValue}. */ + public static final int INT_TEXT = 5; + /** The attribute token. See {@link #intValue}. */ + public static final int INT_ATTR = 6; + /** The namespace declaration token. See {@link #intValue}. */ + public static final int INT_NAMESPACE = 7; + /** The comment token. See {@link #intValue}. */ + public static final int INT_COMMENT = 8; + /** The processing instruction token. See {@link #intValue}. */ + public static final int INT_PROCINST = 9; + + /** True if no token. */ + public boolean isNone ( ) { return this == NONE; } + /** True if is start-document token. */ + public boolean isStartdoc ( ) { return this == STARTDOC; } + /** True if is end-document token. */ + public boolean isEnddoc ( ) { return this == ENDDOC; } + /** True if is start-element token. */ + public boolean isStart ( ) { return this == START; } + /** True if is end-element token. */ + public boolean isEnd ( ) { return this == END; } + /** True if is text token. */ + public boolean isText ( ) { return this == TEXT; } + /** True if is attribute token. */ + public boolean isAttr ( ) { return this == ATTR; } + /** True if is namespace declaration token. */ + public boolean isNamespace ( ) { return this == NAMESPACE; } + /** True if is comment token. */ + public boolean isComment ( ) { return this == COMMENT; } + /** True if is processing instruction token. */ + public boolean isProcinst ( ) { return this == PROCINST; } + + /** True if is start-document or start-element token */ + public boolean isContainer ( ) { return this == STARTDOC || this == START; } + /** True if is end-document or end-element token */ + public boolean isFinish ( ) { return this == ENDDOC || this == END; } + /** True if is attribute or namespace declaration token */ + public boolean isAnyAttr ( ) { return this == NAMESPACE || this == ATTR; } + + /** The singleton no-token type */ + public static final TokenType NONE = new TokenType( "NONE", INT_NONE ); + /** The singleton start-document token type */ + public static final TokenType STARTDOC = new TokenType( "STARTDOC", INT_STARTDOC ); + /** The singleton start-document token type */ + public static final TokenType ENDDOC = new TokenType( "ENDDOC", INT_ENDDOC ); + /** The singleton start-element token type */ + public static final TokenType START = new TokenType( "START", INT_START ); + /** The singleton end-element token type */ + public static final TokenType END = new TokenType( "END", INT_END ); + /** The singleton text token type */ + public static final TokenType TEXT = new TokenType( "TEXT", INT_TEXT ); + /** The singleton attribute token type */ + public static final TokenType ATTR = new TokenType( "ATTR", INT_ATTR ); + /** The singleton namespace declaration token type */ + public static final TokenType NAMESPACE = new TokenType( "NAMESPACE", INT_NAMESPACE ); + /** The singleton comment token type */ + public static final TokenType COMMENT = new TokenType( "COMMENT", INT_COMMENT ); + /** The singleton processing instruction token type */ + public static final TokenType PROCINST = new TokenType( "PROCINST", INT_PROCINST ); + + private TokenType ( String name, int value ) + { + _name = name; + _value = value; + } + + private String _name; + private int _value; + } + + /** + * Deallocates resources needed to manage the cursor, rendering this cursor + * inoperable. Because cursors are managed by a mechanism which stores the + * XML, simply letting a cursor go out of scope and having the garbage collector + * attempt to reclaim it may not produce desirable performance.

    + * + * So, explicitly disposing a cursor allows the underlying implementation + * to release its responsibility of maintaining its position.

    + * + * After a cursor has been disposed, it may not be used again. It can + * throw IllegalStateException or NullPointerException if used after + * disposal.

    + */ + + void dispose ( ); + + /** + * Moves this cursor to the same position as the moveTo cursor. if the + * moveTo cursor is in a different document from this cursor, this cursor + * will not be moved, and false returned. + * + * @param moveTo The cursor at the location to which this cursor + * should be moved. + * @return true if the cursor moved; otherwise, false. + */ + + boolean toCursor ( XmlCursor moveTo ); + + /** + * Saves the current location of this cursor on an internal stack of saved + * positions (independent of selection). This location may be restored + * later by calling the pop() method. + */ + + void push ( ); + + /** + * Restores the cursor location most recently saved with the push() method. + * + * @return true if there was a location to restore; otherwise, false. + */ + + boolean pop ( ); + + /** + * Executes the specified XPath expression against the XML that this + * cursor is in. The cursor's position does not change. To navigate to the + * selections, use {@link #hasNextSelection} and {@link #toNextSelection} (similar to + * {@link java.util.Iterator}).

    + * + * The root referred to by the expression should be given as + * a dot. The following is an example path expression: + *
    +     * cursor.selectPath("./purchase-order/line-item");
    +     * 
    + * + * Note that this method does not support top-level XPath functions. + * + * @param path The path expression to execute. + * @throws XmlRuntimeException If the query expression is invalid. + */ + void selectPath ( String path ); + + /** + * Executes the specified XPath expression against the XML that this + * cursor is in. The cursor's position does not change. To navigate to the + * selections, use hasNextSelection and toNextSelection (similar to + * java.util.Iterator).

    + * + * The root referred to by the expression should be given as + * a dot. The following is an example path expression: + *
    +     * cursor.selectPath("./purchase-order/line-item");
    +     * 
    + * + * Note that this method does not support top-level XPath functions. + * + * @param path The path expression to execute. + * @param options Options for the query. For example, you can call + * the {@link XmlOptions#setXqueryCurrentNodeVar(String) XmlOptions.setXqueryCurrentNodeVar(String)} + * method to specify a particular name for the query expression + * variable that indicates the context node. + * @throws XmlRuntimeException If the query expression is invalid. + */ + void selectPath ( String path, XmlOptions options ); + + /** + * Returns whether or not there is a next selection. + * + * @return true if there is a next selection; otherwise, false. + */ + + boolean hasNextSelection ( ); + + /** + * Moves this cursor to the next location in the selection, + * if any. See the {@link #selectPath} and {@link #addToSelection} methods. + * + * @return true if the cursor moved; otherwise, false. + */ + + boolean toNextSelection ( ); + + /** + * Moves this cursor to the specified location in the selection. + * If i is less than zero or greater than or equal to the selection + * count, this method returns false. + * + * See also the selectPath() and addToSelection() methods. + * + * @param i The index of the desired location. + * @return true if the cursor was moved; otherwise, false. + */ + + boolean toSelection ( int i ); + + /** + * Returns the count of the current selection. See also the selectPath() + * and addToSelection() methods. + * + * You may experience better performance if you use the iteration + * model using the toNextSelection method, rather than + * the indexing model using the getSelectionCount and + * toSelection methods. + * + * @return A number indicating the size of the current selection. + */ + + int getSelectionCount ( ); + + + /** + * Appends the current location of the cursor to the selection. + * See also the selectPath() method. You can use this as an + * alternative to calling the selectPath method when you want + * to define your own selection. + */ + + void addToSelection ( ); + + /** + * Clears this cursor's selection, but does not modify the document. + */ + void clearSelections ( ); + + /** + * Moves this cursor to the same position as the bookmark. If the + * bookmark is in a different document from this cursor or if the + * bookmark is orphaned, this cursor + * will not be moved, and false will be returned. + * + * @param bookmark The bookmark at the location to which this + * cursor should be moved. + * @return true if the cursor moved; otherwise, false. + */ + + boolean toBookmark ( XmlBookmark bookmark ); + + /** + * Moves this cursor to the location after its current position + * where a bookmark with the given key exists. Returns false if no + * such bookmark exists. + * + * @param key The key held by the next bookmark at the location to + * which this cursor should be moved. + * @return The next corresponding bookmark, if it exists; null if there + * is no next bookmark with the specified key. + */ + + XmlBookmark toNextBookmark ( Object key ); + + /** + * Moves this cursor to the location before its current position + * where a bookmark with the given key exists. Returns false if no + * such bookmark exists. + * + * @param key The key held by the previous bookmark at the location to + * which this cursor should be moved. + * @return The previous corresponding bookmark, if it exists; null if + * there is no previous bookmark with the specified key. + */ + + XmlBookmark toPrevBookmark ( Object key ); + + /** + * Returns the name of the current token. Names may be associated with + * START, ATTR, NAMESPACE or PROCINST. Returns null if there is no + * name associated with the current token. For START and ATTR, the + * name returned identifies the name of the element or attribute. + * For NAMESPACE, the local part of the name is the prefix, while + * the URI is the namespace defined. For PROCINST, the local part + * is the target and the uri is "". + *

    + * In the following example, xmlObject represents + * an XML instance whose root element is not preceded by any other XML. + * This code prints the root element name (here, the local name, or + * name without URI). + *

    +     * XmlCursor cursor = xmlObject.newCursor();
    +     * cursor.toFirstContentToken();
    +     * String elementName = cursor.getName().getLocalPart();
    +     * System.out.println(elementName);
    +     * 
    + * + * @return The name of the XML at this cursor's location; null if there + * is no name. + */ + + QName getName ( ); + + /** + * Sets the name of the current token. This token can be START, NAMESPACE, + * ATTR or PROCINST. + * + * @param name The new name for the current token. + */ + + void setName ( QName name ); + + /** + * Returns the namespace URI indicated by the given prefix. The current + * context must be at a START or STARTDOC. Namespace prefix mappings + * are queried for the mappings defined at the current container first, + * then parents are queried. The prefix can be "" or null to indicate + * a search for the default namespace. To conform with the + * XML spec, the default namespace will return the no-namespace ("") + * if it is not mapped.

    + * + * Note that this queries the current state of the document. When the + * document is persisted, the saving mechanism may synthesize namespaces + * (ns1, ns2, and so on) for the purposes of persistence. These namepaces are + * only present in the serialized form, and are not reflected back into + * the document being saved. + * + * @param prefix The namespace prefix for the requested namespace. + * @return The URI for corresponding to the specified prefix if it + * exists; otherwise, null. + */ + String namespaceForPrefix ( String prefix ); + + /** + * Returns a prefix that can be used to indicate a namespace URI. The + * current context must be at a START or STARTDOC. If there is an + * existing prefix that indicates the URI in the current context, that + * prefix may be returned. Otherwise, a new prefix for the URI will be + * defined by adding an xmlns attribute to the current container or a + * parent container. + * + * Note that this queries the current state of the document. When the + * document is persisted, the saving mechanism may synthesize namespaces + * (ns1, ns2, and so on) for the purposes of persistence. These namepaces are + * only present in the serialized form, and are not reflected back into + * the document being saved. + * + * @param namespaceURI The namespace URI corresponding to the requested + * prefix. + * @return The prefix corresponding to the specified URI if it exists; + * otherwise, a newly generated prefix. + */ + String prefixForNamespace ( String namespaceURI ); + + /** + * Adds to the specified map, all the namespaces in scope at the container + * where this cursor is positioned. This method is useful for + * container tokens only. + * + * @param addToThis The Map to add the namespaces to. + */ + + void getAllNamespaces ( Map addToThis ); + + /** + * Returns the strongly-typed XmlObject at the current START, + * STARTDOC, or ATTR.

    + * + * The strongly-typed object can be cast to the strongly-typed + * XBean interface corresponding to the XML Schema Type given + * by result.getSchemaType().

    + * + * If a more specific type cannot be determined, an XmlObject + * whose schema type is anyType will be returned. + * + * @return The strongly-typed object at the cursor's current location; + * null if the current location is not a START, STARTDOC, or ATTR. + */ + + XmlObject getObject ( ); + + /** + * Returns the type of the current token. By definition, the current + * token is the token immediately to the right of the cursor. + * If you're in the middle of text, before a character, you get TEXT. + * You can't dive into the text of an ATTR, COMMENT or PROCINST.

    + * + * As an alternative, it may be more convenient for you to use one of the + * methods that test for a particular token type. These include the methods + * isStart(), isStartdoc(), isText(), isAttr(), and so on. Each returns a boolean + * value indicating whether the token that follows the cursor is the type + * in question. + *

    + * + * @return The TokenType instance for the token at the cursor's current + * location. + */ + + TokenType currentTokenType ( ); + + /** + * True if the current token is a STARTDOC token type, meaning + * at the very root of the document. + * + * @return true if this token is a STARTDOC token type; + * otherwise, false. + */ + + boolean isStartdoc ( ); + + /** + * True if this token is an ENDDOC token type, meaning + * at the very end of the document. + * + * @return true if this token is an ENDDOC token type; + * otherwise, false. + */ + + boolean isEnddoc ( ); + + /** + * True if this token is a START token type, meaning + * just before an element's start. + * + * @return true if this token is a START token type; + * otherwise, false. + */ + + boolean isStart ( ); + + /** + * True if this token is an END token type, meaning + * just before an element's end. + * + * @return true if this token is an END token type; + * otherwise, false. + */ + + boolean isEnd ( ); + + /** + * True if the this token is a TEXT token type, meaning + * just before or inside text. + * + * @return true if this token is a TEXT token type; + * otherwise, false. + */ + + boolean isText ( ); + + /** + * True if this token is an ATTR token type, meaning + * just before an attribute. + * + * @return true if this token is an ATTR token type; + * otherwise, false. + */ + + boolean isAttr ( ); + + /** + * True if this token is a NAMESPACE token type, meaning + * just before a namespace declaration. + * + * @return true if this token is a NAMESPACE token type; + * otherwise, false. + */ + + boolean isNamespace ( ); + + /** + * True if this token is a COMMENT token type, meaning + * just before a comment. + * + * @return true if this token is a COMMENT token type; + * otherwise, false. + */ + + boolean isComment ( ); + + /** + * True if this token is a PROCINST token type, meaning + * just before a processing instruction. + * + * @return true if this token is a PROCINST token type; + * otherwise, false. + */ + + boolean isProcinst ( ); + + /** + * True if this token is a container token. The STARTDOC and START + * token types are containers. Containers, including documents and elements, + * have the same content model. In other words, a document and an element + * may have the same contents. For example, a document may contain attributes + * or text, without any child elements. + * + * @return true if this token is a container token; otherwise, false. + */ + + boolean isContainer ( ); + + /** + * True if this token is a finish token. A finish token can be an ENDDOC + * or END token type. + + * @return true if this token is a finish token; otherwise, false. + */ + + boolean isFinish ( ); + + /** + * True if this token is any attribute. This includes an ATTR token type and + * the NAMESPACE token type attribute. + * + * @return true if the current cursor is at any attribute; otherwise, false. + */ + + boolean isAnyAttr ( ); + + /** + * Returns the type of the previous token. By definition, the previous + * token is the token immediately to the left of the cursor.

    + * + * If you're in the middle of text, after a character, you get TEXT. + * + * @return The TokenType instance for the token immediately before the + * token at the cursor's current location. + */ + + TokenType prevTokenType ( ); + + /** + * True if there is a next token. When this is false, as when the cursor is + * at the ENDDOC token, the toNextToken() method returns NONE and does not + * move the cursor. + * + * @return true if there is a next token; otherwise, false. + */ + + boolean hasNextToken ( ); + + + /** + * True if there is a previous token. When this is false, toPrevToken + * returns NONE and does not move the cursor. + * + * @return true if there is a previous token; otherwise, false. + */ + + boolean hasPrevToken ( ); + + /** + * Moves the cursor to the next token. When there are no more tokens + * available, hasNextToken returns false and toNextToken() returns + * NONE and does not move the cursor. Returns the token type + * of the token to the right of the cursor upon a successful move. + * + * @return The token type for the next token if the cursor was moved; + * otherwise, NONE. + */ + + TokenType toNextToken ( ); + + /** + * Moves the cursor to the previous token. When there is no + * previous token, returns NONE, otherwise returns the token + * to the left of the new position of the cursor. + * + * @return The token type for the previous token if the cursor was moved; + * otherwise, NONE. + */ + + TokenType toPrevToken ( ); + + /** + * Moves the cursor to the first token in the content of the current + * START or STARTDOC. That is, the first token after all ATTR and NAMESPACE + * tokens associated with this START.

    + * + * If the current token is not a START or STARTDOC, the cursor is not + * moved and NONE is returned. If the current START or STARTDOC + * has no content, the cursor is moved to the END or ENDDOC token.

    + * + * @return The new current token type. + */ + + TokenType toFirstContentToken ( ); + + + /** + * Moves the cursor to the END or ENDDOC token corresponding to the + * current START or STARTDOC, and returns END or ENDDOC.

    + * + * If the current token is not a START or STARTDOC, the cursor is not + * moved and NONE is returned. + * + * @return The new current token type. + */ + + TokenType toEndToken ( ); + + /** + * Moves the cursor forward by the specified number of characters, and + * stops at the next non-TEXT token. Returns the number of characters + * actually moved across, which is guaranteed to be less than or equal to + * maxCharacterCount. If there is no further text, or if + * there is no text at all, returns zero.

    + * + * Note this does not dive into attribute values, comment contents, + * processing instruction contents, etc., but only content text.

    + * + * You can pass maxCharacterCount < 0 to move over all the text to the + * right. This has the same effect as toNextToken, but returns the amount + * of text moved over. + * + * @param maxCharacterCount The maximum number of characters by which + * the cursor should be moved. + * @return The actual number of characters by which the cursor was moved; + * 0 if the cursor was not moved. + */ + + int toNextChar ( int maxCharacterCount ); + + /** + * Moves the cursor backwards by the number of characters given. Has + * similar characteristics to the {@link #toNextChar(int) toNextChar} method. + * + * @param maxCharacterCount The maximum number of characters by which + * the cursor should be moved. + * @return The actual number of characters by which the cursor was moved; + * 0 if the cursor was not moved. + */ + + int toPrevChar ( int maxCharacterCount ); + + /** + * Moves the cursor to the next sibling element, or returns + * false and does not move the cursor if there is no next sibling + * element. (By definition the position of an element is the same + * as the position of its START token.) + * + * If the current token is not s START, the cursor will be + * moved to the next START without moving out of the scope of the + * current element. + * + * @return true if the cursor was moved; otherwise, false. + */ + + boolean toNextSibling ( ); + + /** + * Moves the cursor to the previous sibling element, or returns + * false and does not move the cursor if there is no previous sibling + * element. (By definition the position of an element is the same + * as the position of its START token.) + * + * @return true if the cursor was moved; otherwise, false. + */ + + boolean toPrevSibling ( ); + + /** + * Moves the cursor to the parent element or STARTDOC, or returns + * false and does not move the cursor if there is no parent.

    + * + * Works if you're in attributes or content. Returns false only if at + * STARTDOC. Note that the parent of an END token is the corresponding + * START token. + * + * @return true if the cursor was moved; false if the cursor is at the STARTDOC + * token. + */ + + boolean toParent ( ); + + /** + * Moves the cursor to the first child element, or returns false and + * does not move the cursor if there are no element children.

    + * + * If the cursor is not currently in an element, it moves into the + * first child element of the next element. + * + * @return true if the cursor was moved; otherwise, false. + */ + + boolean toFirstChild ( ); + + /** + * Moves the cursor to the last element child, or returns false and + * does not move the cursor if there are no element children. + * + * @return true if the cursor was moved; otherwise, false. + */ + + boolean toLastChild ( ); + + /** + * Moves the cursor to the first child element of the specified name in + * no namespace. + * + * @param name The name of the element to move the cursor to. + * @return true if the cursor was moved; otherwise, false. + */ + + boolean toChild ( String name ); + + /** + * Moves the cursor to the first child element of the specified name in the + * specified namespace. + * + * @param namespace The namespace URI for the element to move the cursor + * to. + * @param name The name of the element to move to. + * @return true if the cursor was moved; otherwise, false. + * @throws IllegalArgumentException If the name is not a valid local name. + */ + + boolean toChild ( String namespace, String name ); + + /** + * Moves the cursor to the first child element of the specified qualified name. + * + * @param name The name of the element to move the cursor to. + */ + + boolean toChild ( QName name ); + + /** + * Moves the cursor to the child element specified by index. + * + * @param index The position of the element in the sequence of child + * elements. + * @return true if the cursor was moved; otherwise, false. + */ + + boolean toChild ( int index ); + + /** + * Moves the cursor to the specified index child element of the + * specified name, where that element is the . + * + * @param name The name of the child element to move the cursor to. + * @param index The position of the element in the sequence of child + * elements. + * @return true if the cursor was moved; otherwise, false. + */ + + boolean toChild ( QName name, int index ); + + /** + * Moves the cursor to the next sibling element of the specified name in no + * namespace. + * + * @param name The name of the element to move the cursor to. + * @return true if the cursor was moved; otherwise, false. + */ + + boolean toNextSibling ( String name ); + + /** + * Moves the cursor to the next sibling element of the specified name + * in the specified namespace. + * + * @param namespace The namespace URI for the element to move the cursor + * to. + * @param name The name of the element to move the cursor to. + * @return true if the cursor was moved; otherwise, false. + */ + + boolean toNextSibling ( String namespace, String name ); + + + /** + * Moves the cursor to the next sibling element of the specified + * qualified name. + * + * @param name The name of the element to move the cursor to. + * @return true if the cursor was moved; otherwise, false. + */ + + boolean toNextSibling ( QName name ); + + /** + * Moves the cursor to the first attribute of this element, or + * returns false and does not move the cursor if there are no + * attributes. The order of attributes is arbitrary, but stable.

    + * + * If the cursor is on a STARTDOC of a document-fragment, this method will + * move it to the first top level attribute if one exists.

    + * + * xmlns attributes (namespace declarations) are not considered + * attributes by this function.

    + * + * The cursor must be on a START or STARTDOC (in the case of a + * document fragment with top level attributes) for this method to + * succeed. + * + * Example for looping through attributes: + *
    +     *      XmlCursor cursor = ... //cursor on START or STARTDOC
    +     *      if (cursor.toFirstAttribute())
    +     *      {
    +     *          do
    +     *          {
    +     *              // do something using attribute's name and value
    +     *              cursor.getName();
    +     *              cursor.getTextValue();
    +     *          }
    +     *          while (cursor.toNextAttribute());
    +     *      }
    +     * 
    + * + * @return true if the cursor was moved; otherwise, false. + */ + + boolean toFirstAttribute ( ); + + /** + * Moves the cursor to the last attribute of this element, or + * returns false and does not move the cursor if there are no + * attributes. The order of attributes is arbitrary, but stable.

    + * + * xmlns attributes (namespace declarations) are not considered + * attributes by this function.

    + * + * The cursor must be on a START or STARTDOC for this method + * to succeed. + * + * @return true if the cursor was moved; otherwise, false. + */ + + boolean toLastAttribute ( ); + + /** + * Moves the cursor to the next sibling attribute, or returns + * false and does not move the cursor if there is no next + * sibling attribute. The order of attributes is arbitrary, but stable.

    + * + * xmlns attributes (namespace declarations) are not considered + * attributes by this function.

    + * + * The cursor must be on an attribute for this method to succeed. + * @see #toFirstAttribute() + * + * @return true if the cursor was moved; otherwise, false. + */ + + boolean toNextAttribute ( ); + + /** + * Moves the cursor to the previous sibling attribute, or returns + * false and does not move the cursor if there is no previous + * sibling attribute. The order of attributes is arbitrary, but stable.

    + * + * xmlns attributes (namespace declarations) are not considered + * attributes by this function.

    + * + * The cursor must be on an attribute for this method to succeed. + * + * @return true if the cursor was moved; otherwise, false. + */ + + boolean toPrevAttribute ( ); + + /** + * When at a START or STARTDOC, returns the attribute text for the given + * attribute. When not at a START or STARTDOC or the attribute does not + * exist, returns null. + * + * @param attrName The name of the attribute whose value is requested. + * @return The attribute's value if it has one; otherwise, null. + */ + + String getAttributeText ( QName attrName ); + + /** + * When at a START or STARTDOC, sets the attribute text for the given + * attribute. When not at a START or STARTDOC returns false. + * If the attribute does not exist, one is created. + * + * @param attrName The name of the attribute whose value is being set. + * @param value The new value for the attribute. + * @return true if the new value was set; otherwise, false. + */ + + boolean setAttributeText ( QName attrName, String value ); + + /** + * When at a START or STARTDOC, removes the attribute with the given name. + * + * @param attrName The name of the attribute that should be removed. + * @return true if the attribute was removed; otherwise, false. + */ + + boolean removeAttribute ( QName attrName ); + + /** + * Gets the text value of the current document, element, attribute, + * comment, procinst or text token.

    + * + * When getting the text value of an element, non-text content such + * as comments and processing instructions are ignored and text is concatenated. + * For elements that have nested element children, this + * returns the concatenated text of all mixed content and the + * text of all the element children, recursing in first-to-last + * depthfirst order.

    + * + * For attributes, including namespaces, this returns the attribute value.

    + * + * For comments and processing instructions, this returns the text content + * of the comment or PI, not including the delimiting sequences <!-- -->, <? ?>. + * For a PI, the name of the PI is also not included. + *

    + * The value of an empty tag is the empty string.

    + * + * If the current token is END or ENDDOC, this throws an {@link java.lang.IllegalStateException}.

    + * + * @return The text value of the current token if the token's type is + * START, STARTDOC, TEXT, ATTR, COMMENT, PROCINST, or NAMESPACE; null + * if the type is NONE. + */ + + String getTextValue ( ); + + /** + * Copies the text value of the current document, element, attribute, + * comment, processing instruction or text token, counting right from + * this cursor's location up to maxCharacterCount, + * and copies the returned text into returnedChars.

    + * + * When getting the text value of an element, non-text content such + * as comments and processing instructions are ignored and text is concatenated. + * For elements that have nested element children, this + * returns the concatenated text of all mixed content and the + * text of all the element children, recursing in first-to-last + * depthfirst order.

    + * + * For attributes, including namespaces, this returns the attribute value.

    + * + * For comments and processing instructions, this returns the text contents + * of the comment or PI, not including the delimiting sequences <!-- -->, <? ?>. For + * a PI, the text will not include the name of the PI.

    + * + * If the current token is END or ENDDOC, this throws an {@link java.lang.IllegalStateException}.

    + * + * The value of an empty tag is the empty string.

    + * + * @param returnedChars A character array to hold the returned characters. + * @param offset The position within returnedChars to which the first of the + * returned characters should be copied. + * @param maxCharacterCount The maximum number of characters after this cursor's + * location to copy. A negative value specifies that all characters should be copied. + * @return The actual number of characters copied; 0 if no characters + * were copied. + */ + + int getTextValue ( char[] returnedChars, int offset, int maxCharacterCount ); + + /** + * Returns the characters of the current TEXT token. If the current token + * is not TEXT, returns "". If in the middle of a TEXT token, returns + * those chars to the right of the cursor of the TEXT token. + * + * @return The requested text; an empty string if the current token type is + * not TEXT. + */ + + /** + * Sets the text value of the XML at this cursor's location if that XML's + * token type is START, STARTDOC, ATTR, COMMENT or PROCINST.

    + * + * For elements that have nested children this first removes all + * the content of the element and replaces it with the given text. + * + * @param text The text to use as a new value. + * @throws java.lang.IllegalStateException If the token type at this + * cursor's location is not START, STARTDOC, ATTR, COMMENT or + * PROCINST. + */ + void setTextValue ( String text ); + + /** + * Sets the text value of the XML at this cursor's location (if that XML's + * token type is START, STARTDOC, ATTR, COMMENT or PROCINST) to the + * contents of the specified character array.

    + * + * For elements that have nested children this first removes all + * the content of the element and replaces it with the given text. + * + * @param sourceChars A character array containing the XML's new value. + * @param offset The position within sourceChars from which the first of + * the source characters should be copied. + * @param length The maximum number of characters to set as the XML's new + * value. + * @throws java.lang.IllegalArgumentException If the token type at this + * cursor's location is not START, STARTDOC, ATTR, COMMENT or + * PROCINST. + */ + void setTextValue ( char[] sourceChars, int offset, int length ); + + /** + * Returns characters to the right of the cursor up to the next token. + */ + String getChars ( ); + + /** + * Copies characters up to the specified maximum number, counting right from + * this cursor's location to the character at maxCharacterCount. The + * returned characters are added to returnedChars, with the first + * character copied to the offset position. The maxCharacterCount + * parameter should be less than or equal to the length of returnedChars + * minus offset. Copies a number of characters, which is + * either maxCharacterCount or the number of characters up to the next token, + * whichever is less. + * + * @param returnedChars A character array to hold the returned characters. + * @param offset The position within returnedChars at which the first of the + * returned characters should be added. + * @param maxCharacterCount The maximum number of characters after this cursor's + * location to return. + * @return The actual number of characters returned; 0 if no characters + * were returned or if the current token is not TEXT. + */ + + int getChars ( char[] returnedChars, int offset, int maxCharacterCount ); + + /** + * Moves the cursor to the STARTDOC token, which is the + * root of the document. + */ + + void toStartDoc ( ); + + /** + * Moves the cursor to the ENDDOC token, which is the end + * of the document. + */ + + void toEndDoc ( ); + + /** + * Determines if the specified cursor is in the same document as + * this cursor. + * + * @param cursor The cursor that may be in the same document + * as this cursor. + * @return true if the specified cursor is in the same document; + * otherwise, false. + */ + + boolean isInSameDocument ( XmlCursor cursor ); + + /** + * Returns an integer indicating whether this cursor is before, + * after, or at the same position as the specified cursor.

    + * + * a.comparePosition(b) < 0 means a is to the left of b.
    + * a.comparePosition(b) == 0 means a is at the same position as b.
    + * a.comparePosition(b) > 0 means a is to the right of b.

    + * + * The sort order of cursors in the document is the token order. + * For example, if cursor "a" is at a START token and the cursor "b" + * is at a token within the contents of the same element, then + * a.comparePosition(b) will return -1, meaning that the position + * of a is before b. + * + * @param cursor The cursor whose position should be compared + * with this cursor. + * @return 1 if this cursor is after the specified cursor; 0 if + * this cursor is at the same position as the specified cursor; + * -1 if this cursor is before the specified cursor. + * @throws java.lang.IllegalArgumentException If the specified + * cursor is not in the same document as this cursor. + */ + + int comparePosition ( XmlCursor cursor ); + + /** + * Determines if this cursor is to the left of (or before) + * the specified cursor. Note that this is the same as + * a.comparePosition(b) < 0 + * + * @param cursor The cursor whose position should be compared + * with this cursor. + * @return true if this cursor is to the left of the specified + * cursor; otherwise, false. + */ + + boolean isLeftOf ( XmlCursor cursor ); + + /** + * Determines if this cursor is at the same position as + * the specified cursor. Note that this is the same as + * a.comparePosition(b) == 0 + * + * @param cursor The cursor whose position should be compared + * with this cursor. + * @return true if this cursor is at the same position as + * the specified cursor; otherwise, false. + */ + + boolean isAtSamePositionAs ( XmlCursor cursor ); + + /** + * Determines if this cursor is to the right of (or after) + * the specified cursor. Note that this is the same as + * a.comparePosition(b) > 0 + * + * @param cursor The cursor whose position should be compared + * with this cursor. + * @return true if this cursor is to the right of the specified + * cursor; otherwise, false. + */ + + boolean isRightOf ( XmlCursor cursor ); + + /** + * Executes the specified XQuery expression against the XML this + * cursor is in.

    + * + * The query may be a String or a compiled query. You can precompile + * an XQuery expression using the XmlBeans.compileQuery method.

    + * + * The root referred to by the expression should be given as + * a dot. The following is an example path expression: + *
    +     * XmlCursor results = cursor.execQuery("purchase-order/line-item[price <= 20.00]");
    +     * 
    + * + * @param query The XQuery expression to execute. + * @return A cursor containing the results of the query. + * @throws XmlRuntimeException If the query expression is invalid. + */ + + XmlCursor execQuery ( String query ); + + /** + * Executes the specified XQuery expression against the XML this + * cursor is in, and using the specified options.

    + * + * @param query The XQuery expression to execute. + * @param options Options for the query. For example, you can call + * the {@link XmlOptions#setXqueryCurrentNodeVar(String) XmlOptions.setXqueryCurrentNodeVar(String)} + * method to specify a particular name for the query expression + * variable that indicates the context node. + * @throws XmlRuntimeException If the query expression is invalid. + */ + + XmlCursor execQuery ( String query, XmlOptions options ); + + /** + * Represents the state of a dcoument at a particular point + * in time. It is used to determine if a document has been changed + * since that point in time. + */ + interface ChangeStamp + { + /** + * Returns whether or not the document assoiated with this ChangeStamp + * has been altered since the ChangeStamp had been created. + */ + public boolean hasChanged ( ); + } + + /** + * Returns the current change stamp for the document the current cursor is in. + * This change stamp can be queried at a later point in time to find out + * if the document has changed. + * + * @return The change stamp for the document the current cursor is in. + */ + ChangeStamp getDocChangeStamp ( ); + + /** + * Subclasses of XmlBookmark can be used to annotate an XML document. + * This class is abstract to prevent parties from inadvertently + * interfering with each others' bookmarks without explicitly + * sharing a bookmark class. + */ + + abstract class XmlBookmark + { + /** + * Constructs a strongly-referenced bookmark. + */ + public XmlBookmark ( ) { this( false ); } + + /** + * Constructs a bookmark. + * @param weak true if the document's reference to the bookmark should be a WeakReference + */ + public XmlBookmark ( boolean weak ) + { + _ref = weak ? new WeakReference( this ) : null; + } + + /** + * Call the createCursor method to create a new cursor which is + * positioned at the same splace as the bookmark. It is much more + * efficient to call toBookmark on an existing cursor than it + * is to create a new cursor. However, toBookmark may fail if the + * bookmark is in a different document than the cursor. It is + * under these circumstances where createCursor needs to be called + * on the bookmark. Subsequent navigations to bookmark + * positions should attempt to reuse the last cursor to + * improve performace. + */ + public final XmlCursor createCursor ( ) + { + return _currentMark == null ? null : _currentMark.createCursor(); + } + + /** + * Moves the given cursor to this bookmark, and returns it. + */ + public final XmlCursor toBookmark ( XmlCursor c ) + { + return c == null || !c.toBookmark( this ) ? createCursor() : c; + } + + /** + * The default key for bookmarks is the class which implements + * them. This way, multiple parties using bookmarks in the + * same instance document will not interfere with eachother. + * One can, however, override getKey() to use a key other than + * the class. + */ + public Object getKey ( ) + { + return this.getClass(); + } + + /** + * The mark is set by the host document; it is capable of + * returning an XmlCursor implementation at the location of + * the bookmark. + */ + public XmlMark _currentMark; + + /** + * If non-null, the ref is used by the host document + * to maintain a reference to the bookmark. If it is a weak + * reference, the host document will not prevent the Bookmark + * from being garbage collected. + */ + public final Reference _ref; + } + + /** + * An abstract {@link XmlCursor} factory. + * Implementations of XmlCursor implement XmlMark to be able to + * reconstitute a cursor from a bookmark. When content moves between + * implementations, the XmlMark is set to the implmentation's which + * recieves the new content. + */ + + interface XmlMark + { + XmlCursor createCursor ( ); + } + + /** + * Sets a bookmark to the document at this cursor's location. + * + * The bookmark is attached to the token in the tree immediately + * after the cursor. If the tree is manipulated to move + * that object to a different place, the bookmark moves with it. + * If the tree is manipulated to delete that token from the + * tree, the bookmark is orphaned. Copy operations do not copy + * bookmarks. + * + * @param bookmark The bookmark to set. + */ + + void setBookmark ( XmlBookmark bookmark ); + + /** + * Retrieves the bookmark with the specified key + * at this cursor's location. If there is no bookmark whose key is + * given by the specified key at the current position, null is returned. + * If the {@link XmlCursor.XmlBookmark#getKey() getKey} method is not overridden on + * the bookmark, then the bookmark's class is used as the key. + * + * @param key The key for the bookmark to retrieve. + * @return The requested bookmark; null if there is no bookmark + * corresponding to the specified key. + */ + + XmlBookmark getBookmark ( Object key ); + + /** + * Clears the bookmark whose key is specified, if the bookmark + * exists at this cursor's location. + * + * @param key The for the bookmark to clear. + */ + + void clearBookmark ( Object key ); + + /** + * Retrieves all the bookmarks at this location, adding them to + * the specified collection. Bookmarks held by weak references are + * added to this collection as Weak referenced objects pointing to the + * bookmark. + * + * @param listToFill The collection that will contain bookmarks + * returned by this method. + */ + + void getAllBookmarkRefs ( Collection listToFill ); + + /** + * Removes the XML that is immediately after this cursor. + * + * For the TEXT, ATTR, NAMESPACE, COMMENT and PROCINST tokens, a single + * token is removed. For a START token, the corresponding element and all + * of its contents are removed. For all other tokens, this is a no-op. + * You cannot remove a STARTDOC. + * + * The cursors located in the XML that was removed all collapse to the + * same location. All bookmarks in this XML will be orphaned. + * + * @return true if anything was removed; false only if the cursor is + * just before END or ENDDOC token. + * @throws java.lang.IllegalArgumentException If the cursor is at a + * STARTDOC token. + */ + + boolean removeXml ( ); + + /** + * Moves the XML immediately after this cursor to the location + * specified by the toHere cursor, shifting XML at that location + * to the right to make room. For the TEXT, ATTR, NAMESPACE, + * COMMENT and PROCINST tokens, a single token is moved. For a start token, the + * element and all of its contents are moved. For all other tokens, this + * is a no-op. + * + * The bookmarks located in the XML that was moved also move to the + * new location; the cursors don't move with the content. + * + * @param toHere The cursor at the location to which the XML should + * be moved. + * @return true if anything was moved. This only happens when the XML to be + * moved contains the target of the move. + * @throws java.lang.IllegalArgumentException If the operation is not allowed + * at the cursor's location. This includes attempting to move an end token or the + * document as a whole. Also, moving to a location before the start document or moving + * an attribute to a location other than after another attribute or start token + * will throw. + */ + + boolean moveXml ( XmlCursor toHere ); + + /** + * Copies the XML immediately after this cursor to the location + * specified by the toHere cursor. For the TEXT, ATTR, NAMESPACE, + * COMMENT and PROCINST tokens, a single token is copied. For a start token, + * the element and all of its contents are copied. For all other tokens, this + * is a no-op. + * + * The cursors and bookmarks located in the XML that was copied are also copied + * to the new location. + * + * @param toHere The cursor at the location to which the XML should + * be copied. + * @return true if anything was copied; false if the token supports the operation, + * but nothing was copied. + * @throws java.lang.IllegalArgumentException If the operation is not allowed + * at the cursor's location. + */ + + boolean copyXml ( XmlCursor toHere ); + + /** + * Removes the contents of the container (STARTDOC OR START) immediately after + * this cursor. For all other situations, returns false. Does + * not remove attributes or namspaces. + * + * @return true if anything was copied; otherwise, false. + */ + + boolean removeXmlContents ( ); + + /** + * Moves the contents of the container (STARTDOC OR START) immediately after + * this cursor to the location specified by the toHere cursor. + * For all other situations, returns false. Does not move attributes or + * namespaces. + * + * @param toHere The cursor at the location to which the XML should be moved. + * @return true if anything was moved; otherwise, false. + */ + boolean moveXmlContents ( XmlCursor toHere ); + + /** + * Copies the contents of the container (STARTDOC OR START) immediately to + * the right of the cursor to the location specified by the toHere cursor. + * For all other situations, returns false. Does not copy attributes or + * namespaces. + * + * @param toHere The cursor at the location to which the XML should + * be copied. + * @return true if anything was copied; otherwise, false. + */ + boolean copyXmlContents ( XmlCursor toHere ); + + /** + * Removes characters up to the specified maximum number, counting right from + * this cursor's location to the character at maxCharacterCount. The + * space remaining from removing the characters collapses up to this cursor. + * + * @param maxCharacterCount The maximum number of characters after this cursor's + * location to remove. + * @return The actual number of characters removed. + * @throws java.lang.IllegalArgumentException If the operation is not allowed + * at the cursor's location. + */ + + int removeChars ( int maxCharacterCount ); + + /** + * Moves characters immediately after this cursor to the position immediately + * after the specified cursor. Characters are counted to the right up to the + * specified maximum number. XML after the destination cursor is + * shifted to the right to make room. The space remaining from moving the + * characters collapses up to this cursor. + * + * @param maxCharacterCount The maximum number of characters after this cursor's + * location to move. + * @param toHere The cursor to which the characters should be moved. + * @return The actual number of characters moved. + * @throws java.lang.IllegalArgumentException If the operation is not allowed + * at the cursor's location. + */ + + int moveChars ( int maxCharacterCount, XmlCursor toHere ); + + /** + * Copies characters to the position immediately after the specified cursor. + * Characters are counted to the right up to the specified maximum number. + * XML after the destination cursor is shifted to the right to make room. + * + * @param maxCharacterCount The maximum number of characters after this cursor's + * location to copy. + * @param toHere The cursor to which the characters should be copied. + * @return The actual number of characters copied. + * @throws java.lang.IllegalArgumentException If the operation is not allowed + * at the cursor's location. + */ + + int copyChars ( int maxCharacterCount, XmlCursor toHere ); + + /** + * Inserts the specified text immediately before this cursor's location. + * + * @param text The text to insert. + * @throws java.lang.IllegalArgumentException If the insertion is not allowed + * at the cursor's location. + */ + + void insertChars ( String text ); + + /** + * Inserts an element immediately before this cursor's location, giving + * the element the specified qualified name. + * + * @param name The qualified name for the element. + * @throws java.lang.IllegalArgumentException If the insertion is not allowed + * at the cursor's location. + */ + + void insertElement ( QName name ); + + /** + * Inserts an element immediately before this cursor's location, giving + * the element the specified local name. + * + * @param localName The local name for the new element. + * @throws java.lang.IllegalArgumentException If the insertion is not allowed + * at the cursor's location. + */ + + void insertElement ( String localName ); + + /** + * Inserts a new element immediately before this cursor's location, giving the + * element the specified local name and associating it with specified namespace + * + * @param localName The local name for the new element. + * @param uri The URI for the new element's namespace. + * @throws java.lang.IllegalArgumentException If the insertion is not allowed + * at the cursor's location. + */ + + void insertElement ( String localName, String uri ); + + /** + * Inserts a new element around this cursor, giving the element the specified + * qualified name. After the element is inserted, this cursor is between its start + * and end. This cursor can then be used to insert additional XML into + * the new element. + * + * @param name The qualified name for the new element. + * @throws java.lang.IllegalArgumentException If the insertion is not allowed + * at the cursor's location. + */ + + void beginElement ( QName name ); + + /** + * Inserts a new element around this cursor, giving the element the specified + * local name. After the element is inserted, this cursor is between its start + * and end. This cursor can then be used to insert additional XML into + * the new element. + * + * @param localName The local name for the new element. + * @throws java.lang.IllegalArgumentException If the insertion is not allowed + * at the cursor's location. + */ + + void beginElement ( String localName ); + + /** + * Inserts a new element around this cursor, giving the element the specified + * local name and associating it with the specified namespace. After the element + * is inserted, this cursor is between its start and end. This cursor + * can then be used to insert additional XML into the new element. + * + * @param localName The local name for the new element. + * @param uri The URI for the new element's namespace. + * @throws java.lang.IllegalArgumentException If the insertion is not allowed + * at the cursor's location. + */ + + void beginElement ( String localName, String uri ); + + /** + * Inserts a new element immediately before this cursor's location, giving the + * element the specified qualified name and content. + * + * @param name The qualified name for the new element. + * @param text The content for the new element. + * @throws java.lang.IllegalArgumentException If the insertion is not allowed + * at the cursor's location. + */ + + void insertElementWithText ( QName name, String text ); + + /** + * Inserts a new element immediately before this cursor's location, giving the + * element the specified local name and content. + * + * @param localName The local name for the new element. + * @param text The content for the new element. + * @throws java.lang.IllegalArgumentException If the insertion is not allowed + * at the cursor's location. + */ + + void insertElementWithText ( String localName, String text ); + + /** + * Inserts a new element immediately before this cursor's location, giving the + * element the specified local name, associating it with the specified namespace, + * and giving it the specified content. + * + * @param localName The local name for the new element. + * @param uri The URI for the new element's namespace. + * @param text The content for the new element. + * @throws java.lang.IllegalArgumentException If the insertion is not allowed + * at the cursor's location. + */ + + void insertElementWithText ( String localName, String uri, String text ); + + /** + * Inserts a new attribute immediately before this cursor's location, giving it + * the specified local name. + * + * @param localName The local name for the new attribute. + * @throws java.lang.IllegalArgumentException If the insertion is not allowed + * at the cursor's location. + */ + + void insertAttribute ( String localName ); + + /** + * Inserts a new attribute immediately before this cursor's location, giving it + * the specified local name and associating it with the specified namespace. + * + * @param localName The local name for the new attribute. + * @param uri The URI for the new attribute's namespace. + * @throws java.lang.IllegalArgumentException If the insertion is not allowed + * at the cursor's location. + */ + + void insertAttribute ( String localName, String uri ); + + /** + * Inserts a new attribute immediately before this cursor's location, giving it + * the specified name. + * + * @param name The local name for the new attribute. + * @throws java.lang.IllegalArgumentException If the insertion is not allowed + * at the cursor's location. + */ + + void insertAttribute ( QName name ); + + /** + * Inserts a new attribute immediately before this cursor's location, giving it + * the specified value and name. + * + * @param Name The local name for the new attribute. + * @param value The value for the new attribute. + * @throws java.lang.IllegalArgumentException If the insertion is not allowed + * at the cursor's location. + */ + + void insertAttributeWithValue ( String Name, String value ); + + /** + * Inserts an attribute immediately before the cursor's location, giving it + * the specified name and value, and associating it with the specified namespace. + * + * @param name The name for the new attribute. + * @param uri The URI for the new attribute's namespace. + * @param value The value for the new attribute. + * @throws java.lang.IllegalArgumentException If the insertion is not allowed + * at the cursor's location. + */ + + void insertAttributeWithValue ( String name, String uri, String value ); + + /** + * Inserts an attribute immediately before the cursor's location, giving it + * the specified name and value. + * + * @param name The name for the new attribute. + * @param value The value for the new attribute. + * @throws java.lang.IllegalArgumentException If the insertion is not allowed + * at the cursor's location. + */ + + void insertAttributeWithValue ( QName name, String value ); + + /** + * Inserts a namespace declaration immediately before the cursor's location, + * giving it the specified prefix and URI. + * + * @param prefix The prefix for the namespace. + * @param namespace The URI for the namespace. + * @throws java.lang.IllegalArgumentException If the insertion is not allowed + * at the cursor's location. + */ + + void insertNamespace ( String prefix, String namespace ); + + /** + * Inserts an XML comment immediately before the cursor's location, + * giving it the specified content. + * + * @param text The new comment's content. + * @throws java.lang.IllegalArgumentException If the insertion is not allowed + * at the cursor's location. + */ + + void insertComment ( String text ); + + /** + * Inserts an XML processing instruction immediately before the cursor's location, + * giving it the specified target and text. + * + * @param target The target for the processing instruction. + * @param text The new processing instruction's text. + * @throws java.lang.IllegalStateException If the insertion is not allowed + * at the cursor's location. + */ + + void insertProcInst ( String target, String text ); +} diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlDate.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlDate.java new file mode 100644 index 000000000..7d2fd261c --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlDate.java @@ -0,0 +1,185 @@ +/* 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; + +import javax.xml.stream.XMLStreamReader; + + +import java.util.Date; +import java.util.Calendar; + + +/** + * Corresponds to the XML Schema + * xs:date type. + *

    + * Convertible to {@link Calendar}, {@link Date}, and {@link GDate}. + * + * @see XmlCalendar + * @see GDate + */ +public interface XmlDate extends XmlAnySimpleType +{ + /** The constant {@link SchemaType} object representing this schema type. */ + public static final SchemaType type = XmlBeans.getBuiltinTypeSystem().typeForHandle("_BI_date"); + + + /** + * Returns this value as a {@link Calendar} + * @deprecated replaced with {@link #getCalendarValue} + **/ + Calendar calendarValue(); + /** + * Sets this value as a {@link Calendar} + * @deprecated replaced with {@link #setCalendarValue} + **/ + void set(Calendar c); + /** + * Returns this value as a {@link GDate} + * @deprecated replaced with {@link #getGDateValue} + **/ + GDate gDateValue(); + /** + * Sets this value as a {@link GDateSpecification} + * @deprecated replaced with {@link #setGDateValue} + **/ + void set(GDateSpecification gd); + /** + * Returns this value as a {@link Date} + * @deprecated replaced with {@link #getDateValue} + **/ + Date dateValue(); + /** + * Sets this value as a {@link Date} + * @deprecated replaced with {@link #setDateValue} + **/ + void set(Date d); + + /** Returns this value as a {@link Calendar} */ + Calendar getCalendarValue(); + /** Sets this value as a {@link Calendar} */ + void setCalendarValue(Calendar c); + /** Returns this value as a {@link GDate} */ + GDate getGDateValue(); + /** Sets this value as a {@link GDateSpecification} */ + void setGDateValue(GDate gd); + /** Returns this value as a {@link Date} */ + Date getDateValue(); + /** Sets this value as a {@link Date} */ + void setDateValue(Date d); + + /** + * A class with methods for creating instances + * of {@link XmlDate}. + */ + public static final class Factory + { + /** Creates an empty instance of {@link XmlDate} */ + public static XmlDate newInstance() { + return (XmlDate) XmlBeans.getContextTypeLoader().newInstance( type, null ); } + + /** Creates an empty instance of {@link XmlDate} */ + public static XmlDate newInstance(org.apache.xmlbeans.XmlOptions options) { + return (XmlDate) XmlBeans.getContextTypeLoader().newInstance( type, options ); } + + /** Creates an immutable {@link XmlDate} value */ + public static XmlDate newValue(Object obj) { + return (XmlDate) type.newValue( obj ); } + + /** Parses a {@link XmlDate} fragment from a String. For example: "<xml-fragment>2003-06-14</xml-fragment>". */ + public static XmlDate parse(java.lang.String s) throws org.apache.xmlbeans.XmlException { + return (XmlDate) XmlBeans.getContextTypeLoader().parse( s, type, null ); } + + /** Parses a {@link XmlDate} fragment from a String. For example: "<xml-fragment>2003-06-14</xml-fragment>". */ + public static XmlDate parse(java.lang.String s, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (XmlDate) XmlBeans.getContextTypeLoader().parse( s, type, options ); } + + /** Parses a {@link XmlDate} fragment from a File. */ + public static XmlDate parse(java.io.File f) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlDate) XmlBeans.getContextTypeLoader().parse( f, type, null ); } + + /** Parses a {@link XmlDate} fragment from a File. */ + public static XmlDate parse(java.io.File f, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlDate) XmlBeans.getContextTypeLoader().parse( f, type, options ); } + + /** Parses a {@link XmlDate} fragment from a URL. */ + public static XmlDate parse(java.net.URL u) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlDate) XmlBeans.getContextTypeLoader().parse( u, type, null ); } + + /** Parses a {@link XmlDate} fragment from a URL. */ + public static XmlDate parse(java.net.URL u, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlDate) XmlBeans.getContextTypeLoader().parse( u, type, options ); } + + /** Parses a {@link XmlDate} fragment from an InputStream. */ + public static XmlDate parse(java.io.InputStream is) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlDate) XmlBeans.getContextTypeLoader().parse( is, type, null ); } + + /** Parses a {@link XmlDate} fragment from an InputStream. */ + public static XmlDate parse(java.io.InputStream is, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlDate) XmlBeans.getContextTypeLoader().parse( is, type, options ); } + + /** Parses a {@link XmlDate} fragment from a Reader. */ + public static XmlDate parse(java.io.Reader r) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlDate) XmlBeans.getContextTypeLoader().parse( r, type, null ); } + + /** Parses a {@link XmlDate} fragment from a Reader. */ + public static XmlDate parse(java.io.Reader r, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlDate) XmlBeans.getContextTypeLoader().parse( r, type, options ); } + + /** Parses a {@link XmlDate} fragment from a DOM Node. */ + public static XmlDate parse(org.w3c.dom.Node node) throws org.apache.xmlbeans.XmlException { + return (XmlDate) XmlBeans.getContextTypeLoader().parse( node, type, null ); } + + /** Parses a {@link XmlDate} fragment from a DOM Node. */ + public static XmlDate parse(org.w3c.dom.Node node, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (XmlDate) XmlBeans.getContextTypeLoader().parse( node, type, options ); } + + /** Parses a {@link XmlDate} fragment from an XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XmlDate parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (XmlDate) XmlBeans.getContextTypeLoader().parse( xis, type, null ); } + + /** Parses a {@link XmlDate} fragment from an XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XmlDate parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (XmlDate) XmlBeans.getContextTypeLoader().parse( xis, type, options ); } + + /** Parses a {@link XmlDate} fragment from an XMLStreamReader. */ + public static XmlDate parse(javax.xml.stream.XMLStreamReader xsr) throws org.apache.xmlbeans.XmlException { + return (XmlDate) XmlBeans.getContextTypeLoader().parse( xsr, type, null ); } + + /** Parses a {@link XmlDate} fragment from an XMLStreamReader. */ + public static XmlDate parse(javax.xml.stream.XMLStreamReader xsr, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException{ + return (XmlDate) XmlBeans.getContextTypeLoader().parse( xsr, type, options ); } + + /** Returns a validating XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, null ); } + + /** Returns a validating XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, options ); } + + private Factory() { } // No instance of this class allowed + } +} + diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlDateTime.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlDateTime.java new file mode 100644 index 000000000..1dabef759 --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlDateTime.java @@ -0,0 +1,188 @@ +/* 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; + +import javax.xml.stream.XMLStreamReader; + + +import java.util.Date; +import java.util.Calendar; + + +/** + * Corresponds to the XML Schema + * xs:dateTime type. + *

    + * Convertible to {@link Calendar}, {@link Date}, and {@link GDate}. + * + *

    + * The XmlDateTime class only encapsulates a schema DateTime value, if you need to perform operations + * on dates, see the GDate class + * @see XmlCalendar + * @see GDate + * @see GDuration + */ +public interface XmlDateTime extends XmlAnySimpleType +{ + /** The constant {@link SchemaType} object representing this schema type. */ + public static final SchemaType type = XmlBeans.getBuiltinTypeSystem().typeForHandle("_BI_dateTime"); + + /** + * Returns this value as a {@link Calendar} + * @deprecated replaced with {@link #getCalendarValue} + **/ + Calendar calendarValue(); + /** + * Sets this value as a {@link Calendar} + * @deprecated replaced with {@link #setCalendarValue} + **/ + void set(Calendar c); + /** + * Returns this value as a {@link GDate} + * @deprecated replaced with {@link #getGDateValue} + **/ + GDate gDateValue(); + /** + * Sets this value as a {@link GDateSpecification} + * @deprecated replaced with {@link #setGDateValue} + **/ + void set(GDateSpecification gd); + /** + * Returns this value as a {@link Date} + * @deprecated replaced with {@link #getDateValue} + **/ + Date dateValue(); + /** + * Sets this value as a {@link Date} + * @deprecated replaced with {@link #setDateValue} + **/ + void set(Date d); + + /** Returns this value as a {@link Calendar} */ + Calendar getCalendarValue(); + /** Sets this value as a {@link Calendar} */ + void setCalendarValue(Calendar c); + /** Returns this value as a {@link GDate} */ + GDate getGDateValue(); + /** Sets this value as a {@link GDateSpecification} */ + void setGDateValue(GDate gd); + /** Returns this value as a {@link Date} */ + Date getDateValue(); + /** Sets this value as a {@link Date} */ + void setDateValue(Date d); + + /** + * A class with methods for creating instances + * of {@link XmlDateTime}. + */ + public static final class Factory + { + /** Creates an empty instance of {@link XmlDateTime} */ + public static XmlDateTime newInstance() { + return (XmlDateTime) XmlBeans.getContextTypeLoader().newInstance( type, null ); } + + /** Creates an empty instance of {@link XmlDateTime} */ + public static XmlDateTime newInstance(org.apache.xmlbeans.XmlOptions options) { + return (XmlDateTime) XmlBeans.getContextTypeLoader().newInstance( type, options ); } + + /** Creates an immutable {@link XmlDateTime} value */ + public static XmlDateTime newValue(Object obj) { + return (XmlDateTime) type.newValue( obj ); } + + /** Parses a {@link XmlDateTime} fragment from a String. For example: "<xml-fragment>2003-06-14T12:00:00</xml-fragment>". */ + public static XmlDateTime parse(java.lang.String s) throws org.apache.xmlbeans.XmlException { + return (XmlDateTime) XmlBeans.getContextTypeLoader().parse( s, type, null ); } + + /** Parses a {@link XmlDateTime} fragment from a String. For example: "<xml-fragment>2003-06-14T12:00:00</xml-fragment>". */ + public static XmlDateTime parse(java.lang.String s, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (XmlDateTime) XmlBeans.getContextTypeLoader().parse( s, type, options ); } + + /** Parses a {@link XmlDateTime} fragment from a File. */ + public static XmlDateTime parse(java.io.File f) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlDateTime) XmlBeans.getContextTypeLoader().parse( f, type, null ); } + + /** Parses a {@link XmlDateTime} fragment from a File. */ + public static XmlDateTime parse(java.io.File f, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlDateTime) XmlBeans.getContextTypeLoader().parse( f, type, options ); } + + /** Parses a {@link XmlDateTime} fragment from a URL. */ + public static XmlDateTime parse(java.net.URL u) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlDateTime) XmlBeans.getContextTypeLoader().parse( u, type, null ); } + + /** Parses a {@link XmlDateTime} fragment from a URL. */ + public static XmlDateTime parse(java.net.URL u, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlDateTime) XmlBeans.getContextTypeLoader().parse( u, type, options ); } + + /** Parses a {@link XmlDateTime} fragment from an InputStream. */ + public static XmlDateTime parse(java.io.InputStream is) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlDateTime) XmlBeans.getContextTypeLoader().parse( is, type, null ); } + + /** Parses a {@link XmlDateTime} fragment from an InputStream. */ + public static XmlDateTime parse(java.io.InputStream is, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlDateTime) XmlBeans.getContextTypeLoader().parse( is, type, options ); } + + /** Parses a {@link XmlDateTime} fragment from a Reader. */ + public static XmlDateTime parse(java.io.Reader r) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlDateTime) XmlBeans.getContextTypeLoader().parse( r, type, null ); } + + /** Parses a {@link XmlDateTime} fragment from a Reader. */ + public static XmlDateTime parse(java.io.Reader r, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlDateTime) XmlBeans.getContextTypeLoader().parse( r, type, options ); } + + /** Parses a {@link XmlDateTime} fragment from a DOM Node. */ + public static XmlDateTime parse(org.w3c.dom.Node node) throws org.apache.xmlbeans.XmlException { + return (XmlDateTime) XmlBeans.getContextTypeLoader().parse( node, type, null ); } + + /** Parses a {@link XmlDateTime} fragment from a DOM Node. */ + public static XmlDateTime parse(org.w3c.dom.Node node, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (XmlDateTime) XmlBeans.getContextTypeLoader().parse( node, type, options ); } + + /** Parses a {@link XmlDateTime} fragment from an XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XmlDateTime parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (XmlDateTime) XmlBeans.getContextTypeLoader().parse( xis, type, null ); } + + /** Parses a {@link XmlDateTime} fragment from an XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XmlDateTime parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (XmlDateTime) XmlBeans.getContextTypeLoader().parse( xis, type, options ); } + + /** Parses a {@link XmlDateTime} fragment from an XMLStreamReader. */ + public static XmlDateTime parse(javax.xml.stream.XMLStreamReader xsr) throws org.apache.xmlbeans.XmlException { + return (XmlDateTime) XmlBeans.getContextTypeLoader().parse( xsr, type, null ); } + + /** Parses a {@link XmlDateTime} fragment from an XMLStreamReader. */ + public static XmlDateTime parse(javax.xml.stream.XMLStreamReader xsr, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException{ + return (XmlDateTime) XmlBeans.getContextTypeLoader().parse( xsr, type, options ); } + + /** Returns a validating XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, null ); } + + /** Returns a validating XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, options ); } + + private Factory() { } // No instance of this class allowed + } +} + diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlDecimal.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlDecimal.java new file mode 100644 index 000000000..ad8c3edc0 --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlDecimal.java @@ -0,0 +1,151 @@ +/* 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; + +import javax.xml.stream.XMLStreamReader; + + +import java.math.BigDecimal; + +/** + * Corresponds to the XML Schema + * xs:decimal type. + *

    + * Convertible to {@link BigDecimal}. + */ +public interface XmlDecimal extends XmlAnySimpleType +{ + /** The constant {@link SchemaType} object representing this schema type. */ + public static final SchemaType type = XmlBeans.getBuiltinTypeSystem().typeForHandle("_BI_decimal"); + + /** Returns this value as a {@link BigDecimal} */ + BigDecimal getBigDecimalValue(); + /** Sets this value as a {@link BigDecimal} */ + void setBigDecimalValue(BigDecimal bd); + + /** + * Returns this value as a {@link BigDecimal} + * @deprecated replaced with {@link #getBigDecimalValue} + **/ + BigDecimal bigDecimalValue(); + /** + * Sets this value as a {@link BigDecimal} + * @deprecated replaced with {@link #setBigDecimalValue} + **/ + void set(BigDecimal bd); + + /** + * A class with methods for creating instances + * of {@link XmlDecimal}. + */ + public static final class Factory + { + /** Creates an empty instance of {@link XmlDecimal} */ + public static XmlDecimal newInstance() { + return (XmlDecimal) XmlBeans.getContextTypeLoader().newInstance( type, null ); } + + /** Creates an empty instance of {@link XmlDecimal} */ + public static XmlDecimal newInstance(org.apache.xmlbeans.XmlOptions options) { + return (XmlDecimal) XmlBeans.getContextTypeLoader().newInstance( type, options ); } + + /** Creates an immutable {@link XmlDecimal} value */ + public static XmlDecimal newValue(Object obj) { + return (XmlDecimal) type.newValue( obj ); } + + /** Parses a {@link XmlDecimal} fragment from a String. For example: "<xml-fragment>1234.56789</xml-fragment>". */ + public static XmlDecimal parse(java.lang.String s) throws org.apache.xmlbeans.XmlException { + return (XmlDecimal) XmlBeans.getContextTypeLoader().parse( s, type, null ); } + + /** Parses a {@link XmlDecimal} fragment from a String. For example: "<xml-fragment>1234.56789</xml-fragment>". */ + public static XmlDecimal parse(java.lang.String s, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (XmlDecimal) XmlBeans.getContextTypeLoader().parse( s, type, options ); } + + /** Parses a {@link XmlDecimal} fragment from a File. */ + public static XmlDecimal parse(java.io.File f) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlDecimal) XmlBeans.getContextTypeLoader().parse( f, type, null ); } + + /** Parses a {@link XmlDecimal} fragment from a File. */ + public static XmlDecimal parse(java.io.File f, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlDecimal) XmlBeans.getContextTypeLoader().parse( f, type, options ); } + + /** Parses a {@link XmlDecimal} fragment from a URL. */ + public static XmlDecimal parse(java.net.URL u) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlDecimal) XmlBeans.getContextTypeLoader().parse( u, type, null ); } + + /** Parses a {@link XmlDecimal} fragment from a URL. */ + public static XmlDecimal parse(java.net.URL u, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlDecimal) XmlBeans.getContextTypeLoader().parse( u, type, options ); } + + /** Parses a {@link XmlDecimal} fragment from an InputStream. */ + public static XmlDecimal parse(java.io.InputStream is) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlDecimal) XmlBeans.getContextTypeLoader().parse( is, type, null ); } + + /** Parses a {@link XmlDecimal} fragment from an InputStream. */ + public static XmlDecimal parse(java.io.InputStream is, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlDecimal) XmlBeans.getContextTypeLoader().parse( is, type, options ); } + + /** Parses a {@link XmlDecimal} fragment from a Reader. */ + public static XmlDecimal parse(java.io.Reader r) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlDecimal) XmlBeans.getContextTypeLoader().parse( r, type, null ); } + + /** Parses a {@link XmlDecimal} fragment from a Reader. */ + public static XmlDecimal parse(java.io.Reader r, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlDecimal) XmlBeans.getContextTypeLoader().parse( r, type, options ); } + + /** Parses a {@link XmlDecimal} fragment from a DOM Node. */ + public static XmlDecimal parse(org.w3c.dom.Node node) throws org.apache.xmlbeans.XmlException { + return (XmlDecimal) XmlBeans.getContextTypeLoader().parse( node, type, null ); } + + /** Parses a {@link XmlDecimal} fragment from a DOM Node. */ + public static XmlDecimal parse(org.w3c.dom.Node node, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (XmlDecimal) XmlBeans.getContextTypeLoader().parse( node, type, options ); } + + /** Parses a {@link XmlDecimal} fragment from an XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XmlDecimal parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (XmlDecimal) XmlBeans.getContextTypeLoader().parse( xis, type, null ); } + + /** Parses a {@link XmlDecimal} fragment from an XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XmlDecimal parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (XmlDecimal) XmlBeans.getContextTypeLoader().parse( xis, type, options ); } + + /** Parses a {@link XmlDecimal} fragment from an XMLStreamReader. */ + public static XmlDecimal parse(javax.xml.stream.XMLStreamReader xsr) throws org.apache.xmlbeans.XmlException { + return (XmlDecimal) XmlBeans.getContextTypeLoader().parse( xsr, type, null ); } + + /** Parses a {@link XmlDecimal} fragment from an XMLStreamReader. */ + public static XmlDecimal parse(javax.xml.stream.XMLStreamReader xsr, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException{ + return (XmlDecimal) XmlBeans.getContextTypeLoader().parse( xsr, type, options ); } + + /** Returns a validating XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, null ); } + + /** Returns a validating XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, options ); } + + private Factory() { } // No instance of this class allowed + } +} + diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlDocumentProperties.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlDocumentProperties.java new file mode 100644 index 000000000..f61fad586 --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlDocumentProperties.java @@ -0,0 +1,200 @@ +/* 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; + +/** + * This class is used to attach arbitrary information to an XML + * document. It also defines several well-known types of + * information that can be attached or found on a document. + *

    + * For example, suppose you wanted to associate a filename + * with the document containing an xml object "xobj". This + * could be done via the following code: + *

    + * tokenSource.documentProperties().set(XmlDocumentProperties.NAME, "MyFilename.xml"); + *

    + * To fetch the filename later, given an xobj2 anywhere in the + * same document, you can write: + *

    + * filename = (String)tokenSource.documentProperties().get(XmlDocumentProperties.NAME); + */ +public abstract class XmlDocumentProperties +{ + /** + * Sets the name of the XML document file. Typically a URL, but may + * be any String. + * @param sourceName the name to set + * @see XmlOptions#setDocumentSourceName + */ + public void setSourceName ( String sourceName ) { put( SOURCE_NAME, sourceName ); } + /** + * Returns the name of the XML document file. Typically a URL, but may + * be any String. + * @see XmlOptions#setDocumentSourceName + */ + public String getSourceName ( ) { return (String) get( SOURCE_NAME ); } + + /** + * Sets the encoding to use for the XML document. Should be a valid + * XML encoding string. + * @param encoding the ISO encoding name + * @see XmlOptions#setCharacterEncoding + */ + public void setEncoding ( String encoding ) { put( ENCODING, encoding ); } + /** + * Returns the encoding used for the XML document, as an ISO encoding name. + * @see XmlOptions#setCharacterEncoding + */ + public String getEncoding ( ) { return (String) get( ENCODING ); } + + /** + * Sets the XML version string to use in the <?xml?> declaration. + * (The XML specification is quite stable at "1.0".) + * @param version the XML version string + */ + public void setVersion ( String version ) { put( VERSION, version ); } + /** + * Returns the XML version string used in the <?xml?> declaration. + */ + public String getVersion ( ) { return (String) get( VERSION ); } + + /** + * Sets the standalone property. + * @param standalone whether standalone is true or not + */ + public void setStandalone ( boolean standalone ) { put( STANDALONE, standalone ? "true" : null ); } + /** + * Returns the standalone property + */ + public boolean getStandalone ( ) { return get( STANDALONE ) != null; } + + /** + * Sets the DOCTYPE name use in the <!DOCTYPE> declaration. + * @param doctypename the doctypename + */ + public void setDoctypeName ( String doctypename ) { put( DOCTYPE_NAME, doctypename ); } + /** + * Returns the DOCTYPE name used in the <!DOCTYPE> declaration. + */ + public String getDoctypeName ( ) { return (String) get( DOCTYPE_NAME ); } + + /** + * Sets the DOCTYPE public ID to use in the <!DOCTYPE> declaration. + * @param publicid the public ID + */ + public void setDoctypePublicId ( String publicid ) { put( DOCTYPE_PUBLIC_ID, publicid ); } + /** + * Returns the DOCTYPE public ID used in the <!DOCTYPE> declaration. + */ + public String getDoctypePublicId ( ) { return (String) get( DOCTYPE_PUBLIC_ID ); } + + /** + * Sets the DOCTYPE system ID to use in the <!DOCTYPE> declaration. + * @param systemid the system ID + */ + public void setDoctypeSystemId ( String systemid ) { put( DOCTYPE_SYSTEM_ID, systemid ); } + /** + * Returns the DOCTYPE system ID used in the <!DOCTYPE> declaration. + */ + public String getDoctypeSystemId ( ) { return (String) get( DOCTYPE_SYSTEM_ID ); } + + /** + * Sets the message digest used to summarize the document. + * @param digest the bytes of the digest + * + * @see XmlOptions#setLoadMessageDigest + */ + public void setMessageDigest( byte[] digest ) { put( MESSAGE_DIGEST, digest ); } + /** + * Returns the message digest used to summarize the document. + * + * @see XmlOptions#setLoadMessageDigest + */ + public byte[] getMessageDigest( ) { return (byte[]) get( MESSAGE_DIGEST ); } + + /** + * Used to store the original name (a String) for + * the source from which the XML document was loaded. + * This name, if present, is used to identify the + * document when reporting validation or comilation errors. + * + * XmlObject.Factory.parse(File) and SchemaTypeLoader.loadInstance(File) + * both automatically set this value to the filename. + */ + public static final Object SOURCE_NAME = new Object(); + + /** + * Document encoding + */ + public static final Object ENCODING = new Object(); + + /** + * Document version + */ + public static final Object VERSION = new Object(); + + /** + * Document standlone + */ + public static final Object STANDALONE = new Object(); + + /** + * Doc type name + */ + public static final Object DOCTYPE_NAME = new Object(); + + /** + * Doc type public id + */ + public static final Object DOCTYPE_PUBLIC_ID = new Object(); + + /** + * Doc type system id + */ + public static final Object DOCTYPE_SYSTEM_ID = new Object(); + + /** + * SHA message digest + */ + public static final Object MESSAGE_DIGEST = new Object(); + + /** + * Attaches a value to the root of the document containing + * the given token source. + * + * @param key The key: there can be one value for each key. + * @param value The value to attach to the document. + */ + public abstract Object put ( Object key, Object value ); + + /** + * Returns a value previously attached to a document using set. + * + * @param key The key: this is the key that was previously + * passed to set to store the value. + * @return The saved value, or null if none is found. + */ + public abstract Object get ( Object key ); + + /** + * Removes a value previously attached to a document using set. + * + * @param key The key: this is the key that was previously + * passed to set to store the value. + */ + public abstract Object remove ( Object key ); +} + diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlDouble.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlDouble.java new file mode 100644 index 000000000..77d1ff0d2 --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlDouble.java @@ -0,0 +1,149 @@ +/* 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; + +import javax.xml.stream.XMLStreamReader; + + +/** + * Corresponds to the XML Schema + * xs:double type. + *

    + * Naturally, convertible to a Java double. + */ +public interface XmlDouble extends XmlAnySimpleType +{ + /** The constant {@link SchemaType} object representing this schema type. */ + public static final SchemaType type = XmlBeans.getBuiltinTypeSystem().typeForHandle("_BI_double"); + + /** Returns this value as a double */ + double getDoubleValue(); + /** Sets this value as a double */ + void setDoubleValue(double v); + + /** + * Returns this value as a double + * @deprecated replaced with {@link #getDoubleValue} + **/ + double doubleValue(); + /** + * Sets this value as a double + * @deprecated replaced with {@link #setDoubleValue} + **/ + void set(double v); + + /** + * A class with methods for creating instances + * of {@link XmlDouble}. + */ + public static final class Factory + { + /** Creates an empty instance of {@link XmlDouble} */ + public static XmlDouble newInstance() { + return (XmlDouble) XmlBeans.getContextTypeLoader().newInstance( type, null ); } + + /** Creates an empty instance of {@link XmlDouble} */ + public static XmlDouble newInstance(org.apache.xmlbeans.XmlOptions options) { + return (XmlDouble) XmlBeans.getContextTypeLoader().newInstance( type, options ); } + + /** Creates an immutable {@link XmlDouble} value */ + public static XmlDouble newValue(Object obj) { + return (XmlDouble) type.newValue( obj ); } + + /** Parses a {@link XmlDouble} fragment from a String. For example: "<xml-fragment>123.34e+57</xml-fragment>". */ + public static XmlDouble parse(java.lang.String s) throws org.apache.xmlbeans.XmlException { + return (XmlDouble) XmlBeans.getContextTypeLoader().parse( s, type, null ); } + + /** Parses a {@link XmlDouble} fragment from a String. For example: "<xml-fragment>123.34e+57</xml-fragment>". */ + public static XmlDouble parse(java.lang.String s, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (XmlDouble) XmlBeans.getContextTypeLoader().parse( s, type, options ); } + + /** Parses a {@link XmlDouble} fragment from a File. */ + public static XmlDouble parse(java.io.File f) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlDouble) XmlBeans.getContextTypeLoader().parse( f, type, null ); } + + /** Parses a {@link XmlDouble} fragment from a File. */ + public static XmlDouble parse(java.io.File f, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlDouble) XmlBeans.getContextTypeLoader().parse( f, type, options ); } + + /** Parses a {@link XmlDouble} fragment from a URL. */ + public static XmlDouble parse(java.net.URL u) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlDouble) XmlBeans.getContextTypeLoader().parse( u, type, null ); } + + /** Parses a {@link XmlDouble} fragment from a URL. */ + public static XmlDouble parse(java.net.URL u, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlDouble) XmlBeans.getContextTypeLoader().parse( u, type, options ); } + + /** Parses a {@link XmlDouble} fragment from an InputStream. */ + public static XmlDouble parse(java.io.InputStream is) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlDouble) XmlBeans.getContextTypeLoader().parse( is, type, null ); } + + /** Parses a {@link XmlDouble} fragment from an InputStream. */ + public static XmlDouble parse(java.io.InputStream is, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlDouble) XmlBeans.getContextTypeLoader().parse( is, type, options ); } + + /** Parses a {@link XmlDouble} fragment from a Reader. */ + public static XmlDouble parse(java.io.Reader r) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlDouble) XmlBeans.getContextTypeLoader().parse( r, type, null ); } + + /** Parses a {@link XmlDouble} fragment from a Reader. */ + public static XmlDouble parse(java.io.Reader r, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlDouble) XmlBeans.getContextTypeLoader().parse( r, type, options ); } + + /** Parses a {@link XmlDouble} fragment from a DOM Node. */ + public static XmlDouble parse(org.w3c.dom.Node node) throws org.apache.xmlbeans.XmlException { + return (XmlDouble) XmlBeans.getContextTypeLoader().parse( node, type, null ); } + + /** Parses a {@link XmlDouble} fragment from a DOM Node. */ + public static XmlDouble parse(org.w3c.dom.Node node, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (XmlDouble) XmlBeans.getContextTypeLoader().parse( node, type, options ); } + + /** Parses a {@link XmlDouble} fragment from an XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XmlDouble parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (XmlDouble) XmlBeans.getContextTypeLoader().parse( xis, type, null ); } + + /** Parses a {@link XmlDouble} fragment from an XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XmlDouble parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (XmlDouble) XmlBeans.getContextTypeLoader().parse( xis, type, options ); } + + /** Parses a {@link XmlDouble} fragment from an XMLStreamReader. */ + public static XmlDouble parse(javax.xml.stream.XMLStreamReader xsr) throws org.apache.xmlbeans.XmlException { + return (XmlDouble) XmlBeans.getContextTypeLoader().parse( xsr, type, null ); } + + /** Parses a {@link XmlDouble} fragment from an XMLStreamReader. */ + public static XmlDouble parse(javax.xml.stream.XMLStreamReader xsr, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException{ + return (XmlDouble) XmlBeans.getContextTypeLoader().parse( xsr, type, options ); } + + /** Returns a validating XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, null ); } + + /** Returns a validating XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, options ); } + + private Factory() { } // No instance of this class allowed + } +} + diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlDuration.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlDuration.java new file mode 100644 index 000000000..f1debb2cd --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlDuration.java @@ -0,0 +1,151 @@ +/* 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; + +import javax.xml.stream.XMLStreamReader; + + +/** + * Corresponds to the XML Schema + * xs:duration type. + *

    + * Convertible to a {@link GDuration}. + * + * @see GDuration + */ +public interface XmlDuration extends XmlAnySimpleType +{ + /** The constant {@link SchemaType} object representing this schema type. */ + public static final SchemaType type = XmlBeans.getBuiltinTypeSystem().typeForHandle("_BI_duration"); + + /** Returns this value as a {@link GDuration} */ + GDuration getGDurationValue(); + /** Sets this value as a {@link GDuration} */ + void setGDurationValue(GDuration gd); + + /** + * Returns this value as a {@link GDuration} + * @deprecated replaced with {@link #getGDurationValue} + **/ + GDuration gDurationValue(); + /** + * Sets this value as a {@link GDuration} + * @deprecated replaced with {@link #setGDurationValue} + **/ + void set(GDurationSpecification gd); + + /** + * A class with methods for creating instances + * of {@link XmlDuration}. + */ + public static final class Factory + { + /** Creates an empty instance of {@link XmlDuration} */ + public static XmlDuration newInstance() { + return (XmlDuration) XmlBeans.getContextTypeLoader().newInstance( type, null ); } + + /** Creates an empty instance of {@link XmlDuration} */ + public static XmlDuration newInstance(org.apache.xmlbeans.XmlOptions options) { + return (XmlDuration) XmlBeans.getContextTypeLoader().newInstance( type, options ); } + + /** Creates an immutable {@link XmlDuration} value */ + public static XmlDuration newValue(Object obj) { + return (XmlDuration) type.newValue( obj ); } + + /** Parses a {@link XmlDuration} fragment from a String. For example: "<xml-fragment>P1Y2MT2H</xml-fragment>". */ + public static XmlDuration parse(java.lang.String s) throws org.apache.xmlbeans.XmlException { + return (XmlDuration) XmlBeans.getContextTypeLoader().parse( s, type, null ); } + + /** Parses a {@link XmlDuration} fragment from a String. For example: "<xml-fragment>P1Y2MT2H</xml-fragment>". */ + public static XmlDuration parse(java.lang.String s, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (XmlDuration) XmlBeans.getContextTypeLoader().parse( s, type, options ); } + + /** Parses a {@link XmlDuration} fragment from a File. */ + public static XmlDuration parse(java.io.File f) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlDuration) XmlBeans.getContextTypeLoader().parse( f, type, null ); } + + /** Parses a {@link XmlDuration} fragment from a File. */ + public static XmlDuration parse(java.io.File f, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlDuration) XmlBeans.getContextTypeLoader().parse( f, type, options ); } + + /** Parses a {@link XmlDuration} fragment from a URL. */ + public static XmlDuration parse(java.net.URL u) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlDuration) XmlBeans.getContextTypeLoader().parse( u, type, null ); } + + /** Parses a {@link XmlDuration} fragment from a URL. */ + public static XmlDuration parse(java.net.URL u, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlDuration) XmlBeans.getContextTypeLoader().parse( u, type, options ); } + + /** Parses a {@link XmlDuration} fragment from an InputStream. */ + public static XmlDuration parse(java.io.InputStream is) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlDuration) XmlBeans.getContextTypeLoader().parse( is, type, null ); } + + /** Parses a {@link XmlDuration} fragment from an InputStream. */ + public static XmlDuration parse(java.io.InputStream is, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlDuration) XmlBeans.getContextTypeLoader().parse( is, type, options ); } + + /** Parses a {@link XmlDuration} fragment from a Reader. */ + public static XmlDuration parse(java.io.Reader r) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlDuration) XmlBeans.getContextTypeLoader().parse( r, type, null ); } + + /** Parses a {@link XmlDuration} fragment from a Reader. */ + public static XmlDuration parse(java.io.Reader r, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlDuration) XmlBeans.getContextTypeLoader().parse( r, type, options ); } + + /** Parses a {@link XmlDuration} fragment from a DOM Node. */ + public static XmlDuration parse(org.w3c.dom.Node node) throws org.apache.xmlbeans.XmlException { + return (XmlDuration) XmlBeans.getContextTypeLoader().parse( node, type, null ); } + + /** Parses a {@link XmlDuration} fragment from a DOM Node. */ + public static XmlDuration parse(org.w3c.dom.Node node, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (XmlDuration) XmlBeans.getContextTypeLoader().parse( node, type, options ); } + + /** Parses a {@link XmlDuration} fragment from an XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XmlDuration parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (XmlDuration) XmlBeans.getContextTypeLoader().parse( xis, type, null ); } + + /** Parses a {@link XmlDuration} fragment from an XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XmlDuration parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (XmlDuration) XmlBeans.getContextTypeLoader().parse( xis, type, options ); } + + /** Parses a {@link XmlDuration} fragment from an XMLStreamReader. */ + public static XmlDuration parse(javax.xml.stream.XMLStreamReader xsr) throws org.apache.xmlbeans.XmlException { + return (XmlDuration) XmlBeans.getContextTypeLoader().parse( xsr, type, null ); } + + /** Parses a {@link XmlDuration} fragment from an XMLStreamReader. */ + public static XmlDuration parse(javax.xml.stream.XMLStreamReader xsr, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException{ + return (XmlDuration) XmlBeans.getContextTypeLoader().parse( xsr, type, options ); } + + /** Returns a validating XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, null ); } + + /** Returns a validating XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, options ); } + + private Factory() { } // No instance of this class allowed + } +} + diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlENTITIES.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlENTITIES.java new file mode 100644 index 000000000..6481db47d --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlENTITIES.java @@ -0,0 +1,160 @@ +/* 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; + +import javax.xml.stream.XMLStreamReader; + + +import java.util.List; + + +/** + * Corresponds to the XML Schema + * xs:ENTITIES type, + * a list type. + *

    + * A list type. + */ +public interface XmlENTITIES extends XmlAnySimpleType +{ + /** The constant {@link SchemaType} object representing this schema type. */ + public static final SchemaType type = XmlBeans.getBuiltinTypeSystem().typeForHandle("_BI_ENTITIES"); + + /** Returns the value as a {@link List} of {@link String} values */ + List getListValue(); + /** Returns the value as a {@link List} of {@link XmlENTITY} values **/ + List xgetListValue(); + /** Sets the value as a {@link List} */ + void setListValue(List l); + + /** + * Returns the value as a {@link List} of {@link String} values + * @deprecated replaced by {@link #getListValue} + **/ + List listValue(); + /** + * Returns the value as a {@link List} of {@link XmlENTITY} values + * @deprecated replaced by {@link #getListValue} + **/ + List xlistValue(); + /** + * Sets the value as a {@link List} + * @deprecated replaced by {@link #getListValue} + **/ + void set(List l); + + /** + * A class with methods for creating instances + * of {@link XmlENTITIES}. + */ + public static final class Factory + { + /** Creates an empty instance of {@link XmlENTITIES} */ + public static XmlENTITIES newInstance() { + return (XmlENTITIES) XmlBeans.getContextTypeLoader().newInstance( type, null ); } + + /** Creates an empty instance of {@link XmlENTITIES} */ + public static XmlENTITIES newInstance(org.apache.xmlbeans.XmlOptions options) { + return (XmlENTITIES) XmlBeans.getContextTypeLoader().newInstance( type, options ); } + + /** Creates an immutable {@link XmlENTITIES} value */ + public static XmlENTITIES newValue(Object obj) { + return (XmlENTITIES) type.newValue( obj ); } + + /** Parses a {@link XmlENTITIES} fragment from a String. */ + public static XmlENTITIES parse(java.lang.String s) throws org.apache.xmlbeans.XmlException { + return (XmlENTITIES) XmlBeans.getContextTypeLoader().parse( s, type, null ); } + + /** Parses a {@link XmlENTITIES} fragment from a String. */ + public static XmlENTITIES parse(java.lang.String s, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (XmlENTITIES) XmlBeans.getContextTypeLoader().parse( s, type, options ); } + + /** Parses a {@link XmlENTITIES} fragment from a File. */ + public static XmlENTITIES parse(java.io.File f) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlENTITIES) XmlBeans.getContextTypeLoader().parse( f, type, null ); } + + /** Parses a {@link XmlENTITIES} fragment from a File. */ + public static XmlENTITIES parse(java.io.File f, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlENTITIES) XmlBeans.getContextTypeLoader().parse( f, type, options ); } + + /** Parses a {@link XmlENTITIES} fragment from a URL. */ + public static XmlENTITIES parse(java.net.URL u) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlENTITIES) XmlBeans.getContextTypeLoader().parse( u, type, null ); } + + /** Parses a {@link XmlENTITIES} fragment from a URL. */ + public static XmlENTITIES parse(java.net.URL u, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlENTITIES) XmlBeans.getContextTypeLoader().parse( u, type, options ); } + + /** Parses a {@link XmlENTITIES} fragment from an InputStream. */ + public static XmlENTITIES parse(java.io.InputStream is) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlENTITIES) XmlBeans.getContextTypeLoader().parse( is, type, null ); } + + /** Parses a {@link XmlENTITIES} fragment from an InputStream. */ + public static XmlENTITIES parse(java.io.InputStream is, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlENTITIES) XmlBeans.getContextTypeLoader().parse( is, type, options ); } + + /** Parses a {@link XmlENTITIES} fragment from a Reader. */ + public static XmlENTITIES parse(java.io.Reader r) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlENTITIES) XmlBeans.getContextTypeLoader().parse( r, type, null ); } + + /** Parses a {@link XmlENTITIES} fragment from a Reader. */ + public static XmlENTITIES parse(java.io.Reader r, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlENTITIES) XmlBeans.getContextTypeLoader().parse( r, type, options ); } + + /** Parses a {@link XmlENTITIES} fragment from a DOM Node. */ + public static XmlENTITIES parse(org.w3c.dom.Node node) throws org.apache.xmlbeans.XmlException { + return (XmlENTITIES) XmlBeans.getContextTypeLoader().parse( node, type, null ); } + + /** Parses a {@link XmlENTITIES} fragment from a DOM Node. */ + public static XmlENTITIES parse(org.w3c.dom.Node node, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (XmlENTITIES) XmlBeans.getContextTypeLoader().parse( node, type, options ); } + + /** Parses a {@link XmlENTITIES} fragment from an XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XmlENTITIES parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (XmlENTITIES) XmlBeans.getContextTypeLoader().parse( xis, type, null ); } + + /** Parses a {@link XmlENTITIES} fragment from an XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XmlENTITIES parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (XmlENTITIES) XmlBeans.getContextTypeLoader().parse( xis, type, options ); } + + /** Parses a {@link XmlENTITIES} fragment from an XMLStreamReader. */ + public static XmlENTITIES parse(javax.xml.stream.XMLStreamReader xsr) throws org.apache.xmlbeans.XmlException { + return (XmlENTITIES) XmlBeans.getContextTypeLoader().parse( xsr, type, null ); } + + /** Parses a {@link XmlENTITIES} fragment from an XMLStreamReader. */ + public static XmlENTITIES parse(javax.xml.stream.XMLStreamReader xsr, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException{ + return (XmlENTITIES) XmlBeans.getContextTypeLoader().parse( xsr, type, options ); } + + /** Returns a validating XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, null ); } + + /** Returns a validating XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, options ); } + + private Factory() { } // No instance of this class allowed + } +} + diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlENTITY.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlENTITY.java new file mode 100644 index 000000000..d5ed9f0cc --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlENTITY.java @@ -0,0 +1,133 @@ +/* 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; + +import javax.xml.stream.XMLStreamReader; + + +/** + * Corresponds to the XML Schema + * xs:ENTITY type. + *

    + * Convertible to {@link String}. + */ +public interface XmlENTITY extends XmlNCName +{ + /** The constant {@link SchemaType} object representing this schema type. */ + public static final SchemaType type = XmlBeans.getBuiltinTypeSystem().typeForHandle("_BI_ENTITY"); + + /** + * A class with methods for creating instances + * of {@link XmlENTITY}. + */ + public static final class Factory + { + /** Creates an empty instance of {@link XmlENTITY} */ + public static XmlENTITY newInstance() { + return (XmlENTITY) XmlBeans.getContextTypeLoader().newInstance( type, null ); } + + /** Creates an empty instance of {@link XmlENTITY} */ + public static XmlENTITY newInstance(org.apache.xmlbeans.XmlOptions options) { + return (XmlENTITY) XmlBeans.getContextTypeLoader().newInstance( type, options ); } + + /** Creates an immutable {@link XmlENTITY} value */ + public static XmlENTITY newValue(Object obj) { + return (XmlENTITY) type.newValue( obj ); } + + /** Parses a {@link XmlENTITY} fragment from a String. */ + public static XmlENTITY parse(java.lang.String s) throws org.apache.xmlbeans.XmlException { + return (XmlENTITY) XmlBeans.getContextTypeLoader().parse( s, type, null ); } + + /** Parses a {@link XmlENTITY} fragment from a String. */ + public static XmlENTITY parse(java.lang.String s, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (XmlENTITY) XmlBeans.getContextTypeLoader().parse( s, type, options ); } + + /** Parses a {@link XmlENTITY} fragment from a File. */ + public static XmlENTITY parse(java.io.File f) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlENTITY) XmlBeans.getContextTypeLoader().parse( f, type, null ); } + + /** Parses a {@link XmlENTITY} fragment from a File. */ + public static XmlENTITY parse(java.io.File f, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlENTITY) XmlBeans.getContextTypeLoader().parse( f, type, options ); } + + /** Parses a {@link XmlENTITY} fragment from a URL. */ + public static XmlENTITY parse(java.net.URL u) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlENTITY) XmlBeans.getContextTypeLoader().parse( u, type, null ); } + + /** Parses a {@link XmlENTITY} fragment from a URL. */ + public static XmlENTITY parse(java.net.URL u, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlENTITY) XmlBeans.getContextTypeLoader().parse( u, type, options ); } + + /** Parses a {@link XmlENTITY} fragment from an InputStream. */ + public static XmlENTITY parse(java.io.InputStream is) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlENTITY) XmlBeans.getContextTypeLoader().parse( is, type, null ); } + + /** Parses a {@link XmlENTITY} fragment from an InputStream. */ + public static XmlENTITY parse(java.io.InputStream is, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlENTITY) XmlBeans.getContextTypeLoader().parse( is, type, options ); } + + /** Parses a {@link XmlENTITY} fragment from a Reader. */ + public static XmlENTITY parse(java.io.Reader r) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlENTITY) XmlBeans.getContextTypeLoader().parse( r, type, null ); } + + /** Parses a {@link XmlENTITY} fragment from a Reader. */ + public static XmlENTITY parse(java.io.Reader r, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlENTITY) XmlBeans.getContextTypeLoader().parse( r, type, options ); } + + /** Parses a {@link XmlENTITY} fragment from a DOM Node. */ + public static XmlENTITY parse(org.w3c.dom.Node node) throws org.apache.xmlbeans.XmlException { + return (XmlENTITY) XmlBeans.getContextTypeLoader().parse( node, type, null ); } + + /** Parses a {@link XmlENTITY} fragment from a DOM Node. */ + public static XmlENTITY parse(org.w3c.dom.Node node, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (XmlENTITY) XmlBeans.getContextTypeLoader().parse( node, type, options ); } + + /** Parses a {@link XmlENTITY} fragment from an XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XmlENTITY parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (XmlENTITY) XmlBeans.getContextTypeLoader().parse( xis, type, null ); } + + /** Parses a {@link XmlENTITY} fragment from an XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XmlENTITY parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (XmlENTITY) XmlBeans.getContextTypeLoader().parse( xis, type, options ); } + + /** Parses a {@link XmlENTITY} fragment from an XMLStreamReader. */ + public static XmlENTITY parse(javax.xml.stream.XMLStreamReader xsr) throws org.apache.xmlbeans.XmlException { + return (XmlENTITY) XmlBeans.getContextTypeLoader().parse( xsr, type, null ); } + + /** Parses a {@link XmlENTITY} fragment from an XMLStreamReader. */ + public static XmlENTITY parse(javax.xml.stream.XMLStreamReader xsr, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException{ + return (XmlENTITY) XmlBeans.getContextTypeLoader().parse( xsr, type, options ); } + + /** Returns a validating XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, null ); } + + /** Returns a validating XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, options ); } + + private Factory() { } // No instance of this class allowed + } +} + diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlError.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlError.java new file mode 100644 index 000000000..72b1f7a5a --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlError.java @@ -0,0 +1,641 @@ +/* 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; + +import java.net.URI; +import java.net.URISyntaxException; +import java.io.File; +import java.util.ResourceBundle; +import java.util.PropertyResourceBundle; +import java.text.MessageFormat; +import javax.xml.stream.Location; + +/** + * Represents a message at a specific XML location. + *

    + * The message can be an error, warning, or simple information, and + * it may optionally be associated with a specific location in + * an XML document. The class includes methods for extracting + * the location as a line number, XmlCursor, or XmlObject, as + * well as for obtaining and message and severity of the + * error. + * + * @see XmlOptions#setErrorListener + * @see XmlException + */ +public class XmlError implements java.io.Serializable +{ + private static final long serialVersionUID = 1L; + + private static final ResourceBundle _bundle = PropertyResourceBundle.getBundle("org.apache.xmlbeans.message"); + + private String _message; + private String _code; + private String _source; + private int _severity = SEVERITY_ERROR; + private int _line = -1; + private int _column = -1; + private int _offset = -1; + + private transient XmlCursor _cursor; + + /** + * Copy constructor. + * @param src The original XmlError to copy. + */ + public XmlError(XmlError src) + { + _message = src.getMessage(); + _code = src.getErrorCode(); + _severity = src.getSeverity(); + _source = src.getSourceName(); + _line = src.getLine(); + _column = src.getColumn(); + _offset = src.getOffset(); + _cursor = src.getCursorLocation(); + } + + /** + * The static factory methods should be used instead of + * this constructor. + */ + private XmlError(String message, String code, int severity, + String source, int line, int column, int offset, XmlCursor cursor) + { + _message = message; + _code = code; + _severity = severity; + _source = source; + _line = line; + _column = column; + _offset = offset; + _cursor = cursor; + } + + private XmlError(String code, Object[] args, int severity, + String source, int line, int column, int offset, XmlCursor cursor) + { + this(XmlError.formattedMessage(code, args), code, severity, source, line, column, offset, cursor); + } + + /** + * The static factory methods should be used instead of + * this constructor. + */ + protected XmlError(String message, String code, int severity, XmlCursor cursor) + { + String source = null; + int line = -1; + int column = -1; + int offset = -1; + + if (cursor != null) + { + // Hunt down the line/column/offset + source = cursor.documentProperties().getSourceName(); + + XmlCursor c = cursor.newCursor(); + + XmlLineNumber ln = + (XmlLineNumber) c.getBookmark( XmlLineNumber.class ); + + if (ln == null) + ln = (XmlLineNumber) c.toPrevBookmark( XmlLineNumber.class ); + + if (ln != null) + { + line = ln.getLine(); + column = ln.getColumn(); + offset = ln.getOffset(); + } + + c.dispose(); + } + + _message = message; + _code = code; + _severity = severity; + _source = source; + _line = line; + _column = column; + _offset = offset; + _cursor = cursor; + } + + protected XmlError(String code, Object[] args, int severity, XmlCursor cursor) + { + this(XmlError.formattedMessage(code, args), code, severity, cursor); + } + + /** + * The static factory methods should be used instead of + * this constructor. + */ + protected XmlError(String message, String code, int severity, Location loc) + { + String source = null; + int line = -1; + int column = -1; + + if (loc != null) + { + line = loc.getLineNumber(); + column = loc.getColumnNumber(); + source = loc.getPublicId(); + if (source==null) + source = loc.getSystemId(); + } + + _message = message; + _code = code; + _severity = severity; + _source = source; + _line = line; + _column = column; + } + + protected XmlError(String code, Object[] args, int severity, Location loc) + { + this(XmlError.formattedMessage(code, args), code, severity, loc); + } + + /** + * Returns an XmlError for the given message, with no location and {@link #SEVERITY_ERROR}. + * @param message the error message + */ + public static XmlError forMessage(String message) + { + return forMessage(message, SEVERITY_ERROR); + } + + /** + * Returns an XmlError for the given message, with no location and the given severity. + * @param message the error message + * @param severity the severity ({@link #SEVERITY_ERROR}, {@link #SEVERITY_WARNING}, or {@link #SEVERITY_INFO}) + */ + public static XmlError forMessage(String message, int severity) + { + return forSource(message, severity, null); + } + + /** + * Returns an XmlError for the given message, with no location and the given severity. + * @param code the error code + * @param args the arguments to use in formatting the error message + */ + public static XmlError forMessage(String code, Object[] args) + { + return forSource(code, args, SEVERITY_ERROR, null); + } + + /** + * Returns an XmlError for the given message, with no location and the given severity. + * @param code the error code + * @param args the arguments to use in formatting the error message + * @param severity the severity ({@link #SEVERITY_ERROR}, {@link #SEVERITY_WARNING}, or {@link #SEVERITY_INFO}) + */ + public static XmlError forMessage(String code, Object[] args, int severity) + { + return forSource(code, args, severity, null); + } + + /** + * Returns an XmlError for the given message, located in the given file and {@link #SEVERITY_ERROR}. + * @param message the error message + * @param sourceName the URL or other name for the file + */ + public static XmlError forSource(String message, String sourceName) + { + return forLocation(message, SEVERITY_ERROR, sourceName, -1, -1, -1); + } + + /** + * Returns an XmlError for the given message, with the given severity, located in the given file. + * @param message the error message + * @param severity the severity ({@link #SEVERITY_ERROR}, {@link #SEVERITY_WARNING}, or {@link #SEVERITY_INFO}) + * @param sourceName the URL or other name for the file + */ + public static XmlError forSource(String message, int severity, String sourceName) + { + return forLocation(message, severity, sourceName, -1, -1, -1); + } + + /** + * Returns an XmlError for the given message, with the given severity, located in the given file. + * @param code the error code + * @param args the arguments to use in formatting the error message + * @param severity the severity ({@link #SEVERITY_ERROR}, {@link #SEVERITY_WARNING}, or {@link #SEVERITY_INFO}) + * @param sourceName the URL or other name for the file + */ + public static XmlError forSource(String code, Object[] args, int severity, String sourceName) + { + return forLocation(code, args, severity, sourceName, -1, -1, -1); + } + + /** + * Returns an XmlError for the given message, located at a specific point in the given file and {@link #SEVERITY_ERROR}. + * @param message the error message + * @param sourceName the URL or other name for the file + * @param location the location from an xml stream + */ + public static XmlError forLocation(String message, String sourceName, Location location) + { + return new XmlError(message, (String)null, SEVERITY_ERROR, sourceName, + location.getLineNumber(), location.getColumnNumber(), -1, null); + } + + /** + * Returns an XmlError for the given message, located at a specific point in the given file and {@link #SEVERITY_ERROR}. + * @param message the error message + * @param sourceName the URL or other name for the file + * @param line the 1-based line number, or -1 if not known + * @param column the 1-based column number, or -1 if not known + * @param offset the 0-base file character offset, or -1 if not known + */ + public static XmlError forLocation(String message, String sourceName, int line, int column, int offset) + { + return new XmlError(message, (String)null, SEVERITY_ERROR, sourceName, line, column, offset, null); + } + + /** + * Returns an XmlError for the given message, with the given severity, located at a specific point in the given file. + * @param code the error code + * @param args the arguments to use in formatting the error message + * @param severity the severity ({@link #SEVERITY_ERROR}, {@link #SEVERITY_WARNING}, or {@link #SEVERITY_INFO}) + * @param sourceName the URL or other name for the file + * @param line the 1-based line number, or -1 if not known + * @param column the 1-based column number, or -1 if not known + * @param offset the 0-base file character offset, or -1 if not known + */ + public static XmlError forLocation(String code, Object[] args, int severity, String sourceName, int line, int column, int offset) + { + return new XmlError(code, args, severity, sourceName, line, column, offset, null); + } + + /** + * Returns an XmlError for the given message, with the given severity, located at a specific point in the given file. + * @param message the error message + * @param severity the severity ({@link #SEVERITY_ERROR}, {@link #SEVERITY_WARNING}, or {@link #SEVERITY_INFO}) + * @param sourceName the URL or other name for the file + * @param line the 1-based line number, or -1 if not known + * @param column the 1-based column number, or -1 if not known + * @param offset the 0-base file character offset, or -1 if not known + */ + public static XmlError forLocation(String message, int severity, String sourceName, int line, int column, int offset) + { + return new XmlError(message, (String)null, severity, sourceName, line, column, offset, null); + } + + /** + * Returns an XmlError for the given message, with the given severity, located at the given physcial location and XmlCursor. + * @param message the error message + * @param severity the severity ({@link #SEVERITY_ERROR}, {@link #SEVERITY_WARNING}, or {@link #SEVERITY_INFO}) + * @param sourceName the URL or other name for the file + * @param line the 1-based line number, or -1 if not known + * @param column the 1-based column number, or -1 if not known + * @param offset the 0-base file character offset, or -1 if not known + * @param cursor the XmlCursor representing the location of the error + */ + public static XmlError forLocationAndCursor(String message, int severity, String sourceName, int line, int column, int offset, XmlCursor cursor) + { + return new XmlError(message, (String)null, severity, sourceName, line, column, offset, cursor); + } + + /** + * Returns an XmlError for the given message, located at the XmlObject, with {@link #SEVERITY_ERROR}. + * @param message the error message + * @param xobj the XmlObject representing the location of the error + */ + public static XmlError forObject(String message, XmlObject xobj) + { + return forObject(message, SEVERITY_ERROR, xobj); + } + + /** + * Returns an XmlError for the given message, located at the XmlObject, with {@link #SEVERITY_ERROR}. + * @param code the error code + * @param args the arguments to use in formatting the error message + * @param xobj the XmlObject representing the location of the error + */ + public static XmlError forObject(String code, Object[] args, XmlObject xobj) + { + return forObject(code, args, SEVERITY_ERROR, xobj); + } + + /** + * Returns an XmlError for the given message, with the given severity, located at the XmlObject. + * @param message the error message + * @param severity the severity ({@link #SEVERITY_ERROR}, {@link #SEVERITY_WARNING}, or {@link #SEVERITY_INFO}) + * @param xobj the XmlObject representing the location of the error + */ + public static XmlError forObject(String message, int severity, XmlObject xobj) + { + if (xobj == null) + return forMessage(message, severity); + + XmlCursor cur = xobj.newCursor(); + XmlError result = forCursor(message, severity, cur); + return result; + } + + /** + * Returns an XmlError for the given message, with the given severity, located at the XmlObject. + * @param code the error code + * @param args the arguments to use in formatting the error message + * @param severity the severity ({@link #SEVERITY_ERROR}, {@link #SEVERITY_WARNING}, or {@link #SEVERITY_INFO}) + * @param xobj the XmlObject representing the location of the error + */ + public static XmlError forObject(String code, Object[] args, int severity, XmlObject xobj) + { + if (xobj == null) + return forMessage(code, args, severity); + + XmlCursor cur = xobj.newCursor(); + XmlError result = forCursor(code, args, severity, cur); + return result; + } + + /** + * Returns an XmlError for the given message, located at the XmlCursor, with {@link #SEVERITY_ERROR}. + * @param message the error message + * @param cursor the XmlCursor representing the location of the error + */ + public static XmlError forCursor(String message, XmlCursor cursor) + { + return forCursor(message, SEVERITY_ERROR, cursor); + } + + /** + * Returns an XmlError for the given message, located at the XmlCursor, with {@link #SEVERITY_ERROR}. + * @param code the error code + * @param args the arguments to use in formatting the error message + * @param cursor the XmlCursor representing the location of the error + */ + public static XmlError forCursor(String code, Object[] args, XmlCursor cursor) + { + return forCursor(code, args, SEVERITY_ERROR, cursor); + } + + /** + * Returns an XmlError for the given message, with the given severity, located at the XmlCursor. + * @param message the error message + * @param severity the severity ({@link #SEVERITY_ERROR}, {@link #SEVERITY_WARNING}, or {@link #SEVERITY_INFO}) + * @param cursor the XmlCursor representing the location of the error + */ + public static XmlError forCursor(String message, int severity, XmlCursor cursor) + { + return new XmlError(message, (String)null, severity, cursor); + } + + /** + * Returns an XmlError for the given message, with the given severity, located at the XmlCursor. + * @param code the error code + * @param args the arguments to use in formatting the error message + * @param severity the severity ({@link #SEVERITY_ERROR}, {@link #SEVERITY_WARNING}, or {@link #SEVERITY_INFO}) + * @param cursor the XmlCursor representing the location of the error + */ + public static XmlError forCursor(String code, Object[] args, int severity, XmlCursor cursor) + { + return new XmlError(code, args, severity, cursor); + } + + /** + * Tries to produce a nicely formatted filename from the given string. + */ + protected static String formattedFileName(String rawString, URI base) + { + if (rawString == null) + return null; + + URI uri = null; + + try + { + // if it looks like an absolute URI, treat it as such + uri = new URI(rawString); + + // otherwise, treat it like a filename + if (!uri.isAbsolute()) + uri = null; + } + catch (URISyntaxException e) + { + uri = null; + } + + // looks like a filename; convert it to uri for relativization + if (uri == null) + uri = new File(rawString).toURI(); + + if (base != null) + uri = base.relativize(uri); + + // filenames get their file: stripped off and their /'s turned into \'s (MSDOS) + if (uri.isAbsolute() ? uri.getScheme().compareToIgnoreCase("file") == 0 : + base != null && base.isAbsolute() && base.getScheme().compareToIgnoreCase("file") == 0) + { + try + { + return (new File(uri)).toString(); + } + catch (Exception e) {}; + } + + return uri.toString(); + } + + /** + * Tries to format a message using the error code. + */ + public static String formattedMessage(String code, Object[] args) + { + if (code == null) + return null; + + String message; + + try + { + message = MessageFormat.format(_bundle.getString(code), args); + } + catch (java.util.MissingResourceException e) + { + return MessageFormat.format(_bundle.getString("message.missing.resource"), + new Object[] { e.getMessage() }); + } + catch (IllegalArgumentException e) + { + return MessageFormat.format(_bundle.getString("message.pattern.invalid"), + new Object[] { e.getMessage() }); + } + + return message; + } + + /** + * An error. See {@link #getSeverity}. + */ + public static final int SEVERITY_ERROR = 0; + /** + * A warning. See {@link #getSeverity}. + */ + public static final int SEVERITY_WARNING = 1; + /** + * An informational message. See {@link #getSeverity}. + */ + public static final int SEVERITY_INFO = 2; + + /** + * Returns the severity. Either {@link #SEVERITY_ERROR}, {@link #SEVERITY_WARNING}, or {@link #SEVERITY_INFO}. + */ + public int getSeverity ( ) { return _severity; } + + /** + * Returns the error message without location information. + */ + public String getMessage ( ) { return _message; } + + /** + * Returns the error code or null. See {@link XmlErrorCodes}. + */ + public String getErrorCode ( ) { return _code; } + + /** + * Returns the URL (or other name) of the file with the error, if available. + */ + public String getSourceName ( ) { return _source; } + + /** + * Returns the line number of the error, if available, -1 if not. + */ + public int getLine ( ) { return _line; } + + /** + * Returns the column number of the error, if available, -1 if not. + */ + public int getColumn ( ) { return _column; } + + /** + * Returns the file character offset of the error, if available, -1 if not. + */ + public int getOffset ( ) { return _offset; } + + /** + * Returns a location object of the given type. XmlCursor.class and + * XmlObject.class can be passed, for example. Null if not available. + */ + public Object getLocation ( Object type ) + { + if (type == XmlCursor.class) + return _cursor; + if (type == XmlObject.class && _cursor != null) + return _cursor.getObject(); + return null; + } + + /** + * Returns a location of the error as an {@link XmlCursor}, null if + * not available. + */ + public XmlCursor getCursorLocation ( ) + { + return (XmlCursor) getLocation( XmlCursor.class ); + } + + /** + * Returns a location of the error as an {@link XmlObject}, null if + * not available. + */ + public XmlObject getObjectLocation ( ) + { + return (XmlObject) getLocation( XmlObject.class ); + } + + /** + * Produces a standard string for the error message, complete with + * filename and location offsets if available. + */ + public String toString ( ) + { + return toString( null ); + } + + /** + * Produces a standard string with the error message. If a non-null + * URI is supplied, source names are relativized against the given + * URI. + */ + public String toString ( URI base ) + { + // modified to carefully match the IDE's + // workshop.workspace.ant.AntLogger regex + // which also matches javac (davidbau) + + StringBuffer sb = new StringBuffer(); + + String source = formattedFileName(getSourceName(), base); + + if ( source != null ) + { + sb.append( source ); + int line = getLine(); + if ( line < 0 ) + line = 0; + + sb.append( ':' ); + sb.append( line ); + sb.append( ':' ); + if (getColumn() > 0) + { + sb.append( getColumn() ); + sb.append( ':' ); + } + sb.append(" "); + } + + switch ( getSeverity() ) + { + case SEVERITY_ERROR : sb.append( "error: " ); break; + case SEVERITY_WARNING : sb.append( "warning: " ); break; + case SEVERITY_INFO : break; + } + + if (getErrorCode() != null) + { + sb.append(getErrorCode()).append(": "); + } + + String msg = getMessage(); + + sb.append( msg == null ? "" : msg ); + + return sb.toString(); + } + + public static String severityAsString(int severity) + { + switch (severity) { + case SEVERITY_ERROR: + return ("error"); + case SEVERITY_WARNING: + return ("warning"); + case SEVERITY_INFO: + return "info"; + default: + throw new IllegalArgumentException("unknown severity"); + } + } +} diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlErrorCodes.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlErrorCodes.java new file mode 100644 index 000000000..0a3c92425 --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlErrorCodes.java @@ -0,0 +1,1899 @@ +/* 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; + +public abstract class XmlErrorCodes +{ + + public static final int MISMATCHED_TARGET_NAMESPACE = 4; + public static final int CANNOT_FIND_RESOURCE = 56; + public static final int REDUNDANT_NESTED_TYPE = 7; + public static final int ELEMENT_MISSING_NAME = 8; + public static final int REDUNDANT_DEFAULT_FIXED = 9; + public static final int MODEL_GROUP_MISSING_NAME = 10; + public static final int ATTRIBUTE_GROUP_MISSING_NAME = 12; + public static final int CYCLIC_DEPENDENCY = 13; + public static final int FACET_DUPLICATED = 19; + public static final int FACET_VALUE_MALFORMED = 20; + public static final int MALFORMED_NUMBER = 21; + public static final int REDUNDANT_CONTENT_MODEL = 26; + public static final int MISSING_RESTRICTION_OR_EXTENSION = 27; + public static final int MISSING_BASE = 28; + public static final int ELEMENT_EXTRA_REF = 30; + public static final int EXPLICIT_GROUP_NEEDED = 32; + public static final int GROUP_MISSING_REF = 33; + public static final int DUPLICATE_ATTRIBUTE_NAME = 37; + public static final int DUPLICATE_ANY_ATTRIBUTE = 38; + public static final int ATTRIBUTE_GROUP_MISSING_REF = 39; + public static final int CANNOT_EXTEND_ALL = 42; + public static final int INVALID_SCHEMA = 46; + public static final int DUPLICATE_GLOBAL_ELEMENT = 47; + public static final int DUPLICATE_GLOBAL_ATTRIBUTE = 48; + public static final int DUPLICATE_GLOBAL_TYPE = 49; + public static final int MALFORMED_SIMPLE_TYPE_DEFN = 52; + public static final int INVALID_NAME = 53; + public static final int CANNOT_DERIVE_FINAL = 54; + public static final int IDC_NOT_FOUND = 55; + public static final int NONDETERMINISTIC_MODEL = 57; + public static final int XPATH_COMPILATION_FAILURE = 58; + public static final int DUPLICATE_IDENTITY_CONSTRAINT = 59; + public static final int ILLEGAL_RESTRICTION = 45; + public static final int INCONSISTENT_TYPE = 50; + + /* general */ + + public static final int UNSUPPORTED_FEATURE = 51; + public static final int GENERIC_ERROR = 60; + + + // + // xmlbeans errors + // + + public static final String INVALID_DOCUMENT_TYPE = "invalid.document.type"; + public static final String CANNOT_LOAD_FILE = "cannot.load.file"; + public static final String EXCEPTION_EXCEEDED_ENTITY_BYTES = "exceeded-entity-bytes"; + public static final String EXCEPTION_LOADING_URL = "exception.loading.url"; + public static final String EXCEPTION_VALUE_NOT_SUPPORTED_J2S = "exception.value.not.supported.j2s"; + public static final String EXCEPTION_VALUE_NOT_SUPPORTED_S2J = "exception.value.not.supported.s2j"; + + public static final String EXCEPTION_XQRL_XPATH_NOT_VALID = "exception.xqrl.xpath.not.valid"; + public static final String EXCEPTION_XQRL_EXCEPTION = "exception.xqrl.exception"; + + // + // xml errors + // + + /** + * uniqattspec: See + * XML 1.0: Unique Att Spec + */ + public static final String XML_DUPLICATE_ATTRIBUTE = "uniqattspec"; + + // + // schema errors + // + + /** + * cvc-assess-attr: See + * XMLSchema Structures 1.0: Schema-Validity Assessment (Attribute) + */ + public static final String ASSESS_ATTR_SCHEMA_VALID = "cvc-assess-attr"; + + /** + * cvc-assess-attr.1.2: See clause 1.2 of + * XMLSchema Structures 1.0: Schema-Validity Assessment (Attribute) + */ + public static final String ASSESS_ATTR_SCHEMA_VALID$NOT_RESOLVED = "cvc-assess-attr.1.2"; + + /** + * cvc-assess-elt: See + * XMLSchema Structures 1.0: Schema-Validity Assessment (Element) + */ + public static final String ASSESS_ELEM_SCHEMA_VALID = "cvc-assess-elt"; + + /** + * cvc-assess-elt.1.1.1.3.2: See clause 1.1.1.3.2 of + * XMLSchema Structures 1.0: Schema-Validity Assessment (Element) + */ + public static final String ASSESS_ELEM_SCHEMA_VALID$NOT_RESOLVED = "cvc-assess-elt.1.1.1.3.2"; + + /** + * cvc-attribute: See + * XMLSchema Structures 1.0: Attribute Locally Valid + */ + public static final String ATTR_LOCALLY_VALID = "cvc-attribute"; + + /** + * cvc-attribute.1: See clause 1 of + * XMLSchema Structures 1.0: Attribute Locally Valid + */ + public static final String ATTR_LOCALLY_VALID$NO_TYPE = "cvc-attribute.1"; + + /** + * cvc-attribute.4: See clause 4 of + * XMLSchema Structures 1.0: Attribute Locally Valid + */ + public static final String ATTR_LOCALLY_VALID$FIXED = "cvc-attribute.4"; + + /** + * cvc-au: See + * XMLSchema Structures 1.0: Attribute Locally Valid (Use) + */ + public static final String ATTR_USE_LOCALLY_VALID = "cvc-au"; + + /** + * cvc-complex-type: See + * XMLSchema Structures 1.0: Element Locally Valid (Complex Type) + */ + public static final String ELEM_COMPLEX_TYPE_LOCALLY_VALID = "cvc-complex-type"; + + /** + * cvc-complex-type.2.1: See clause 2.1 of + * XMLSchema Structures 1.0: Element Locally Valid (Complex Type) + */ + public static final String ELEM_COMPLEX_TYPE_LOCALLY_VALID$EMPTY_WITH_CONTENT = "cvc-complex-type.2.1"; + + /** + * cvc-complex-type.2.2: See clause 2.2 of + * XMLSchema Structures 1.0: Element Locally Valid (Complex Type) + */ + public static final String ELEM_COMPLEX_TYPE_LOCALLY_VALID$SIMPLE_TYPE_WITH_CONTENT = "cvc-complex-type.2.2"; + + /** + * cvc-complex-type.2.4a: See clause 2.4 of + * XMLSchema Structures 1.0: Element Locally Valid (Complex Type) + */ + public static final String ELEM_COMPLEX_TYPE_LOCALLY_VALID$EXPECTED_DIFFERENT_ELEMENT = "cvc-complex-type.2.4a"; + + /** + * cvc-complex-type.2.4b: See clause 2.4 of + * XMLSchema Structures 1.0: Element Locally Valid (Complex Type) + */ + public static final String ELEM_COMPLEX_TYPE_LOCALLY_VALID$ELEMENT_NOT_ALLOWED = "cvc-complex-type.2.4b"; + + /** + * cvc-complex-type.2.4c: See clause 2.4 of + * XMLSchema Structures 1.0: Element Locally Valid (Complex Type) + */ + public static final String ELEM_COMPLEX_TYPE_LOCALLY_VALID$MISSING_ELEMENT = "cvc-complex-type.2.4c"; + + /** + * cvc-complex-type.2.4d: See clause 2.4 of + * XMLSchema Structures 1.0: Element Locally Valid (Complex Type) + */ + public static final String ELEM_COMPLEX_TYPE_LOCALLY_VALID$EXPECTED_ELEMENT = "cvc-complex-type.2.4d"; + + /** + * cvc-complex-type.2.3: See clause 2.3 of + * XMLSchema Structures 1.0: Element Locally Valid (Complex Type) + */ + public static final String ELEM_COMPLEX_TYPE_LOCALLY_VALID$ELEMENT_ONLY_WITH_TEXT = "cvc-complex-type.2.3"; + + /** + * cvc-complex-type.3.1: See clause 3.1 of + * XMLSchema Structures 1.0: Element Locally Valid (Complex Type) + */ + public static final String ELEM_COMPLEX_TYPE_LOCALLY_VALID$ATTRIBUTE_VALID = "cvc-complex-type.3.1"; + + /** + * cvc-complex-type.3.2.1: See clause 3.2.1 of + * XMLSchema Structures 1.0: Element Locally Valid (Complex Type) + */ + public static final String ELEM_COMPLEX_TYPE_LOCALLY_VALID$NO_WILDCARD = "cvc-complex-type.3.2.1"; + + /** + * cvc-complex-type.3.2.2: See clause 3.2.2 of + * XMLSchema Structures 1.0: Element Locally Valid (Complex Type) + */ + public static final String ELEM_COMPLEX_TYPE_LOCALLY_VALID$NOT_WILDCARD_VALID = "cvc-complex-type.3.2.2"; + + /** + * cvc-complex-type.4: See clause 4 of + * XMLSchema Structures 1.0: Element Locally Valid (Complex Type) + */ + public static final String ELEM_COMPLEX_TYPE_LOCALLY_VALID$MISSING_REQUIRED_ATTRIBUTE = "cvc-complex-type.4"; + + /** + * cvc-datatype-valid: See + * XMLSchema Datatypes 1.0: Datatype Valid + */ + public static final String DATATYPE_VALID = "cvc-datatype-valid"; + + /** + * cvc-datatype-valid.1.1: See clause 1.1 of + * XMLSchema Datatypes 1.0: Datatype Valid + */ + public static final String DATATYPE_VALID$PATTERN_VALID = "cvc-datatype-valid.1.1"; + + /** + * cvc-datatype-valid.1.1b: See clause 1.1 of + * XMLSchema Datatypes 1.0: Datatype Valid + */ + public static final String DATATYPE_VALID$PATTERN_VALID$NO_VALUE = "cvc-datatype-valid.1.1b"; + + /** + * cvc-datatype-valid.1.2.3: See clause 1.2.3 of + * XMLSchema Datatypes 1.0: Datatype Valid + */ + public static final String DATATYPE_VALID$UNION = "cvc-datatype-valid.1.2.3"; + + /** + * cvc-elt: See + * XMLSchema Structures 1.0: Element Locally Valid (Element) + */ + public static final String ELEM_LOCALLY_VALID = "cvc-elt"; + + /** + * cvc-elt.1: See clause 1 of + * XMLSchema Structures 1.0: Element Locally Valid (Element) + */ + public static final String ELEM_LOCALLY_VALID$NO_TYPE = "cvc-elt.1"; + + /** + * cvc-elt.2: See clause 2 of + * XMLSchema Structures 1.0: Element Locally Valid (Element) + */ + public static final String ELEM_LOCALLY_VALID$ABSTRACT = "cvc-elt.2"; + + /** + * cvc-elt.3.1: See clause 3.1 of + * XMLSchema Structures 1.0: Element Locally Valid (Element) + */ + public static final String ELEM_LOCALLY_VALID$NOT_NILLABLE = "cvc-elt.3.1"; + + /** + * cvc-elt.3.2.1: See clause 3.2.1 of + * XMLSchema Structures 1.0: Element Locally Valid (Element) + */ + public static final String ELEM_LOCALLY_VALID$NIL_WITH_CONTENT = "cvc-elt.3.2.1"; + + /** + * cvc-elt.3.2.2: See clause 3.2.2 of + * XMLSchema Structures 1.0: Element Locally Valid (Element) + */ + public static final String ELEM_LOCALLY_VALID$NIL_WITH_FIXED = "cvc-elt.3.2.2"; + + /** + * cvc-elt.4.1: See clause 4.1 of + * XMLSchema Structures 1.0: Element Locally Valid (Element) + */ + public static final String ELEM_LOCALLY_VALID$XSI_TYPE_INVALID_QNAME = "cvc-elt.4.1"; + + /** + * cvc-elt.4.2: See clause 4.2 of + * XMLSchema Structures 1.0: Element Locally Valid (Element) + */ + public static final String ELEM_LOCALLY_VALID$XSI_TYPE_NOT_FOUND = "cvc-elt.4.2"; + + /** + * cvc-elt.4.3a: See clause 4.3 of + * XMLSchema Structures 1.0: Element Locally Valid (Element) + */ + public static final String ELEM_LOCALLY_VALID$XSI_TYPE_NOT_DERIVED = "cvc-elt.4.3a"; + + /** + * cvc-elt.4.3b: See clause 4.3 of + * XMLSchema Structures 1.0: Element Locally Valid (Element) + */ + public static final String ELEM_LOCALLY_VALID$XSI_TYPE_BLOCK_EXTENSION = "cvc-elt.4.3b"; + + /** + * cvc-elt.4.3c: See clause 4.3 of + * XMLSchema Structures 1.0: Element Locally Valid (Element) + */ + public static final String ELEM_LOCALLY_VALID$XSI_TYPE_BLOCK_RESTRICTION = "cvc-elt.4.3c"; + + /** + * cvc-elt.5.2.2.1: See clause 5.2.2.1 of + * XMLSchema Structures 1.0: Element Locally Valid (Element) + */ + public static final String ELEM_LOCALLY_VALID$FIXED_WITH_CONTENT = "cvc-elt.5.2.2.1"; + + /** + * cvc-elt.5.2.2.2.1: See clause 5.2.2.2.1 of + * XMLSchema Structures 1.0: Element Locally Valid (Element) + */ + public static final String ELEM_LOCALLY_VALID$FIXED_VALID_MIXED_CONTENT = "cvc-elt.5.2.2.2.1"; + + /** + * cvc-elt.5.2.2.2.2: See clause 5.2.2.2.2 of + * XMLSchema Structures 1.0: Element Locally Valid (Element) + */ + public static final String ELEM_LOCALLY_VALID$FIXED_VALID_SIMPLE_TYPE = "cvc-elt.5.2.2.2.2"; + + /** + * cvc-elt.4.3d: See clause 4.3 of + * XMLSchema Structures 1.0: Element Locally Valid (Element) + */ + public static final String ELEM_LOCALLY_VALID$XSI_TYPE_PROHIBITED_SUBST = "cvc-elt.4.3d"; + + /** + * cvc-enumeration-valid: See + * XMLSchema Datatypes 1.0: enumeration valid + */ + public static final String DATATYPE_ENUM_VALID = "cvc-enumeration-valid"; + + /** + * cvc-enumeration-valid.b: See + * XMLSchema Datatypes 1.0: enumeration valid + */ + public static final String DATATYPE_ENUM_VALID$NO_VALUE = "cvc-enumeration-valid.b"; + + /** + * cvc-facet-valid: See + * XMLSchema Datatypes 1.0: Facet Valid + */ + public static final String DATATYPE_FACET_VALID = "cvc-facet-valid"; + + /** + * cvc-fractionDigits-valid: See + * XMLSchema Datatypes 1.0: fractionDigits Valid + */ + public static final String DATATYPE_FRACTION_DIGITS_VALID = "cvc-fractionDigits-valid"; + + /** + * cvc-id.2: See clause 2 of + * XMLSchema Structures 1.0: Validation Root Valid (ID/IDREF) + */ + public static final String ID_VALID$DUPLICATE = "cvc-id.2"; + + /** + * cvc-identity-constraint: See + * XMLSchema Structures 1.0: Identity-constraint Satisfied + */ + public static final String IDENTITY_CONSTRAINT_VALID = "cvc-identity-constraint"; + + /** + * cvc-identity-constraint.4.1: See clause 4.1 of + * XMLSchema Structures 1.0: Identity-constraint Satisfied + */ + public static final String IDENTITY_CONSTRAINT_VALID$DUPLICATE_UNIQUE = "cvc-identity-constraint.4.1"; + + /** + * cvc-identity-constraint.4.2.2: See clause 4.2.2 + * XMLSchema Structures 1.0: Identity-constraint Satisfied + */ + public static final String IDENTITY_CONSTRAINT_VALID$DUPLICATE_KEY = "cvc-identity-constraint.4.2.2"; + + /** + * cvc-identity-constraint.4.3: See clause 4.3 + * XMLSchema Structures 1.0: Identity-constraint Satisfied + */ + public static final String IDENTITY_CONSTRAINT_VALID$KEYREF_KEY_NOT_FOUND = "cvc-identity-constraint.4.3"; + + /** + * cvc-length-valid: See + * XMLSchema Datatypes 1.0: Length Valid + */ + public static final String DATATYPE_LENGTH_VALID = "cvc-length-valid"; + + /** + * cvc-length-valid.1.1: See clause 1.1 of + * XMLSchema Datatypes 1.0: Length Valid + */ + public static final String DATATYPE_LENGTH_VALID$STRING = "cvc-length-valid.1.1"; + + /** + * cvc-length-valid.1.2: See clause 1.2 of + * XMLSchema Datatypes 1.0: Length Valid + */ + public static final String DATATYPE_LENGTH_VALID$BINARY = "cvc-length-valid.1.2"; + + /** + * cvc-length-valid.2: See clause 2 of + * XMLSchema Datatypes 1.0: Length Valid + */ + public static final String DATATYPE_LENGTH_VALID$LIST_LENGTH = "cvc-length-valid.2"; + + /** + * cvc-maxExclusive-valid: See + * XMLSchema Datatypes 1.0: maxExclusive Valid + */ + public static final String DATATYPE_MAX_EXCLUSIVE_VALID = "cvc-maxExclusive-valid"; + + /** + * cvc-maxInclusive-valid: See + * XMLSchema Datatypes 1.0: maxInclusive Valid + */ + public static final String DATATYPE_MAX_INCLUSIVE_VALID = "cvc-maxInclusive-valid"; + + /** + * cvc-maxLength-valid: See + * XMLSchema Datatypes 1.0: maxLength Valid + */ + public static final String DATATYPE_MAX_LENGTH_VALID = "cvc-maxLength-valid"; + + /** + * cvc-maxLength-valid.1.1: See clause 1.1 of + * XMLSchema Datatypes 1.0: maxLength Valid + */ + public static final String DATATYPE_MAX_LENGTH_VALID$STRING = "cvc-maxLength-valid.1.1"; + + /** + * cvc-maxLength-valid.1.2: See clause 1.2 of + * XMLSchema Datatypes 1.0: maxLength Valid + */ + public static final String DATATYPE_MAX_LENGTH_VALID$BINARY = "cvc-maxLength-valid.1.2"; + + /** + * cvc-maxLength-valid.2: See clause 2 of + * XMLSchema Datatypes 1.0: maxLength Valid + */ + public static final String DATATYPE_MAX_LENGTH_VALID$LIST_LENGTH = "cvc-maxLength-valid.2"; + + /** + * cvc-minExclusive-valid: See + * XMLSchema Datatypes 1.0: minExclusive Valid + */ + public static final String DATATYPE_MIN_EXCLUSIVE_VALID = "cvc-minExclusive-valid"; + + /** + * cvc-minInclusive-valid: See + * XMLSchema Datatypes 1.0: minInclusive Valid + */ + public static final String DATATYPE_MIN_INCLUSIVE_VALID = "cvc-minInclusive-valid"; + + /** + * cvc-minLength-valid: See + * XMLSchema Datatypes 1.0: minLength Valid + */ + public static final String DATATYPE_MIN_LENGTH_VALID = "cvc-minLength-valid"; + + /** + * cvc-minLength-valid.1.1: See clause 1.1 of + * XMLSchema Datatypes 1.0: minLength Valid + */ + public static final String DATATYPE_MIN_LENGTH_VALID$STRING = "cvc-minLength-valid.1.1"; + + /** + * cvc-minLength-valid.1.2: See clause 1.2 of + * XMLSchema Datatypes 1.0: minLength Valid + */ + public static final String DATATYPE_MIN_LENGTH_VALID$BINARY = "cvc-minLength-valid.1.2"; + + /** + * cvc-minLength-valid.2: See clause 2 of + * XMLSchema Datatypes 1.0: minLength Valid + */ + public static final String DATATYPE_MIN_LENGTH_VALID$LIST_LENGTH = "cvc-minLength-valid.2"; + + /** + * cvc-model-group: See + * XMLSchema Structures 1.0: Element Sequence Valid + */ + public static final String MODEL_GROUP_VALID = "cvc-model-group"; + + /** + * cvc-particle: See + * XMLSchema Structures 1.0: Element Sequence Locally Valid (Particle) + */ + public static final String PARTICLE_VALID = "cvc-particle"; + + /** + * cvc-particle.1.3: See + * XMLSchema Structures 1.0: Element Sequence Locally Valid (Particle) + */ + public static final String PARTICLE_VALID$NOT_WILDCARD_VALID = "cvc-particle.1.3"; + + /** + * cvc-particle.2.3.3a: See + * XMLSchema Structures 1.0: Element Sequence Locally Valid (Particle) + */ + public static final String PARTICLE_VALID$BLOCK_SUBSTITUTION = "cvc-particle.2.3.3a"; + + /** + * cvc-pattern-valid: See + * XMLSchema Datatypes 1.0: pattern valid + */ + public static final String DATATYPE_PATTERN_VALID = "cvc-pattern-valid"; + + /** + * cvc-resolve-instance: See + * XMLSchema Structures 1.0: QName resolution (Instance) + */ + public static final String RESOLVE_QNAME_INSTANCE_VALID = "cvc-resolve-instance"; // KHK: ? is the name good + + /** + * cvc-simple-type: See + * XMLSchema Structures 1.0: String Valid + */ + public static final String SIMPLE_TYPE_STRING_VALID = "cvc-simple-type"; + + /** + * cvc-totalDigits-valid: See + * XMLSchema Datatypes 1.0: totalDigits Valid + */ + public static final String DATATYPE_TOTAL_DIGITS_VALID = "cvc-totalDigits-valid"; + + /** + * cvc-type: See + * XMLSchema Structures 1.0: Element Locally Valid (Type) + */ + public static final String ELEM_TYPE_LOCALLY_VALID = "cvc-type"; + + /** + * cvc-type.2: See clause 2 of + * XMLSchema Structures 1.0: Element Locally Valid (Type) + */ + public static final String ELEM_TYPE_LOCALLY_VALID$ABSTRACT = "cvc-type.2"; + + /** + * cvc-wildcard: See + * XMLSchema Structures 1.0: Item Valid (Wildcard) + */ + public static final String WILDCARD_ITEM_VALID = "cvc-wildcard"; + + /** + * cvc-wildcard-namespace: See + * XMLSchema Structures 1.0: Wildcard allows Namespace Name + */ + public static final String WILDCARD_NAMESPACE_NAME_VALID = "cvc-wildcard-namespace"; + + /** + * schema_reference: See + * XMLSchema Structures 1.0: Schema Document Location Strategy + */ + public static final String SCHEMA_REFERENCE = "schema_reference"; + + /** + * src-annotation: See + * XMLSchema Structures 1.0: Annotation Definition Representation OK + */ + public static final String SCHEMA_ANNOTATION = "src-annotation"; + + /** + * src-attribute: See + * XMLSchema Structures 1.0: Attribute Declaration Representation OK + */ + public static final String SCHEMA_ATTR = "src-attribute"; + + /** + * src-attribute.1: See clause 1 of + * XMLSchema Structures 1.0: Attribute Declaration Representation OK + */ + public static final String SCHEMA_ATTR$DEFAULT_OR_FIXED = "src-attribute.1"; + + /** + * au-value_constraint: See description for + * XMLSchema Structures 1.0: The Attribute Use Schema Component + */ + public static final String SCHEMA_ATTR$FIXED_NOT_MATCH = "au-value_constraint"; + + /** + * src-attribute.2: See clause 2 of + * XMLSchema Structures 1.0: Attribute Declaration Representation OK + */ + public static final String SCHEMA_ATTR$DEFAULT_AND_USE_OPTIONAL = "src-attribute.2"; + + /** + * src-attribute.3.1a: See clause 3.1 of + * XMLSchema Structures 1.0: Attribute Declaration Representation OK + */ + public static final String SCHEMA_ATTR$REF_OR_NAME_HAS_BOTH = "src-attribute.3.1a"; + + /** + * src-attribute.3.1b: See clause 3.1 of + * XMLSchema Structures 1.0: Attribute Declaration Representation OK + */ + public static final String SCHEMA_ATTR$REF_OR_NAME_HAS_NEITHER = "src-attribute.3.1b"; + + /** + * src-attribute.3.2: See clause 3.2 of + * XMLSchema Structures 1.0: Attribute Declaration Representation OK + */ + public static final String SCHEMA_ATTR$REF_FEATURES = "src-attribute.3.2"; + + /** + * src-attribute.4: See clause 4 of + * XMLSchema Structures 1.0: Attribute Declaration Representation OK + */ + public static final String SCHEMA_ATTR$TYPE_ATTR_OR_NESTED_TYPE = "src-attribute.4"; + + /** + * src-attribute_group: See + * XMLSchema Structures 1.0: Attribute Group Definition Representation OK + */ + public static final String SCHEMA_ATTR_GROUP = "src-attribute_group"; + + /** + * src-attribute_group.3: See clause 3 of + * XMLSchema Structures 1.0: Attribute Group Definition Representation OK + */ + public static final String SCHEMA_ATTR_GROUP$SELF_REF = "src-attribute_group.3"; + + /** + * src-ct: See + * XMLSchema Structures 1.0: Complex Type Definition Representation OK + */ + public static final String SCHEMA_COMPLEX_TYPE = "src-ct"; + + /** + * src-ct.1: See clause 1 of + * XMLSchema Structures 1.0: Complex Type Definition Representation OK + */ + public static final String SCHEMA_COMPLEX_TYPE$COMPLEX_CONTENT = "src-ct.1"; + + /** + * src-ct.2: See clause 2 of + * XMLSchema Structures 1.0: Complex Type Definition Representation OK + */ + public static final String SCHEMA_COMPLEX_TYPE$SIMPLE_CONTENT = "src-ct.2"; + + /** + * src-element: See + * XMLSchema Structures 1.0: Element Declaration Representation OK + */ + public static final String SCHEMA_ELEM = "src-element"; + + /** + * src-element.1: See clause 1 of + * XMLSchema Structures 1.0: Element Declaration Representation OK + */ + public static final String SCHEMA_ELEM$DEFAULT_OR_FIXED = "src-element.1"; + + /** + * src-element.2.1a: See clause 2.1 of + * XMLSchema Structures 1.0: Element Declaration Representation OK + */ + public static final String SCHEMA_ELEM$REF_OR_NAME_HAS_BOTH = "src-element.2.1a"; + + /** + * src-element.2.1b: See clause 2.1 of + * XMLSchema Structures 1.0: Element Declaration Representation OK + */ + public static final String SCHEMA_ELEM$REF_OR_NAME_HAS_NEITHER = "src-element.2.1b"; + + /** + * src-element.2.2: See clause 2.2 of + * XMLSchema Structures 1.0: Element Declaration Representation OK + */ + public static final String SCHEMA_ELEM$REF_FEATURES = "src-element.2.2"; + + /** + * src-element.3: See clause 3 of + * XMLSchema Structures 1.0: Element Declaration Representation OK + */ + public static final String SCHEMA_ELEM$TYPE_ATTR_OR_NESTED_TYPE = "src-element.3"; + + /** + * src-expredef: See + * XMLSchema Structures 1.0: Individual Component Redefinition + */ + public static final String SCHEMA_REDEFINITION = "src-expredef"; + + /** + * src-identity-constraint: See + * XMLSchema Structures 1.0: Identity-constraint Definition Representation OK + */ + public static final String SCHEMA_IDENTITY_CONSTRAINT = "src-identity-constraint"; + + /** + * src-import: See + * XMLSchema Structures 1.0: Import Constraints and Semantics + */ + public static final String SCHEMA_IMPORT = "src-import"; + + /** + * src-include: See + * XMLSchema Structures 1.0: Inclusion Constraints and Semantics + */ + public static final String SCHEMA_INCLUDE = "src-include"; + + /** + * src-list-itemType-or-simpleType: See + * XMLSchema Datatypes 1.0: itemType attribute or simpleType child + */ + public static final String SCHEMA_SIMPLE_TYPE$LIST_ITEM_TYPE_OR_SIMPLE_TYPE = "src-list-itemType-or-simpleType"; + + /** + * src-model_group: See + * XMLSchema Structures 1.0: Model Group Representation OK + */ + public static final String SCHEMA_MODEL_GROUP = "src-model_group"; + + /** + * src-model_group_defn: See + * XMLSchema Structures 1.0: Model Group Definition Representation OK + */ + public static final String SCHEMA_MODEL_GROUP_DEFN = "src-model_group_defn"; + + /** + * src-multiple-enumerations: See + * XMLSchema Datatypes 1.0: Multiple enumerations + */ + public static final String SCHEMA_MULTIPLE_ENUMS = "src-multiple-enumerations"; + + /** + * src-multiple-patterns: See + * XMLSchema Datatypes 1.0: Multiple patterns + */ + public static final String SCHEMA_MULTIPLE_PATTERNS = "src-multiple-patterns"; + + /** + * src-notation: See + * XMLSchema Structures 1.0: Notation Definition Representation OK + */ + public static final String SCHEMA_NOTATION = "src-notation"; + + /** + * src-qname: See + * XMLSchema Structures 1.0: QName Interpretation + */ + public static final String SCHEMA_QNAME = "src-qname"; + + /** + * src-redefine: See + * XMLSchema Structures 1.0: Redefinition Constraints and Semantics + */ + public static final String SCHEMA_REDEFINE = "src-redefine"; + + /** + * src-redefine.5a: See clause 5 of + * XMLSchema Structures 1.0: Redefinition Constraints and Semantics + */ + public static final String SCHEMA_REDEFINE$EXTEND_OR_RESTRICT = "src-redefine.5a"; + + /** + * src-redefine.5b: See clause 5 of + * XMLSchema Structures 1.0: Redefinition Constraints and Semantics + */ + public static final String SCHEMA_REDEFINE$SAME_TYPE = "src-redefine.5b"; + + /** + * src-redefine.6.1.1: See clause 6.1.1 of + * XMLSchema Structures 1.0: Redefinition Constraints and Semantics + */ + public static final String SCHEMA_REDEFINE$GROUP_SELF_REF = "src-redefine.6.1.1"; + + /** + * src-redefine.6.1.2: See clause 6.1.2 of + * XMLSchema Structures 1.0: Redefinition Constraints and Semantics + */ + public static final String SCHEMA_REDEFINE$GROUP_SELF_REF_MIN_MAX_1 = "src-redefine.6.1.2"; + + /** + * src-redefine.7.1: See clause 7.1 of + * XMLSchema Structures 1.0: Redefinition Constraints and Semantics + */ + public static final String SCHEMA_REDEFINE$ATTR_GROUP_SELF_REF = "src-redefine.7.1"; + + /** + * src-resolve: See + * XMLSchema Structures 1.0: QName resolution (Schema Document) + */ + public static final String SCHEMA_QNAME_RESOLVE = "src-resolve"; + + /** + * src-resolve: See + * XMLSchema Structures 1.0: QName resolution (Schema Document) + */ + public static final String SCHEMA_QNAME_RESOLVE$HELP = "src-resolve.a"; + + /** + * src-restriction-base-or-simpleType: See + * XMLSchema Datatypes 1.0: base attribute or simpleType child + */ + public static final String SCHEMA_SIMPLE_TYPE$RESTICTION_HAS_BASE_OR_SIMPLE_TYPE = "src-restriction-base-or-simpleType"; + + /** + * src-simple-type: See + * XMLSchema Structures 1.0: Simple Type Definition Representation OK + */ + public static final String SCHEMA_SIMPLE_TYPE = "src-simple-type"; + + /** + * src-simple-type.2a: See clause 2 of + * XMLSchema Structures 1.0: Simple Type Definition Representation OK + */ + public static final String SCHEMA_SIMPLE_TYPE$RESTRICTION_HAS_BOTH_BASE_OR_SIMPLE_TYPE = "src-simple-type.2a"; + + /** + * src-simple-type.2b: See clause 2 of + * XMLSchema Structures 1.0: Simple Type Definition Representation OK + */ + public static final String SCHEMA_SIMPLE_TYPE$RESTRICTION_HAS_NEITHER_BASE_OR_SIMPLE_TYPE = "src-simple-type.2b"; + + /** + * src-simple-type.3a: See clause 3 of + * XMLSchema Structures 1.0: Simple Type Definition Representation OK + */ + public static final String SCHEMA_SIMPLE_TYPE$LIST_HAS_BOTH_ITEM_OR_SIMPLE_TYPE = "src-simple-type.3a"; + + /** + * src-simple-type.3b: See clause 3 of + * XMLSchema Structures 1.0: Simple Type Definition Representation OK + */ + public static final String SCHEMA_SIMPLE_TYPE$LIST_HAS_NEITHER_ITEM_OR_SIMPLE_TYPE = "src-simple-type.3b"; + + /** + * src-simple-type.4: See clause 4 of + * XMLSchema Structures 1.0: Simple Type Definition Representation OK + */ + public static final String SCHEMA_SIMPLE_TYPE$CYCLIC_UNION = "src-simple-type.4"; + + /** + * src-single-facet-value: See + * XMLSchema Datatypes 1.0: Single Facet Value + */ + public static final String DATATYPE_SINGLE_FACET_VALUE = "src-single-facet-value"; + + /** + * src-union-memberTypes-or-simpleTypes: See + * XMLSchema Datatypes 1.0: memberTypes attribute or simpleType children + */ + public static final String SCHEMA_SIMPLE_TYPE$UNION_HAS_MEMBER_TYPES_OR_SIMPLE_TYPES = "src-union-memberTypes-or-simpleTypes"; + + /** + * src-wildcard: See + * XMLSchema Structures 1.0: Wildcard Representation OK + */ + public static final String SCHEMA_WILDCARD = "src-wildcard"; + + /** + * a-props-correct: See + * XMLSchema Structures 1.0: Attribute Declaration Properties Correct + */ + public static final String ATTR_PROPERTIES = "a-props-correct"; + + /** + * a-props-correct.2: See clause 2 of + * XMLSchema Spec: Attribute Declaration Properties + */ + public static final String ATTR_PROPERTIES$CONSTRAINT_VALID = "a-props-correct.2"; + + /** + * a-props-correct.3: See clause 3 of + * XMLSchema Spec: Attribute Declaration Properties + */ + public static final String ATTR_PROPERTIES$ID_FIXED_OR_DEFAULT = "a-props-correct.3"; + + /** + * ag-props-correct: See + * XMLSchema Structures 1.0: Attribute Group Definition Properties Correct + */ + public static final String ATTR_GROUP_PROPERTIES = "ag-props-correct"; + + /** + * ag-props-correct.2: See clause 2 of + * XMLSchema Structures 1.0: Attribute Group Definition Properties Correct + */ + public static final String ATTR_GROUP_PROPERTIES$2 = "ag-props-correct.2"; + + /** + * ag-props-correct.3: See clause 3 of + * XMLSchema Structures 1.0: Attribute Group Definition Properties Correct + */ + public static final String ATTR_GROUP_PROPERTIES$TWO_IDS = "ag-props-correct.3"; + + /** + * an-props-correct: See + * XMLSchema Structures 1.0: Annotation Correct + */ + public static final String ANNO_PROPERTIES = "an-props-correct"; + + /** + * au-props-correct: See + * XMLSchema Structures 1.0: Attribute Use Correct + */ + public static final String ATTR_USE_PROPERTIES = "au-props-correct"; + + /** + * c-fields-xpaths: See + * XMLSchema Structures 1.0: Fields Value OK + */ + public static final String FIELDS_XPATH = "c-fields-xpaths"; + + /** + * c-props-correct: See + * XMLSchema Structures 1.0: Identity-constraint Definition Properties Correct + */ + public static final String IDENTITY_CONSTRAINT_PROPERTIES = "c-props-correct"; + + /** + * c-props-correct.1: See clause 1 of + * XMLSchema Structures 1.0: Identity-constraint Definition Properties Correct + */ + public static final String IDENTITY_CONSTRAINT_PROPERTIES$KEYREF_REFERS_TO_KEYREF = "c-props-correct.1"; + + /** + * c-props-correct.2: See clause 2 of + * XMLSchema Structures 1.0: Identity-constraint Definition Properties Correct + */ + public static final String IDENTITY_CONSTRAINT_PROPERTIES$KEY_KEYREF_FIELD_COUNT_EQ = "c-props-correct.2"; + + /** + * c-selector-xpath: See + * XMLSchema Structures 1.0: Selector Value OK + */ + public static final String SELECTOR_XPATH = "c-selector-xpath"; + + /** + * cos-all-limited: See + * XMLSchema Structures 1.0: All Group Limited + */ + public static final String ALL_GROUP_LIMITED = "cos-all-limited"; + + /** + * cos-all-limited.1.2a: See clause 1.2 of + * XMLSchema Structures 1.0: All Group Limited + */ + public static final String ALL_GROUP_LIMITED$IN_MIN_MAX_1_PARTICLE = "cos-all-limited.1.2a"; + + /** + * cos-all-limited.1.2b: See clause 1.2 of + * XMLSchema Structures 1.0: All Group Limited + */ + public static final String ALL_GROUP_LIMITED$IN_COMPLEX_TYPE_DEF_PARTICLE = "cos-all-limited.1.2b"; + + /** + * cos-all-limited.2: See clause 2 of + * XMLSchema Structures 1.0: All Group Limited + */ + public static final String ALL_GROUP_LIMITED$CHILD_PARTICLES_MAX_LTE_1 = "cos-all-limited.2"; + + /** + * cos-applicable-facets: See + * XMLSchema Datatypes 1.0: applicable facets + */ + public static final String FACETS_APPLICABLE = "cos-applicable-facets"; // KHK: name ok? + + /** + * notation-facets: See + * http://www.w3.org/TR/xmlschema-2/#NOTATION-facets + */ + public static final String FACETS_DEPRECATED_NOTATION = "notation-facets"; + + /** + * cos-aw-intersect: See + * XMLSchema Structures 1.0: Attribute Wildcard Intersection + */ + public static final String ATTR_WILDCARD_INTERSECT = "cos-aw-intersect"; + + /** + * cos-aw-union: See + * XMLSchema Structures 1.0: Attribute Wildcard Union + */ + public static final String ATTR_WILDCARD_UNION = "cos-aw-union"; + + /** + * enumeration-required-notation: See + * XMLSchema Datatypes 1.0: Schema Component Constraint: enumeration facet value required for NOTATION + */ + public static final String ATTR_NOTATION_TYPE_FORBIDDEN = "enumeration-required-notation-attr"; + + /** + * XMLSchema Datatypes 1.0: Definition of type NOTATION + */ + public static final String ATTR_COMPATIBILITY_TARGETNS = "notation-targetns-attr"; + + /** + * cos-choice-range: See + * XMLSchema Structures 1.0: Effective Total Range (choice) + */ + public static final String CHOICE_RANGE = "cos-choice-range"; + + /** + * cos-ct-derived-ok: See + * XMLSchema Structures 1.0: Type Derivation OK (Complex) + */ + public static final String COMPLEX_TYPE_DERIVATION = "cos-ct-derived-ok"; + + /** + * cos-ct-extends: See + * XMLSchema Structures 1.0: Derivation Valid (Extension) + */ + public static final String COMPLEX_TYPE_EXTENSION = "cos-ct-extends"; + + /** + * cos-ct-extends.1.4.1: See clause 1.4.1 of + * XMLSchema Structures 1.0: Derivation Valid (Extension) + */ + public static final String COMPLEX_TYPE_EXTENSION$EXTENDING_SIMPLE_CONTENT = "cos-ct-extends.1.4.1"; + + /** + * cos-ct-extends.1.4.2.2: See clause 1.4.2.2 of + * XMLSchema Structures 1.0: Derivation Valid (Extension) + */ + public static final String COMPLEX_TYPE_EXTENSION$BOTH_ELEMEMENT_OR_MIXED = "cos-ct-extends.1.4.2.2"; + + /** + * derivation-ok-restriction.1.1: See clause 1.1 of + * XMLSchema Structures 1.0: Derivation Valid (Extension) + */ + public static final String COMPLEX_TYPE_EXTENSION$FINAL = "cos-ct-extends.1.1"; + + /** + * cos-element-consistant: See + * XMLSchema Structures 1.0: Element Declarations Consistent + */ + public static final String ELEM_CONSISTANT = "cos-element-consistent"; + + /** + * cos-equiv-class: See + * XMLSchema Structures 1.0: Substitution Group + */ + public static final String SUBST_GROUP = "cos-equiv-class"; + + /** + * cos-equiv-derived-ok-rec: See + * XMLSchema Structures 1.0: Substitution Group OK (Transitive) + */ + public static final String SUBST_GROUP_DERIVED = "cos-equiv-derived-ok-rec"; + + /** + * cos-group-emptiable: See + * XMLSchema Structures 1.0: Particle Emptiable + */ + public static final String PARTICLE_EMPTIABLE = "cos-group-emptiable"; + + /** + * cos-list-of-atomic: See + * XMLSchema Datatypes 1.0: list of atomic + */ + public static final String DATATYPE_LIST_OF_ATOMIC = "cos-list-of-atomic"; + + /** + * cos-no-circular-unions: See + * XMLSchema Datatypes 1.0: no circular unions + */ + public static final String DATATYPE_CIRCULAR_UNION = "cos-no-circular-unions"; + + /** + * cos-nonambig: See + * XMLSchema Structures 1.0: Unique Particle Attribution + */ + public static final String UNIQUE_PARTICLE_ATTRIBUTION = "cos-nonambig"; + + /** + * cos-ns-subset: See + * XMLSchema Structures 1.0: Wildcard Subset + */ + public static final String WILDCARD_SUBSET = "cos-ns-subset"; + + /** + * cos-particle-extend: See + * XMLSchema Structures 1.0: Particle Valid (Extension) + */ + public static final String PARTICLE_EXTENSION = "cos-particle-extend"; + + /** + * cos-particle-restrict: See + * XMLSchema Structures 1.0: Particle Valid (Restriction) + */ + public static final String PARTICLE_RESTRICTION = "cos-particle-restrict"; + + /** + * cos-particle-restrict.2: See clause 2 of + * XMLSchema Structures 1.0: Particle Valid (Restriction) + */ + public static final String PARTICLE_RESTRICTION$INVALID_RESTRICTION = "cos-particle-restrict.2"; + + /** + * cos-seq-range: See + * XMLSchema Structures 1.0: Effective Total Range (all and sequence) + */ + public static final String SEQUENCE_RANGE = "cos-seq-range"; + + /** + * cos-st-derived-ok: See + * XMLSchema Structures 1.0: Type Derivation OK (Simple) + */ + public static final String SIMPLE_TYPE_DERIVATION = "cos-st-derived-ok"; + + /** + * cos-st-restricts: See + * XMLSchema Structures 1.0: Derivation Valid (Restriction, Simple) + */ + public static final String SIMPLE_TYPE_RESTRICTION = "cos-st-restricts"; + + /** + * cos-st-restricts.1.1: See clause 1.1 of + * XMLSchema Structures 1.0: Derivation Valid (Restriction, Simple) + */ + public static final String SIMPLE_TYPE_RESTRICTION$ATOMIC_NOT_SIMPLE = "cos-st-restricts.1.1"; + + /** + * cos-st-restricts.2.1a: See clause 2.1 of + * XMLSchema Structures 1.0: Derivation Valid (Restriction, Simple) + */ + public static final String SIMPLE_TYPE_RESTRICTION$LIST_ITEM_NOT_SIMPLE = "cos-st-restricts.2.1a"; + + /** + * cos-st-restricts.2.1a: See clause 2.1 of + * XMLSchema Structures 1.0: Derivation Valid (Restriction, Simple) + */ + public static final String SIMPLE_TYPE_RESTRICTION$LIST_ITEM_IS_LIST = "cos-st-restricts.2.1b"; + + /** + * cos-st-restricts.2.1a: See clause 2.1 of + * XMLSchema Structures 1.0: Derivation Valid (Restriction, Simple) + */ + public static final String SIMPLE_TYPE_RESTRICTION$LIST_ITEM_IS_UNION_OF_LIST = "cos-st-restricts.2.1c"; + + /** + * cos-st-restricts.3.1: See clause 3.1 of + * XMLSchema Structures 1.0: Derivation Valid (Restriction, Simple) + */ + public static final String SIMPLE_TYPE_RESTRICTION$UNION_MEMBER_NOT_SIMPLE = "cos-st-restricts.3.1"; + + /** + * cos-valid-default: See + * XMLSchema Structures 1.0: Element Default Valid (Immediate) + */ + public static final String ELEM_DEFAULT_VALID = "cos-valid-default"; + + /** + * cos-valid-default.2.1: See clause 2.1 of + * XMLSchema Structures 1.0: Element Default Valid (Immediate) + */ + public static final String ELEM_DEFAULT_VALID$SIMPLE_TYPE_OR_MIXED = "cos-valid-default.2.1"; + + /** + * cos-valid-default.2.2.2: See clause 2.2.2 of + * XMLSchema Structures 1.0: Element Default Valid (Immediate) + */ + public static final String ELEM_DEFAULT_VALID$MIXED_AND_EMPTIABLE = "cos-valid-default.2.2.2"; + + /** + * XMLSchema Datatypes 1.0: Definitions of types ID, IDREF, IDREFS, ENTITY, ENTITIES, NOTATION + */ + public static final String ELEM_COMPATIBILITY_TYPE = "id-idref-idrefs-entity-entities-notation"; + + /** + * XMLSchema Datatypes 1.0: Definition of type NOTATION + */ + public static final String ELEM_COMPATIBILITY_TARGETNS = "notation-targetns-elem"; + + /** + * ct-props-correct: See + * XMLSchema Structures 1.0: Complex Type Definition Properties Correct + */ + public static final String COMPLEX_TYPE_PROPERTIES = "ct-props-correct"; + + /** + * ct-props-correct.2: See clause 2 of + * XMLSchema Structures 1.0: Complex Type Definition Properties Correct + */ + public static final String COMPLEX_TYPE_PROPERTIES$SIMPLE_TYPE_EXTENSION = "ct-props-correct.2"; + + /** + * ct-props-correct.4: See clause 4 of + * XMLSchema Structures 1.0: Complex Type Definition Properties Correct + */ + public static final String COMPLEX_TYPE_PROPERTIES$DUPLICATE_ATTRIBUTE = "ct-props-correct.4"; + + /** + * derivation-ok-restriction: See + * XMLSchema Structures 1.0: Derivation Valid (Restriction, Complex) + */ + public static final String COMPLEX_TYPE_RESTRICTION = "derivation-ok-restriction"; + + /** + * derivation-ok-restriction.1: See clause 1 of + * XMLSchema Structures 1.0: Derivation Valid (Restriction, Complex) + */ + public static final String COMPLEX_TYPE_RESTRICTION$FINAL = "derivation-ok-restriction.1"; + + /** + * derivation-ok-restriction.2.1.1: See clause 2.1.1 of + * XMLSchema Structures 1.0: Derivation Valid (Restriction, Complex) + */ + public static final String COMPLEX_TYPE_RESTRICTION$ATTR_REQUIRED = "derivation-ok-restriction.2.1.1"; + + /** + * derivation-ok-restriction.2.2: See clause 2.2 of + * XMLSchema Structures 1.0: Derivation Valid (Restriction, Complex) + */ + public static final String COMPLEX_TYPE_RESTRICTION$ATTR_IN_BASE_WILDCARD_SET = "derivation-ok-restriction.2.2"; + + /** + * derivation-ok-restriction.4.1: See clause 4.1 of + * XMLSchema Structures 1.0: Derivation Valid (Restriction, Complex) + */ + public static final String COMPLEX_TYPE_RESTRICTION$BASE_HAS_ATTR_WILDCARD = "derivation-ok-restriction.4.1"; + + /** + * derivation-ok-restriction.4.2: See clause 4.2 of + * XMLSchema Structures 1.0: Derivation Valid (Restriction, Complex) + */ + public static final String COMPLEX_TYPE_RESTRICTION$ATTR_WILDCARD_SUBSET = "derivation-ok-restriction.4.2"; + + /** + * derivation-ok-restriction.5.1: See clause 5.1 of + * XMLSchema Structures 1.0: Derivation Valid (Restriction, Complex) + */ + public static final String COMPLEX_TYPE_RESTRICTION$SC_AND_SIMPLE_TYPE_OR_MIXED = "derivation-ok-restriction.5.1"; + + /** + * derivation-ok-restriction.5.1.2: See clause 5.1.2 of + * XMLSchema Structures 1.0: Derivation Valid (Restriction, Complex) + */ + public static final String COMPLEX_TYPE_RESTRICTION$SC_AND_MIXED_EMPTIABLE = "derivation-ok-restriction.5.1.2"; + + /** + * derivation-ok-restriction.5.2.2.1: See clause 5.2.2.1 of + * XMLSchema Structures 1.0: Derivation Valid (Restriction, Complex) + */ + public static final String COMPLEX_TYPE_RESTRICTION$SC_NOT_DERIVED = "derivation-ok-restriction.5.2.2.1"; + + /** + * derivation-ok-restriction.5.2: See clause 5.2 of + * XMLSchema Structures 1.0: Derivation Valid (Restriction, Complex) + */ + public static final String COMPLEX_TYPE_RESTRICTION$EMPTY_AND_NOT_SIMPLE = "derivation-ok-restriction.5.2"; + + /** + * derivation-ok-restriction.5.2.2: See clause 5.2.2 of + * XMLSchema Structures 1.0: Derivation Valid (Restriction, Complex) + */ + public static final String COMPLEX_TYPE_RESTRICTION$EMPTY_AND_ELEMENT_OR_MIXED_EMPTIABLE = "derivation-ok-restriction.5.2.2"; + + /** + * derivation-ok-restriction.5.3: See clause 5.3 of + * XMLSchema Structures 1.0: Derivation Valid (Restriction, Complex) + */ + public static final String COMPLEX_TYPE_RESTRICTION$ELEMENT_OR_MIXED_AND_VALID = "derivation-ok-restriction.5.3"; + + /** + * derivation-ok-restriction.5.3a: See clause 5.3 of + * XMLSchema Structures 1.0: Derivation Valid (Restriction, Complex) + */ + public static final String COMPLEX_TYPE_RESTRICTION$ELEMENT_OR_MIXED_AND_MIXED = "derivation-ok-restriction.5.3a"; + + /** + * derivation-ok-restriction.5.3b: See clause 5.3 of + * XMLSchema Structures 1.0: Derivation Valid (Restriction, Complex) + */ + public static final String COMPLEX_TYPE_RESTRICTION$ELEMENT_OR_MIXED_AND_EMPTY = "derivation-ok-restriction.5.3b"; + + /** + * derivation-ok-restriction.5.3c: See clause 5.3 of + * XMLSchema Structures 1.0: Derivation Valid (Restriction, Complex) + */ + public static final String COMPLEX_TYPE_RESTRICTION$ELEMENT_OR_MIXED_AND_SIMPLE = "derivation-ok-restriction.5.3c"; + + /** + * e-props-correct: See + * XMLSchema Structures 1.0: Element Declaration Properties Correct + */ + public static final String ELEM_PROPERTIES = "e-props-correct"; + + /** + * e-props-correct.2: See clause 2 of + * XMLSchema Structures 1.0: Element Declaration Properties Correct + */ + public static final String ELEM_PROPERTIES$CONSTRAINT_VALID = "e-props-correct.2"; + + /** + * e-props-correct.4: See clause 4 of + * XMLSchema Structures 1.0: Element Declaration Properties Correct + */ + public static final String ELEM_PROPERTIES$SUBSTITUTION_VALID = "e-props-correct.4"; + + /** + * e-props-correct.4a: See clause 4 of + * XMLSchema Structures 1.0: Element Declaration Properties Correct + */ + public static final String ELEM_PROPERTIES$SUBSTITUTION_FINAL = "e-props-correct.4a"; + + /** + * enumeration-required-notation: See + * XMLSchema Datatypes 1.0: Schema Component Constraint: enumeration facet value required for NOTATION + */ + public static final String ELEM_NOTATION_TYPE_FORBIDDEN = "enumeration-required-notation-elem"; + + /** + * enumeration-required-notation: See + * XMLSchema Datatypes 1.0: enumeration facet value required for NOTATION + */ + public static final String DATATYPE_ENUM_NOTATION = "enumeration-required-notation"; + + /** + * enumeration-valid-restriction: See + * XMLSchema Datatypes 1.0: enumeration valid restriction + */ + public static final String DATATYPE_ENUM_RESTRICTION = "enumeration-valid-restriction"; + + /** + * fractionDigits-totalDigits: See + * XMLSchema Datatypes 1.0: fractionDigits less than or equal to totalDigits + */ + public static final String DATATYPE_FRACTION_DIGITS_LE_TOTAL_DIGITS = "fractionDigits-totalDigits"; + + /** + * fractionDigits-valid-restriction: See + * XMLSchema Datatypes 1.0: fractionDigits valid restriction + */ + public static final String DATATYPE_FRACTION_DIGITS_RESTRICTION = "fractionDigits-valid-restriction"; + + /** + * length-minLength-maxLength: See + * XMLSchema Datatypes 1.0: length and minLength or maxLength + */ + public static final String DATATYPE_LENGTH = "length-minLength-maxLength"; + + /** + * length-valid-restriction: See + * XMLSchema Datatypes 1.0: length valid restriction + */ + public static final String DATATYPE_LENGTH_RESTRICTION = "length-valid-restriction"; + + /** + * maxExclusive-valid-restriction: See + * XMLSchema Datatypes 1.0: maxExclusive valid restriction + */ + public static final String DATATYPE_MAX_EXCLUSIVE_RESTRICTION = "maxExclusive-valid-restriction"; + + /** + * maxInclusive-maxExclusive: See + * XMLSchema Datatypes 1.0: maxInclusive and maxExclusive + */ + public static final String DATATYPE_MIN_INCLUSIVE_MAX_EXCLUSIVE = "maxInclusive-maxExclusive"; + + /** + * maxInclusive-valid-restriction: See + * XMLSchema Datatypes 1.0: maxInclusive valid restriction + */ + public static final String DATATYPE_MAX_INCLUSIVE_RESTRICTION = "maxInclusive-valid-restriction"; + + /** + * maxLength-valid-restriction: See + * XMLSchema Datatypes 1.0: maxLength valid restriction + */ + public static final String DATATYPE_MAX_LENGTH_RESTRICTION = "maxLength-valid-restriction"; + + /** + * mg-props-correct: See + * XMLSchema Structures 1.0: Model Group Correct + */ + public static final String MODEL_GROUP_PROPERTIES = "mg-props-correct"; + + /** + * mg-props-correct.2: See clause 2 of + * XMLSchema Structures 1.0: Model Group Correct + */ + public static final String MODEL_GROUP_PROPERTIES$CIRCULAR = "mg-props-correct.2"; + + /** + * mgd-props-correct: See + * XMLSchema Structures 1.0: Model Group Definition Properties Correct + */ + public static final String MODEL_GROUP_DEFN_PROPERTIES = "mgd-props-correct"; + + /** + * minExclusive-less-than-equal-to-maxExclusive: See + * XMLSchema Datatypes 1.0: minExclusive <= maxExclusive + */ + public static final String DATATYPE_MIN_EXCLUSIVE_LE_MAX_EXCLUSIVE = "minExclusive-less-than-equal-to-maxExclusive"; + + /** + * minExclusive-less-than-maxInclusive: See + * XMLSchema Datatypes 1.0: minExclusive < maxInclusive + */ + public static final String DATATYPE_MIN_EXCLUSIVE_LE_MAX_INCLUSIVE = "minExclusive-less-than-maxInclusive"; + + /** + * minExclusive-valid-restriction: See + * XMLSchema Datatypes 1.0: minExclusive valid restriction + */ + public static final String DATATYPE_MIN_EXCLUSIVE_RESTRICTION = "minExclusive-valid-restriction"; + + /** + * minInclusive-less-than-equal-to-maxInclusive: See + * XMLSchema Datatypes 1.0: minInclusive <= maxInclusive + */ + public static final String DATATYPE_MIN_INCLUSIVE_LTE_MAX_INCLUSIVE = "minInclusive-less-than-equal-to-maxInclusive"; + + /** + * minInclusive-less-than-maxExclusive: See + * XMLSchema Datatypes 1.0: minInclusive < maxExclusive + */ + public static final String DATATYPE_MIN_INCLUSIVE_LE_MAX_EXCLUSIVE = "minInclusive-less-than-maxExclusive"; + + /** + * minInclusive-minExclusive: See + * XMLSchema Datatypes 1.0: minInclusive and minExclusive + */ + public static final String DATATYPE_MIN_INCLUSIVE_MIN_EXCLUSIVE = "minInclusive-minExclusive"; + + /** + * minInclusive-valid-restriction: See + * XMLSchema Datatypes 1.0: minInclusive valid restriction + */ + public static final String DATATYPE_MIN_INCLUSIVE_RESTRICTION = "minInclusive-valid-restriction"; + + /** + * minLength-less-than-equal-to-maxLength: See + * XMLSchema Datatypes 1.0: minLength <= maxLength + */ + public static final String DATATYPE_MIN_LENGTH_LE_MAX_LENGTH = "minLength-less-than-equal-to-maxLength"; + + /** + * minLength-valid-restriction: See + * XMLSchema Datatypes 1.0: minLength valid restriction + */ + public static final String DATATYPE_MIN_LENGTH_RESTRICTION = "minLength-valid-restriction"; + + /** + * n-props-correct: See + * XMLSchema Structures 1.0: Notation Declaration Correct + */ + public static final String NOTATION_PROPERTIES = "n-props-correct"; + + /** + * no-xmlns: See + * XMLSchema Structures 1.0: xmlns Not Allowed + */ + public static final String NO_XMLNS = "no-xmlns"; + + /** + * no-xsi: See + * XMLSchema Structures 1.0: xsi: Not Allowed + */ + public static final String NO_XSI = "no-xsi"; + + /** + * p-props-correct: See + * XMLSchema Structures 1.0: Particle Correct + */ + public static final String PARTICLE_PROPERTIES = "p-props-correct"; + + /** + * p-props-correct.2.1: See clause 2.1 of + * XMLSchema Structures 1.0: Particle Correct + */ + public static final String PARTICLE_PROPERTIES$MIN_LTE_MAX = "p-props-correct.2.1"; + + /** + * p-props-correct.2.2: See clause 2.2 of + * XMLSchema Structures 1.0: Particle Correct + */ + public static final String PARTICLE_PROPERTIES$MAX_GTE_1 = "p-props-correct.2.2"; + + /** + * range-ok: See + * XMLSchema Structures 1.0: Occurrence Range OK + */ + public static final String OCCURRENCE_RANGE = "range-ok"; + + /** + * range-ok.1: See clause 1 of + * XMLSchema Structures 1.0: Occurrence Range OK + */ + public static final String OCCURRENCE_RANGE$MIN_GTE_MIN = "range-ok.1"; + + /** + * range-ok.2: See clause 2 of + * XMLSchema Structures 1.0: Occurrence Range OK + */ + public static final String OCCURRENCE_RANGE$MAX_LTE_MAX = "range-ok.2"; + + /** + * rcase-MapAndSum: See + * XMLSchema Structures 1.0: Particle Derivation OK (Sequence:Choice -- MapAndSum) + */ + public static final String PARTICLE_DERIVATION_MAP_AND_SUM = "rcase-MapAndSum"; + + /** + * rcase-MapAndSum.1: See clause 1 of + * XMLSchema Structures 1.0: Particle Derivation OK (Sequence:Choice -- MapAndSum) + */ + public static final String PARTICLE_DERIVATION_MAP_AND_SUM$MAP = "rcase-MapAndSum.1"; + + /** + * rcase-MapAndSum.2a: See clause 2 of + * XMLSchema Structures 1.0: Particle Derivation OK (Sequence:Choice -- MapAndSum) + */ + public static final String PARTICLE_DERIVATION_MAP_AND_SUM$SUM_MIN_OCCURS_GTE_MIN_OCCURS = "rcase-MapAndSum.2a"; + + /** + * rcase-MapAndSum.2b: See clause 2 of + * XMLSchema Structures 1.0: Particle Derivation OK (Sequence:Choice -- MapAndSum) + */ + public static final String PARTICLE_DERIVATION_MAP_AND_SUM$SUM_MAX_OCCURS_LTE_MAX_OCCURS = "rcase-MapAndSum.2b"; + + /** + * rcase-NameAndTypeOK: See + * XMLSchema Structures 1.0: Particle Restriction OK (Elt:Elt -- NameAndTypeOK) + */ + public static final String PARTICLE_RESTRICTION_NAME_AND_TYPE = "rcase-NameAndTypeOK"; + + /** + * rcase-NameAndTypeOK.1: See clause 1 of + * XMLSchema Structures 1.0: Particle Restriction OK (Elt:Elt -- NameAndTypeOK) + */ + public static final String PARTICLE_RESTRICTION_NAME_AND_TYPE$NAME = "rcase-NameAndTypeOK.1"; + + /** + * rcase-NameAndTypeOK.2: See clause 2 of + * XMLSchema Structures 1.0: Particle Restriction OK (Elt:Elt -- NameAndTypeOK) + */ + public static final String PARTICLE_RESTRICTION_NAME_AND_TYPE$NILLABLE = "rcase-NameAndTypeOK.2"; + + /** + * rcase-NameAndTypeOK.3: See clause 3 of + * XMLSchema Structures 1.0: Particle Restriction OK (Elt:Elt -- NameAndTypeOK) + */ + //public static final String PARTICLE_RESTRICTION_NAME_AND_TYPE$NAME = "rcase-NameAndTypeOK.3"; + + /** + * rcase-NameAndTypeOK.4: See clause 4 of + * XMLSchema Structures 1.0: Particle Restriction OK (Elt:Elt -- NameAndTypeOK) + */ + public static final String PARTICLE_RESTRICTION_NAME_AND_TYPE$FIXED = "rcase-NameAndTypeOK.4"; + + /** + * rcase-NameAndTypeOK.5: See clause 5 of + * XMLSchema Structures 1.0: Particle Restriction OK (Elt:Elt -- NameAndTypeOK) + */ + public static final String PARTICLE_RESTRICTION_NAME_AND_TYPE$IDENTITY_CONSTRAINTS = "rcase-NameAndTypeOK.5"; + + /** + * rcase-NameAndTypeOK.6: See clause 6 of + * XMLSchema Structures 1.0: Particle Restriction OK (Elt:Elt -- NameAndTypeOK) + */ + public static final String PARTICLE_RESTRICTION_NAME_AND_TYPE$DISALLOWED_SUBSTITUTIONS = "rcase-NameAndTypeOK.6"; + + /** + * rcase-NameAndTypeOK.7a: See clause 7 of + * XMLSchema Structures 1.0: Particle Restriction OK (Elt:Elt -- NameAndTypeOK) + */ + public static final String PARTICLE_RESTRICTION_NAME_AND_TYPE$TYPE_VALID = "rcase-NameAndTypeOK.7a"; + + /** + * rcase-NameAndTypeOK.7b: See clause 7 of + * XMLSchema Structures 1.0: Particle Restriction OK (Elt:Elt -- NameAndTypeOK) + */ + public static final String PARTICLE_RESTRICTION_NAME_AND_TYPE$TYPE_RESTRICTED = "rcase-NameAndTypeOK.7b"; + + /** + * rcase-NSCompat: See + * XMLSchema Structures 1.0: Particle Derivation OK (Elt:Any -- NSCompat) + */ + public static final String PARTICLE_DERIVATION_NS_COMPAT = "rcase-NSCompat"; + + /** + * rcase-NSCompat.1: See clause 1 of + * XMLSchema Structures 1.0: Particle Derivation OK (Elt:Any -- NSCompat) + */ + public static final String PARTICLE_DERIVATION_NS_COMPAT$WILDCARD_VALID = "rcase-NSCompat.1"; + + /** + * rcase-NSRecurseCheckCardinality: See + * XMLSchema Structures 1.0: Particle Derivation OK (All/Choice/Sequence:Any -- NSRecurseCheckCardinality) + */ + public static final String PARTICLE_DERIVATION_NS_RECURSE = "rcase-NSRecurseCheckCardinality"; + + /** + * rcase-NSSubset: See + * XMLSchema Structures 1.0: Particle Derivation OK (Any:Any -- NSSubset) + */ + public static final String PARTICLE_DERIVATION_NS_SUBST = "rcase-NSSubset"; + + /** + * rcase-NSSubset.2: See clause 2 of + * XMLSchema Structures 1.0: Particle Derivation OK (Any:Any -- NSSubset) + */ + public static final String PARTICLE_DERIVATION_NS_SUBST$WILDCARD_SUBSET = "rcase-NSSubset.2"; + + /** + * rcase-Recurse: See + * XMLSchema Structures 1.0: Particle Derivation OK (All:All,Sequence:Sequence -- Recurse) + */ + public static final String PARTICLE_DERIVATION_RECURSE = "rcase-Recurse"; + + /** + * rcase-Recurse.2: See clause 2 of + * XMLSchema Structures 1.0: Particle Derivation OK (All:All,Sequence:Sequence -- Recurse) + */ + public static final String PARTICLE_DERIVATION_RECURSE$MAP = "rcase-Recurse.2"; + + /** + * rcase-Recurse.2.1: See clause 2.1 of + * XMLSchema Structures 1.0: Particle Derivation OK (All:All,Sequence:Sequence -- Recurse) + */ + public static final String PARTICLE_DERIVATION_RECURSE$MAP_VALID = "rcase-Recurse.2.1"; + + /** + * rcase-Recurse.2.2: See clause 2.2 of + * XMLSchema Structures 1.0: Particle Derivation OK (All:All,Sequence:Sequence -- Recurse) + */ + public static final String PARTICLE_DERIVATION_RECURSE$UNMAPPED_ARE_EMPTIABLE = "rcase-Recurse.2.2"; + + /** + * rcase-RecurseAsIfGroup: See + * XMLSchema Structures 1.0: Particle Derivation OK (Elt:All/Choice/Sequence -- RecurseAsIfGroup) + */ + public static final String PARTICLE_DERIVATION_RECURSE_GROUP = "rcase-RecurseAsIfGroup"; + + /** + * rcase-RecurseLax: See + * XMLSchema Structures 1.0: Particle Derivation OK (Choice:Choice -- RecurseLax) + */ + public static final String PARTICLE_DERIVATION_RECURSE_LAX = "rcase-RecurseLax"; + + /** + * rcase-RecurseLax.2: See clause 2 of + * XMLSchema Structures 1.0: Particle Derivation OK (Choice:Choice -- RecurseLax) + */ + public static final String PARTICLE_DERIVATION_RECURSE_LAX$MAP = "rcase-RecurseLax.2"; + + /** + * rcase-RecurseUnordered: See + * XMLSchema Structures 1.0: Particle Derivation OK (Sequence:All -- RecurseUnordered) + */ + public static final String PARTICLE_DERIVATION_RECURSE_UNORDERED = "rcase-RecurseUnordered"; + + /** + * rcase-RecurseUnordered.2: See clause 2 of + * XMLSchema Structures 1.0: Particle Derivation OK (Sequence:All -- RecurseUnordered) + */ + public static final String PARTICLE_DERIVATION_RECURSE_UNORDERED$MAP = "rcase-RecurseUnordered.2"; + + /** + * rcase-RecurseUnordered.2.1: See clause 2.1 of + * XMLSchema Structures 1.0: Particle Derivation OK (Sequence:All -- RecurseUnordered) + */ + public static final String PARTICLE_DERIVATION_RECURSE_UNORDERED$MAP_UNIQUE = "rcase-RecurseUnordered.2.1"; + + /** + * rcase-RecurseUnordered.2.2: See clause 2.2 of + * XMLSchema Structures 1.0: Particle Derivation OK (Sequence:All -- RecurseUnordered) + */ + public static final String PARTICLE_DERIVATION_RECURSE_UNORDERED$MAP_VALID = "rcase-RecurseUnordered.2.2"; + + /** + * rcase-RecurseUnordered.2.2: See clause 2.2 of + * XMLSchema Structures 1.0: Particle Derivation OK (Sequence:All -- RecurseUnordered) + */ + public static final String PARTICLE_DERIVATION_RECURSE_UNORDERED$MAP_MAX_OCCURS_1 = "rcase-RecurseUnordered.2.2a"; + + /** + * rcase-RecurseUnordered.2.3: See clause 2.3 of + * XMLSchema Structures 1.0: Particle Derivation OK (Sequence:All -- RecurseUnordered) + */ + public static final String PARTICLE_DERIVATION_RECURSE_UNORDERED$UNMAPPED_ARE_EMPTIABLE = "rcase-RecurseUnordered.2.3"; + + /** + * sch-props-correct: See + * XMLSchema Structures 1.0: Schema Properties Correct + */ + public static final String SCHEMA_PROPERTIES = "sch-props-correct"; + + /** + * sch-props-correct.2: See clause 2 of + * XMLSchema Structures 1.0: Schema Properties Correct + */ + public static final String SCHEMA_PROPERTIES$DUPLICATE = "sch-props-correct.2"; + + /** + * st-props-correct: See + * XMLSchema Structures 1.0: Simple Type Definition Properties Correct + */ + public static final String SIMPLE_TYPE_PROPERTIES = "st-props-correct"; + + /** + * st-props-correct.3: See clause 3 of + * XMLSchema Structures 1.0: Simple Type Definition Properties Correct + */ + public static final String SIMPLE_TYPE_PROPERTIES$RESTRICTION_FINAL = "st-props-correct.3"; + + /** + * st-props-correct.4.2.1: See clause 4.2.1 of + * XMLSchema Structures 1.0: Simple Type Definition Properties Correct + */ + public static final String SIMPLE_TYPE_PROPERTIES$LIST_FINAL = "st-props-correct.4.2.1"; + + /** + * st-props-correct.4.2.2: See clause 4.2.2 of + * XMLSchema Structures 1.0: Simple Type Definition Properties Correct + */ + public static final String SIMPLE_TYPE_PROPERTIES$UNION_FINAL = "st-props-correct.4.2.2"; + + /** + * st-restrict-facets: See + * XMLSchema Structures 1.0: Simple Type Restriction (Facets) + */ + public static final String SIMPLE_TYPE_RESTRICTION_FACETS = "st-restrict-facets"; + + /** + * totalDigits-valid-restriction: See + * XMLSchema Datatypes 1.0: totalDigits valid restriction + */ + public static final String DATATYPE_TOTAL_DIGITS_RESTRICTION = "totalDigits-valid-restriction"; + + /** + * w-props-correct: See + * XMLSchema Structures 1.0: Wildcard Properties Correct + */ + public static final String WILDCARD_PROPERTIES = "w-props-correct"; + + /** + * whiteSpace-valid-restriction: See + * XMLSchema Datatypes 1.0: whiteSpace valid restriction + */ + public static final String DATATYPE_WHITESPACE_RESTRICTION = "whiteSpace-valid-restriction"; + + // + // datatypes + // + + /** + * anyURI: See + * XMLSchema Datatypes 1.0: anyURI + */ + public static final String ANYURI = "anyURI"; + + /** + * base64Binary: See + * XMLSchema Datatypes 1.0: base64Binary + */ + public static final String BASE64BINARY = "base64Binary"; + + /** + * boolean: See + * XMLSchema Datatypes 1.0: boolean + */ + public static final String BOOLEAN = "boolean"; + + /** + * date: See + * XMLSchema Datatypes 1.0: date + */ + public static final String DATE = "date"; + + /** + * decimal: See + * XMLSchema Datatypes 1.0: decimal + */ + public static final String DECIMAL = "decimal"; + + /** + * double: See + * XMLSchema Datatypes 1.0: double + */ + public static final String DOUBLE = "double"; + + /** + * duration: See + * XMLSchema Datatypes 1.0: duration + */ + public static final String DURATION = "duration"; + + /** + * float: See + * XMLSchema Datatypes 1.0: float + */ + public static final String FLOAT = "float"; + + /** + * hexBinary: See + * XMLSchema Datatypes 1.0: hexBinary + */ + public static final String HEXBINARY = "hexBinary"; + + /** + * int: See + * XMLSchema Datatypes 1.0: int + */ + public static final String INT = "int"; + + /** + * integer: See + * XMLSchema Datatypes 1.0: integer + */ + public static final String INTEGER = "integer"; + + /** + * list: See + * XMLSchema Datatypes 1.0: list + */ + public static final String LIST = "list"; + + /** + * long: See + * XMLSchema Datatypes 1.0: long + */ + public static final String LONG = "long"; + + /** + * NCName: See + * XMLSchema Datatypes 1.0: NCName + */ + public static final String NCNAME = "NCName"; + + /** + * NMTOKEN: See + * XMLSchema Datatypes 1.0: NMTOKEN + */ + public static final String NMTOKEN = "NMTOKEN"; + + /** + * QName: See + * XMLSchema Datatypes 1.0: QName + */ + public static final String QNAME = "QName"; + + /** + * union: See + * XMLSchema Datatypes 1.0: union + */ + public static final String UNION = "union"; + + // + // following error codes aren't defined by the XMLSchema spec + // + + /** + * Found an attribute during validation that was declared use='prohibited': + * See second NOTE at the end of 3.4.2 XML Representation of Complex Type Definitions. + * + *

    + * NOTE: + * The only substantive function of the value prohibited for the + * use attribute of an <attribute> is in establishing + * the correspondence between a complex type defined by restriction and its XML + * representation. It serves to prevent inheritance of an identically named attribute + * use from the {base type definition}. + * Such an <attribute> + * does not correspond to any component, and hence there is no interaction with either explicit + * or inherited wildcards in the operation of Complex Type Definition Validation Rules (3.4.4) + * or Constraints on Complex Type Definition Schema Components (3.4.6). + *
    + */ + public static final String ELEM_COMPLEX_TYPE_LOCALLY_VALID$PROHIBITED_ATTRIBUTE = "cvc-complex-type.prohibited-attribute"; + + /** + * + */ + public static final String SOAPARRAY = "soaparray"; + + /** + * + */ + public static final String FACET_FIXED = "facet-fixed"; + + /** + * + */ + public static final String PATTERN_REGEX = "pattern-regex"; + + /** + * + */ + public static final String MISSING_NAME = "missing-name"; + + /** + * + */ + public static final String RESERVED_TYPE_NAME = "reserved-type-name"; + + /** + * Error code for an invalid attribute value. + */ + public static final String INVALID_VALUE = "invalid-value"; + + /** + * Error code for an invalid attribute value. + */ + public static final String INVALID_VALUE_DETAIL = "invalid-value-detail"; + + /** + * + */ + public static final String INVALID_XPATH = "invalid-xpath"; +} diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlException.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlException.java new file mode 100644 index 000000000..de3474863 --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlException.java @@ -0,0 +1,111 @@ +/* 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; + +import java.util.List; +import java.util.Collections; +import java.util.Collection; +import java.util.ArrayList; + +/** + * A checked exception that can be thrown while processing, + * parsing, or compiling XML. May contain any number of {@link XmlError} + * objects. + *

    + * @see XmlError + * @see XmlRuntimeException + */ +public class XmlException extends Exception +{ + private static final long serialVersionUID = 1L; + + /** + * Constructs an XmlException from a message. + */ + public XmlException ( String m ) { super( m ); } + + /** + * Constructs an XmlException from a message and a cause. + */ + public XmlException ( String m, Throwable t ) { super( m, t ); } + + /** + * Constructs an XmlException from a cause. + */ + public XmlException ( Throwable t ) { super( t ); } + + /** + * Constructs an XmlException from an {@link XmlError}. + */ + public XmlException ( XmlError error ) + { + this( error.toString(), null, error ); + } + + /** + * Constructs an XmlException from a message, a cause, and an {@link XmlError}. + */ + public XmlException ( String m, Throwable t, XmlError error ) + { + this( m, t, Collections.singletonList( error ) ); + } + + /** + * Constructs an XmlException from a message, a cause, and a collection of {@link XmlError XmlErrors}. + */ + public XmlException ( String m, Throwable t, Collection errors ) + { + super( m, t ); + + if (errors != null) + _errors = Collections.unmodifiableList( new ArrayList( errors ) ); + } + + /** + * Constructs an XmlException from an {@link XmlRuntimeException}. + */ + public XmlException ( XmlRuntimeException xmlRuntimeException ) + { + super( + xmlRuntimeException.getMessage(), xmlRuntimeException.getCause() ); + + Collection errors = xmlRuntimeException.getErrors(); + + if (errors != null) + _errors = Collections.unmodifiableList( new ArrayList( errors ) ); + } + + /** + * Returns the first {@link XmlError XmlErrors} that caused the exception, if any. + */ + public XmlError getError ( ) + { + if (_errors == null || _errors.size() == 0) + return null; + + return (XmlError) _errors.get( 0 ); + } + + /** + * Returns the collection of {@link XmlError XmlErrors} that caused the exception, if any. + */ + public Collection getErrors ( ) + { + return _errors; + } + + private List _errors; +} \ No newline at end of file diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlFactoryHook.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlFactoryHook.java new file mode 100644 index 000000000..6aca07f67 --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlFactoryHook.java @@ -0,0 +1,117 @@ +/* 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; + +import org.w3c.dom.Node; +import org.w3c.dom.DOMImplementation; + +import java.io.IOException; +import java.io.InputStream; +import java.io.Reader; +import java.lang.ref.SoftReference; + +import javax.xml.stream.XMLStreamReader; + +import org.apache.xmlbeans.xml.stream.XMLInputStream; +import org.apache.xmlbeans.xml.stream.XMLStreamException; + +/** + * A hook for the XML Bean Factory mechanism. + * Provided for advanced users who wish to provide their own + * implementation of the Factory.parse methods. This is used, for example, + * to defer reading XML streams until needed. + *

    + * To use the hook, call XmlFactoryHook.ThreadContext.setHook(), passing + * your own XmlFactoryHook implementation. Then every call to a Factory + * method will be delgated to your hook. + * + *

    + * MyHook hook = new MyHook();
    + * XmlFactoryHook.ThreadContext.setHook(hook);
    + * // this results in a call to hook.parse(...)
    + * XmlObject.Factory.parse(new File("test.xml"));
    + * 
    + * + * If the hook needs to turn around and invoke the built-in parsers, then + * it should do so by calling the appropriate method on the passed + * SchemaTypeLoader. Since SchemaTypeLoader.parse() methods delegate + * to the registered hook, a hook that wishes to actually invoke the + * default parser without having itself called back again should + * unregister itself before calling loader.parse(), and then re-register + * itself again after the call. + *
    + * void parse(SchemaTypeLoader loader, ...)
    + * {
    + *     XmlFactoryHook remember = XmlFactoryHook.ThreadContext.getHook();
    + *     XmlFactoryHook.ThreadContext.setHook(null);
    + *     loader.parse(...); // isn't hooked.
    + *     XmlFactoryHook.ThreadContext.setHook(remember);
    + * }
    + * 
    + */ +public interface XmlFactoryHook +{ + /** Hooks Factory.newInstance calls */ + public XmlObject newInstance ( SchemaTypeLoader loader, SchemaType type, XmlOptions options ); + /** Hooks Factory.parse calls */ + public XmlObject parse ( SchemaTypeLoader loader, String xmlText, SchemaType type, XmlOptions options ) throws XmlException; + /** Hooks Factory.parse calls */ + public XmlObject parse ( SchemaTypeLoader loader, InputStream jiois, SchemaType type, XmlOptions options ) throws XmlException, IOException; + /** Hooks Factory.parse calls */ + public XmlObject parse ( SchemaTypeLoader loader, XMLStreamReader xsr, SchemaType type, XmlOptions options ) throws XmlException; + /** Hooks Factory.parse calls */ + public XmlObject parse ( SchemaTypeLoader loader, Reader jior, SchemaType type, XmlOptions options ) throws XmlException, IOException; + /** Hooks Factory.parse calls */ + public XmlObject parse ( SchemaTypeLoader loader, Node node, SchemaType type, XmlOptions options ) throws XmlException; + /** Hooks Factory.parse calls + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public XmlObject parse ( SchemaTypeLoader loader, XMLInputStream xis, SchemaType type, XmlOptions options ) throws XmlException, XMLStreamException; + /** Hooks Factory.newXmlSaxHandler calls */ + public XmlSaxHandler newXmlSaxHandler ( SchemaTypeLoader loader, SchemaType type, XmlOptions options ); + /** Hooks Factory.newDomImplementation calls */ + public DOMImplementation newDomImplementation ( SchemaTypeLoader loader, XmlOptions options ); + + /** + * Used to manage the XmlFactoryHook for the current thread. + */ + public final static class ThreadContext + { + private static ThreadLocal threadHook = new ThreadLocal(); + + /** + * Returns the current thread's hook, or null if none. + */ + public static XmlFactoryHook getHook() + { + SoftReference softRef = (SoftReference)threadHook.get(); + return softRef==null ? null : (XmlFactoryHook)softRef.get(); + } + + /** + * Sets the hook for the current thread. + */ + public static void setHook(XmlFactoryHook hook) + { + threadHook.set(new SoftReference(hook)); + } + + // provided to prevent unwanted construction + private ThreadContext() + { + } + } +} diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlFloat.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlFloat.java new file mode 100644 index 000000000..23dd2eb6d --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlFloat.java @@ -0,0 +1,149 @@ +/* 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; + +import javax.xml.stream.XMLStreamReader; + + +/** + * Corresponds to the XML Schema + * xs:float type. + *

    + * Naturally, convertible to a Java float. + */ +public interface XmlFloat extends XmlAnySimpleType +{ + /** The constant {@link SchemaType} object representing this schema type. */ + public static final SchemaType type = XmlBeans.getBuiltinTypeSystem().typeForHandle("_BI_float"); + + /** Returns this value as a float */ + float getFloatValue(); + /** Sets this value as a float */ + void setFloatValue(float v); + + /** + * Returns this value as a float + * @deprecated replaced by {@link #getFloatValue} + **/ + float floatValue(); + /** + * Sets this value as a float + * @deprecated replaced by {@link #setFloatValue} + **/ + void set(float v); + + /** + * A class with methods for creating instances + * of {@link XmlFloat}. + */ + public static final class Factory + { + /** Creates an empty instance of {@link XmlFloat} */ + public static XmlFloat newInstance() { + return (XmlFloat) XmlBeans.getContextTypeLoader().newInstance( type, null ); } + + /** Creates an empty instance of {@link XmlFloat} */ + public static XmlFloat newInstance(org.apache.xmlbeans.XmlOptions options) { + return (XmlFloat) XmlBeans.getContextTypeLoader().newInstance( type, options ); } + + /** Creates an immutable {@link XmlFloat} value */ + public static XmlFloat newValue(Object obj) { + return (XmlFloat) type.newValue( obj ); } + + /** Parses a {@link XmlFloat} fragment from a String. For example: "<xml-fragment>12.34e+5</xml-fragment>". */ + public static XmlFloat parse(java.lang.String s) throws org.apache.xmlbeans.XmlException { + return (XmlFloat) XmlBeans.getContextTypeLoader().parse( s, type, null ); } + + /** Parses a {@link XmlFloat} fragment from a String. For example: "<xml-fragment>12.34e+5</xml-fragment>". */ + public static XmlFloat parse(java.lang.String s, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (XmlFloat) XmlBeans.getContextTypeLoader().parse( s, type, options ); } + + /** Parses a {@link XmlFloat} fragment from a File. */ + public static XmlFloat parse(java.io.File f) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlFloat) XmlBeans.getContextTypeLoader().parse( f, type, null ); } + + /** Parses a {@link XmlFloat} fragment from a File. */ + public static XmlFloat parse(java.io.File f, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlFloat) XmlBeans.getContextTypeLoader().parse( f, type, options ); } + + /** Parses a {@link XmlFloat} fragment from a URL. */ + public static XmlFloat parse(java.net.URL u) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlFloat) XmlBeans.getContextTypeLoader().parse( u, type, null ); } + + /** Parses a {@link XmlFloat} fragment from a URL. */ + public static XmlFloat parse(java.net.URL u, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlFloat) XmlBeans.getContextTypeLoader().parse( u, type, options ); } + + /** Parses a {@link XmlFloat} fragment from an InputStream. */ + public static XmlFloat parse(java.io.InputStream is) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlFloat) XmlBeans.getContextTypeLoader().parse( is, type, null ); } + + /** Parses a {@link XmlFloat} fragment from an InputStream. */ + public static XmlFloat parse(java.io.InputStream is, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlFloat) XmlBeans.getContextTypeLoader().parse( is, type, options ); } + + /** Parses a {@link XmlFloat} fragment from a Reader. */ + public static XmlFloat parse(java.io.Reader r) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlFloat) XmlBeans.getContextTypeLoader().parse( r, type, null ); } + + /** Parses a {@link XmlFloat} fragment from a Reader. */ + public static XmlFloat parse(java.io.Reader r, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlFloat) XmlBeans.getContextTypeLoader().parse( r, type, options ); } + + /** Parses a {@link XmlFloat} fragment from a DOM Node. */ + public static XmlFloat parse(org.w3c.dom.Node node) throws org.apache.xmlbeans.XmlException { + return (XmlFloat) XmlBeans.getContextTypeLoader().parse( node, type, null ); } + + /** Parses a {@link XmlFloat} fragment from a DOM Node. */ + public static XmlFloat parse(org.w3c.dom.Node node, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (XmlFloat) XmlBeans.getContextTypeLoader().parse( node, type, options ); } + + /** Parses a {@link XmlFloat} fragment from an XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XmlFloat parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (XmlFloat) XmlBeans.getContextTypeLoader().parse( xis, type, null ); } + + /** Parses a {@link XmlFloat} fragment from an XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XmlFloat parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (XmlFloat) XmlBeans.getContextTypeLoader().parse( xis, type, options ); } + + /** Parses a {@link XmlFloat} fragment from an XMLStreamReader. */ + public static XmlFloat parse(javax.xml.stream.XMLStreamReader xsr) throws org.apache.xmlbeans.XmlException { + return (XmlFloat) XmlBeans.getContextTypeLoader().parse( xsr, type, null ); } + + /** Parses a {@link XmlFloat} fragment from an XMLStreamReader. */ + public static XmlFloat parse(javax.xml.stream.XMLStreamReader xsr, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException{ + return (XmlFloat) XmlBeans.getContextTypeLoader().parse( xsr, type, options ); } + + /** Returns a validating XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, null ); } + + /** Returns a validating XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, options ); } + + private Factory() { } // No instance of this class allowed + } +} + diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlGDay.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlGDay.java new file mode 100644 index 000000000..913fdd6df --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlGDay.java @@ -0,0 +1,184 @@ +/* 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; + +import javax.xml.stream.XMLStreamReader; + + +import java.util.Calendar; + + +/** + * Corresponds to the XML Schema + * xs:gDay type. + * A gDay specifies only a day-of-month. + *

    + * Convertible to {@link Calendar}, {@link GDate}, or an int. + * + * @see XmlCalendar + * @see GDate + */ +public interface XmlGDay extends XmlAnySimpleType +{ + /** The constant {@link SchemaType} object representing this schema type. */ + public static final SchemaType type = XmlBeans.getBuiltinTypeSystem().typeForHandle("_BI_gDay"); + + /** Returns this value as a {@link Calendar} */ + Calendar getCalendarValue(); + /** Sets this value as a {@link Calendar} */ + void setCalendarValue(Calendar c); + /** Returns this value as a {@link GDate} */ + GDate getGDateValue(); + /** Sets this value as a {@link GDateSpecification} */ + void setGDateValue(GDate gd); + /** Returns this value as an int from 1-31 */ + int getIntValue(); + /** Sets this value as an int from 1-31 */ + void setIntValue(int v); + + /** + * Returns this value as a {@link Calendar} + * @deprecated replaced with {@link #getCalendarValue} + **/ + Calendar calendarValue(); + /** + * Sets this value as a {@link Calendar} + * @deprecated replaced with {@link #setCalendarValue} + **/ + void set(Calendar c); + /** + * Returns this value as a {@link GDate} + * @deprecated replaced with {@link #getGDateValue} + **/ + GDate gDateValue(); + /** + * Sets this value as a {@link GDateSpecification} + * @deprecated replaced with {@link #setGDateValue} + **/ + void set(GDateSpecification gd); + /** + * Returns this value as an int from 1-31 + * @deprecated replaced with {@link #getIntValue} + **/ + int intValue(); + /** + * Sets this value as an int from 1-31 + * @deprecated replaced with {@link #setIntValue} + **/ + void set(int v); + + /** + * A class with methods for creating instances + * of {@link XmlGDay}. + */ + public static final class Factory + { + /** Creates an empty instance of {@link XmlGDay} */ + public static XmlGDay newInstance() { + return (XmlGDay) XmlBeans.getContextTypeLoader().newInstance( type, null ); } + + /** Creates an empty instance of {@link XmlGDay} */ + public static XmlGDay newInstance(org.apache.xmlbeans.XmlOptions options) { + return (XmlGDay) XmlBeans.getContextTypeLoader().newInstance( type, options ); } + + /** Creates an immutable {@link XmlGDay} value */ + public static XmlGDay newValue(Object obj) { + return (XmlGDay) type.newValue( obj ); } + + /** Parses a {@link XmlGDay} fragment from a String. For example: "<xml-fragment>---14</xml-fragment>". */ + public static XmlGDay parse(java.lang.String s) throws org.apache.xmlbeans.XmlException { + return (XmlGDay) XmlBeans.getContextTypeLoader().parse( s, type, null ); } + + /** Parses a {@link XmlGDay} fragment from a String. For example: "<xml-fragment>---14</xml-fragment>". */ + public static XmlGDay parse(java.lang.String s, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (XmlGDay) XmlBeans.getContextTypeLoader().parse( s, type, options ); } + + /** Parses a {@link XmlGDay} fragment from a File. */ + public static XmlGDay parse(java.io.File f) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlGDay) XmlBeans.getContextTypeLoader().parse( f, type, null ); } + + /** Parses a {@link XmlGDay} fragment from a File. */ + public static XmlGDay parse(java.io.File f, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlGDay) XmlBeans.getContextTypeLoader().parse( f, type, options ); } + + /** Parses a {@link XmlGDay} fragment from a URL. */ + public static XmlGDay parse(java.net.URL u) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlGDay) XmlBeans.getContextTypeLoader().parse( u, type, null ); } + + /** Parses a {@link XmlGDay} fragment from a URL. */ + public static XmlGDay parse(java.net.URL u, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlGDay) XmlBeans.getContextTypeLoader().parse( u, type, options ); } + + /** Parses a {@link XmlGDay} fragment from an InputStream. */ + public static XmlGDay parse(java.io.InputStream is) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlGDay) XmlBeans.getContextTypeLoader().parse( is, type, null ); } + + /** Parses a {@link XmlGDay} fragment from an InputStream. */ + public static XmlGDay parse(java.io.InputStream is, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlGDay) XmlBeans.getContextTypeLoader().parse( is, type, options ); } + + /** Parses a {@link XmlGDay} fragment from a Reader. */ + public static XmlGDay parse(java.io.Reader r) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlGDay) XmlBeans.getContextTypeLoader().parse( r, type, null ); } + + /** Parses a {@link XmlGDay} fragment from a Reader. */ + public static XmlGDay parse(java.io.Reader r, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlGDay) XmlBeans.getContextTypeLoader().parse( r, type, options ); } + + /** Parses a {@link XmlGDay} fragment from a DOM Node. */ + public static XmlGDay parse(org.w3c.dom.Node node) throws org.apache.xmlbeans.XmlException { + return (XmlGDay) XmlBeans.getContextTypeLoader().parse( node, type, null ); } + + /** Parses a {@link XmlGDay} fragment from a DOM Node. */ + public static XmlGDay parse(org.w3c.dom.Node node, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (XmlGDay) XmlBeans.getContextTypeLoader().parse( node, type, options ); } + + /** Parses a {@link XmlGDay} fragment from an XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XmlGDay parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (XmlGDay) XmlBeans.getContextTypeLoader().parse( xis, type, null ); } + + /** Parses a {@link XmlGDay} fragment from an XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XmlGDay parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (XmlGDay) XmlBeans.getContextTypeLoader().parse( xis, type, options ); } + + /** Parses a {@link XmlGDay} fragment from an XMLStreamReader. */ + public static XmlGDay parse(javax.xml.stream.XMLStreamReader xsr) throws org.apache.xmlbeans.XmlException { + return (XmlGDay) XmlBeans.getContextTypeLoader().parse( xsr, type, null ); } + + /** Parses a {@link XmlGDay} fragment from an XMLStreamReader. */ + public static XmlGDay parse(javax.xml.stream.XMLStreamReader xsr, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException{ + return (XmlGDay) XmlBeans.getContextTypeLoader().parse( xsr, type, options ); } + + /** Returns a validating XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, null ); } + + /** Returns a validating XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, options ); } + + private Factory() { } // No instance of this class allowed + } +} + diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlGMonth.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlGMonth.java new file mode 100644 index 000000000..f9a310e9c --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlGMonth.java @@ -0,0 +1,184 @@ +/* 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; + +import javax.xml.stream.XMLStreamReader; + + +import java.util.Calendar; + + +/** + * Corresponds to the XML Schema + * xs:gMonth type. + * A gMonth specifies only a month-of-year. + *

    + * Convertible to {@link Calendar}, {@link GDate}, or an int. + * + * @see XmlCalendar + * @see GDate + */ +public interface XmlGMonth extends XmlAnySimpleType +{ + /** The constant {@link SchemaType} object representing this schema type. */ + public static final SchemaType type = XmlBeans.getBuiltinTypeSystem().typeForHandle("_BI_gMonth"); + + /** Returns this value as a {@link Calendar} */ + Calendar getCalendarValue(); + /** Sets this value as a {@link Calendar} */ + void setCalendarValue(Calendar c); + /** Returns this value as a {@link GDate} */ + GDate getGDateValue(); + /** Sets this value as a {@link GDateSpecification} */ + void setGDateValue(GDate gd); + /** Returns this value as an int from 1-12 */ + int getIntValue(); + /** Sets this value as an int from 1-12 */ + void setIntValue(int v); + + /** + * Returns this value as a {@link Calendar} + * @deprecated replaced with {@link #getCalendarValue} + **/ + Calendar calendarValue(); + /** + * Sets this value as a {@link Calendar} + * @deprecated replaced with {@link #setCalendarValue} + **/ + void set(Calendar c); + /** + * Returns this value as a {@link GDate} + * @deprecated replaced with {@link #getGDateValue} + **/ + GDate gDateValue(); + /** + * Sets this value as a {@link GDateSpecification} + * @deprecated replaced with {@link #setGDateValue} + **/ + void set(GDateSpecification gd); + /** + * Returns this value as an int from 1-12 + * @deprecated replaced with {@link #getIntValue} + **/ + int intValue(); + /** + * Sets this value as an int from 1-12 + * @deprecated replaced with {@link #setIntValue} + **/ + void set(int v); + + /** + * A class with methods for creating instances + * of {@link XmlGMonth}. + */ + public static final class Factory + { + /** Creates an empty instance of {@link XmlGMonth} */ + public static XmlGMonth newInstance() { + return (XmlGMonth) XmlBeans.getContextTypeLoader().newInstance( type, null ); } + + /** Creates an empty instance of {@link XmlGMonth} */ + public static XmlGMonth newInstance(org.apache.xmlbeans.XmlOptions options) { + return (XmlGMonth) XmlBeans.getContextTypeLoader().newInstance( type, options ); } + + /** Creates an immutable {@link XmlGMonth} value */ + public static XmlGMonth newValue(Object obj) { + return (XmlGMonth) type.newValue( obj ); } + + /** Parses a {@link XmlGMonth} fragment from a String. For example: "<xml-fragment>--06</xml-fragment>". */ + public static XmlGMonth parse(java.lang.String s) throws org.apache.xmlbeans.XmlException { + return (XmlGMonth) XmlBeans.getContextTypeLoader().parse( s, type, null ); } + + /** Parses a {@link XmlGMonth} fragment from a String. For example: "<xml-fragment>--06</xml-fragment>". */ + public static XmlGMonth parse(java.lang.String s, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (XmlGMonth) XmlBeans.getContextTypeLoader().parse( s, type, options ); } + + /** Parses a {@link XmlGMonth} fragment from a File. */ + public static XmlGMonth parse(java.io.File f) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlGMonth) XmlBeans.getContextTypeLoader().parse( f, type, null ); } + + /** Parses a {@link XmlGMonth} fragment from a File. */ + public static XmlGMonth parse(java.io.File f, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlGMonth) XmlBeans.getContextTypeLoader().parse( f, type, options ); } + + /** Parses a {@link XmlGMonth} fragment from a URL. */ + public static XmlGMonth parse(java.net.URL u) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlGMonth) XmlBeans.getContextTypeLoader().parse( u, type, null ); } + + /** Parses a {@link XmlGMonth} fragment from a URL. */ + public static XmlGMonth parse(java.net.URL u, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlGMonth) XmlBeans.getContextTypeLoader().parse( u, type, options ); } + + /** Parses a {@link XmlGMonth} fragment from an InputStream. */ + public static XmlGMonth parse(java.io.InputStream is) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlGMonth) XmlBeans.getContextTypeLoader().parse( is, type, null ); } + + /** Parses a {@link XmlGMonth} fragment from an InputStream. */ + public static XmlGMonth parse(java.io.InputStream is, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlGMonth) XmlBeans.getContextTypeLoader().parse( is, type, options ); } + + /** Parses a {@link XmlGMonth} fragment from a Reader. */ + public static XmlGMonth parse(java.io.Reader r) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlGMonth) XmlBeans.getContextTypeLoader().parse( r, type, null ); } + + /** Parses a {@link XmlGMonth} fragment from a Reader. */ + public static XmlGMonth parse(java.io.Reader r, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlGMonth) XmlBeans.getContextTypeLoader().parse( r, type, options ); } + + /** Parses a {@link XmlGMonth} fragment from a DOM Node. */ + public static XmlGMonth parse(org.w3c.dom.Node node) throws org.apache.xmlbeans.XmlException { + return (XmlGMonth) XmlBeans.getContextTypeLoader().parse( node, type, null ); } + + /** Parses a {@link XmlGMonth} fragment from a DOM Node. */ + public static XmlGMonth parse(org.w3c.dom.Node node, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (XmlGMonth) XmlBeans.getContextTypeLoader().parse( node, type, options ); } + + /** Parses a {@link XmlGMonth} fragment from an XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XmlGMonth parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (XmlGMonth) XmlBeans.getContextTypeLoader().parse( xis, type, null ); } + + /** Parses a {@link XmlGMonth} fragment from an XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XmlGMonth parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (XmlGMonth) XmlBeans.getContextTypeLoader().parse( xis, type, options ); } + + /** Parses a {@link XmlGMonth} fragment from an XMLStreamReader. */ + public static XmlGMonth parse(javax.xml.stream.XMLStreamReader xsr) throws org.apache.xmlbeans.XmlException { + return (XmlGMonth) XmlBeans.getContextTypeLoader().parse( xsr, type, null ); } + + /** Parses a {@link XmlGMonth} fragment from an XMLStreamReader. */ + public static XmlGMonth parse(javax.xml.stream.XMLStreamReader xsr, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException{ + return (XmlGMonth) XmlBeans.getContextTypeLoader().parse( xsr, type, options ); } + + /** Returns a validating XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, null ); } + + /** Returns a validating XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, options ); } + + private Factory() { } // No instance of this class allowed + } +} + diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlGMonthDay.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlGMonthDay.java new file mode 100644 index 000000000..20c7c7315 --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlGMonthDay.java @@ -0,0 +1,170 @@ +/* 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; + +import javax.xml.stream.XMLStreamReader; + + +import java.util.Calendar; + + +/** + * Corresponds to the XML Schema + * xs:gMonthDay type. + * A gMonthDay specifies a day of a specific month without specifying the year. + *

    + * Convertible to {@link Calendar} or {@link GDate}. + * + * @see XmlCalendar + * @see GDate + */ +public interface XmlGMonthDay extends XmlAnySimpleType +{ + /** The constant {@link SchemaType} object representing this schema type. */ + public static final SchemaType type = XmlBeans.getBuiltinTypeSystem().typeForHandle("_BI_gMonthDay"); + + /** Returns this value as a {@link Calendar} */ + Calendar getCalendarValue(); + /** Sets this value as a {@link Calendar} */ + void setCalendarValue(Calendar c); + /** Returns this value as a {@link GDate} */ + GDate getGDateValue(); + /** Sets this value as a {@link GDateSpecification} */ + void setGDateValue(GDate gd); + + /** + * Returns this value as a {@link Calendar} + * @deprecated replaced with {@link #getCalendarValue} + **/ + Calendar calendarValue(); + /** + * Sets this value as a {@link Calendar} + * @deprecated replaced with {@link #setCalendarValue} + **/ + void set(Calendar c); + /** + * Returns this value as a {@link GDate} + * @deprecated replaced with {@link #getGDateValue} + **/ + GDate gDateValue(); + /** + * Sets this value as a {@link GDateSpecification} + * @deprecated replaced with {@link #setGDateValue} + **/ + void set(GDateSpecification gd); + + /** + * A class with methods for creating instances + * of {@link XmlGMonthDay}. + */ + public static final class Factory + { + /** Creates an empty instance of {@link XmlGMonthDay} */ + public static XmlGMonthDay newInstance() { + return (XmlGMonthDay) XmlBeans.getContextTypeLoader().newInstance( type, null ); } + + /** Creates an empty instance of {@link XmlGMonthDay} */ + public static XmlGMonthDay newInstance(org.apache.xmlbeans.XmlOptions options) { + return (XmlGMonthDay) XmlBeans.getContextTypeLoader().newInstance( type, options ); } + + /** Creates an immutable {@link XmlGMonthDay} value */ + public static XmlGMonthDay newValue(Object obj) { + return (XmlGMonthDay) type.newValue( obj ); } + + /** Parses a {@link XmlGMonthDay} fragment from a String. For example: "<xml-fragment>--06-14</xml-fragment>". */ + public static XmlGMonthDay parse(java.lang.String s) throws org.apache.xmlbeans.XmlException { + return (XmlGMonthDay) XmlBeans.getContextTypeLoader().parse( s, type, null ); } + + /** Parses a {@link XmlGMonthDay} fragment from a String. For example: "<xml-fragment>--06-14</xml-fragment>". */ + public static XmlGMonthDay parse(java.lang.String s, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (XmlGMonthDay) XmlBeans.getContextTypeLoader().parse( s, type, options ); } + + /** Parses a {@link XmlGMonthDay} fragment from a File. */ + public static XmlGMonthDay parse(java.io.File f) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlGMonthDay) XmlBeans.getContextTypeLoader().parse( f, type, null ); } + + /** Parses a {@link XmlGMonthDay} fragment from a File. */ + public static XmlGMonthDay parse(java.io.File f, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlGMonthDay) XmlBeans.getContextTypeLoader().parse( f, type, options ); } + + /** Parses a {@link XmlGMonthDay} fragment from a URL. */ + public static XmlGMonthDay parse(java.net.URL u) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlGMonthDay) XmlBeans.getContextTypeLoader().parse( u, type, null ); } + + /** Parses a {@link XmlGMonthDay} fragment from a URL. */ + public static XmlGMonthDay parse(java.net.URL u, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlGMonthDay) XmlBeans.getContextTypeLoader().parse( u, type, options ); } + + /** Parses a {@link XmlGMonthDay} fragment from an InputStream. */ + public static XmlGMonthDay parse(java.io.InputStream is) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlGMonthDay) XmlBeans.getContextTypeLoader().parse( is, type, null ); } + + /** Parses a {@link XmlGMonthDay} fragment from an InputStream. */ + public static XmlGMonthDay parse(java.io.InputStream is, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlGMonthDay) XmlBeans.getContextTypeLoader().parse( is, type, options ); } + + /** Parses a {@link XmlGMonthDay} fragment from a Reader. */ + public static XmlGMonthDay parse(java.io.Reader r) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlGMonthDay) XmlBeans.getContextTypeLoader().parse( r, type, null ); } + + /** Parses a {@link XmlGMonthDay} fragment from a Reader. */ + public static XmlGMonthDay parse(java.io.Reader r, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlGMonthDay) XmlBeans.getContextTypeLoader().parse( r, type, options ); } + + /** Parses a {@link XmlGMonthDay} fragment from a DOM Node. */ + public static XmlGMonthDay parse(org.w3c.dom.Node node) throws org.apache.xmlbeans.XmlException { + return (XmlGMonthDay) XmlBeans.getContextTypeLoader().parse( node, type, null ); } + + /** Parses a {@link XmlGMonthDay} fragment from a DOM Node. */ + public static XmlGMonthDay parse(org.w3c.dom.Node node, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (XmlGMonthDay) XmlBeans.getContextTypeLoader().parse( node, type, options ); } + + /** Parses a {@link XmlGMonthDay} fragment from an XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XmlGMonthDay parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (XmlGMonthDay) XmlBeans.getContextTypeLoader().parse( xis, type, null ); } + + /** Parses a {@link XmlGMonthDay} fragment from an XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XmlGMonthDay parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (XmlGMonthDay) XmlBeans.getContextTypeLoader().parse( xis, type, options ); } + + /** Parses a {@link XmlGMonthDay} fragment from an XMLStreamReader. */ + public static XmlGMonthDay parse(javax.xml.stream.XMLStreamReader xsr) throws org.apache.xmlbeans.XmlException { + return (XmlGMonthDay) XmlBeans.getContextTypeLoader().parse( xsr, type, null ); } + + /** Parses a {@link XmlGMonthDay} fragment from an XMLStreamReader. */ + public static XmlGMonthDay parse(javax.xml.stream.XMLStreamReader xsr, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException{ + return (XmlGMonthDay) XmlBeans.getContextTypeLoader().parse( xsr, type, options ); } + + /** Returns a validating XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, null ); } + + /** Returns a validating XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, options ); } + + private Factory() { } // No instance of this class allowed + } +} + diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlGYear.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlGYear.java new file mode 100644 index 000000000..52ebb43e6 --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlGYear.java @@ -0,0 +1,184 @@ +/* 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; + +import javax.xml.stream.XMLStreamReader; + + +import java.util.Calendar; + + +/** + * Corresponds to the XML Schema + * xs:gYear type. + * A gYear specifies a Gregorian year (AD). + *

    + * Convertible to {@link Calendar}, {@link GDate}, or an int. + * + * @see XmlCalendar + * @see GDate + */ +public interface XmlGYear extends XmlAnySimpleType +{ + /** The constant {@link SchemaType} object representing this schema type. */ + public static final SchemaType type = XmlBeans.getBuiltinTypeSystem().typeForHandle("_BI_gYear"); + + /** Returns this value as a {@link Calendar} */ + Calendar getCalendarValue(); + /** Sets this value as a {@link Calendar} */ + void setCalendarValue(Calendar c); + /** Returns this value as a {@link GDate} */ + GDate getGDateValue(); + /** Sets this value as a {@link GDateSpecification} */ + void setGDateValue(GDate gd); + /** Returns this value as an int from 1-31 */ + int getIntValue(); + /** Sets this value as an int from 1-31 */ + void setIntValue(int v); + + /** + * Returns this value as a {@link Calendar} + * @deprecated replaced with {@link #getCalendarValue} + **/ + Calendar calendarValue(); + /** + * Sets this value as a {@link Calendar} + * @deprecated replaced with {@link #setCalendarValue} + **/ + void set(Calendar c); + /** + * Returns this value as a {@link GDate} + * @deprecated replaced with {@link #getGDateValue} + **/ + GDate gDateValue(); + /** + * Sets this value as a {@link GDateSpecification} + * @deprecated replaced with {@link #setGDateValue} + **/ + void set(GDateSpecification gd); + /** + * Returns this value as an int from 1-31 + * @deprecated replaced with {@link #getIntValue} + **/ + int intValue(); + /** + * Sets this value as an int from 1-31 + * @deprecated replaced with {@link #setIntValue} + **/ + void set(int v); + + /** + * A class with methods for creating instances + * of {@link XmlGYear}. + */ + public static final class Factory + { + /** Creates an empty instance of {@link XmlGYear} */ + public static XmlGYear newInstance() { + return (XmlGYear) XmlBeans.getContextTypeLoader().newInstance( type, null ); } + + /** Creates an empty instance of {@link XmlGYear} */ + public static XmlGYear newInstance(org.apache.xmlbeans.XmlOptions options) { + return (XmlGYear) XmlBeans.getContextTypeLoader().newInstance( type, options ); } + + /** Creates an immutable {@link XmlGYear} value */ + public static XmlGYear newValue(Object obj) { + return (XmlGYear) type.newValue( obj ); } + + /** Parses a {@link XmlGYear} fragment from a String. For example: "<xml-fragment>2003</xml-fragment>". */ + public static XmlGYear parse(java.lang.String s) throws org.apache.xmlbeans.XmlException { + return (XmlGYear) XmlBeans.getContextTypeLoader().parse( s, type, null ); } + + /** Parses a {@link XmlGYear} fragment from a String. For example: "<xml-fragment>2003</xml-fragment>". */ + public static XmlGYear parse(java.lang.String s, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (XmlGYear) XmlBeans.getContextTypeLoader().parse( s, type, options ); } + + /** Parses a {@link XmlGYear} fragment from a File. */ + public static XmlGYear parse(java.io.File f) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlGYear) XmlBeans.getContextTypeLoader().parse( f, type, null ); } + + /** Parses a {@link XmlGYear} fragment from a File. */ + public static XmlGYear parse(java.io.File f, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlGYear) XmlBeans.getContextTypeLoader().parse( f, type, options ); } + + /** Parses a {@link XmlGYear} fragment from a URL. */ + public static XmlGYear parse(java.net.URL u) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlGYear) XmlBeans.getContextTypeLoader().parse( u, type, null ); } + + /** Parses a {@link XmlGYear} fragment from a URL. */ + public static XmlGYear parse(java.net.URL u, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlGYear) XmlBeans.getContextTypeLoader().parse( u, type, options ); } + + /** Parses a {@link XmlGYear} fragment from an InputStream. */ + public static XmlGYear parse(java.io.InputStream is) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlGYear) XmlBeans.getContextTypeLoader().parse( is, type, null ); } + + /** Parses a {@link XmlGYear} fragment from an InputStream. */ + public static XmlGYear parse(java.io.InputStream is, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlGYear) XmlBeans.getContextTypeLoader().parse( is, type, options ); } + + /** Parses a {@link XmlGYear} fragment from a Reader. */ + public static XmlGYear parse(java.io.Reader r) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlGYear) XmlBeans.getContextTypeLoader().parse( r, type, null ); } + + /** Parses a {@link XmlGYear} fragment from a Reader. */ + public static XmlGYear parse(java.io.Reader r, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlGYear) XmlBeans.getContextTypeLoader().parse( r, type, options ); } + + /** Parses a {@link XmlGYear} fragment from a DOM Node. */ + public static XmlGYear parse(org.w3c.dom.Node node) throws org.apache.xmlbeans.XmlException { + return (XmlGYear) XmlBeans.getContextTypeLoader().parse( node, type, null ); } + + /** Parses a {@link XmlGYear} fragment from a DOM Node. */ + public static XmlGYear parse(org.w3c.dom.Node node, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (XmlGYear) XmlBeans.getContextTypeLoader().parse( node, type, options ); } + + /** Parses a {@link XmlGYear} fragment from an XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XmlGYear parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (XmlGYear) XmlBeans.getContextTypeLoader().parse( xis, type, null ); } + + /** Parses a {@link XmlGYear} fragment from an XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XmlGYear parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (XmlGYear) XmlBeans.getContextTypeLoader().parse( xis, type, options ); } + + /** Parses a {@link XmlGYear} fragment from an XMLStreamReader. */ + public static XmlGYear parse(javax.xml.stream.XMLStreamReader xsr) throws org.apache.xmlbeans.XmlException { + return (XmlGYear) XmlBeans.getContextTypeLoader().parse( xsr, type, null ); } + + /** Parses a {@link XmlGYear} fragment from an XMLStreamReader. */ + public static XmlGYear parse(javax.xml.stream.XMLStreamReader xsr, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException{ + return (XmlGYear) XmlBeans.getContextTypeLoader().parse( xsr, type, options ); } + + /** Returns a validating XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, null ); } + + /** Returns a validating XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, options ); } + + private Factory() { } // No instance of this class allowed + } +} + diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlGYearMonth.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlGYearMonth.java new file mode 100644 index 000000000..cb2f55c82 --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlGYearMonth.java @@ -0,0 +1,171 @@ +/* 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; + +import javax.xml.stream.XMLStreamReader; + + +import java.util.Date; +import java.util.Calendar; + + +/** + * Corresponds to the XML Schema + * xs:gYearMonth type. + * A gYearMonth specifies a month in a specific year. + *

    + * Convertible to {@link Calendar}, {@link GDate}. + * + * @see XmlCalendar + * @see GDate + */ +public interface XmlGYearMonth extends XmlAnySimpleType +{ + /** The constant {@link SchemaType} object representing this schema type. */ + public static final SchemaType type = XmlBeans.getBuiltinTypeSystem().typeForHandle("_BI_gYearMonth"); + + /** Returns this value as a {@link Calendar} */ + Calendar getCalendarValue(); + /** Sets this value as a {@link Calendar} */ + void setCalendarValue(Calendar c); + /** Returns this value as a {@link GDate} */ + GDate getGDateValue(); + /** Sets this value as a {@link GDateSpecification} */ + void setGDateValue(GDate gd); + + /** + * Returns this value as a {@link Calendar} + * @deprecated replaced with {@link #getCalendarValue} + **/ + Calendar calendarValue(); + /** + * Sets this value as a {@link Calendar} + * @deprecated replaced with {@link #setCalendarValue} + **/ + void set(Calendar c); + /** + * Returns this value as a {@link GDate} + * @deprecated replaced with {@link #getGDateValue} + **/ + GDate gDateValue(); + /** + * Sets this value as a {@link GDateSpecification} + * @deprecated replaced with {@link #setGDateValue} + **/ + void set(GDateSpecification gd); + + /** + * A class with methods for creating instances + * of {@link XmlGYearMonth}. + */ + public static final class Factory + { + /** Creates an empty instance of {@link XmlGYearMonth} */ + public static XmlGYearMonth newInstance() { + return (XmlGYearMonth) XmlBeans.getContextTypeLoader().newInstance( type, null ); } + + /** Creates an empty instance of {@link XmlGYearMonth} */ + public static XmlGYearMonth newInstance(org.apache.xmlbeans.XmlOptions options) { + return (XmlGYearMonth) XmlBeans.getContextTypeLoader().newInstance( type, options ); } + + /** Creates an immutable {@link XmlGYearMonth} value */ + public static XmlGYearMonth newValue(Object obj) { + return (XmlGYearMonth) type.newValue( obj ); } + + /** Parses a {@link XmlGYearMonth} fragment from a String. For example: "<xml-fragment>2003-06</xml-fragment>". */ + public static XmlGYearMonth parse(java.lang.String s) throws org.apache.xmlbeans.XmlException { + return (XmlGYearMonth) XmlBeans.getContextTypeLoader().parse( s, type, null ); } + + /** Parses a {@link XmlGYearMonth} fragment from a String. For example: "<xml-fragment>2003-06</xml-fragment>". */ + public static XmlGYearMonth parse(java.lang.String s, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (XmlGYearMonth) XmlBeans.getContextTypeLoader().parse( s, type, options ); } + + /** Parses a {@link XmlGYearMonth} fragment from a File. */ + public static XmlGYearMonth parse(java.io.File f) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlGYearMonth) XmlBeans.getContextTypeLoader().parse( f, type, null ); } + + /** Parses a {@link XmlGYearMonth} fragment from a File. */ + public static XmlGYearMonth parse(java.io.File f, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlGYearMonth) XmlBeans.getContextTypeLoader().parse( f, type, options ); } + + /** Parses a {@link XmlGYearMonth} fragment from a URL. */ + public static XmlGYearMonth parse(java.net.URL u) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlGYearMonth) XmlBeans.getContextTypeLoader().parse( u, type, null ); } + + /** Parses a {@link XmlGYearMonth} fragment from a URL. */ + public static XmlGYearMonth parse(java.net.URL u, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlGYearMonth) XmlBeans.getContextTypeLoader().parse( u, type, options ); } + + /** Parses a {@link XmlGYearMonth} fragment from an InputStream. */ + public static XmlGYearMonth parse(java.io.InputStream is) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlGYearMonth) XmlBeans.getContextTypeLoader().parse( is, type, null ); } + + /** Parses a {@link XmlGYearMonth} fragment from an InputStream. */ + public static XmlGYearMonth parse(java.io.InputStream is, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlGYearMonth) XmlBeans.getContextTypeLoader().parse( is, type, options ); } + + /** Parses a {@link XmlGYearMonth} fragment from a Reader. */ + public static XmlGYearMonth parse(java.io.Reader r) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlGYearMonth) XmlBeans.getContextTypeLoader().parse( r, type, null ); } + + /** Parses a {@link XmlGYearMonth} fragment from a Reader. */ + public static XmlGYearMonth parse(java.io.Reader r, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlGYearMonth) XmlBeans.getContextTypeLoader().parse( r, type, options ); } + + /** Parses a {@link XmlGYearMonth} fragment from a DOM Node. */ + public static XmlGYearMonth parse(org.w3c.dom.Node node) throws org.apache.xmlbeans.XmlException { + return (XmlGYearMonth) XmlBeans.getContextTypeLoader().parse( node, type, null ); } + + /** Parses a {@link XmlGYearMonth} fragment from a DOM Node. */ + public static XmlGYearMonth parse(org.w3c.dom.Node node, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (XmlGYearMonth) XmlBeans.getContextTypeLoader().parse( node, type, options ); } + + /** Parses a {@link XmlGYearMonth} fragment from an XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XmlGYearMonth parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (XmlGYearMonth) XmlBeans.getContextTypeLoader().parse( xis, type, null ); } + + /** Parses a {@link XmlGYearMonth} fragment from an XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XmlGYearMonth parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (XmlGYearMonth) XmlBeans.getContextTypeLoader().parse( xis, type, options ); } + + /** Parses a {@link XmlGYearMonth} fragment from an XMLStreamReader. */ + public static XmlGYearMonth parse(javax.xml.stream.XMLStreamReader xsr) throws org.apache.xmlbeans.XmlException { + return (XmlGYearMonth) XmlBeans.getContextTypeLoader().parse( xsr, type, null ); } + + /** Parses a {@link XmlGYearMonth} fragment from an XMLStreamReader. */ + public static XmlGYearMonth parse(javax.xml.stream.XMLStreamReader xsr, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException{ + return (XmlGYearMonth) XmlBeans.getContextTypeLoader().parse( xsr, type, options ); } + + /** Returns a validating XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, null ); } + + /** Returns a validating XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, options ); } + + private Factory() { } // No instance of this class allowed + } +} + diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlHexBinary.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlHexBinary.java new file mode 100644 index 000000000..54fd14ca7 --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlHexBinary.java @@ -0,0 +1,152 @@ +/* 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; + +import javax.xml.stream.XMLStreamReader; + + +/** + * Corresponds to the XML Schema + * xs:hexBinary type. + *

    + * Convertible to a byte array. + */ +public interface XmlHexBinary extends XmlAnySimpleType +{ + /** The constant {@link SchemaType} object representing this schema type. */ + public static final SchemaType type = XmlBeans.getBuiltinTypeSystem().typeForHandle("_BI_hexBinary"); + + /** + * Returns this value as a byte array. + * @deprecated replaced by {@link #getByteArrayValue} + **/ + byte[] byteArrayValue(); + + /** + * Sets this value as a byte array. + * @deprecated replaced by {@link #setByteArrayValue} + **/ + void set(byte[] ba); + + /** Returns this value as a byte array. **/ + byte[] getByteArrayValue(); + /** Sets this value as a byte array. */ + void setByteArrayValue(byte[] ba); + + + + /** + * A class with methods for creating instances + * of {@link XmlHexBinary}. + */ + public static final class Factory + { + /** Creates an empty instance of {@link XmlHexBinary} */ + public static XmlHexBinary newInstance() { + return (XmlHexBinary) XmlBeans.getContextTypeLoader().newInstance( type, null ); } + + /** Creates an empty instance of {@link XmlHexBinary} */ + public static XmlHexBinary newInstance(org.apache.xmlbeans.XmlOptions options) { + return (XmlHexBinary) XmlBeans.getContextTypeLoader().newInstance( type, options ); } + + /** Creates an immutable {@link XmlHexBinary} value */ + public static XmlHexBinary newValue(Object obj) { + return (XmlHexBinary) type.newValue( obj ); } + + /** Parses a {@link XmlHexBinary} fragment from a String. For example: "<xml-fragment>68656c6c6f</xml-fragment>". */ + public static XmlHexBinary parse(java.lang.String s) throws org.apache.xmlbeans.XmlException { + return (XmlHexBinary) XmlBeans.getContextTypeLoader().parse( s, type, null ); } + + /** Parses a {@link XmlHexBinary} fragment from a String. For example: "<xml-fragment>68656c6c6f</xml-fragment>". */ + public static XmlHexBinary parse(java.lang.String s, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (XmlHexBinary) XmlBeans.getContextTypeLoader().parse( s, type, options ); } + + /** Parses a {@link XmlHexBinary} fragment from a File. */ + public static XmlHexBinary parse(java.io.File f) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlHexBinary) XmlBeans.getContextTypeLoader().parse( f, type, null ); } + + /** Parses a {@link XmlHexBinary} fragment from a File. */ + public static XmlHexBinary parse(java.io.File f, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlHexBinary) XmlBeans.getContextTypeLoader().parse( f, type, options ); } + + /** Parses a {@link XmlHexBinary} fragment from a URL. */ + public static XmlHexBinary parse(java.net.URL u) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlHexBinary) XmlBeans.getContextTypeLoader().parse( u, type, null ); } + + /** Parses a {@link XmlHexBinary} fragment from a URL. */ + public static XmlHexBinary parse(java.net.URL u, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlHexBinary) XmlBeans.getContextTypeLoader().parse( u, type, options ); } + + /** Parses a {@link XmlHexBinary} fragment from an InputStream. */ + public static XmlHexBinary parse(java.io.InputStream is) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlHexBinary) XmlBeans.getContextTypeLoader().parse( is, type, null ); } + + /** Parses a {@link XmlHexBinary} fragment from an InputStream. */ + public static XmlHexBinary parse(java.io.InputStream is, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlHexBinary) XmlBeans.getContextTypeLoader().parse( is, type, options ); } + + /** Parses a {@link XmlHexBinary} fragment from a Reader. */ + public static XmlHexBinary parse(java.io.Reader r) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlHexBinary) XmlBeans.getContextTypeLoader().parse( r, type, null ); } + + /** Parses a {@link XmlHexBinary} fragment from a Reader. */ + public static XmlHexBinary parse(java.io.Reader r, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlHexBinary) XmlBeans.getContextTypeLoader().parse( r, type, options ); } + + /** Parses a {@link XmlHexBinary} fragment from a DOM Node. */ + public static XmlHexBinary parse(org.w3c.dom.Node node) throws org.apache.xmlbeans.XmlException { + return (XmlHexBinary) XmlBeans.getContextTypeLoader().parse( node, type, null ); } + + /** Parses a {@link XmlHexBinary} fragment from a DOM Node. */ + public static XmlHexBinary parse(org.w3c.dom.Node node, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (XmlHexBinary) XmlBeans.getContextTypeLoader().parse( node, type, options ); } + + /** Parses a {@link XmlHexBinary} fragment from an XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XmlHexBinary parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (XmlHexBinary) XmlBeans.getContextTypeLoader().parse( xis, type, null ); } + + /** Parses a {@link XmlHexBinary} fragment from an XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XmlHexBinary parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (XmlHexBinary) XmlBeans.getContextTypeLoader().parse( xis, type, options ); } + + /** Parses a {@link XmlHexBinary} fragment from an XMLStreamReader. */ + public static XmlHexBinary parse(javax.xml.stream.XMLStreamReader xsr) throws org.apache.xmlbeans.XmlException { + return (XmlHexBinary) XmlBeans.getContextTypeLoader().parse( xsr, type, null ); } + + /** Parses a {@link XmlHexBinary} fragment from an XMLStreamReader. */ + public static XmlHexBinary parse(javax.xml.stream.XMLStreamReader xsr, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException{ + return (XmlHexBinary) XmlBeans.getContextTypeLoader().parse( xsr, type, options ); } + + /** Returns a validating XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, null ); } + + /** Returns a validating XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, options ); } + + private Factory() { } // No instance of this class allowed + } +} + diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlID.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlID.java new file mode 100644 index 000000000..4493f7d6b --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlID.java @@ -0,0 +1,136 @@ +/* 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; + +import javax.xml.stream.XMLStreamReader; + + +/** + * Corresponds to the XML Schema + * xs:ID type. + *

    + * When validated, IDs must be unique within a document. An element + * may not have more than one attribute whose type is ID. + *

    + * Convertible to a {@link String}. + */ +public interface XmlID extends XmlNCName +{ + /** The constant {@link SchemaType} object representing this schema type. */ + public static final SchemaType type = XmlBeans.getBuiltinTypeSystem().typeForHandle("_BI_ID"); + + /** + * A class with methods for creating instances + * of {@link XmlID}. + */ + public static final class Factory + { + /** Creates an empty instance of {@link XmlID} */ + public static XmlID newInstance() { + return (XmlID) XmlBeans.getContextTypeLoader().newInstance( type, null ); } + + /** Creates an empty instance of {@link XmlID} */ + public static XmlID newInstance(org.apache.xmlbeans.XmlOptions options) { + return (XmlID) XmlBeans.getContextTypeLoader().newInstance( type, options ); } + + /** Creates an immutable {@link XmlID} value */ + public static XmlID newValue(Object obj) { + return (XmlID) type.newValue( obj ); } + + /** Parses a {@link XmlID} fragment from a String. For example: "<xml-fragment>n1</xml-fragment>". */ + public static XmlID parse(java.lang.String s) throws org.apache.xmlbeans.XmlException { + return (XmlID) XmlBeans.getContextTypeLoader().parse( s, type, null ); } + + /** Parses a {@link XmlID} fragment from a String. For example: "<xml-fragment>n1</xml-fragment>". */ + public static XmlID parse(java.lang.String s, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (XmlID) XmlBeans.getContextTypeLoader().parse( s, type, options ); } + + /** Parses a {@link XmlID} fragment from a File. */ + public static XmlID parse(java.io.File f) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlID) XmlBeans.getContextTypeLoader().parse( f, type, null ); } + + /** Parses a {@link XmlID} fragment from a File. */ + public static XmlID parse(java.io.File f, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlID) XmlBeans.getContextTypeLoader().parse( f, type, options ); } + + /** Parses a {@link XmlID} fragment from a URL. */ + public static XmlID parse(java.net.URL u) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlID) XmlBeans.getContextTypeLoader().parse( u, type, null ); } + + /** Parses a {@link XmlID} fragment from a URL. */ + public static XmlID parse(java.net.URL u, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlID) XmlBeans.getContextTypeLoader().parse( u, type, options ); } + + /** Parses a {@link XmlID} fragment from an InputStream. */ + public static XmlID parse(java.io.InputStream is) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlID) XmlBeans.getContextTypeLoader().parse( is, type, null ); } + + /** Parses a {@link XmlID} fragment from an InputStream. */ + public static XmlID parse(java.io.InputStream is, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlID) XmlBeans.getContextTypeLoader().parse( is, type, options ); } + + /** Parses a {@link XmlID} fragment from a Reader. */ + public static XmlID parse(java.io.Reader r) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlID) XmlBeans.getContextTypeLoader().parse( r, type, null ); } + + /** Parses a {@link XmlID} fragment from a Reader. */ + public static XmlID parse(java.io.Reader r, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlID) XmlBeans.getContextTypeLoader().parse( r, type, options ); } + + /** Parses a {@link XmlID} fragment from a DOM Node. */ + public static XmlID parse(org.w3c.dom.Node node) throws org.apache.xmlbeans.XmlException { + return (XmlID) XmlBeans.getContextTypeLoader().parse( node, type, null ); } + + /** Parses a {@link XmlID} fragment from a DOM Node. */ + public static XmlID parse(org.w3c.dom.Node node, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (XmlID) XmlBeans.getContextTypeLoader().parse( node, type, options ); } + + /** Parses a {@link XmlID} fragment from an XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XmlID parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (XmlID) XmlBeans.getContextTypeLoader().parse( xis, type, null ); } + + /** Parses a {@link XmlID} fragment from an XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XmlID parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (XmlID) XmlBeans.getContextTypeLoader().parse( xis, type, options ); } + + /** Parses a {@link XmlID} fragment from an XMLStreamReader. */ + public static XmlID parse(javax.xml.stream.XMLStreamReader xsr) throws org.apache.xmlbeans.XmlException { + return (XmlID) XmlBeans.getContextTypeLoader().parse( xsr, type, null ); } + + /** Parses a {@link XmlID} fragment from an XMLStreamReader. */ + public static XmlID parse(javax.xml.stream.XMLStreamReader xsr, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException{ + return (XmlID) XmlBeans.getContextTypeLoader().parse( xsr, type, options ); } + + /** Returns a validating XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, null ); } + + /** Returns a validating XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, options ); } + + private Factory() { } // No instance of this class allowed + } +} + diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlIDREF.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlIDREF.java new file mode 100644 index 000000000..6f6e7efb3 --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlIDREF.java @@ -0,0 +1,137 @@ +/* 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; + +import javax.xml.stream.XMLStreamReader; + + +/** + * Corresponds to the XML Schema + * xs:IDREF type. + *

    + * When validated, IDREF values must match an ID value that is present within + * the document. This rule is only verified when a whole document is validated + * at once. + *

    + * Convertible to a {@link String}. + */ +public interface XmlIDREF extends XmlNCName +{ + /** The constant {@link SchemaType} object representing this schema type. */ + public static final SchemaType type = XmlBeans.getBuiltinTypeSystem().typeForHandle("_BI_IDREF"); + + /** + * A class with methods for creating instances + * of {@link XmlIDREF}. + */ + public static final class Factory + { + /** Creates an empty instance of {@link XmlIDREF} */ + public static XmlIDREF newInstance() { + return (XmlIDREF) XmlBeans.getContextTypeLoader().newInstance( type, null ); } + + /** Creates an empty instance of {@link XmlIDREF} */ + public static XmlIDREF newInstance(org.apache.xmlbeans.XmlOptions options) { + return (XmlIDREF) XmlBeans.getContextTypeLoader().newInstance( type, options ); } + + /** Creates an immutable {@link XmlIDREF} value */ + public static XmlIDREF newValue(Object obj) { + return (XmlIDREF) type.newValue( obj ); } + + /** Parses a {@link XmlIDREF} fragment from a String. */ + public static XmlIDREF parse(java.lang.String s) throws org.apache.xmlbeans.XmlException { + return (XmlIDREF) XmlBeans.getContextTypeLoader().parse( s, type, null ); } + + /** Parses a {@link XmlIDREF} fragment from a String. */ + public static XmlIDREF parse(java.lang.String s, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (XmlIDREF) XmlBeans.getContextTypeLoader().parse( s, type, options ); } + + /** Parses a {@link XmlIDREF} fragment from a File. */ + public static XmlIDREF parse(java.io.File f) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlIDREF) XmlBeans.getContextTypeLoader().parse( f, type, null ); } + + /** Parses a {@link XmlIDREF} fragment from a File. */ + public static XmlIDREF parse(java.io.File f, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlIDREF) XmlBeans.getContextTypeLoader().parse( f, type, options ); } + + /** Parses a {@link XmlIDREF} fragment from a URL. */ + public static XmlIDREF parse(java.net.URL u) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlIDREF) XmlBeans.getContextTypeLoader().parse( u, type, null ); } + + /** Parses a {@link XmlIDREF} fragment from a URL. */ + public static XmlIDREF parse(java.net.URL u, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlIDREF) XmlBeans.getContextTypeLoader().parse( u, type, options ); } + + /** Parses a {@link XmlIDREF} fragment from an InputStream. */ + public static XmlIDREF parse(java.io.InputStream is) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlIDREF) XmlBeans.getContextTypeLoader().parse( is, type, null ); } + + /** Parses a {@link XmlIDREF} fragment from an InputStream. */ + public static XmlIDREF parse(java.io.InputStream is, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlIDREF) XmlBeans.getContextTypeLoader().parse( is, type, options ); } + + /** Parses a {@link XmlIDREF} fragment from a Reader. */ + public static XmlIDREF parse(java.io.Reader r) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlIDREF) XmlBeans.getContextTypeLoader().parse( r, type, null ); } + + /** Parses a {@link XmlIDREF} fragment from a Reader. */ + public static XmlIDREF parse(java.io.Reader r, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlIDREF) XmlBeans.getContextTypeLoader().parse( r, type, options ); } + + /** Parses a {@link XmlIDREF} fragment from a DOM Node. */ + public static XmlIDREF parse(org.w3c.dom.Node node) throws org.apache.xmlbeans.XmlException { + return (XmlIDREF) XmlBeans.getContextTypeLoader().parse( node, type, null ); } + + /** Parses a {@link XmlIDREF} fragment from a DOM Node. */ + public static XmlIDREF parse(org.w3c.dom.Node node, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (XmlIDREF) XmlBeans.getContextTypeLoader().parse( node, type, options ); } + + /** Parses a {@link XmlIDREF} fragment from an XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XmlIDREF parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (XmlIDREF) XmlBeans.getContextTypeLoader().parse( xis, type, null ); } + + /** Parses a {@link XmlIDREF} fragment from an XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XmlIDREF parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (XmlIDREF) XmlBeans.getContextTypeLoader().parse( xis, type, options ); } + + /** Parses a {@link XmlIDREF} fragment from an XMLStreamReader. */ + public static XmlIDREF parse(javax.xml.stream.XMLStreamReader xsr) throws org.apache.xmlbeans.XmlException { + return (XmlIDREF) XmlBeans.getContextTypeLoader().parse( xsr, type, null ); } + + /** Parses a {@link XmlIDREF} fragment from an XMLStreamReader. */ + public static XmlIDREF parse(javax.xml.stream.XMLStreamReader xsr, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException{ + return (XmlIDREF) XmlBeans.getContextTypeLoader().parse( xsr, type, options ); } + + /** Returns a validating XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, null ); } + + /** Returns a validating XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, options ); } + + private Factory() { } // No instance of this class allowed + } +} + diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlIDREFS.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlIDREFS.java new file mode 100644 index 000000000..867477291 --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlIDREFS.java @@ -0,0 +1,164 @@ +/* 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; + +import javax.xml.stream.XMLStreamReader; + + +import java.util.List; + + +/** + * Corresponds to the XML Schema + * xs:IDREFS type, + * a list type. + *

    + * When validated, IDREF values must match an ID value that is present within + * the document. This rule is only verified when a whole document is validated + * at once. + *

    + * Convertible to a {@link List}. + */ +public interface XmlIDREFS extends XmlAnySimpleType +{ + /** The constant {@link SchemaType} object representing this schema type. */ + public static final SchemaType type = XmlBeans.getBuiltinTypeSystem().typeForHandle("_BI_IDREFS"); + + /** Returns the value as a {@link List} of {@link String} values */ + List getListValue(); + /** Returns the value as a {@link List} of {@link XmlIDREF} values */ + List xgetListValue(); + /** Sets the value as a {@link List} */ + void setListValue(List l); + + /** + * Returns the value as a {@link List} of {@link String} values + * @deprecated replaced by {@link #getListValue} + **/ + List listValue(); + /** + * Returns the value as a {@link List} of {@link XmlIDREF} values + * @deprecated replaced by {@link #getListValue} + **/ + List xlistValue(); + /** + * Sets the value as a {@link List} + * @deprecated replaced by {@link #getListValue} + **/ + void set(List l); + + /** + * A class with methods for creating instances + * of {@link XmlIDREFS}. + */ + public static final class Factory + { + /** Creates an empty instance of {@link XmlIDREFS} */ + public static XmlIDREFS newInstance() { + return (XmlIDREFS) XmlBeans.getContextTypeLoader().newInstance( type, null ); } + + /** Creates an empty instance of {@link XmlIDREFS} */ + public static XmlIDREFS newInstance(org.apache.xmlbeans.XmlOptions options) { + return (XmlIDREFS) XmlBeans.getContextTypeLoader().newInstance( type, options ); } + + /** Creates an immutable {@link XmlIDREFS} value */ + public static XmlIDREFS newValue(Object obj) { + return (XmlIDREFS) type.newValue( obj ); } + + /** Parses a {@link XmlIDREFS} fragment from a String. */ + public static XmlIDREFS parse(java.lang.String s) throws org.apache.xmlbeans.XmlException { + return (XmlIDREFS) XmlBeans.getContextTypeLoader().parse( s, type, null ); } + + /** Parses a {@link XmlIDREFS} fragment from a String. */ + public static XmlIDREFS parse(java.lang.String s, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (XmlIDREFS) XmlBeans.getContextTypeLoader().parse( s, type, options ); } + + /** Parses a {@link XmlIDREFS} fragment from a File. */ + public static XmlIDREFS parse(java.io.File f) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlIDREFS) XmlBeans.getContextTypeLoader().parse( f, type, null ); } + + /** Parses a {@link XmlIDREFS} fragment from a File. */ + public static XmlIDREFS parse(java.io.File f, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlIDREFS) XmlBeans.getContextTypeLoader().parse( f, type, options ); } + + /** Parses a {@link XmlIDREFS} fragment from a URL. */ + public static XmlIDREFS parse(java.net.URL u) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlIDREFS) XmlBeans.getContextTypeLoader().parse( u, type, null ); } + + /** Parses a {@link XmlIDREFS} fragment from a URL. */ + public static XmlIDREFS parse(java.net.URL u, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlIDREFS) XmlBeans.getContextTypeLoader().parse( u, type, options ); } + + /** Parses a {@link XmlIDREFS} fragment from an InputStream. */ + public static XmlIDREFS parse(java.io.InputStream is) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlIDREFS) XmlBeans.getContextTypeLoader().parse( is, type, null ); } + + /** Parses a {@link XmlIDREFS} fragment from an InputStream. */ + public static XmlIDREFS parse(java.io.InputStream is, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlIDREFS) XmlBeans.getContextTypeLoader().parse( is, type, options ); } + + /** Parses a {@link XmlIDREFS} fragment from a Reader. */ + public static XmlIDREFS parse(java.io.Reader r) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlIDREFS) XmlBeans.getContextTypeLoader().parse( r, type, null ); } + + /** Parses a {@link XmlIDREFS} fragment from a Reader. */ + public static XmlIDREFS parse(java.io.Reader r, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlIDREFS) XmlBeans.getContextTypeLoader().parse( r, type, options ); } + + /** Parses a {@link XmlIDREFS} fragment from a DOM Node. */ + public static XmlIDREFS parse(org.w3c.dom.Node node) throws org.apache.xmlbeans.XmlException { + return (XmlIDREFS) XmlBeans.getContextTypeLoader().parse( node, type, null ); } + + /** Parses a {@link XmlIDREFS} fragment from a DOM Node. */ + public static XmlIDREFS parse(org.w3c.dom.Node node, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (XmlIDREFS) XmlBeans.getContextTypeLoader().parse( node, type, options ); } + + /** Parses a {@link XmlIDREFS} fragment from an XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XmlIDREFS parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (XmlIDREFS) XmlBeans.getContextTypeLoader().parse( xis, type, null ); } + + /** Parses a {@link XmlIDREFS} fragment from an XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XmlIDREFS parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (XmlIDREFS) XmlBeans.getContextTypeLoader().parse( xis, type, options ); } + + /** Parses a {@link XmlIDREFS} fragment from an XMLStreamReader. */ + public static XmlIDREFS parse(javax.xml.stream.XMLStreamReader xsr) throws org.apache.xmlbeans.XmlException { + return (XmlIDREFS) XmlBeans.getContextTypeLoader().parse( xsr, type, null ); } + + /** Parses a {@link XmlIDREFS} fragment from an XMLStreamReader. */ + public static XmlIDREFS parse(javax.xml.stream.XMLStreamReader xsr, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException{ + return (XmlIDREFS) XmlBeans.getContextTypeLoader().parse( xsr, type, options ); } + + /** Returns a validating XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, null ); } + + /** Returns a validating XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, options ); } + + private Factory() { } // No instance of this class allowed + } +} + diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlInt.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlInt.java new file mode 100644 index 000000000..a2b3df4d2 --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlInt.java @@ -0,0 +1,150 @@ +/* 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; + +import javax.xml.stream.XMLStreamReader; + + +/** + * Corresponds to the XML Schema + * xs:int type. + * One of the derived types based on xs:decimal. + *

    + * Naturally, convertible to a Java int. + */ +public interface XmlInt extends XmlLong +{ + /** The constant {@link SchemaType} object representing this schema type. */ + public static final SchemaType type = XmlBeans.getBuiltinTypeSystem().typeForHandle("_BI_int"); + + /** Returns this value as an int */ + int getIntValue(); + /** Sets this value as an int */ + void setIntValue(int v); + + /** + * Returns this value as an int + * @deprecated replaced with {@link #getIntValue} + **/ + int intValue(); + /** + * Sets this value as an int + * @deprecated replaced with {@link #setIntValue} + **/ + void set(int v); + + /** + * A class with methods for creating instances + * of {@link XmlInt}. + */ + public static final class Factory + { + /** Creates an empty instance of {@link XmlInt} */ + public static XmlInt newInstance() { + return (XmlInt) XmlBeans.getContextTypeLoader().newInstance( type, null ); } + + /** Creates an empty instance of {@link XmlInt} */ + public static XmlInt newInstance(org.apache.xmlbeans.XmlOptions options) { + return (XmlInt) XmlBeans.getContextTypeLoader().newInstance( type, options ); } + + /** Creates an immutable {@link XmlInt} value */ + public static XmlInt newValue(Object obj) { + return (XmlInt) type.newValue( obj ); } + + /** Parses a {@link XmlInt} fragment from a String. For example: "<xml-fragment>1234567</xml-fragment>". */ + public static XmlInt parse(java.lang.String s) throws org.apache.xmlbeans.XmlException { + return (XmlInt) XmlBeans.getContextTypeLoader().parse( s, type, null ); } + + /** Parses a {@link XmlInt} fragment from a String. For example: "<xml-fragment>1234567</xml-fragment>". */ + public static XmlInt parse(java.lang.String s, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (XmlInt) XmlBeans.getContextTypeLoader().parse( s, type, options ); } + + /** Parses a {@link XmlInt} fragment from a File. */ + public static XmlInt parse(java.io.File f) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlInt) XmlBeans.getContextTypeLoader().parse( f, type, null ); } + + /** Parses a {@link XmlInt} fragment from a File. */ + public static XmlInt parse(java.io.File f, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlInt) XmlBeans.getContextTypeLoader().parse( f, type, options ); } + + /** Parses a {@link XmlInt} fragment from a URL. */ + public static XmlInt parse(java.net.URL u) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlInt) XmlBeans.getContextTypeLoader().parse( u, type, null ); } + + /** Parses a {@link XmlInt} fragment from a URL. */ + public static XmlInt parse(java.net.URL u, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlInt) XmlBeans.getContextTypeLoader().parse( u, type, options ); } + + /** Parses a {@link XmlInt} fragment from an InputStream. */ + public static XmlInt parse(java.io.InputStream is) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlInt) XmlBeans.getContextTypeLoader().parse( is, type, null ); } + + /** Parses a {@link XmlInt} fragment from an InputStream. */ + public static XmlInt parse(java.io.InputStream is, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlInt) XmlBeans.getContextTypeLoader().parse( is, type, options ); } + + /** Parses a {@link XmlInt} fragment from a Reader. */ + public static XmlInt parse(java.io.Reader r) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlInt) XmlBeans.getContextTypeLoader().parse( r, type, null ); } + + /** Parses a {@link XmlInt} fragment from a Reader. */ + public static XmlInt parse(java.io.Reader r, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlInt) XmlBeans.getContextTypeLoader().parse( r, type, options ); } + + /** Parses a {@link XmlInt} fragment from a DOM Node. */ + public static XmlInt parse(org.w3c.dom.Node node) throws org.apache.xmlbeans.XmlException { + return (XmlInt) XmlBeans.getContextTypeLoader().parse( node, type, null ); } + + /** Parses a {@link XmlInt} fragment from a DOM Node. */ + public static XmlInt parse(org.w3c.dom.Node node, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (XmlInt) XmlBeans.getContextTypeLoader().parse( node, type, options ); } + + /** Parses a {@link XmlInt} fragment from an XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XmlInt parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (XmlInt) XmlBeans.getContextTypeLoader().parse( xis, type, null ); } + + /** Parses a {@link XmlInt} fragment from an XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XmlInt parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (XmlInt) XmlBeans.getContextTypeLoader().parse( xis, type, options ); } + + /** Parses a {@link XmlInt} fragment from an XMLStreamReader. */ + public static XmlInt parse(javax.xml.stream.XMLStreamReader xsr) throws org.apache.xmlbeans.XmlException { + return (XmlInt) XmlBeans.getContextTypeLoader().parse( xsr, type, null ); } + + /** Parses a {@link XmlInt} fragment from an XMLStreamReader. */ + public static XmlInt parse(javax.xml.stream.XMLStreamReader xsr, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException{ + return (XmlInt) XmlBeans.getContextTypeLoader().parse( xsr, type, options ); } + + /** Returns a validating XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, null ); } + + /** Returns a validating XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, options ); } + + private Factory() { } // No instance of this class allowed + } +} + diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlInteger.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlInteger.java new file mode 100644 index 000000000..dbb013e5e --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlInteger.java @@ -0,0 +1,156 @@ +/* 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; + +import javax.xml.stream.XMLStreamReader; + + +import java.math.BigInteger; + +/** + * Corresponds to the XML Schema + * xs:integer type. + * One of the derived types based on xs:decimal. + *

    + * This type should not be confused with xs:int + * or Java {@link Integer}. This type represents an arbitrary-precision integer with + * any number of digits, while a Java int or an xs:int is a 32-bit finite-precision integer. + *

    + * Convertible to a Java {@link BigInteger}. + */ +public interface XmlInteger extends XmlDecimal +{ + /** The constant {@link SchemaType} object representing this schema type. */ + public static final SchemaType type = XmlBeans.getBuiltinTypeSystem().typeForHandle("_BI_integer"); + + /** Returns this value as a {@link BigInteger} */ + BigInteger getBigIntegerValue(); + /** Sets this value as a {@link BigInteger} */ + void setBigIntegerValue(BigInteger bi); + + /** + * Returns this value as a {@link BigInteger} + * @deprecated replaced with {@link #getBigIntegerValue} + **/ + BigInteger bigIntegerValue(); + /** + * Sets this value as a {@link BigInteger} + * @deprecated replaced with {@link #setBigIntegerValue} + **/ + void set(BigInteger bi); + + /** + * A class with methods for creating instances + * of {@link XmlInteger}. + */ + public static final class Factory + { + /** Creates an empty instance of {@link XmlInteger} */ + public static XmlInteger newInstance() { + return (XmlInteger) XmlBeans.getContextTypeLoader().newInstance( type, null ); } + + /** Creates an empty instance of {@link XmlInteger} */ + public static XmlInteger newInstance(org.apache.xmlbeans.XmlOptions options) { + return (XmlInteger) XmlBeans.getContextTypeLoader().newInstance( type, options ); } + + /** Creates an immutable {@link XmlInteger} value */ + public static XmlInteger newValue(Object obj) { + return (XmlInteger) type.newValue( obj ); } + + /** Parses a {@link XmlInteger} fragment from a String. For example: "<xml-fragment>1234567890</xml-fragment>". */ + public static XmlInteger parse(java.lang.String s) throws org.apache.xmlbeans.XmlException { + return (XmlInteger) XmlBeans.getContextTypeLoader().parse( s, type, null ); } + + /** Parses a {@link XmlInteger} fragment from a String. For example: "<xml-fragment>1234567890</xml-fragment>". */ + public static XmlInteger parse(java.lang.String s, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (XmlInteger) XmlBeans.getContextTypeLoader().parse( s, type, options ); } + + /** Parses a {@link XmlInteger} fragment from a File. */ + public static XmlInteger parse(java.io.File f) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlInteger) XmlBeans.getContextTypeLoader().parse( f, type, null ); } + + /** Parses a {@link XmlInteger} fragment from a File. */ + public static XmlInteger parse(java.io.File f, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlInteger) XmlBeans.getContextTypeLoader().parse( f, type, options ); } + + /** Parses a {@link XmlInteger} fragment from a URL. */ + public static XmlInteger parse(java.net.URL u) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlInteger) XmlBeans.getContextTypeLoader().parse( u, type, null ); } + + /** Parses a {@link XmlInteger} fragment from a URL. */ + public static XmlInteger parse(java.net.URL u, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlInteger) XmlBeans.getContextTypeLoader().parse( u, type, options ); } + + /** Parses a {@link XmlInteger} fragment from an InputStream. */ + public static XmlInteger parse(java.io.InputStream is) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlInteger) XmlBeans.getContextTypeLoader().parse( is, type, null ); } + + /** Parses a {@link XmlInteger} fragment from an InputStream. */ + public static XmlInteger parse(java.io.InputStream is, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlInteger) XmlBeans.getContextTypeLoader().parse( is, type, options ); } + + /** Parses a {@link XmlInteger} fragment from a Reader. */ + public static XmlInteger parse(java.io.Reader r) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlInteger) XmlBeans.getContextTypeLoader().parse( r, type, null ); } + + /** Parses a {@link XmlInteger} fragment from a Reader. */ + public static XmlInteger parse(java.io.Reader r, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlInteger) XmlBeans.getContextTypeLoader().parse( r, type, options ); } + + /** Parses a {@link XmlInteger} fragment from a DOM Node. */ + public static XmlInteger parse(org.w3c.dom.Node node) throws org.apache.xmlbeans.XmlException { + return (XmlInteger) XmlBeans.getContextTypeLoader().parse( node, type, null ); } + + /** Parses a {@link XmlInteger} fragment from a DOM Node. */ + public static XmlInteger parse(org.w3c.dom.Node node, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (XmlInteger) XmlBeans.getContextTypeLoader().parse( node, type, options ); } + + /** Parses a {@link XmlInteger} fragment from an XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XmlInteger parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (XmlInteger) XmlBeans.getContextTypeLoader().parse( xis, type, null ); } + + /** Parses a {@link XmlInteger} fragment from an XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XmlInteger parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (XmlInteger) XmlBeans.getContextTypeLoader().parse( xis, type, options ); } + + /** Parses a {@link XmlInteger} fragment from an XMLStreamReader. */ + public static XmlInteger parse(javax.xml.stream.XMLStreamReader xsr) throws org.apache.xmlbeans.XmlException { + return (XmlInteger) XmlBeans.getContextTypeLoader().parse( xsr, type, null ); } + + /** Parses a {@link XmlInteger} fragment from an XMLStreamReader. */ + public static XmlInteger parse(javax.xml.stream.XMLStreamReader xsr, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException{ + return (XmlInteger) XmlBeans.getContextTypeLoader().parse( xsr, type, options ); } + + /** Returns a validating XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, null ); } + + /** Returns a validating XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, options ); } + + private Factory() { } // No instance of this class allowed + } +} + diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlLanguage.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlLanguage.java new file mode 100644 index 000000000..59ccc6033 --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlLanguage.java @@ -0,0 +1,135 @@ +/* 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; + +import javax.xml.stream.XMLStreamReader; + + +/** + * Corresponds to the XML Schema + * xs:language type. + *

    + * This type is intended to represent an standard ISO language code string. + *

    + * Convertible to a Java {@link String}. + */ +public interface XmlLanguage extends XmlToken +{ + /** The constant {@link SchemaType} object representing this schema type. */ + public static final SchemaType type = XmlBeans.getBuiltinTypeSystem().typeForHandle("_BI_language"); + + /** + * A class with methods for creating instances + * of {@link XmlLanguage}. + */ + public static final class Factory + { + /** Creates an empty instance of {@link XmlLanguage} */ + public static XmlLanguage newInstance() { + return (XmlLanguage) XmlBeans.getContextTypeLoader().newInstance( type, null ); } + + /** Creates an empty instance of {@link XmlLanguage} */ + public static XmlLanguage newInstance(org.apache.xmlbeans.XmlOptions options) { + return (XmlLanguage) XmlBeans.getContextTypeLoader().newInstance( type, options ); } + + /** Creates an immutable {@link XmlLanguage} value */ + public static XmlLanguage newValue(Object obj) { + return (XmlLanguage) type.newValue( obj ); } + + /** Parses a {@link XmlLanguage} fragment from a String. For example: "<xml-fragment>en-us</xml-fragment>". */ + public static XmlLanguage parse(java.lang.String s) throws org.apache.xmlbeans.XmlException { + return (XmlLanguage) XmlBeans.getContextTypeLoader().parse( s, type, null ); } + + /** Parses a {@link XmlLanguage} fragment from a String. For example: "<xml-fragment>en-us</xml-fragment>". */ + public static XmlLanguage parse(java.lang.String s, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (XmlLanguage) XmlBeans.getContextTypeLoader().parse( s, type, options ); } + + /** Parses a {@link XmlLanguage} fragment from a File. */ + public static XmlLanguage parse(java.io.File f) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlLanguage) XmlBeans.getContextTypeLoader().parse( f, type, null ); } + + /** Parses a {@link XmlLanguage} fragment from a File. */ + public static XmlLanguage parse(java.io.File f, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlLanguage) XmlBeans.getContextTypeLoader().parse( f, type, options ); } + + /** Parses a {@link XmlLanguage} fragment from a URL. */ + public static XmlLanguage parse(java.net.URL u) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlLanguage) XmlBeans.getContextTypeLoader().parse( u, type, null ); } + + /** Parses a {@link XmlLanguage} fragment from a URL. */ + public static XmlLanguage parse(java.net.URL u, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlLanguage) XmlBeans.getContextTypeLoader().parse( u, type, options ); } + + /** Parses a {@link XmlLanguage} fragment from an InputStream. */ + public static XmlLanguage parse(java.io.InputStream is) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlLanguage) XmlBeans.getContextTypeLoader().parse( is, type, null ); } + + /** Parses a {@link XmlLanguage} fragment from an InputStream. */ + public static XmlLanguage parse(java.io.InputStream is, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlLanguage) XmlBeans.getContextTypeLoader().parse( is, type, options ); } + + /** Parses a {@link XmlLanguage} fragment from a Reader. */ + public static XmlLanguage parse(java.io.Reader r) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlLanguage) XmlBeans.getContextTypeLoader().parse( r, type, null ); } + + /** Parses a {@link XmlLanguage} fragment from a Reader. */ + public static XmlLanguage parse(java.io.Reader r, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlLanguage) XmlBeans.getContextTypeLoader().parse( r, type, options ); } + + /** Parses a {@link XmlLanguage} fragment from a DOM Node. */ + public static XmlLanguage parse(org.w3c.dom.Node node) throws org.apache.xmlbeans.XmlException { + return (XmlLanguage) XmlBeans.getContextTypeLoader().parse( node, type, null ); } + + /** Parses a {@link XmlLanguage} fragment from a DOM Node. */ + public static XmlLanguage parse(org.w3c.dom.Node node, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (XmlLanguage) XmlBeans.getContextTypeLoader().parse( node, type, options ); } + + /** Parses a {@link XmlLanguage} fragment from an XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XmlLanguage parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (XmlLanguage) XmlBeans.getContextTypeLoader().parse( xis, type, null ); } + + /** Parses a {@link XmlLanguage} fragment from an XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XmlLanguage parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (XmlLanguage) XmlBeans.getContextTypeLoader().parse( xis, type, options ); } + + /** Parses a {@link XmlLanguage} fragment from an XMLStreamReader. */ + public static XmlLanguage parse(javax.xml.stream.XMLStreamReader xsr) throws org.apache.xmlbeans.XmlException { + return (XmlLanguage) XmlBeans.getContextTypeLoader().parse( xsr, type, null ); } + + /** Parses a {@link XmlLanguage} fragment from an XMLStreamReader. */ + public static XmlLanguage parse(javax.xml.stream.XMLStreamReader xsr, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException{ + return (XmlLanguage) XmlBeans.getContextTypeLoader().parse( xsr, type, options ); } + + /** Returns a validating XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, null ); } + + /** Returns a validating XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, options ); } + + private Factory() { } // No instance of this class allowed + } +} + diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlLineNumber.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlLineNumber.java new file mode 100644 index 000000000..fb22a4f94 --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlLineNumber.java @@ -0,0 +1,74 @@ +/* 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; + +import org.apache.xmlbeans.XmlCursor.XmlBookmark; + +/** + * A subclass of XmlBookmark that holds line number information. + * If a document is parsed with line numbers + * enabled, these bookmarks will be placed at appropriate locations + * within the document. + * + * @see XmlOptions#setLoadLineNumbers + */ +public class XmlLineNumber extends XmlBookmark +{ + /** + * Constructs a line number with no column or offset information. + * @param line the line number - the first line is 1 + */ + public XmlLineNumber ( int line ) { this( line, -1, -1 ); } + + /** + * Constructs a line number and column with no file offset information. + * @param line the line number - the first line is 1 + * @param line the column number - the first column is 1 + */ + public XmlLineNumber ( int line, int column ) { this( line, column, -1 ); } + + /** + * Constructs a line number and column with no file offset information. + * @param line the line number - the first line is 1 + * @param line the column number - the first column is 1 + * @param line the file character offset - the first character in the file is 0 + */ + public XmlLineNumber ( int line, int column, int offset ) + { + super( false ); + + _line = line; + _column = column; + _offset = offset; + } + + /** + * Returns the 1-based line number, or -1 if not known. + */ + public int getLine ( ) { return _line; } + + /** + * Returns the 1-based column number, or -1 if not known. + */ + public int getColumn ( ) { return _column; } + + /** + * Returns the 0-based file offset number, or -1 if not known. + */ + public int getOffset ( ) { return _offset; } + + private int _line, _column, _offset; +} diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlLong.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlLong.java new file mode 100644 index 000000000..e1f296b94 --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlLong.java @@ -0,0 +1,150 @@ +/* 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; + +import javax.xml.stream.XMLStreamReader; + + +/** + * Corresponds to the XML Schema + * xs:long type. + * One of the derived types based on xs:decimal. + *

    + * Naturally, convertible to a Java long. + */ +public interface XmlLong extends XmlInteger +{ + /** The constant {@link SchemaType} object representing this schema type. */ + public static final SchemaType type = XmlBeans.getBuiltinTypeSystem().typeForHandle("_BI_long"); + + /** Returns this value as a long */ + long getLongValue(); + /** Sets this value as a long */ + void setLongValue(long v); + + /** + * Returns this value as a long + * @deprecated replaced with {@link #getLongValue} + **/ + long longValue(); + /** + * Sets this value as a long + * @deprecated replaced with {@link #setLongValue} + **/ + void set(long v); + + /** + * A class with methods for creating instances + * of {@link XmlLong}. + */ + public static final class Factory + { + /** Creates an empty instance of {@link XmlLong} */ + public static XmlLong newInstance() { + return (XmlLong) XmlBeans.getContextTypeLoader().newInstance( type, null ); } + + /** Creates an empty instance of {@link XmlLong} */ + public static XmlLong newInstance(org.apache.xmlbeans.XmlOptions options) { + return (XmlLong) XmlBeans.getContextTypeLoader().newInstance( type, options ); } + + /** Creates an immutable {@link XmlLong} value */ + public static XmlLong newValue(Object obj) { + return (XmlLong) type.newValue( obj ); } + + /** Parses a {@link XmlLong} fragment from a String. For example: "<xml-fragment>123456789</xml-fragment>". */ + public static XmlLong parse(java.lang.String s) throws org.apache.xmlbeans.XmlException { + return (XmlLong) XmlBeans.getContextTypeLoader().parse( s, type, null ); } + + /** Parses a {@link XmlLong} fragment from a String. For example: "<xml-fragment>123456789</xml-fragment>". */ + public static XmlLong parse(java.lang.String s, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (XmlLong) XmlBeans.getContextTypeLoader().parse( s, type, options ); } + + /** Parses a {@link XmlLong} fragment from a File. */ + public static XmlLong parse(java.io.File f) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlLong) XmlBeans.getContextTypeLoader().parse( f, type, null ); } + + /** Parses a {@link XmlLong} fragment from a File. */ + public static XmlLong parse(java.io.File f, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlLong) XmlBeans.getContextTypeLoader().parse( f, type, options ); } + + /** Parses a {@link XmlLong} fragment from a URL. */ + public static XmlLong parse(java.net.URL u) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlLong) XmlBeans.getContextTypeLoader().parse( u, type, null ); } + + /** Parses a {@link XmlLong} fragment from a URL. */ + public static XmlLong parse(java.net.URL u, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlLong) XmlBeans.getContextTypeLoader().parse( u, type, options ); } + + /** Parses a {@link XmlLong} fragment from an InputStream. */ + public static XmlLong parse(java.io.InputStream is) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlLong) XmlBeans.getContextTypeLoader().parse( is, type, null ); } + + /** Parses a {@link XmlLong} fragment from an InputStream. */ + public static XmlLong parse(java.io.InputStream is, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlLong) XmlBeans.getContextTypeLoader().parse( is, type, options ); } + + /** Parses a {@link XmlLong} fragment from a Reader. */ + public static XmlLong parse(java.io.Reader r) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlLong) XmlBeans.getContextTypeLoader().parse( r, type, null ); } + + /** Parses a {@link XmlLong} fragment from a Reader. */ + public static XmlLong parse(java.io.Reader r, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlLong) XmlBeans.getContextTypeLoader().parse( r, type, options ); } + + /** Parses a {@link XmlLong} fragment from a DOM Node. */ + public static XmlLong parse(org.w3c.dom.Node node) throws org.apache.xmlbeans.XmlException { + return (XmlLong) XmlBeans.getContextTypeLoader().parse( node, type, null ); } + + /** Parses a {@link XmlLong} fragment from a DOM Node. */ + public static XmlLong parse(org.w3c.dom.Node node, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (XmlLong) XmlBeans.getContextTypeLoader().parse( node, type, options ); } + + /** Parses a {@link XmlLong} fragment from an XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XmlLong parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (XmlLong) XmlBeans.getContextTypeLoader().parse( xis, type, null ); } + + /** Parses a {@link XmlLong} fragment from an XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XmlLong parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (XmlLong) XmlBeans.getContextTypeLoader().parse( xis, type, options ); } + + /** Parses a {@link XmlLong} fragment from an XMLStreamReader. */ + public static XmlLong parse(javax.xml.stream.XMLStreamReader xsr) throws org.apache.xmlbeans.XmlException { + return (XmlLong) XmlBeans.getContextTypeLoader().parse( xsr, type, null ); } + + /** Parses a {@link XmlLong} fragment from an XMLStreamReader. */ + public static XmlLong parse(javax.xml.stream.XMLStreamReader xsr, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException{ + return (XmlLong) XmlBeans.getContextTypeLoader().parse( xsr, type, options ); } + + /** Returns a validating XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, null ); } + + /** Returns a validating XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, options ); } + + private Factory() { } // No instance of this class allowed + } +} + diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlNCName.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlNCName.java new file mode 100644 index 000000000..de819dd94 --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlNCName.java @@ -0,0 +1,139 @@ +/* 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; + +import javax.xml.stream.XMLStreamReader; + + +/** + * Corresponds to the XML Schema + * xs:Name type. + * One of the derived types based on xs:string. + *

    + * This kind of string is the same as the non-colonized strings that are used + * for XML localnames and prefixes, "my-href.2". It is just a physical + * string, however, and it should NOT be confused with {@link XmlQName}, + * which is a logical combination of localname and namespace URI. + *

    + * Convertible to {@link String}. + */ +public interface XmlNCName extends XmlName +{ + /** The constant {@link SchemaType} object representing this schema type. */ + public static final SchemaType type = XmlBeans.getBuiltinTypeSystem().typeForHandle("_BI_NCName"); + + /** + * A class with methods for creating instances + * of {@link XmlNCName}. + */ + public static final class Factory + { + /** Creates an empty instance of {@link XmlNCName} */ + public static XmlNCName newInstance() { + return (XmlNCName) XmlBeans.getContextTypeLoader().newInstance( type, null ); } + + /** Creates an empty instance of {@link XmlNCName} */ + public static XmlNCName newInstance(org.apache.xmlbeans.XmlOptions options) { + return (XmlNCName) XmlBeans.getContextTypeLoader().newInstance( type, options ); } + + /** Creates an immutable {@link XmlNCName} value */ + public static XmlNCName newValue(Object obj) { + return (XmlNCName) type.newValue( obj ); } + + /** Parses a {@link XmlNCName} fragment from a String. For example: "<xml-fragment>My-Name</xml-fragment>". */ + public static XmlNCName parse(java.lang.String s) throws org.apache.xmlbeans.XmlException { + return (XmlNCName) XmlBeans.getContextTypeLoader().parse( s, type, null ); } + + /** Parses a {@link XmlNCName} fragment from a String. For example: "<xml-fragment>My-Name</xml-fragment>". */ + public static XmlNCName parse(java.lang.String s, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (XmlNCName) XmlBeans.getContextTypeLoader().parse( s, type, options ); } + + /** Parses a {@link XmlNCName} fragment from a File. */ + public static XmlNCName parse(java.io.File f) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlNCName) XmlBeans.getContextTypeLoader().parse( f, type, null ); } + + /** Parses a {@link XmlNCName} fragment from a File. */ + public static XmlNCName parse(java.io.File f, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlNCName) XmlBeans.getContextTypeLoader().parse( f, type, options ); } + + /** Parses a {@link XmlNCName} fragment from a URL. */ + public static XmlNCName parse(java.net.URL u) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlNCName) XmlBeans.getContextTypeLoader().parse( u, type, null ); } + + /** Parses a {@link XmlNCName} fragment from a URL. */ + public static XmlNCName parse(java.net.URL u, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlNCName) XmlBeans.getContextTypeLoader().parse( u, type, options ); } + + /** Parses a {@link XmlNCName} fragment from an InputStream. */ + public static XmlNCName parse(java.io.InputStream is) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlNCName) XmlBeans.getContextTypeLoader().parse( is, type, null ); } + + /** Parses a {@link XmlNCName} fragment from an InputStream. */ + public static XmlNCName parse(java.io.InputStream is, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlNCName) XmlBeans.getContextTypeLoader().parse( is, type, options ); } + + /** Parses a {@link XmlNCName} fragment from a Reader. */ + public static XmlNCName parse(java.io.Reader r) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlNCName) XmlBeans.getContextTypeLoader().parse( r, type, null ); } + + /** Parses a {@link XmlNCName} fragment from a Reader. */ + public static XmlNCName parse(java.io.Reader r, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlNCName) XmlBeans.getContextTypeLoader().parse( r, type, options ); } + + /** Parses a {@link XmlNCName} fragment from a DOM Node. */ + public static XmlNCName parse(org.w3c.dom.Node node) throws org.apache.xmlbeans.XmlException { + return (XmlNCName) XmlBeans.getContextTypeLoader().parse( node, type, null ); } + + /** Parses a {@link XmlNCName} fragment from a DOM Node. */ + public static XmlNCName parse(org.w3c.dom.Node node, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (XmlNCName) XmlBeans.getContextTypeLoader().parse( node, type, options ); } + + /** Parses a {@link XmlNCName} fragment from an XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XmlNCName parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (XmlNCName) XmlBeans.getContextTypeLoader().parse( xis, type, null ); } + + /** Parses a {@link XmlNCName} fragment from an XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XmlNCName parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (XmlNCName) XmlBeans.getContextTypeLoader().parse( xis, type, options ); } + + /** Parses a {@link XmlNCName} fragment from an XMLStreamReader. */ + public static XmlNCName parse(javax.xml.stream.XMLStreamReader xsr) throws org.apache.xmlbeans.XmlException { + return (XmlNCName) XmlBeans.getContextTypeLoader().parse( xsr, type, null ); } + + /** Parses a {@link XmlNCName} fragment from an XMLStreamReader. */ + public static XmlNCName parse(javax.xml.stream.XMLStreamReader xsr, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException{ + return (XmlNCName) XmlBeans.getContextTypeLoader().parse( xsr, type, options ); } + + /** Returns a validating XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, null ); } + + /** Returns a validating XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, options ); } + + private Factory() { } // No instance of this class allowed + } +} + diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlNMTOKEN.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlNMTOKEN.java new file mode 100644 index 000000000..591cc43f0 --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlNMTOKEN.java @@ -0,0 +1,138 @@ +/* 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; + +import javax.xml.stream.XMLStreamReader; + + +/** + * Corresponds to the XML Schema + * xs:NMTOKEN type. + * One of the derived types based on xs:string. + *

    + * An NMTOKEN is XML's closest concept to an "identifier"; for example, + * it does not permit spaces and only limited punctuation. So NMTOKEN is + * commonly used to describe a single token or enumerated string value. + *

    + * Convertible to {@link String}. + */ +public interface XmlNMTOKEN extends XmlToken +{ + /** The constant {@link SchemaType} object representing this schema type. */ + public static final SchemaType type = XmlBeans.getBuiltinTypeSystem().typeForHandle("_BI_NMTOKEN"); + + /** + * A class with methods for creating instances + * of {@link XmlNMTOKEN}. + */ + public static final class Factory + { + /** Creates an empty instance of {@link XmlNMTOKEN} */ + public static XmlNMTOKEN newInstance() { + return (XmlNMTOKEN) XmlBeans.getContextTypeLoader().newInstance( type, null ); } + + /** Creates an empty instance of {@link XmlNMTOKEN} */ + public static XmlNMTOKEN newInstance(org.apache.xmlbeans.XmlOptions options) { + return (XmlNMTOKEN) XmlBeans.getContextTypeLoader().newInstance( type, options ); } + + /** Creates an immutable {@link XmlNMTOKEN} value */ + public static XmlNMTOKEN newValue(Object obj) { + return (XmlNMTOKEN) type.newValue( obj ); } + + /** Parses a {@link XmlNMTOKEN} fragment from a String. For example: "<xml-fragment>sample-1.2</xml-fragment>". */ + public static XmlNMTOKEN parse(java.lang.String s) throws org.apache.xmlbeans.XmlException { + return (XmlNMTOKEN) XmlBeans.getContextTypeLoader().parse( s, type, null ); } + + /** Parses a {@link XmlNMTOKEN} fragment from a String. For example: "<xml-fragment>sample-1.2</xml-fragment>". */ + public static XmlNMTOKEN parse(java.lang.String s, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (XmlNMTOKEN) XmlBeans.getContextTypeLoader().parse( s, type, options ); } + + /** Parses a {@link XmlNMTOKEN} fragment from a File. */ + public static XmlNMTOKEN parse(java.io.File f) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlNMTOKEN) XmlBeans.getContextTypeLoader().parse( f, type, null ); } + + /** Parses a {@link XmlNMTOKEN} fragment from a File. */ + public static XmlNMTOKEN parse(java.io.File f, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlNMTOKEN) XmlBeans.getContextTypeLoader().parse( f, type, options ); } + + /** Parses a {@link XmlNMTOKEN} fragment from a URL. */ + public static XmlNMTOKEN parse(java.net.URL u) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlNMTOKEN) XmlBeans.getContextTypeLoader().parse( u, type, null ); } + + /** Parses a {@link XmlNMTOKEN} fragment from a URL. */ + public static XmlNMTOKEN parse(java.net.URL u, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlNMTOKEN) XmlBeans.getContextTypeLoader().parse( u, type, options ); } + + /** Parses a {@link XmlNMTOKEN} fragment from an InputStream. */ + public static XmlNMTOKEN parse(java.io.InputStream is) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlNMTOKEN) XmlBeans.getContextTypeLoader().parse( is, type, null ); } + + /** Parses a {@link XmlNMTOKEN} fragment from an InputStream. */ + public static XmlNMTOKEN parse(java.io.InputStream is, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlNMTOKEN) XmlBeans.getContextTypeLoader().parse( is, type, options ); } + + /** Parses a {@link XmlNMTOKEN} fragment from a Reader. */ + public static XmlNMTOKEN parse(java.io.Reader r) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlNMTOKEN) XmlBeans.getContextTypeLoader().parse( r, type, null ); } + + /** Parses a {@link XmlNMTOKEN} fragment from a Reader. */ + public static XmlNMTOKEN parse(java.io.Reader r, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlNMTOKEN) XmlBeans.getContextTypeLoader().parse( r, type, options ); } + + /** Parses a {@link XmlNMTOKEN} fragment from a DOM Node. */ + public static XmlNMTOKEN parse(org.w3c.dom.Node node) throws org.apache.xmlbeans.XmlException { + return (XmlNMTOKEN) XmlBeans.getContextTypeLoader().parse( node, type, null ); } + + /** Parses a {@link XmlNMTOKEN} fragment from a DOM Node. */ + public static XmlNMTOKEN parse(org.w3c.dom.Node node, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (XmlNMTOKEN) XmlBeans.getContextTypeLoader().parse( node, type, options ); } + + /** Parses a {@link XmlNMTOKEN} fragment from an XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XmlNMTOKEN parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (XmlNMTOKEN) XmlBeans.getContextTypeLoader().parse( xis, type, null ); } + + /** Parses a {@link XmlNMTOKEN} fragment from an XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XmlNMTOKEN parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (XmlNMTOKEN) XmlBeans.getContextTypeLoader().parse( xis, type, options ); } + + /** Parses a {@link XmlNMTOKEN} fragment from an XMLStreamReader. */ + public static XmlNMTOKEN parse(javax.xml.stream.XMLStreamReader xsr) throws org.apache.xmlbeans.XmlException { + return (XmlNMTOKEN) XmlBeans.getContextTypeLoader().parse( xsr, type, null ); } + + /** Parses a {@link XmlNMTOKEN} fragment from an XMLStreamReader. */ + public static XmlNMTOKEN parse(javax.xml.stream.XMLStreamReader xsr, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException{ + return (XmlNMTOKEN) XmlBeans.getContextTypeLoader().parse( xsr, type, options ); } + + /** Returns a validating XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, null ); } + + /** Returns a validating XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, options ); } + + private Factory() { } // No instance of this class allowed + } +} + diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlNMTOKENS.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlNMTOKENS.java new file mode 100644 index 000000000..53fe2786f --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlNMTOKENS.java @@ -0,0 +1,161 @@ +/* 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; + +import javax.xml.stream.XMLStreamReader; + + +import java.util.List; + + +/** + * Corresponds to the XML Schema + * xs:NMTOKENS type, + * a list type. + *

    + * Convertible to {@link List}. + */ +public interface XmlNMTOKENS extends XmlAnySimpleType +{ + /** The constant {@link SchemaType} object representing this schema type. */ + public static final SchemaType type = XmlBeans.getBuiltinTypeSystem().typeForHandle("_BI_NMTOKENS"); + + /** Returns the value as a {@link List} of {@link String} values */ + List getListValue(); + /** Returns the value as a {@link List} of {@link XmlNMTOKEN} values */ + List xgetListValue(); + /** Sets the value as a {@link List} */ + void setListValue(List l); + + /** + * Returns the value as a {@link List} of {@link String} values + * @deprecated replaced by {@link #getListValue} + **/ + List listValue(); + /** + * Returns the value as a {@link List} of {@link XmlNMTOKEN} values + * @deprecated replaced by {@link #getListValue} + **/ + List xlistValue(); + /** + * Sets the value as a {@link List} + * @deprecated replaced by {@link #getListValue} + **/ + void set(List l); + + + /** + * A class with methods for creating instances + * of {@link XmlNMTOKENS}. + */ + public static final class Factory + { + /** Creates an empty instance of {@link XmlNMTOKENS} */ + public static XmlNMTOKENS newInstance() { + return (XmlNMTOKENS) XmlBeans.getContextTypeLoader().newInstance( type, null ); } + + /** Creates an empty instance of {@link XmlNMTOKENS} */ + public static XmlNMTOKENS newInstance(org.apache.xmlbeans.XmlOptions options) { + return (XmlNMTOKENS) XmlBeans.getContextTypeLoader().newInstance( type, options ); } + + /** Creates an immutable {@link XmlNMTOKENS} value */ + public static XmlNMTOKENS newValue(Object obj) { + return (XmlNMTOKENS) type.newValue( obj ); } + + /** Parses a {@link XmlNMTOKENS} fragment from a String. For example: "<xml-fragment>sample-1.1 sample-1.2 sample-1.3</xml-fragment>". */ + public static XmlNMTOKENS parse(java.lang.String s) throws org.apache.xmlbeans.XmlException { + return (XmlNMTOKENS) XmlBeans.getContextTypeLoader().parse( s, type, null ); } + + /** Parses a {@link XmlNMTOKENS} fragment from a String. For example: "<xml-fragment>sample-1.1 sample-1.2 sample-1.3</xml-fragment>". */ + public static XmlNMTOKENS parse(java.lang.String s, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (XmlNMTOKENS) XmlBeans.getContextTypeLoader().parse( s, type, options ); } + + /** Parses a {@link XmlNMTOKENS} fragment from a File. */ + public static XmlNMTOKENS parse(java.io.File f) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlNMTOKENS) XmlBeans.getContextTypeLoader().parse( f, type, null ); } + + /** Parses a {@link XmlNMTOKENS} fragment from a File. */ + public static XmlNMTOKENS parse(java.io.File f, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlNMTOKENS) XmlBeans.getContextTypeLoader().parse( f, type, options ); } + + /** Parses a {@link XmlNMTOKENS} fragment from a URL. */ + public static XmlNMTOKENS parse(java.net.URL u) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlNMTOKENS) XmlBeans.getContextTypeLoader().parse( u, type, null ); } + + /** Parses a {@link XmlNMTOKENS} fragment from a URL. */ + public static XmlNMTOKENS parse(java.net.URL u, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlNMTOKENS) XmlBeans.getContextTypeLoader().parse( u, type, options ); } + + /** Parses a {@link XmlNMTOKENS} fragment from an InputStream. */ + public static XmlNMTOKENS parse(java.io.InputStream is) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlNMTOKENS) XmlBeans.getContextTypeLoader().parse( is, type, null ); } + + /** Parses a {@link XmlNMTOKENS} fragment from an InputStream. */ + public static XmlNMTOKENS parse(java.io.InputStream is, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlNMTOKENS) XmlBeans.getContextTypeLoader().parse( is, type, options ); } + + /** Parses a {@link XmlNMTOKENS} fragment from a Reader. */ + public static XmlNMTOKENS parse(java.io.Reader r) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlNMTOKENS) XmlBeans.getContextTypeLoader().parse( r, type, null ); } + + /** Parses a {@link XmlNMTOKENS} fragment from a Reader. */ + public static XmlNMTOKENS parse(java.io.Reader r, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlNMTOKENS) XmlBeans.getContextTypeLoader().parse( r, type, options ); } + + /** Parses a {@link XmlNMTOKENS} fragment from a DOM Node. */ + public static XmlNMTOKENS parse(org.w3c.dom.Node node) throws org.apache.xmlbeans.XmlException { + return (XmlNMTOKENS) XmlBeans.getContextTypeLoader().parse( node, type, null ); } + + /** Parses a {@link XmlNMTOKENS} fragment from a DOM Node. */ + public static XmlNMTOKENS parse(org.w3c.dom.Node node, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (XmlNMTOKENS) XmlBeans.getContextTypeLoader().parse( node, type, options ); } + + /** Parses a {@link XmlNMTOKENS} fragment from an XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XmlNMTOKENS parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (XmlNMTOKENS) XmlBeans.getContextTypeLoader().parse( xis, type, null ); } + + /** Parses a {@link XmlNMTOKENS} fragment from an XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XmlNMTOKENS parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (XmlNMTOKENS) XmlBeans.getContextTypeLoader().parse( xis, type, options ); } + + /** Parses a {@link XmlNMTOKENS} fragment from an XMLStreamReader. */ + public static XmlNMTOKENS parse(javax.xml.stream.XMLStreamReader xsr) throws org.apache.xmlbeans.XmlException { + return (XmlNMTOKENS) XmlBeans.getContextTypeLoader().parse( xsr, type, null ); } + + /** Parses a {@link XmlNMTOKENS} fragment from an XMLStreamReader. */ + public static XmlNMTOKENS parse(javax.xml.stream.XMLStreamReader xsr, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException{ + return (XmlNMTOKENS) XmlBeans.getContextTypeLoader().parse( xsr, type, options ); } + + /** Returns a validating XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, null ); } + + /** Returns a validating XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, options ); } + + private Factory() { } // No instance of this class allowed + } +} + diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlNOTATION.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlNOTATION.java new file mode 100644 index 000000000..872955998 --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlNOTATION.java @@ -0,0 +1,137 @@ +/* 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; + +import javax.xml.stream.XMLStreamReader; + + +/** + * Corresponds to the XML Schema + * xs:NOTATION type. + *

    + * NOTATIONs are a mechanism in XML Schema that is provided + * for partial backward compatibility with NOTATIONs in DTDs. XML Schema + * users should almost never have any reason to use this data type. + *

    + * Convertible to {@link String}. + */ +public interface XmlNOTATION extends XmlAnySimpleType +{ + /** The constant {@link SchemaType} object representing this schema type. */ + public static final SchemaType type = XmlBeans.getBuiltinTypeSystem().typeForHandle("_BI_NOTATION"); + + /** + * A class with methods for creating instances + * of {@link XmlNOTATION}. + */ + public static final class Factory + { + /** Creates an empty instance of {@link XmlNOTATION} */ + public static XmlNOTATION newInstance() { + return (XmlNOTATION) XmlBeans.getContextTypeLoader().newInstance( type, null ); } + + /** Creates an empty instance of {@link XmlNOTATION} */ + public static XmlNOTATION newInstance(org.apache.xmlbeans.XmlOptions options) { + return (XmlNOTATION) XmlBeans.getContextTypeLoader().newInstance( type, options ); } + + /** Creates an immutable {@link XmlNOTATION} value */ + public static XmlNOTATION newValue(Object obj) { + return (XmlNOTATION) type.newValue( obj ); } + + /** Parses a {@link XmlNOTATION} fragment from a String. */ + public static XmlNOTATION parse(java.lang.String s) throws org.apache.xmlbeans.XmlException { + return (XmlNOTATION) XmlBeans.getContextTypeLoader().parse( s, type, null ); } + + /** Parses a {@link XmlNOTATION} fragment from a String. */ + public static XmlNOTATION parse(java.lang.String s, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (XmlNOTATION) XmlBeans.getContextTypeLoader().parse( s, type, options ); } + + /** Parses a {@link XmlNOTATION} fragment from a File. */ + public static XmlNOTATION parse(java.io.File f) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlNOTATION) XmlBeans.getContextTypeLoader().parse( f, type, null ); } + + /** Parses a {@link XmlNOTATION} fragment from a File. */ + public static XmlNOTATION parse(java.io.File f, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlNOTATION) XmlBeans.getContextTypeLoader().parse( f, type, options ); } + + /** Parses a {@link XmlNOTATION} fragment from a URL. */ + public static XmlNOTATION parse(java.net.URL u) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlNOTATION) XmlBeans.getContextTypeLoader().parse( u, type, null ); } + + /** Parses a {@link XmlNOTATION} fragment from a URL. */ + public static XmlNOTATION parse(java.net.URL u, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlNOTATION) XmlBeans.getContextTypeLoader().parse( u, type, options ); } + + /** Parses a {@link XmlNOTATION} fragment from an InputStream. */ + public static XmlNOTATION parse(java.io.InputStream is) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlNOTATION) XmlBeans.getContextTypeLoader().parse( is, type, null ); } + + /** Parses a {@link XmlNOTATION} fragment from an InputStream. */ + public static XmlNOTATION parse(java.io.InputStream is, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlNOTATION) XmlBeans.getContextTypeLoader().parse( is, type, options ); } + + /** Parses a {@link XmlNOTATION} fragment from a Reader. */ + public static XmlNOTATION parse(java.io.Reader r) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlNOTATION) XmlBeans.getContextTypeLoader().parse( r, type, null ); } + + /** Parses a {@link XmlNOTATION} fragment from a Reader. */ + public static XmlNOTATION parse(java.io.Reader r, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlNOTATION) XmlBeans.getContextTypeLoader().parse( r, type, options ); } + + /** Parses a {@link XmlNOTATION} fragment from a DOM Node. */ + public static XmlNOTATION parse(org.w3c.dom.Node node) throws org.apache.xmlbeans.XmlException { + return (XmlNOTATION) XmlBeans.getContextTypeLoader().parse( node, type, null ); } + + /** Parses a {@link XmlNOTATION} fragment from a DOM Node. */ + public static XmlNOTATION parse(org.w3c.dom.Node node, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (XmlNOTATION) XmlBeans.getContextTypeLoader().parse( node, type, options ); } + + /** Parses a {@link XmlNOTATION} fragment from an XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XmlNOTATION parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (XmlNOTATION) XmlBeans.getContextTypeLoader().parse( xis, type, null ); } + + /** Parses a {@link XmlNOTATION} fragment from an XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XmlNOTATION parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (XmlNOTATION) XmlBeans.getContextTypeLoader().parse( xis, type, options ); } + + /** Parses a {@link XmlNOTATION} fragment from an XMLStreamReader. */ + public static XmlNOTATION parse(javax.xml.stream.XMLStreamReader xsr) throws org.apache.xmlbeans.XmlException { + return (XmlNOTATION) XmlBeans.getContextTypeLoader().parse( xsr, type, null ); } + + /** Parses a {@link XmlNOTATION} fragment from an XMLStreamReader. */ + public static XmlNOTATION parse(javax.xml.stream.XMLStreamReader xsr, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException{ + return (XmlNOTATION) XmlBeans.getContextTypeLoader().parse( xsr, type, options ); } + + /** Returns a validating XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, null ); } + + /** Returns a validating XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, options ); } + + private Factory() { } // No instance of this class allowed + } +} + diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlName.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlName.java new file mode 100644 index 000000000..b6b51c425 --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlName.java @@ -0,0 +1,139 @@ +/* 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; + +import javax.xml.stream.XMLStreamReader; + + +/** + * Corresponds to the XML Schema + * xs:Name type. + * One of the derived types based on xs:string. + *

    + * This kind of string is the same as the lexical representation used for XML 1.0 + * element and attribute names, e.g., "pre:a-b.cdef". It is just a physical + * string, however, and it should NOT be confused with {@link XmlQName}, + * which is a logical combination of localname and namespace URI. + *

    + * Convertible to {@link String}. + */ +public interface XmlName extends XmlToken +{ + /** The constant {@link SchemaType} object representing this schema type. */ + public static final SchemaType type = XmlBeans.getBuiltinTypeSystem().typeForHandle("_BI_Name"); + + /** + * A class with methods for creating instances + * of {@link XmlName}. + */ + public static final class Factory + { + /** Creates an empty instance of {@link XmlName} */ + public static XmlName newInstance() { + return (XmlName) XmlBeans.getContextTypeLoader().newInstance( type, null ); } + + /** Creates an empty instance of {@link XmlName} */ + public static XmlName newInstance(org.apache.xmlbeans.XmlOptions options) { + return (XmlName) XmlBeans.getContextTypeLoader().newInstance( type, options ); } + + /** Creates an immutable {@link XmlName} value */ + public static XmlName newValue(Object obj) { + return (XmlName) type.newValue( obj ); } + + /** Parses a {@link XmlName} fragment from a String. For example: "<xml-fragment>My:Name</xml-fragment>". */ + public static XmlName parse(java.lang.String s) throws org.apache.xmlbeans.XmlException { + return (XmlName) XmlBeans.getContextTypeLoader().parse( s, type, null ); } + + /** Parses a {@link XmlName} fragment from a String. For example: "<xml-fragment>My:Name</xml-fragment>". */ + public static XmlName parse(java.lang.String s, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (XmlName) XmlBeans.getContextTypeLoader().parse( s, type, options ); } + + /** Parses a {@link XmlName} fragment from a File. */ + public static XmlName parse(java.io.File f) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlName) XmlBeans.getContextTypeLoader().parse( f, type, null ); } + + /** Parses a {@link XmlName} fragment from a File. */ + public static XmlName parse(java.io.File f, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlName) XmlBeans.getContextTypeLoader().parse( f, type, options ); } + + /** Parses a {@link XmlName} fragment from a URL. */ + public static XmlName parse(java.net.URL u) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlName) XmlBeans.getContextTypeLoader().parse( u, type, null ); } + + /** Parses a {@link XmlName} fragment from a URL. */ + public static XmlName parse(java.net.URL u, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlName) XmlBeans.getContextTypeLoader().parse( u, type, options ); } + + /** Parses a {@link XmlName} fragment from an InputStream. */ + public static XmlName parse(java.io.InputStream is) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlName) XmlBeans.getContextTypeLoader().parse( is, type, null ); } + + /** Parses a {@link XmlName} fragment from an InputStream. */ + public static XmlName parse(java.io.InputStream is, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlName) XmlBeans.getContextTypeLoader().parse( is, type, options ); } + + /** Parses a {@link XmlName} fragment from a Reader. */ + public static XmlName parse(java.io.Reader r) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlName) XmlBeans.getContextTypeLoader().parse( r, type, null ); } + + /** Parses a {@link XmlName} fragment from a Reader. */ + public static XmlName parse(java.io.Reader r, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlName) XmlBeans.getContextTypeLoader().parse( r, type, options ); } + + /** Parses a {@link XmlName} fragment from a DOM Node. */ + public static XmlName parse(org.w3c.dom.Node node) throws org.apache.xmlbeans.XmlException { + return (XmlName) XmlBeans.getContextTypeLoader().parse( node, type, null ); } + + /** Parses a {@link XmlName} fragment from a DOM Node. */ + public static XmlName parse(org.w3c.dom.Node node, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (XmlName) XmlBeans.getContextTypeLoader().parse( node, type, options ); } + + /** Parses a {@link XmlName} fragment from an XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XmlName parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (XmlName) XmlBeans.getContextTypeLoader().parse( xis, type, null ); } + + /** Parses a {@link XmlName} fragment from an XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XmlName parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (XmlName) XmlBeans.getContextTypeLoader().parse( xis, type, options ); } + + /** Parses a {@link XmlName} fragment from an XMLStreamReader. */ + public static XmlName parse(javax.xml.stream.XMLStreamReader xsr) throws org.apache.xmlbeans.XmlException { + return (XmlName) XmlBeans.getContextTypeLoader().parse( xsr, type, null ); } + + /** Parses a {@link XmlName} fragment from an XMLStreamReader. */ + public static XmlName parse(javax.xml.stream.XMLStreamReader xsr, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException{ + return (XmlName) XmlBeans.getContextTypeLoader().parse( xsr, type, options ); } + + /** Returns a validating XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, null ); } + + /** Returns a validating XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, options ); } + + private Factory() { } // No instance of this class allowed + } +} + diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlNegativeInteger.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlNegativeInteger.java new file mode 100644 index 000000000..d6ef98d7c --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlNegativeInteger.java @@ -0,0 +1,136 @@ +/* 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; + +import javax.xml.stream.XMLStreamReader; + + +/** + * Corresponds to the XML Schema + * xs:negativeInteger type. + * One of the derived types based on xs:decimal. + *

    + * Verified to be negative when validating. + *

    + * Convertible to {@link java.math.BigInteger}. + */ +public interface XmlNegativeInteger extends XmlNonPositiveInteger +{ + /** The constant {@link SchemaType} object representing this schema type. */ + public static final SchemaType type = XmlBeans.getBuiltinTypeSystem().typeForHandle("_BI_negativeInteger"); + + /** + * A class with methods for creating instances + * of {@link XmlNegativeInteger}. + */ + public static final class Factory + { + /** Creates an empty instance of {@link XmlNegativeInteger} */ + public static XmlNegativeInteger newInstance() { + return (XmlNegativeInteger) XmlBeans.getContextTypeLoader().newInstance( type, null ); } + + /** Creates an empty instance of {@link XmlNegativeInteger} */ + public static XmlNegativeInteger newInstance(org.apache.xmlbeans.XmlOptions options) { + return (XmlNegativeInteger) XmlBeans.getContextTypeLoader().newInstance( type, options ); } + + /** Creates an immutable {@link XmlNegativeInteger} value */ + public static XmlNegativeInteger newValue(Object obj) { + return (XmlNegativeInteger) type.newValue( obj ); } + + /** Parses a {@link XmlNegativeInteger} fragment from a String. For example: "<xml-fragment>-1234567890</xml-fragment>". */ + public static XmlNegativeInteger parse(java.lang.String s) throws org.apache.xmlbeans.XmlException { + return (XmlNegativeInteger) XmlBeans.getContextTypeLoader().parse( s, type, null ); } + + /** Parses a {@link XmlNegativeInteger} fragment from a String. For example: "<xml-fragment>-1234567890</xml-fragment>". */ + public static XmlNegativeInteger parse(java.lang.String s, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (XmlNegativeInteger) XmlBeans.getContextTypeLoader().parse( s, type, options ); } + + /** Parses a {@link XmlNegativeInteger} fragment from a File. */ + public static XmlNegativeInteger parse(java.io.File f) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlNegativeInteger) XmlBeans.getContextTypeLoader().parse( f, type, null ); } + + /** Parses a {@link XmlNegativeInteger} fragment from a File. */ + public static XmlNegativeInteger parse(java.io.File f, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlNegativeInteger) XmlBeans.getContextTypeLoader().parse( f, type, options ); } + + /** Parses a {@link XmlNegativeInteger} fragment from a URL. */ + public static XmlNegativeInteger parse(java.net.URL u) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlNegativeInteger) XmlBeans.getContextTypeLoader().parse( u, type, null ); } + + /** Parses a {@link XmlNegativeInteger} fragment from a URL. */ + public static XmlNegativeInteger parse(java.net.URL u, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlNegativeInteger) XmlBeans.getContextTypeLoader().parse( u, type, options ); } + + /** Parses a {@link XmlNegativeInteger} fragment from an InputStream. */ + public static XmlNegativeInteger parse(java.io.InputStream is) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlNegativeInteger) XmlBeans.getContextTypeLoader().parse( is, type, null ); } + + /** Parses a {@link XmlNegativeInteger} fragment from an InputStream. */ + public static XmlNegativeInteger parse(java.io.InputStream is, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlNegativeInteger) XmlBeans.getContextTypeLoader().parse( is, type, options ); } + + /** Parses a {@link XmlNegativeInteger} fragment from a Reader. */ + public static XmlNegativeInteger parse(java.io.Reader r) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlNegativeInteger) XmlBeans.getContextTypeLoader().parse( r, type, null ); } + + /** Parses a {@link XmlNegativeInteger} fragment from a Reader. */ + public static XmlNegativeInteger parse(java.io.Reader r, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlNegativeInteger) XmlBeans.getContextTypeLoader().parse( r, type, options ); } + + /** Parses a {@link XmlNegativeInteger} fragment from a DOM Node. */ + public static XmlNegativeInteger parse(org.w3c.dom.Node node) throws org.apache.xmlbeans.XmlException { + return (XmlNegativeInteger) XmlBeans.getContextTypeLoader().parse( node, type, null ); } + + /** Parses a {@link XmlNegativeInteger} fragment from a DOM Node. */ + public static XmlNegativeInteger parse(org.w3c.dom.Node node, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (XmlNegativeInteger) XmlBeans.getContextTypeLoader().parse( node, type, options ); } + + /** Parses a {@link XmlNegativeInteger} fragment from an XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XmlNegativeInteger parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (XmlNegativeInteger) XmlBeans.getContextTypeLoader().parse( xis, type, null ); } + + /** Parses a {@link XmlNegativeInteger} fragment from an XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XmlNegativeInteger parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (XmlNegativeInteger) XmlBeans.getContextTypeLoader().parse( xis, type, options ); } + + /** Parses a {@link XmlNegativeInteger} fragment from an XMLStreamReader. */ + public static XmlNegativeInteger parse(javax.xml.stream.XMLStreamReader xsr) throws org.apache.xmlbeans.XmlException { + return (XmlNegativeInteger) XmlBeans.getContextTypeLoader().parse( xsr, type, null ); } + + /** Parses a {@link XmlNegativeInteger} fragment from an XMLStreamReader. */ + public static XmlNegativeInteger parse(javax.xml.stream.XMLStreamReader xsr, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException{ + return (XmlNegativeInteger) XmlBeans.getContextTypeLoader().parse( xsr, type, options ); } + + /** Returns a validating XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, null ); } + + /** Returns a validating XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, options ); } + + private Factory() { } // No instance of this class allowed + } +} + diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlNonNegativeInteger.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlNonNegativeInteger.java new file mode 100644 index 000000000..5b47c07ae --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlNonNegativeInteger.java @@ -0,0 +1,136 @@ +/* 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; + +import javax.xml.stream.XMLStreamReader; + + +/** + * Corresponds to the XML Schema + * xs:nonNegativeInteger type. + * One of the derived types based on xs:decimal. + *

    + * Verified to be zero or positive when validating. + *

    + * Convertible to {@link java.math.BigInteger}. + */ +public interface XmlNonNegativeInteger extends XmlInteger +{ + /** The constant {@link SchemaType} object representing this schema type. */ + public static final SchemaType type = XmlBeans.getBuiltinTypeSystem().typeForHandle("_BI_nonNegativeInteger"); + + /** + * A class with methods for creating instances + * of {@link XmlNonNegativeInteger}. + */ + public static final class Factory + { + /** Creates an empty instance of {@link XmlNonNegativeInteger} */ + public static XmlNonNegativeInteger newInstance() { + return (XmlNonNegativeInteger) XmlBeans.getContextTypeLoader().newInstance( type, null ); } + + /** Creates an empty instance of {@link XmlNonNegativeInteger} */ + public static XmlNonNegativeInteger newInstance(org.apache.xmlbeans.XmlOptions options) { + return (XmlNonNegativeInteger) XmlBeans.getContextTypeLoader().newInstance( type, options ); } + + /** Creates an immutable {@link XmlNonNegativeInteger} value */ + public static XmlNonNegativeInteger newValue(Object obj) { + return (XmlNonNegativeInteger) type.newValue( obj ); } + + /** Parses a {@link XmlNonNegativeInteger} fragment from a String. For example: "<xml-fragment>1234567890</xml-fragment>". */ + public static XmlNonNegativeInteger parse(java.lang.String s) throws org.apache.xmlbeans.XmlException { + return (XmlNonNegativeInteger) XmlBeans.getContextTypeLoader().parse( s, type, null ); } + + /** Parses a {@link XmlNonNegativeInteger} fragment from a String. For example: "<xml-fragment>1234567890</xml-fragment>". */ + public static XmlNonNegativeInteger parse(java.lang.String s, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (XmlNonNegativeInteger) XmlBeans.getContextTypeLoader().parse( s, type, options ); } + + /** Parses a {@link XmlNonNegativeInteger} fragment from a File. */ + public static XmlNonNegativeInteger parse(java.io.File f) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlNonNegativeInteger) XmlBeans.getContextTypeLoader().parse( f, type, null ); } + + /** Parses a {@link XmlNonNegativeInteger} fragment from a File. */ + public static XmlNonNegativeInteger parse(java.io.File f, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlNonNegativeInteger) XmlBeans.getContextTypeLoader().parse( f, type, options ); } + + /** Parses a {@link XmlNonNegativeInteger} fragment from a URL. */ + public static XmlNonNegativeInteger parse(java.net.URL u) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlNonNegativeInteger) XmlBeans.getContextTypeLoader().parse( u, type, null ); } + + /** Parses a {@link XmlNonNegativeInteger} fragment from a URL. */ + public static XmlNonNegativeInteger parse(java.net.URL u, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlNonNegativeInteger) XmlBeans.getContextTypeLoader().parse( u, type, options ); } + + /** Parses a {@link XmlNonNegativeInteger} fragment from an InputStream. */ + public static XmlNonNegativeInteger parse(java.io.InputStream is) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlNonNegativeInteger) XmlBeans.getContextTypeLoader().parse( is, type, null ); } + + /** Parses a {@link XmlNonNegativeInteger} fragment from an InputStream. */ + public static XmlNonNegativeInteger parse(java.io.InputStream is, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlNonNegativeInteger) XmlBeans.getContextTypeLoader().parse( is, type, options ); } + + /** Parses a {@link XmlNonNegativeInteger} fragment from a Reader. */ + public static XmlNonNegativeInteger parse(java.io.Reader r) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlNonNegativeInteger) XmlBeans.getContextTypeLoader().parse( r, type, null ); } + + /** Parses a {@link XmlNonNegativeInteger} fragment from a Reader. */ + public static XmlNonNegativeInteger parse(java.io.Reader r, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlNonNegativeInteger) XmlBeans.getContextTypeLoader().parse( r, type, options ); } + + /** Parses a {@link XmlNonNegativeInteger} fragment from a DOM Node. */ + public static XmlNonNegativeInteger parse(org.w3c.dom.Node node) throws org.apache.xmlbeans.XmlException { + return (XmlNonNegativeInteger) XmlBeans.getContextTypeLoader().parse( node, type, null ); } + + /** Parses a {@link XmlNonNegativeInteger} fragment from a DOM Node. */ + public static XmlNonNegativeInteger parse(org.w3c.dom.Node node, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (XmlNonNegativeInteger) XmlBeans.getContextTypeLoader().parse( node, type, options ); } + + /** Parses a {@link XmlNonNegativeInteger} fragment from an XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XmlNonNegativeInteger parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (XmlNonNegativeInteger) XmlBeans.getContextTypeLoader().parse( xis, type, null ); } + + /** Parses a {@link XmlNonNegativeInteger} fragment from an XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XmlNonNegativeInteger parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (XmlNonNegativeInteger) XmlBeans.getContextTypeLoader().parse( xis, type, options ); } + + /** Parses a {@link XmlNonNegativeInteger} fragment from an XMLStreamReader. */ + public static XmlNonNegativeInteger parse(javax.xml.stream.XMLStreamReader xsr) throws org.apache.xmlbeans.XmlException { + return (XmlNonNegativeInteger) XmlBeans.getContextTypeLoader().parse( xsr, type, null ); } + + /** Parses a {@link XmlNonNegativeInteger} fragment from an XMLStreamReader. */ + public static XmlNonNegativeInteger parse(javax.xml.stream.XMLStreamReader xsr, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (XmlNonNegativeInteger) XmlBeans.getContextTypeLoader().parse( xsr, type, options ); } + + /** Returns a validating XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, null ); } + + /** Returns a validating XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, options ); } + + private Factory() { } // No instance of this class allowed + } +} + diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlNonPositiveInteger.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlNonPositiveInteger.java new file mode 100644 index 000000000..3f22e4a02 --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlNonPositiveInteger.java @@ -0,0 +1,136 @@ +/* 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; + +import javax.xml.stream.XMLStreamReader; + + +/** + * Corresponds to the XML Schema + * xs:nonPositiveInteger type. + * One of the derived types based on xs:decimal. + *

    + * Verified to be zero or negative when validating. + *

    + * Convertible to {@link java.math.BigInteger}. + */ +public interface XmlNonPositiveInteger extends XmlInteger +{ + /** The constant {@link SchemaType} object representing this schema type. */ + public static final SchemaType type = XmlBeans.getBuiltinTypeSystem().typeForHandle("_BI_nonPositiveInteger"); + + /** + * A class with methods for creating instances + * of {@link XmlNonPositiveInteger}. + */ + public static final class Factory + { + /** Creates an empty instance of {@link XmlNonPositiveInteger} */ + public static XmlNonPositiveInteger newInstance() { + return (XmlNonPositiveInteger) XmlBeans.getContextTypeLoader().newInstance( type, null ); } + + /** Creates an empty instance of {@link XmlNonPositiveInteger} */ + public static XmlNonPositiveInteger newInstance(org.apache.xmlbeans.XmlOptions options) { + return (XmlNonPositiveInteger) XmlBeans.getContextTypeLoader().newInstance( type, options ); } + + /** Creates an immutable {@link XmlNonPositiveInteger} value */ + public static XmlNonPositiveInteger newValue(Object obj) { + return (XmlNonPositiveInteger) type.newValue( obj ); } + + /** Parses a {@link XmlNonPositiveInteger} fragment from a String. For example: "<xml-fragment>-1234567890</xml-fragment>". */ + public static XmlNonPositiveInteger parse(java.lang.String s) throws org.apache.xmlbeans.XmlException { + return (XmlNonPositiveInteger) XmlBeans.getContextTypeLoader().parse( s, type, null ); } + + /** Parses a {@link XmlNonPositiveInteger} fragment from a String. For example: "<xml-fragment>-1234567890</xml-fragment>". */ + public static XmlNonPositiveInteger parse(java.lang.String s, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (XmlNonPositiveInteger) XmlBeans.getContextTypeLoader().parse( s, type, options ); } + + /** Parses a {@link XmlNonPositiveInteger} fragment from a File. */ + public static XmlNonPositiveInteger parse(java.io.File f) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlNonPositiveInteger) XmlBeans.getContextTypeLoader().parse( f, type, null ); } + + /** Parses a {@link XmlNonPositiveInteger} fragment from a File. */ + public static XmlNonPositiveInteger parse(java.io.File f, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlNonPositiveInteger) XmlBeans.getContextTypeLoader().parse( f, type, options ); } + + /** Parses a {@link XmlNonPositiveInteger} fragment from a URL. */ + public static XmlNonPositiveInteger parse(java.net.URL u) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlNonPositiveInteger) XmlBeans.getContextTypeLoader().parse( u, type, null ); } + + /** Parses a {@link XmlNonPositiveInteger} fragment from a URL. */ + public static XmlNonPositiveInteger parse(java.net.URL u, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlNonPositiveInteger) XmlBeans.getContextTypeLoader().parse( u, type, options ); } + + /** Parses a {@link XmlNonPositiveInteger} fragment from an InputStream. */ + public static XmlNonPositiveInteger parse(java.io.InputStream is) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlNonPositiveInteger) XmlBeans.getContextTypeLoader().parse( is, type, null ); } + + /** Parses a {@link XmlNonPositiveInteger} fragment from an InputStream. */ + public static XmlNonPositiveInteger parse(java.io.InputStream is, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlNonPositiveInteger) XmlBeans.getContextTypeLoader().parse( is, type, options ); } + + /** Parses a {@link XmlNonPositiveInteger} fragment from a Reader. */ + public static XmlNonPositiveInteger parse(java.io.Reader r) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlNonPositiveInteger) XmlBeans.getContextTypeLoader().parse( r, type, null ); } + + /** Parses a {@link XmlNonPositiveInteger} fragment from a Reader. */ + public static XmlNonPositiveInteger parse(java.io.Reader r, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlNonPositiveInteger) XmlBeans.getContextTypeLoader().parse( r, type, options ); } + + /** Parses a {@link XmlNonPositiveInteger} fragment from a DOM Node. */ + public static XmlNonPositiveInteger parse(org.w3c.dom.Node node) throws org.apache.xmlbeans.XmlException { + return (XmlNonPositiveInteger) XmlBeans.getContextTypeLoader().parse( node, type, null ); } + + /** Parses a {@link XmlNonPositiveInteger} fragment from a DOM Node. */ + public static XmlNonPositiveInteger parse(org.w3c.dom.Node node, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (XmlNonPositiveInteger) XmlBeans.getContextTypeLoader().parse( node, type, options ); } + + /** Parses a {@link XmlNonPositiveInteger} fragment from an XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XmlNonPositiveInteger parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (XmlNonPositiveInteger) XmlBeans.getContextTypeLoader().parse( xis, type, null ); } + + /** Parses a {@link XmlNonPositiveInteger} fragment from an XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XmlNonPositiveInteger parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (XmlNonPositiveInteger) XmlBeans.getContextTypeLoader().parse( xis, type, options ); } + + /** Parses a {@link XmlNonPositiveInteger} fragment from an XMLStreamReader. */ + public static XmlNonPositiveInteger parse(javax.xml.stream.XMLStreamReader xsr) throws org.apache.xmlbeans.XmlException { + return (XmlNonPositiveInteger) XmlBeans.getContextTypeLoader().parse( xsr, type, null ); } + + /** Parses a {@link XmlNonPositiveInteger} fragment from an XMLStreamReader. */ + public static XmlNonPositiveInteger parse(javax.xml.stream.XMLStreamReader xsr, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (XmlNonPositiveInteger) XmlBeans.getContextTypeLoader().parse( xsr, type, options ); } + + /** Returns a validating XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, null ); } + + /** Returns a validating XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, options ); } + + private Factory() { } // No instance of this class allowed + } +} + diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlNormalizedString.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlNormalizedString.java new file mode 100644 index 000000000..a0cf2d69f --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlNormalizedString.java @@ -0,0 +1,143 @@ +/* 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; + +import javax.xml.stream.XMLStreamReader; + + +/** + * Corresponds to the XML Schema + * xs:normalizedString type. + * One of the derived types based on xs:string. + *

    + * An normalizedString simply is a string where all the carriage return, + * linefeed, and tab characters have been normalized (switched to) ordinary + * space characters. Use normalizedString for long strings to make them + * insensitive to line breaking. If you wish to often be insensitive to + * runs of whitespace (as is often the case), use + * xs:token + * (aka {@link XmlToken}) instead. + *

    + * Convertible to {@link String}. When obtaining the stringValue, the + * whitespace-normalized value is returned. + */ +public interface XmlNormalizedString extends XmlString +{ + /** The constant {@link SchemaType} object representing this schema type. */ + public static final SchemaType type = XmlBeans.getBuiltinTypeSystem().typeForHandle("_BI_normalizedString"); + + /** + * A class with methods for creating instances + * of {@link XmlNormalizedString}. + */ + public static final class Factory + { + /** Creates an empty instance of {@link XmlNormalizedString} */ + public static XmlNormalizedString newInstance() { + return (XmlNormalizedString) XmlBeans.getContextTypeLoader().newInstance( type, null ); } + + /** Creates an empty instance of {@link XmlNormalizedString} */ + public static XmlNormalizedString newInstance(org.apache.xmlbeans.XmlOptions options) { + return (XmlNormalizedString) XmlBeans.getContextTypeLoader().newInstance( type, options ); } + + /** Creates an immutable {@link XmlNormalizedString} value */ + public static XmlNormalizedString newValue(Object obj) { + return (XmlNormalizedString) type.newValue( obj ); } + + /** Parses a {@link XmlNormalizedString} fragment from a String. For example: "<xml-fragment> string to normalize </xml-fragment>". */ + public static XmlNormalizedString parse(java.lang.String s) throws org.apache.xmlbeans.XmlException { + return (XmlNormalizedString) XmlBeans.getContextTypeLoader().parse( s, type, null ); } + + /** Parses a {@link XmlNormalizedString} fragment from a String. For example: "<xml-fragment> string to normalize </xml-fragment>". */ + public static XmlNormalizedString parse(java.lang.String s, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (XmlNormalizedString) XmlBeans.getContextTypeLoader().parse( s, type, options ); } + + /** Parses a {@link XmlNormalizedString} fragment from a File. */ + public static XmlNormalizedString parse(java.io.File f) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlNormalizedString) XmlBeans.getContextTypeLoader().parse( f, type, null ); } + + /** Parses a {@link XmlNormalizedString} fragment from a File. */ + public static XmlNormalizedString parse(java.io.File f, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlNormalizedString) XmlBeans.getContextTypeLoader().parse( f, type, options ); } + + /** Parses a {@link XmlNormalizedString} fragment from a URL. */ + public static XmlNormalizedString parse(java.net.URL u) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlNormalizedString) XmlBeans.getContextTypeLoader().parse( u, type, null ); } + + /** Parses a {@link XmlNormalizedString} fragment from a URL. */ + public static XmlNormalizedString parse(java.net.URL u, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlNormalizedString) XmlBeans.getContextTypeLoader().parse( u, type, options ); } + + /** Parses a {@link XmlNormalizedString} fragment from an InputStream. */ + public static XmlNormalizedString parse(java.io.InputStream is) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlNormalizedString) XmlBeans.getContextTypeLoader().parse( is, type, null ); } + + /** Parses a {@link XmlNormalizedString} fragment from an InputStream. */ + public static XmlNormalizedString parse(java.io.InputStream is, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlNormalizedString) XmlBeans.getContextTypeLoader().parse( is, type, options ); } + + /** Parses a {@link XmlNormalizedString} fragment from a Reader. */ + public static XmlNormalizedString parse(java.io.Reader r) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlNormalizedString) XmlBeans.getContextTypeLoader().parse( r, type, null ); } + + /** Parses a {@link XmlNormalizedString} fragment from a Reader. */ + public static XmlNormalizedString parse(java.io.Reader r, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (XmlNormalizedString) XmlBeans.getContextTypeLoader().parse( r, type, options ); } + + /** Parses a {@link XmlNormalizedString} fragment from a DOM Node. */ + public static XmlNormalizedString parse(org.w3c.dom.Node node) throws org.apache.xmlbeans.XmlException { + return (XmlNormalizedString) XmlBeans.getContextTypeLoader().parse( node, type, null ); } + + /** Parses a {@link XmlNormalizedString} fragment from a DOM Node. */ + public static XmlNormalizedString parse(org.w3c.dom.Node node, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (XmlNormalizedString) XmlBeans.getContextTypeLoader().parse( node, type, options ); } + + /** Parses a {@link XmlNormalizedString} fragment from an XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XmlNormalizedString parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (XmlNormalizedString) XmlBeans.getContextTypeLoader().parse( xis, type, null ); } + + /** Parses a {@link XmlNormalizedString} fragment from an XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XmlNormalizedString parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (XmlNormalizedString) XmlBeans.getContextTypeLoader().parse( xis, type, options ); } + + /** Parses a {@link XmlNormalizedString} fragment from an XMLStreamReader. */ + public static XmlNormalizedString parse(javax.xml.stream.XMLStreamReader xsr) throws org.apache.xmlbeans.XmlException { + return (XmlNormalizedString) XmlBeans.getContextTypeLoader().parse( xsr, type, null ); } + + /** Parses a {@link XmlNormalizedString} fragment from an XMLStreamReader. */ + public static XmlNormalizedString parse(javax.xml.stream.XMLStreamReader xsr, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (XmlNormalizedString) XmlBeans.getContextTypeLoader().parse( xsr, type, options ); } + + /** Returns a validating XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, null ); } + + /** Returns a validating XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, options ); } + + private Factory() { } // No instance of this class allowed + } +} + diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlObject.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlObject.java new file mode 100644 index 000000000..40105a082 --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlObject.java @@ -0,0 +1,852 @@ +/* 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; + +import org.apache.xmlbeans.xml.stream.XMLInputStream; +import org.apache.xmlbeans.xml.stream.XMLStreamException; + +import javax.xml.stream.XMLStreamReader; +import javax.xml.namespace.QName; + +import org.w3c.dom.Node; +import org.w3c.dom.DOMImplementation; + +import java.io.InputStream; +import java.io.File; +import java.io.Reader; +import java.io.IOException; + +/** + * Corresponds to the XML Schema + * xs:anyType, + * the base type for all XML Beans. + *

    + * Since all XML Schema types are translated into corresponding XML Bean + * classes, and all Schema type derivation corresponds to Java class + * inheritance, the fact that all Schema types derive from xs:anyType means + * that all XML Bean classes derive from XmlObject. + *

    + * On this base class you will find a number of common facilities that + * all XML Bean classes provide: + *

    + *

      + *
    • Every XML Bean class has an inner Factory class for creating and parsing + * instances, including XmlObject. Use {@link XmlObject.Factory} itself + * to produce untyped XML trees or XML trees that implement specific + * subtypes of XmlObject depending on a recognized root document element. + * If you depend on the automatic type inference, you will want to understand + * the type inference issues described below. + *
    • To write out an accurate XML file for the XML tree under this + * XmlObject, use one of the {@link #save} methods, + * or {@link #newInputStream} or {@link #newReader}. + * Use {@link #toString} to produce a pretty-printed representation of the + * XML subtree under this XML Object. If you save interior portions of + * an XML document, you will want to understand the inner contents + * versus outer container issues described below. + *
    • It is also simple to copy an XmlObject instance to or from a standard + * DOM tree or SAX stream. Use {@link XmlObject.Factory#parse(Node)}, + * for example, to load from DOM; use {@link XmlObject.Factory#newXmlSaxHandler} + * to load from SAX; use {@link #newDomNode()} to save to DOM; and use + * {@link #save(org.xml.sax.ContentHandler, org.xml.sax.ext.LexicalHandler)} + * to save to SAX. + *
    • Use {@link #validate} to validate the subtree of XML under this + * XML Object. If you wish to get information about the location + * and reason for validation errors, see {@link XmlOptions#setErrorListener}, + * and use {@link #validate(XmlOptions)}. + *
    • Use {@link #newCursor} to access the full XML infoset, for example, + * if you need to determine interleaved element order or manipulate + * annotations, comments, or mixed content. You can get an element name with + * a cursor by calling {@link XmlCursor#getName() cursor.getName()} when the + * cursor is positioned at an element's START token. See {@link XmlCursor}. + *
    • Use {@link #selectPath} to find other XmlObjects in the subtree underneath + * this XmlObject using relative XPaths. (In selectPath, "." indicates + * the current element or attribute.) + *
    + *

    + * Type inference. When using {@link XmlObject.Factory} to parse XML documents, + * the actual document type is not {@link XmlObject#type} itself, but a subtype + * based on the contents of the parsed document. If the parsed document + * contains a recognized root document element, then the actual type of the + * loaded instance will be the matching Document type. For example: + *

    + * XmlObject xobj = XmlObject.Factory.parse(myDocument);
    + * if (xobj instanceof MyOrderDocument) // starts w/ <my-order>
    + * {
    + *     MyOrderDocument mydoc = (MyOrderDocument)xobj;
    + *     if (!xobj.validate())
    + *         System.out.println("Not a valid my-order document");
    + * }
    + * else
    + * {
    + *     System.out.println("Not a my-order document");
    + * }
    + * 
    + * Every XML Bean class has its own inner Factory class, + * so if you actually know exactly which XML Bean document type + * you want to load as in the example above, you should use the + * the specific XML Bean Factory class instead. For example: + *
    + * MyOrderDocument mydoc = MyOrderDocument.Factory.parse(myDocument);
    + * 
    + * The code above will throw an exception if the parsed document + * does not begin with the proper (my-order) element. + *

    + * Inner versus outer. An XmlObject represents the + * contents of an element or attribute, not the element + * or attribute itself. So when you validate or save an XmlObject, you + * are validating or saving its contents, not its container. For example, + * if the XmlObject represents the contents of an element which happens + * to itself be in the wrong order relative to its siblings, validate will + * not complain about the misplacement of the element itself. On the other hand, if + * elements within the XmlObject are in the wrong order, validate + * will complain. Similarly, when saving the contents of an interior + * XmlObject, it is the contents of an element, not the element itself, + * which is saved by default. + *

    + * Reading and writing fragments. When reading or writing the contents of a + * whole XML document, the standard XML reprentation for a document is used. + * However, there is no standard concrete XML representation for "just the + * contents" of an interior element or attribute. So when one is needed, + * the tag <xml-fragment> is used to wrap the contents. This tag is used + * can also be used to load just the contents for an XmlObject document fragment + * of arbitrary type. If you wish to save out the XmlObject's container element + * along with its contents, use {@link XmlOptions#setSaveOuter}. + *

    + * Implementing XmlObject. The XMLBeans library does not support arbitrary + * implementations of XmlObject - in almost all cases, you should only use + * the implementations of XmlObject provided by the XMLBeans compiler itself. + * If you need to implement XmlObject yourself, you should subclass + * FilterXmlObject in order to delegate to another underlying XmlObject + * implementation. This technique will allow you to use your code unchanged + * with future versions of XMLBeans that add additional methods on XmlObject. + */ +public interface XmlObject extends XmlTokenSource +{ + /** The constant {@link SchemaType} object representing this schema type. */ + public static final SchemaType type = XmlBeans.getBuiltinTypeSystem().typeForHandle("_BI_anyType"); + + /** + * The schema type for this instance. This is a permanent, + * unchanging property of the instance. + */ + SchemaType schemaType(); + + /** + * Returns true if the contents of this object are valid + * accoring to schemaType(). + *

    + * Does a deep validation of the entire subtree under the + * object, but does not validate the parents or siblings + * of the object if the object is in the interior of an xml + * tree. + */ + boolean validate(); + + /** + *

    Just like validate(), but with options.

    + *

    If you wish to collect error messages and locations while validating, + * use the {@link XmlOptions#setErrorListener} method. With that method, + * you can specify an object in which to store messages related to validation. + * The following is a simple example.

    + * + *
    +     * // Create an XmlOptions instance and set the error listener.
    +     * XmlOptions validateOptions = new XmlOptions();
    +     * ArrayList errorList = new ArrayList();
    +     * validateOptions.setErrorListener(errorList);
    +     * 
    +     * // Validate the XML.
    +     * boolean isValid = newEmp.validate(validateOptions);
    +     * 
    +     * // If the XML isn't valid, loop through the listener's contents,
    +     * // printing contained messages.
    +     * if (!isValid)
    +     * {
    +     *      for (int i = 0; i < errorList.size(); i++)
    +     *      {
    +     *          XmlError error = (XmlError)errorList.get(i);
    +     *          
    +     *          System.out.println("\n");
    +     *          System.out.println("Message: " + error.getMessage() + "\n");
    +     *          System.out.println("Location of invalid XML: " + 
    +     *              error.getCursorLocation().xmlText() + "\n");
    +     *      }
    +     * }
    +     * 
    + * + * @param options An object that implements the {@link java.util.Collection + * Collection} interface. + */ + boolean validate(XmlOptions options); + + /** + * Selects a path. Path can be a string or precompiled path String. + *

    + * The path must be a relative path, where "." represents the + * element or attribute containg this XmlObject, and it must select + * only other elements or attributes. If a non-element or non-attribute + * is selected, an unchecked exception is thrown. + *

    + * The array that is returned contains all the selected + * XmlObjects, within the same document, listed in document + * order. The actual array type of the result is inferred + * from the closest common base type of selected results. + *

    + * Here is an example of usage. Suppose we have a global + * element definition for "owner" whose type is "person": + *

    +     *   <schema targetNamespace="http://openuri.org/sample">
    +     *      <element name="owner" type="person"/>
    +     *      <complexType name="person">
    +     *         [...]
    +     *      </complexType>
    +     *   </schema>
    +     * 
    + * and suppose "owner" tags can be scattered throughout the + * document. Then we can write the following code to find + * them all: + *
    +     * import org.openuri.sample.Person;
    +     * import org.apache.xmlbeans.*;
    +     * [...]
    +     *   XmlObject xobj = XmlObject.Factory.parse(myFile);
    +     *   Person[] results;
    +     *   results = (Person[])xobj.selectPath(
    +     *      "declare namespace s='http://www.openuri.org/sample' " +
    +     *      ".//s:owner");
    +     * 
    + * Notice the way in which namespace declarations are done in XPath 2.0. + * Since XPath can only navigate within an XML document - it cannot + * construct new XML - the resulting XmlObjects all reside in + * the same XML document as this XmlObject itself. + */ + XmlObject[] selectPath ( String path ); + + /** + * Selects a path, applying options. + * + * @see #selectPath(String) + */ + XmlObject[] selectPath ( String path, XmlOptions options ); + + + /** + * Executes a query. Query can be a string or precompiled query String. + *

    + * An XQuery is very similar to an XPath, except that it also permits + * construction of new XML. As a result, the XmlObjects that are + * returned from execQuery are in newly created documents, separate + * from the XmlObject on which the query is executed. + *

    + * Syntax and usage is otherwise similar to selectPath. + *

    + * @see #selectPath(String) + */ + XmlObject[] execQuery ( String query ); + + /** + * Executes a query with options. + * + * Use the options parameter to specify the following:

    + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
    To specify thisUse this method
    The document type for the root element.{@link XmlOptions#setDocumentType}
    To replace the document element with the specified QName when constructing the + * resulting document.{@link XmlOptions#setLoadReplaceDocumentElement}
    To strip all insignificant whitespace when constructing a document.{@link XmlOptions#setLoadStripWhitespace}
    To strip all comments when constructing a document.{@link XmlOptions#setLoadStripComments}
    To strip all processing instructions when constructing a document.{@link XmlOptions#setLoadStripProcinsts}
    A map of namespace URI substitutions to use when constructing a document.{@link XmlOptions#setLoadSubstituteNamespaces}
    Additional namespace mappings to be added when constructing a document.{@link XmlOptions#setLoadAdditionalNamespaces}
    To trim the underlying XML text buffer immediately after constructing + * a document, resulting in a smaller memory footprint.{@link XmlOptions#setLoadTrimTextBuffer}
    Whether value facets should be checked as they are set.{@link XmlOptions#setValidateOnSet}
    + * + * @param query The XQuery expression. + * @param options Options as described. + * + * @see #execQuery(String) + */ + XmlObject[] execQuery ( String query, XmlOptions options ); + + + /** + * Changes the schema type associated with this data and + * returns a new XmlObject instance whose schemaType is the + * new type. + *

    + * Returns the new XmlObject if the type change was successful, + * the old XmlObject if no changes could be made.

    + * Certain type changes may be prohibited in the interior of an xml + * tree due to schema type system constraints (that is, due + * to a parent container within which the newly specified + * type is not permissible), but there are no constraints + * at the roottype changes are never + * prohibited at the root of an xml tree. + *

    + * If the type change is allowed, then the new XmlObject should + * be used rather than the old one. The old XmlObject instance and + * any other XmlObject instances in the subtree are permanently + * invalidated and should not be used. (They will return + * XmlValueDisconnectedException if you try to use them.) + * + * If a type change is done on the interior of an Xml + * tree, then xsi:type attributes are updated as needed. + */ + XmlObject changeType(SchemaType newType); + + /** + * Changes the schema type associated with this data using substitution + * groups and returns an XmlObject instance whose schemaType is the + * new type and container name is the new name. + *

    + * Returns the new XmlObject if the substitution was successful, + * the old XmlObject if no changes could be made.

    + * In order for the operation to succeed, several conditions must hold: + *

    • the container of this type must be an element
    • + *
    • a global element with the name newName must exist + * and must be in the substition group of the containing element
    • + *
    • the newType type must be consistent with the declared + * type of the new element
    + *

    + * If the type change is allowed, then the new XmlObject should + * be used rather than the old one. The old XmlObject instance and + * any other XmlObject instances in the subtree are permanently + * invalidated and should not be used. (They will return + * XmlValueDisconnectedException if you try to use them.) + * If necessary, xsi:type attributes are updated. + */ + XmlObject substitute(QName newName, SchemaType newType); + + /** + * True if the value is nil. Note that in order to be nil, + * the value must be in an element, and the element containing + * the value must be marked as nillable in the schema. + */ + boolean isNil(); + + /** + * Sets the value to nil. The element containing the value must + * be marked as nillable in the schema. + */ + void setNil(); + + + /** + * Returns an XML string for this XML object. + *

    + * The string is pretty-printed. If you want a non-pretty-printed + * string, or if you want to control options precisely, use the + * xmlText() methods. + *

    + * Note that when producing XML any object other than very root of the + * document, then you are guaranteed to be looking at only a fragment + * of XML, i.e., just the contents of an element or attribute, and + * and we will produce a string that starts with an <xml-fragment> tag. + * The XmlOptions.setSaveOuter() option on xmlText can be used to produce + * the actual element name above the object if you wish. + */ + String toString(); + + /** + * True if the value is an immutable value. Immutable values do not + * have a position in a tree; rather, they are stand-alone simple type + * values. If the object is immutable, the equals() methods tests for + * value equality, and the object can be used as the key for a hash. + */ + boolean isImmutable(); + + /** + * Set the value/type of this XmlObject to be a copy of the source + * XmlObject. Because the type of the source may be different than this + * target, this XmlObject may become defunct. In this case the new + * XmlObject is returned. If no type change happens, the same this will be + * returned. + */ + XmlObject set(XmlObject srcObj); + + /** + * Returns a deep copy of this XmlObject. The returned object has the + * same type as the current object, and has all the content of + * the XML document underneath the current object. Note that + * any parts of the XML document above or outside this XmlObject are + * not copied. + * + * Note: The result object will be in the same synchronization domain as the source, + * and additional synchronization is required for concurent access. + * To use a different synchronization domain use setCopyUseNewSynchronizationDomain + * option with copy(XmlOptions) method. + * @see #copy(XmlOptions) + * @see org.apache.xmlbeans.XmlOptions#setCopyUseNewSynchronizationDomain(boolean) + */ + XmlObject copy(); + + /** + * Returns a deep copy of this XmlObject. The returned object has the + * same type as the current object, and has all the content of + * the XML document underneath the current object. Note that + * any parts of the XML document above or outside this XmlObject are + * not copied. + * + * Note: The result object will be in the same synchronization domain as the source, + * and additional synchronization is required for concurent access. + * To use a different synchronization domain use setCopyUseNewSynchronizationDomain + * option when creating the original XmlObject. + * @see org.apache.xmlbeans.XmlOptions#setCopyUseNewSynchronizationDomain(boolean) + */ + XmlObject copy(XmlOptions options); + + /** + * True if the xml values are equal. Two different objects + * (which are distinguished by equals(obj) == false) may of + * course have equal values (valueEquals(obj) == true). + *

    + * Usually this method can be treated as an ordinary equvalence + * relation, but actually it is not is not transitive. + * Here is a precise specification: + *

    + * There are two categories of XML object: objects with a known + * instance type, and objects whose only known type is one of the + * ur-types (either AnyType or AnySimpleType). The first category + * is compared in terms of logical value spaces, and the second + * category is compared lexically. + *

    + * Within each of these two categories, valueEquals is a well-behaved + * equivalence relation. However, when comparing an object of known + * type with an object with ur-type, the comparison is done by attempting + * to convert the lexical form of the ur-typed object into the other + * type, and then comparing the results. Ur-typed objects are therefore + * treated as lexical wildcards and may be equal to objects in different + * value spaces, even though the objects in different value spaces are + * not equal to each other. + *

    + * For example, the anySimpleType value "1" will compare as an + * equalValue to the string "1", the float value "1.0", the double + * value "1.0", the decimal "1", and the GYear "1", even though + * all these objects will compare unequal to each other since they + * lie in different value spaces. + * Note: as of XMLBeans 2.2.1 only implemented for simple type values. + */ + boolean valueEquals(XmlObject obj); + + int valueHashCode(); + + /** + * Impelements the Comparable interface by comparing two simple + * xml values based on their standard XML schema ordering. + * Throws a ClassCastException if no standard ordering applies, + * or if the two values are incomparable within a partial order. + */ + int compareTo(Object obj); + + /** + * This comparison method is similar to compareTo, but rather + * than throwing a ClassCastException when two values are incomparable, + * it returns the number 2. The result codes are -1 if this object + * is less than obj, 1 if this object is greater than obj, zero if + * the objects are equal, and 2 if the objects are incomparable. + */ + int compareValue(XmlObject obj); + + /** LESS_THAN is -1. See {@link #compareValue}. */ + static final int LESS_THAN = -1; + + /** EQUAL is 0. See {@link #compareValue}. */ + static final int EQUAL = 0; + + /** GREATER_THAN is 1. See {@link #compareValue}. */ + static final int GREATER_THAN = 1; + + /** NOT_EQUAL is 2. See {@link #compareValue}. */ + static final int NOT_EQUAL = 2; + + /** + * Selects the contents of the children elements with the given name. + * @param elementName The name of the elements to be selected. + * @return Returns the contents of the selected elements. + */ + XmlObject[] selectChildren(QName elementName); + + /** + * Selects the contents of the children elements with the given name. + * @param elementUri The URI of the elements to be selected. + * @param elementLocalName The local name of the elements to be selected. + * @return Returns the contents of the selected elements. + */ + XmlObject[] selectChildren(String elementUri, String elementLocalName); + + /** + * Selects the contents of the children elements that are contained in the elementNameSet. + * @param elementNameSet Set of element names to be selected. + * @return Returns the contents of the selected elements. + * @see SchemaType#qnameSetForWildcardElements() + * @see QNameSetBuilder for creating sets of qnames + */ + XmlObject[] selectChildren(QNameSet elementNameSet); + + /** + * Selects the content of the attribute with the given name. + * @param attributeName The name of the attribute to be selected. + * @return Returns the contents of the selected attribute. + */ + XmlObject selectAttribute(QName attributeName); + + /** + * Selects the content of the attribute with the given name. + * @param attributeUri The URI of the attribute to be selected. + * @param attributeLocalName The local name of the attribute to be selected. + * @return Returns the content of the selected attribute. + */ + XmlObject selectAttribute(String attributeUri, String attributeLocalName); + + /** + * Selects the contents of the attributes that are contained in the elementNameSet. + * @param attributeNameSet Set of attribute names to be selected. + * @return Returns the contents of the selected attributes. + * @see SchemaType#qnameSetForWildcardAttributes() + * @see QNameSetBuilder for creating sets of qnames + */ + XmlObject[] selectAttributes(QNameSet attributeNameSet); + + /** + * Static factory class for creating new instances. Note that if + * a type can be inferred from the XML being loaded (for example, + * by recognizing the document element QName), then the instance + * returned by a factory will have the inferred type. Otherwise + * the Factory will returned an untyped document. + */ + public static final class Factory + { + /** + * Creates a new, completely empty instance. + */ + public static XmlObject newInstance ( ) { + return XmlBeans.getContextTypeLoader().newInstance( null, null ); } + + /** + *

    Creates a new, completely empty instance, specifying options + * for the root element's document type and/or whether to validate + * value facets as they are set.

    + * + * Use the options parameter to specify the following:

    + * + * + * + * + * + * + * + * + * + * + * + *
    To specify thisUse this method
    The document type for the root element.{@link XmlOptions#setDocumentType}
    Whether value facets should be checked as they are set.{@link XmlOptions#setValidateOnSet}
    + * + * @param options Options specifying root document type and/or value facet + * checking. + * @return A new, empty instance of XmlObject.

    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 Kfd{mU0sKGMyGI28 literal 0 HcmV?d00001 diff --git a/xmlbeans/maven-plugin/INSTRUCTIONS.txt b/xmlbeans/maven-plugin/INSTRUCTIONS.txt new file mode 100644 index 000000000..cb01d4894 --- /dev/null +++ b/xmlbeans/maven-plugin/INSTRUCTIONS.txt @@ -0,0 +1,68 @@ +Some brief instructions for using the maven xmlbeans2 plugin + +1. Include something like this in your maven.xml: +namespace declaration: + + xmlns:xmlbeans="xmlbeans:maven" + + + + + +where + +sourcedir is a base directory for the list in sourceschema +sourceschema is a comma-delimited list of all the schemas you want to compile +xmlconfigs points to your xmlconfig.xml file +targetdir is where you want generated java source to appear +cataloglocation is the location of an entity resolver catalog to use for resolving namespace to schema locations. + +The generated binary files, both .xsd and the TypeHolder class, will end up in the target/classes directory. + +In addition, you can add precompiled schemas to the "schema classpath" by including them as +dependencies in project.xml with a properties tag like this: + + + geronimo + geronimo-naming-builder + ${pom.currentVersion} + + true + + + +You will probably also want to add a dependency on the plugin to your project.xml file and the other dependencies if you use xmlbeans in unit tests: + + + xmlbeans + xmlbeans-maven-plugin + 2.0-beta1 + plugin + + + + + xmlbeans + xbean + ${xmlbeans_version} + + + + stax + stax + ${stax_version} + + + + stax + stax-api + ${stax_api_version} + + + + diff --git a/xmlbeans/maven-plugin/LICENSE.txt b/xmlbeans/maven-plugin/LICENSE.txt new file mode 100644 index 000000000..6b0b1270f --- /dev/null +++ b/xmlbeans/maven-plugin/LICENSE.txt @@ -0,0 +1,203 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. + diff --git a/xmlbeans/maven-plugin/NOTICE.txt b/xmlbeans/maven-plugin/NOTICE.txt new file mode 100644 index 000000000..439eb83b2 --- /dev/null +++ b/xmlbeans/maven-plugin/NOTICE.txt @@ -0,0 +1,3 @@ +This product includes software developed by +The Apache Software Foundation (http://www.apache.org/). + diff --git a/xmlbeans/maven-plugin/plugin.jelly b/xmlbeans/maven-plugin/plugin.jelly new file mode 100644 index 000000000..c543ee7e3 --- /dev/null +++ b/xmlbeans/maven-plugin/plugin.jelly @@ -0,0 +1,104 @@ + + + + + + + + + + + + + + + + Missing required attribute: maven.xmlbeans2.targetdir + + + Missing required attribute: maven.xmlbeans2.sourcedir + + + Missing required attribute: maven.xmlbeans2.sourceschema + + + Missing required attribute: maven.xmlbeans2.xmlconfigs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/xmlbeans/maven-plugin/plugin.properties b/xmlbeans/maven-plugin/plugin.properties new file mode 100644 index 000000000..d942678e0 --- /dev/null +++ b/xmlbeans/maven-plugin/plugin.properties @@ -0,0 +1,50 @@ +# Copyright 2003-2005 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. + +#These properties can be set in a project.properties file or in an invocation in maven.xml +#dependencies marked with the property true will get included in the xmlbeans classpath +#so you can reuse your xmlbeans generated classes. + +#a typical invocation looks like: +# +# +# +# +# + + +#base location for schemas to compile +maven.xmlbeans2.sourcedir=${basedir}/src/schema + +#comma separated list of schemas to compile, relative to sourcedir above. You must specify this explicitly +maven.xmlbeans2.sourceschema= + +#location of the xmlbeans configuration file +maven.xmlbeans2.xmlconfigs=${basedir}/src/schema/xmlconfig.xml + +#location of an xml catalog. If you use one, you must specify the location yourself. +maven.xmlbeans2.cataloglocation= + +#target directory for generated java code. Binary artifacts are place directly into target/classes. +maven.xmlbeans2.targetdir=${basedir}/target/xmlbeans + +#default base location where schemas will be copied. Unlike the ant task, +#they will include the path of the schema listed in the sourceSchemas parameter. +maven.xmlbeans2.baseSchemaLocation=schemaorg_apache_xmlbeans/src + + + diff --git a/xmlbeans/maven-plugin/project.properties b/xmlbeans/maven-plugin/project.properties new file mode 100644 index 000000000..b51959b14 --- /dev/null +++ b/xmlbeans/maven-plugin/project.properties @@ -0,0 +1,28 @@ +# Copyright 2003-2005 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. + +maven.multiproject.type=plugin + +maven.repo.central=apache.org +maven.repo.central.directory=/www/cvs.apache.org/repository + +maven.remote.group=apcvs + +maven.compile.source=1.4 +maven.compile.target=1.4 +#maven.compile.deprecation=true +maven.compile.debug=true +maven.compile.optimize=true + + diff --git a/xmlbeans/maven-plugin/project.xml b/xmlbeans/maven-plugin/project.xml new file mode 100644 index 000000000..2d7937a7a --- /dev/null +++ b/xmlbeans/maven-plugin/project.xml @@ -0,0 +1,88 @@ + + + + + 3 + + xmlbeans + xmlbeans-maven-plugin + 2.0.0-beta1 + xmlbeans maven plugin + + Apache Software Foundation + http://www.apache.org/ + + + 2004 + org.apache.xmlbeans.maven + + + + + xml-resolver + xml-resolver + 1.1 + + + + xmlbeans + xbean + 2.0.0 + + + + stax + stax-api + 1.0 + + + + maven + maven + 1.0.2 + + + + + + src/java + src/test + + + + **/*Test.java + + + + + + src/plugin-resources + plugin-resources + + + . + + plugin.jelly + plugin.properties + project.properties + project.xml + + + + + diff --git a/xmlbeans/maven-plugin/src/java/org/apache/xmlbeans/maven/SchemaCompilerWrapper.java b/xmlbeans/maven-plugin/src/java/org/apache/xmlbeans/maven/SchemaCompilerWrapper.java new file mode 100644 index 000000000..5bc4261e3 --- /dev/null +++ b/xmlbeans/maven-plugin/src/java/org/apache/xmlbeans/maven/SchemaCompilerWrapper.java @@ -0,0 +1,270 @@ +/** + * + * Copyright 2003-2005 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.maven; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.StringTokenizer; + +import org.apache.maven.project.Resource; +import org.apache.xml.resolver.CatalogManager; +import org.apache.xml.resolver.tools.CatalogResolver; +import org.apache.xmlbeans.impl.tool.SchemaCompiler; +import org.xml.sax.EntityResolver; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + + +/** + * + * + * @version $Rev: 46019 $ $Date: 2004-09-14 02:56:06 -0700 (Tue, 14 Sep 2004) $ + * + * */ +public class SchemaCompilerWrapper { + + private String sourceDir; + private String sourceSchemas; + private String xmlConfigs; + private String javaTargetDir; + private String classTargetDir; + private String catalogLocation; + private String classPath; + private List resources; + private boolean buildSchemas; + //this copy should not end in / + private String baseSchemaLocation = "schemaorg_apache_xmlbeans/src"; + + public String getSourceDir() { + return sourceDir; + } + + public void setSourceDir(String sourceDir) { + this.sourceDir = sourceDir; + } + + public String getSourceSchemas() { + return sourceSchemas; + } + + public void setSourceSchemas(String sourceSchemas) { + this.sourceSchemas = sourceSchemas; + } + + public String getXmlConfigs() { + return xmlConfigs; + } + + public void setXmlConfigs(String xmlConfigs) { + this.xmlConfigs = xmlConfigs; + } + + public String getJavaTargetDir() { + return javaTargetDir; + } + + public void setJavaTargetDir(String javaTargetDir) { + this.javaTargetDir = javaTargetDir; + } + + public String getClassTargetDir() { + return classTargetDir; + } + + public void setClassTargetDir(String classTargetDir) { + this.classTargetDir = classTargetDir; + } + + public String getCatalogLocation() { + return catalogLocation; + } + + public void setCatalogLocation(String catalogLocation) { + this.catalogLocation = catalogLocation; + } + + public String getClassPath() { + return classPath; + } + + public void setClassPath(String classPath) { + this.classPath = classPath; + } + + public List getResources() { + return resources; + } + + public void setResources(List resources) { + this.resources = resources; + } + + public boolean isBuildSchemas() { + return buildSchemas; + } + + public void setBuildSchemas(boolean buildSchemas) { + this.buildSchemas = buildSchemas; + } + + public String getBaseSchemaLocation() { + return baseSchemaLocation; + } + + public void setBaseSchemaLocation(String baseSchemaLocation) { + if (baseSchemaLocation != null && !(baseSchemaLocation.length() == 0)) { + this.baseSchemaLocation = baseSchemaLocation; + } + } + + public void compileSchemas() throws Exception { + List schemas = new ArrayList(); + File base = new File(sourceDir); + Resource resource = new Resource(); + resource.setDirectory(sourceDir); + resource.setTargetPath(baseSchemaLocation); + for (StringTokenizer st = new StringTokenizer(sourceSchemas, ","); st.hasMoreTokens();) { + String schemaName = st.nextToken(); + schemas.add(new File(base, schemaName)); + resource.addInclude(schemaName); + } + resources.add(resource); + if (buildSchemas) { + List configs = new ArrayList(); + + if (xmlConfigs != null) { + for (StringTokenizer st = new StringTokenizer(xmlConfigs, ","); st.hasMoreTokens();) { + String configName = st.nextToken(); + configs.add(new File(configName)); + } + } + List classPathList = new ArrayList(); + List urls = new ArrayList(); + if (classPath != null) { + for (StringTokenizer st = new StringTokenizer(classPath, ","); st.hasMoreTokens();) { + String classpathElement = st.nextToken(); + File file = new File(classpathElement); + classPathList.add(file); + urls.add(file.toURL()); + System.out.println("Adding to classpath: " + file); + } + } + ClassLoader cl = new URLClassLoader((URL[]) urls.toArray(new URL[] {})); + EntityResolver entityResolver = null; + if (catalogLocation != null) { + CatalogManager catalogManager = CatalogManager.getStaticManager(); + catalogManager.setCatalogFiles(catalogLocation); + entityResolver = new CatalogResolver(); + } + URI sourceDirURI = new File(sourceDir).toURI(); + entityResolver = new PassThroughResolver(cl, entityResolver, sourceDirURI, baseSchemaLocation); + + SchemaCompiler.Parameters params = new SchemaCompiler.Parameters(); + params.setBaseDir(null); + params.setXsdFiles((File[])schemas.toArray(new File[] {})); + params.setWsdlFiles(new File[] {}); + params.setJavaFiles(new File[] {}); + params.setConfigFiles((File[])configs.toArray(new File[] {})); + params.setClasspath((File[])classPathList.toArray(new File[] {})); + params.setOutputJar(null); + params.setName(null); + params.setSrcDir(new File(javaTargetDir)); + params.setClassesDir(new File(classTargetDir)); + params.setCompiler(null); + params.setMemoryInitialSize(null); + params.setMemoryMaximumSize(null); + params.setNojavac(true); + params.setQuiet(false); + params.setVerbose(true); + params.setDownload(false); + params.setNoUpa(false); + params.setNoPvr(false); + params.setDebug(true); + params.setErrorListener(new ArrayList()); + params.setRepackage(null); + params.setExtensions(null); + params.setMdefNamespaces(null); + params.setEntityResolver(entityResolver); + + boolean result = SchemaCompiler.compile(params); + if (!result) { + Collection errors = params.getErrorListener(); + for (Iterator iterator = errors.iterator(); iterator.hasNext();) { + Object o = (Object) iterator.next(); + System.out.println("xmlbeans error: " + o); + } + throw new Exception("Schema compilation failed"); + } + } + + } + + private static class PassThroughResolver implements EntityResolver { + private final ClassLoader cl; + private final EntityResolver delegate; + private final URI sourceDir; + //this copy has an / appended + private final String baseSchemaLocation; + + public PassThroughResolver(ClassLoader cl, EntityResolver delegate, URI sourceDir, String baseSchemaLocation) { + this.cl = cl; + this.delegate = delegate; + this.sourceDir = sourceDir; + this.baseSchemaLocation = baseSchemaLocation + "/"; + } + public InputSource resolveEntity(String publicId, + String systemId) + throws SAXException, IOException { + if (delegate != null) { + InputSource is = delegate.resolveEntity(publicId, systemId); + if (is != null) { + return is; + } + } + System.out.println("Could not resolve publicId: " + publicId + ", systemId: " + systemId + " from catalog"); + String localSystemId; + try { + localSystemId = sourceDir.relativize(new URI(systemId)).toString(); + } catch (URISyntaxException e) { + throw (IOException)new IOException("Could not relativeize systemId").initCause(e); + } + InputStream in = cl.getResourceAsStream(localSystemId); + if (in != null) { + System.out.println("found in classpath at: " + localSystemId); + return new InputSource(in); + } + in = cl.getResourceAsStream(baseSchemaLocation + localSystemId); + if (in != null) { + System.out.println("found in classpath at: META-INF/" + localSystemId); + return new InputSource(in); + } + System.out.println("Not found in classpath, looking in current directory: " + systemId); + return new InputSource(systemId); + } + + } +} diff --git a/xmlbeans/samples/AbstractTypes/README.txt b/xmlbeans/samples/AbstractTypes/README.txt new file mode 100644 index 000000000..5d417377b --- /dev/null +++ b/xmlbeans/samples/AbstractTypes/README.txt @@ -0,0 +1,35 @@ +Sample: AbstractTypes +Category: abstracttypes +Author: Radu Preotiuc +Last Updated: Feb. 7, 2005 + +Versions: + xmlbeans-v1 1.0.3 + xmlbeans-v2 + +----------------------------------------------------------------------------- + +This sample illustrates the use of abstract XmlSchema types in XmlBeans. + +The scenario is simple: someone declares a generic XmlSchema containing the +basic structure of a document with abstract, generic types and delivers a .jar +file containing the compiled version of that Schema. We then define our own +customization of that schema implementing the abstract types, we compile this +XmlSchema using the .jar that was provided and create a sample instance +document using XmlBeans. +Here are the steps: + +Step1. Create the schema file "abstractBase.xsd" and compile it +to abstractbase.jar. +Step2. Create a Schema that implements the abstract types defined in +"abstractBase.xsd", and compile it with "abstractbase.jar" on the classpath. +Step3. Use the jars created in steps 1 and 2 to create an instance document +using the concrete types. + +To try out this sample: + +1. Set XMLBEANS_HOME in your environment +2. Ant must be on your PATH +3. To compile the schemas and sample source, run "ant build" +4. To execute the sample, run "ant run" + diff --git a/xmlbeans/samples/AbstractTypes/build.xml b/xmlbeans/samples/AbstractTypes/build.xml new file mode 100644 index 000000000..974033f64 --- /dev/null +++ b/xmlbeans/samples/AbstractTypes/build.xml @@ -0,0 +1,108 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/xmlbeans/samples/AbstractTypes/schemas/abstractBase.xsd b/xmlbeans/samples/AbstractTypes/schemas/abstractBase.xsd new file mode 100644 index 000000000..e8463e18f --- /dev/null +++ b/xmlbeans/samples/AbstractTypes/schemas/abstractBase.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + diff --git a/xmlbeans/samples/AbstractTypes/schemas/myfigures.xsd b/xmlbeans/samples/AbstractTypes/schemas/myfigures.xsd new file mode 100644 index 000000000..cf25d3e25 --- /dev/null +++ b/xmlbeans/samples/AbstractTypes/schemas/myfigures.xsd @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/xmlbeans/samples/AbstractTypes/src/org/apache/xmlbeans/samples/abstracttypes/AbstractTypes.java b/xmlbeans/samples/AbstractTypes/src/org/apache/xmlbeans/samples/abstracttypes/AbstractTypes.java new file mode 100644 index 000000000..237fb34b0 --- /dev/null +++ b/xmlbeans/samples/AbstractTypes/src/org/apache/xmlbeans/samples/abstracttypes/AbstractTypes.java @@ -0,0 +1,69 @@ +/* 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.samples.abstracttypes; + +import abstractFigures.*; +import figures.*; +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.XmlOptions; + +/** + * Test class that builds a document using type substitution + */ +public class AbstractTypes +{ + public static void main(String[] args) + { + buildDocument(true); + } + + public static XmlObject buildDocument(boolean enableOutput) + { + XmlOptions opt = (new XmlOptions()).setSavePrettyPrint(); + + // Build a new document + RootDocument doc = RootDocument.Factory.newInstance(); + RootDocument.Root figures = doc.addNewRoot(); + if (enableOutput) + System.out.println("Empty document:\n" + doc.xmlText(opt) + "\n"); + + // Add abstract figures + Shape s1 = figures.addNewFigure(); + s1.setId("001"); + Shape s2 = figures.addNewFigure(); + s2.setId("002"); + // Document contains two shapes now + // Because the shape is abstract, the document will not yet be valid + if (enableOutput) + { + System.out.println("Document containing the abstract types:\n" + doc.xmlText(opt)); + System.out.println("Valid = " + doc.validate() + "\n"); + } + + // Change the abstract figures to concrete ones + Circle circle = (Circle) s1.changeType(Circle.type); + circle.setRadius(10.0); + Square square = (Square) s2.changeType(Square.type); + square.setSide(20.0); + // Document contains two concrete shapes and is valid + if (enableOutput) + { + System.out.println("Final document:\n" + doc.xmlText(opt)); + System.out.println("Vald = " + doc.validate()); + } + + return doc; + } +} diff --git a/xmlbeans/samples/AbstractTypes/src/org/apache/xmlbeans/samples/abstracttypes/AbstractTypesTest.java b/xmlbeans/samples/AbstractTypes/src/org/apache/xmlbeans/samples/abstracttypes/AbstractTypesTest.java new file mode 100644 index 000000000..3f6b0ae54 --- /dev/null +++ b/xmlbeans/samples/AbstractTypes/src/org/apache/xmlbeans/samples/abstracttypes/AbstractTypesTest.java @@ -0,0 +1,30 @@ +/* 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.samples.abstracttypes; + +import org.apache.xmlbeans.XmlObject; + +/** + * Tests the AbstractTypes sample. + */ +public class AbstractTypesTest +{ + public static void main(String[] args) + { + XmlObject doc = AbstractTypes.buildDocument(false); + + assert doc.validate(); + } +} diff --git a/xmlbeans/samples/Any/README.txt b/xmlbeans/samples/Any/README.txt new file mode 100644 index 000000000..6c160c7b4 --- /dev/null +++ b/xmlbeans/samples/Any/README.txt @@ -0,0 +1,41 @@ +Sample: Any +Author: Steven Traut (straut@bea.com) +Last Updated: June 14, 2005 + +Versions: + xmlbeans-v1 1.0.3 + xmlbeans-v2 + +----------------------------------------------------------------------------- + +This sample illustrates how you can use the XMLBeans API to work with +XML based on schema that features xs:any particles. Unlike other schema +types, xs:any in schema does not result in accessors when you use XMLBeans +to compile schema. Instead, your code must use alternate means to access +and create these parts of the XML. These alternate means include: + +- Using XmlCursor instances to "walk" the XML, retrieving and creating +elements. +- Using the selectPath method to retrieve XML via XPath. +- Using the selectChildren method to retrieve elements that are children +by name. +- Using the DOM API to "walk" the node tree, retrieving elements by +name and creating new elements. + +When you run this sample, you'll see it print four blocks of information +in the console: +- Results of the Any.buildDocFromScratch method, which builds from scratch the +XML contents of any.xml included with this sample. +- Results of the Any.editExistingDocWithSelectChildren method, which receives +any.xml and replaces one of its elements. +- Results of the Any.editExistingDocWithDOM method, which receives +any.xml and adds an element. +- Results of the Any.editExistingDocWithSelectPath method, which receives +any.xml, promotes one of its elements, and adds a new element. + +To try out this sample: + +1. Set XMLBEANS_HOME in your environment +2. Ant must be on your PATH +3. To compile the schemas and sample source, run "ant build" +4. To execute the sample, run "ant run" diff --git a/xmlbeans/samples/Any/build.xml b/xmlbeans/samples/Any/build.xml new file mode 100644 index 000000000..12fae5c9b --- /dev/null +++ b/xmlbeans/samples/Any/build.xml @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/xmlbeans/samples/Any/schemas/any.xsd b/xmlbeans/samples/Any/schemas/any.xsd new file mode 100644 index 000000000..04b0539ff --- /dev/null +++ b/xmlbeans/samples/Any/schemas/any.xsd @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/xmlbeans/samples/Any/src/org/apache/xmlbeans/samples/any/ListOfStrings.java b/xmlbeans/samples/Any/src/org/apache/xmlbeans/samples/any/ListOfStrings.java new file mode 100644 index 000000000..3fd01c704 --- /dev/null +++ b/xmlbeans/samples/Any/src/org/apache/xmlbeans/samples/any/ListOfStrings.java @@ -0,0 +1,195 @@ +/* + * XML Type: ListOfStrings + * Namespace: http://xmlbeans.apache.org/samples/any + * Java type: org.apache.xmlbeans.samples.any.ListOfStrings + * + * Automatically generated - do not modify. + */ +package org.apache.xmlbeans.samples.any; + + +/** + * An XML ListOfStrings(@http://xmlbeans.apache.org/samples/any). + * + * This is a complex type. + */ +public interface ListOfStrings extends org.apache.xmlbeans.XmlObject +{ + public static final org.apache.xmlbeans.SchemaType type = (org.apache.xmlbeans.SchemaType)schema.system.s6EF7A0057B3F4CED74AE6E05BCAAB5DB.TypeSystemHolder.typeSystem.resolveHandle("listofstringse467type"); + + /** + * Gets array of all "stringelement" elements + */ + java.lang.String[] getStringelementArray(); + + /** + * Gets ith "stringelement" element + */ + java.lang.String getStringelementArray(int i); + + /** + * Gets (as xml) array of all "stringelement" elements + */ + org.apache.xmlbeans.XmlString[] xgetStringelementArray(); + + /** + * Gets (as xml) ith "stringelement" element + */ + org.apache.xmlbeans.XmlString xgetStringelementArray(int i); + + /** + * Returns number of "stringelement" element + */ + int sizeOfStringelementArray(); + + /** + * Sets array of all "stringelement" element + */ + void setStringelementArray(java.lang.String[] stringelementArray); + + /** + * Sets ith "stringelement" element + */ + void setStringelementArray(int i, java.lang.String stringelement); + + /** + * Sets (as xml) array of all "stringelement" element + */ + void xsetStringelementArray(org.apache.xmlbeans.XmlString[] stringelementArray); + + /** + * Sets (as xml) ith "stringelement" element + */ + void xsetStringelementArray(int i, org.apache.xmlbeans.XmlString stringelement); + + /** + * Inserts the value as the ith "stringelement" element + */ + void insertStringelement(int i, java.lang.String stringelement); + + /** + * Appends the value as the last "stringelement" element + */ + void addStringelement(java.lang.String stringelement); + + /** + * Inserts and returns a new empty value (as xml) as the ith "stringelement" element + */ + org.apache.xmlbeans.XmlString insertNewStringelement(int i); + + /** + * Appends and returns a new empty value (as xml) as the last "stringelement" element + */ + org.apache.xmlbeans.XmlString addNewStringelement(); + + /** + * Removes the ith "stringelement" element + */ + void removeStringelement(int i); + + /** + * Gets the "id" attribute + */ + java.lang.String getId(); + + /** + * Gets (as xml) the "id" attribute + */ + org.apache.xmlbeans.XmlString xgetId(); + + /** + * True if has "id" attribute + */ + boolean isSetId(); + + /** + * Sets the "id" attribute + */ + void setId(java.lang.String id); + + /** + * Sets (as xml) the "id" attribute + */ + void xsetId(org.apache.xmlbeans.XmlString id); + + /** + * Unsets the "id" attribute + */ + void unsetId(); + + /** + * A factory class with static methods for creating instances + * of this type. + */ + + public static final class Factory + { + public static org.apache.xmlbeans.samples.any.ListOfStrings newInstance() { + return (org.apache.xmlbeans.samples.any.ListOfStrings) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().newInstance( type, null ); } + + public static org.apache.xmlbeans.samples.any.ListOfStrings newInstance(org.apache.xmlbeans.XmlOptions options) { + return (org.apache.xmlbeans.samples.any.ListOfStrings) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().newInstance( type, options ); } + + /** @param xmlAsString the string value to parse */ + public static org.apache.xmlbeans.samples.any.ListOfStrings parse(java.lang.String xmlAsString) throws org.apache.xmlbeans.XmlException { + return (org.apache.xmlbeans.samples.any.ListOfStrings) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( xmlAsString, type, null ); } + + public static org.apache.xmlbeans.samples.any.ListOfStrings parse(java.lang.String xmlAsString, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (org.apache.xmlbeans.samples.any.ListOfStrings) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( xmlAsString, type, options ); } + + /** @param file the file from which to load an xml document */ + public static org.apache.xmlbeans.samples.any.ListOfStrings parse(java.io.File file) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (org.apache.xmlbeans.samples.any.ListOfStrings) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( file, type, null ); } + + public static org.apache.xmlbeans.samples.any.ListOfStrings parse(java.io.File file, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (org.apache.xmlbeans.samples.any.ListOfStrings) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( file, type, options ); } + + public static org.apache.xmlbeans.samples.any.ListOfStrings parse(java.net.URL u) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (org.apache.xmlbeans.samples.any.ListOfStrings) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( u, type, null ); } + + public static org.apache.xmlbeans.samples.any.ListOfStrings parse(java.net.URL u, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (org.apache.xmlbeans.samples.any.ListOfStrings) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( u, type, options ); } + + public static org.apache.xmlbeans.samples.any.ListOfStrings parse(java.io.InputStream is) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (org.apache.xmlbeans.samples.any.ListOfStrings) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( is, type, null ); } + + public static org.apache.xmlbeans.samples.any.ListOfStrings parse(java.io.InputStream is, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (org.apache.xmlbeans.samples.any.ListOfStrings) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( is, type, options ); } + + public static org.apache.xmlbeans.samples.any.ListOfStrings parse(java.io.Reader r) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (org.apache.xmlbeans.samples.any.ListOfStrings) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( r, type, null ); } + + public static org.apache.xmlbeans.samples.any.ListOfStrings parse(java.io.Reader r, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (org.apache.xmlbeans.samples.any.ListOfStrings) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( r, type, options ); } + + public static org.apache.xmlbeans.samples.any.ListOfStrings parse(javax.xml.stream.XMLStreamReader sr) throws org.apache.xmlbeans.XmlException { + return (org.apache.xmlbeans.samples.any.ListOfStrings) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( sr, type, null ); } + + public static org.apache.xmlbeans.samples.any.ListOfStrings parse(javax.xml.stream.XMLStreamReader sr, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (org.apache.xmlbeans.samples.any.ListOfStrings) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( sr, type, options ); } + + public static org.apache.xmlbeans.samples.any.ListOfStrings parse(org.w3c.dom.Node node) throws org.apache.xmlbeans.XmlException { + return (org.apache.xmlbeans.samples.any.ListOfStrings) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( node, type, null ); } + + public static org.apache.xmlbeans.samples.any.ListOfStrings parse(org.w3c.dom.Node node, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (org.apache.xmlbeans.samples.any.ListOfStrings) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( node, type, options ); } + + /** @deprecated {@link XMLInputStream} */ + public static org.apache.xmlbeans.samples.any.ListOfStrings parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (org.apache.xmlbeans.samples.any.ListOfStrings) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( xis, type, null ); } + + /** @deprecated {@link XMLInputStream} */ + public static org.apache.xmlbeans.samples.any.ListOfStrings parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (org.apache.xmlbeans.samples.any.ListOfStrings) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( xis, type, options ); } + + /** @deprecated {@link XMLInputStream} */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return org.apache.xmlbeans.XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, null ); } + + /** @deprecated {@link XMLInputStream} */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return org.apache.xmlbeans.XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, options ); } + + private Factory() { } // No instance of this class allowed + } +} diff --git a/xmlbeans/samples/Any/src/org/apache/xmlbeans/samples/any/RootDocument.java b/xmlbeans/samples/Any/src/org/apache/xmlbeans/samples/any/RootDocument.java new file mode 100644 index 000000000..897cdf6e1 --- /dev/null +++ b/xmlbeans/samples/Any/src/org/apache/xmlbeans/samples/any/RootDocument.java @@ -0,0 +1,198 @@ +/* + * An XML document type. + * Localname: root + * Namespace: http://xmlbeans.apache.org/samples/any + * Java type: org.apache.xmlbeans.samples.any.RootDocument + * + * Automatically generated - do not modify. + */ +package org.apache.xmlbeans.samples.any; + + +/** + * A document containing one root(@http://xmlbeans.apache.org/samples/any) element. + * + * This is a complex type. + */ +public interface RootDocument extends org.apache.xmlbeans.XmlObject +{ + public static final org.apache.xmlbeans.SchemaType type = (org.apache.xmlbeans.SchemaType)schema.system.s6EF7A0057B3F4CED74AE6E05BCAAB5DB.TypeSystemHolder.typeSystem.resolveHandle("root9970doctype"); + + /** + * Gets the "root" element + */ + org.apache.xmlbeans.samples.any.RootDocument.Root getRoot(); + + /** + * Sets the "root" element + */ + void setRoot(org.apache.xmlbeans.samples.any.RootDocument.Root root); + + /** + * Appends and returns a new empty "root" element + */ + org.apache.xmlbeans.samples.any.RootDocument.Root addNewRoot(); + + /** + * An XML root(@http://xmlbeans.apache.org/samples/any). + * + * This is a complex type. + */ + public interface Root extends org.apache.xmlbeans.XmlObject + { + public static final org.apache.xmlbeans.SchemaType type = (org.apache.xmlbeans.SchemaType)schema.system.s6EF7A0057B3F4CED74AE6E05BCAAB5DB.TypeSystemHolder.typeSystem.resolveHandle("root2a6eelemtype"); + + /** + * Gets the "stringelement" element + */ + java.lang.String getStringelement(); + + /** + * Gets (as xml) the "stringelement" element + */ + org.apache.xmlbeans.XmlString xgetStringelement(); + + /** + * Sets the "stringelement" element + */ + void setStringelement(java.lang.String stringelement); + + /** + * Sets (as xml) the "stringelement" element + */ + void xsetStringelement(org.apache.xmlbeans.XmlString stringelement); + + /** + * Gets the "arrayofany" element + */ + org.apache.xmlbeans.samples.any.RootDocument.Root.Arrayofany getArrayofany(); + + /** + * Sets the "arrayofany" element + */ + void setArrayofany(org.apache.xmlbeans.samples.any.RootDocument.Root.Arrayofany arrayofany); + + /** + * Appends and returns a new empty "arrayofany" element + */ + org.apache.xmlbeans.samples.any.RootDocument.Root.Arrayofany addNewArrayofany(); + + /** + * An XML arrayofany(@http://xmlbeans.apache.org/samples/any). + * + * This is a complex type. + */ + public interface Arrayofany extends org.apache.xmlbeans.XmlObject + { + public static final org.apache.xmlbeans.SchemaType type = (org.apache.xmlbeans.SchemaType)schema.system.s6EF7A0057B3F4CED74AE6E05BCAAB5DB.TypeSystemHolder.typeSystem.resolveHandle("arrayofany08d6elemtype"); + + /** + * A factory class with static methods for creating instances + * of this type. + */ + + public static final class Factory + { + public static org.apache.xmlbeans.samples.any.RootDocument.Root.Arrayofany newInstance() { + return (org.apache.xmlbeans.samples.any.RootDocument.Root.Arrayofany) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().newInstance( type, null ); } + + public static org.apache.xmlbeans.samples.any.RootDocument.Root.Arrayofany newInstance(org.apache.xmlbeans.XmlOptions options) { + return (org.apache.xmlbeans.samples.any.RootDocument.Root.Arrayofany) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().newInstance( type, options ); } + + private Factory() { } // No instance of this class allowed + } + } + + /** + * A factory class with static methods for creating instances + * of this type. + */ + + public static final class Factory + { + public static org.apache.xmlbeans.samples.any.RootDocument.Root newInstance() { + return (org.apache.xmlbeans.samples.any.RootDocument.Root) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().newInstance( type, null ); } + + public static org.apache.xmlbeans.samples.any.RootDocument.Root newInstance(org.apache.xmlbeans.XmlOptions options) { + return (org.apache.xmlbeans.samples.any.RootDocument.Root) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().newInstance( type, options ); } + + private Factory() { } // No instance of this class allowed + } + } + + /** + * A factory class with static methods for creating instances + * of this type. + */ + + public static final class Factory + { + public static org.apache.xmlbeans.samples.any.RootDocument newInstance() { + return (org.apache.xmlbeans.samples.any.RootDocument) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().newInstance( type, null ); } + + public static org.apache.xmlbeans.samples.any.RootDocument newInstance(org.apache.xmlbeans.XmlOptions options) { + return (org.apache.xmlbeans.samples.any.RootDocument) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().newInstance( type, options ); } + + /** @param xmlAsString the string value to parse */ + public static org.apache.xmlbeans.samples.any.RootDocument parse(java.lang.String xmlAsString) throws org.apache.xmlbeans.XmlException { + return (org.apache.xmlbeans.samples.any.RootDocument) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( xmlAsString, type, null ); } + + public static org.apache.xmlbeans.samples.any.RootDocument parse(java.lang.String xmlAsString, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (org.apache.xmlbeans.samples.any.RootDocument) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( xmlAsString, type, options ); } + + /** @param file the file from which to load an xml document */ + public static org.apache.xmlbeans.samples.any.RootDocument parse(java.io.File file) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (org.apache.xmlbeans.samples.any.RootDocument) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( file, type, null ); } + + public static org.apache.xmlbeans.samples.any.RootDocument parse(java.io.File file, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (org.apache.xmlbeans.samples.any.RootDocument) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( file, type, options ); } + + public static org.apache.xmlbeans.samples.any.RootDocument parse(java.net.URL u) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (org.apache.xmlbeans.samples.any.RootDocument) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( u, type, null ); } + + public static org.apache.xmlbeans.samples.any.RootDocument parse(java.net.URL u, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (org.apache.xmlbeans.samples.any.RootDocument) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( u, type, options ); } + + public static org.apache.xmlbeans.samples.any.RootDocument parse(java.io.InputStream is) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (org.apache.xmlbeans.samples.any.RootDocument) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( is, type, null ); } + + public static org.apache.xmlbeans.samples.any.RootDocument parse(java.io.InputStream is, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (org.apache.xmlbeans.samples.any.RootDocument) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( is, type, options ); } + + public static org.apache.xmlbeans.samples.any.RootDocument parse(java.io.Reader r) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (org.apache.xmlbeans.samples.any.RootDocument) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( r, type, null ); } + + public static org.apache.xmlbeans.samples.any.RootDocument parse(java.io.Reader r, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (org.apache.xmlbeans.samples.any.RootDocument) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( r, type, options ); } + + public static org.apache.xmlbeans.samples.any.RootDocument parse(javax.xml.stream.XMLStreamReader sr) throws org.apache.xmlbeans.XmlException { + return (org.apache.xmlbeans.samples.any.RootDocument) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( sr, type, null ); } + + public static org.apache.xmlbeans.samples.any.RootDocument parse(javax.xml.stream.XMLStreamReader sr, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (org.apache.xmlbeans.samples.any.RootDocument) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( sr, type, options ); } + + public static org.apache.xmlbeans.samples.any.RootDocument parse(org.w3c.dom.Node node) throws org.apache.xmlbeans.XmlException { + return (org.apache.xmlbeans.samples.any.RootDocument) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( node, type, null ); } + + public static org.apache.xmlbeans.samples.any.RootDocument parse(org.w3c.dom.Node node, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (org.apache.xmlbeans.samples.any.RootDocument) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( node, type, options ); } + + /** @deprecated {@link XMLInputStream} */ + public static org.apache.xmlbeans.samples.any.RootDocument parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (org.apache.xmlbeans.samples.any.RootDocument) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( xis, type, null ); } + + /** @deprecated {@link XMLInputStream} */ + public static org.apache.xmlbeans.samples.any.RootDocument parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (org.apache.xmlbeans.samples.any.RootDocument) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( xis, type, options ); } + + /** @deprecated {@link XMLInputStream} */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return org.apache.xmlbeans.XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, null ); } + + /** @deprecated {@link XMLInputStream} */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return org.apache.xmlbeans.XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, options ); } + + private Factory() { } // No instance of this class allowed + } +} diff --git a/xmlbeans/samples/Any/src/org/apache/xmlbeans/samples/any/StringelementDocument.java b/xmlbeans/samples/Any/src/org/apache/xmlbeans/samples/any/StringelementDocument.java new file mode 100644 index 000000000..5e8fd38ca --- /dev/null +++ b/xmlbeans/samples/Any/src/org/apache/xmlbeans/samples/any/StringelementDocument.java @@ -0,0 +1,116 @@ +/* + * An XML document type. + * Localname: stringelement + * Namespace: http://xmlbeans.apache.org/samples/any + * Java type: org.apache.xmlbeans.samples.any.StringelementDocument + * + * Automatically generated - do not modify. + */ +package org.apache.xmlbeans.samples.any; + + +/** + * A document containing one stringelement(@http://xmlbeans.apache.org/samples/any) element. + * + * This is a complex type. + */ +public interface StringelementDocument extends org.apache.xmlbeans.XmlObject +{ + public static final org.apache.xmlbeans.SchemaType type = (org.apache.xmlbeans.SchemaType)schema.system.s6EF7A0057B3F4CED74AE6E05BCAAB5DB.TypeSystemHolder.typeSystem.resolveHandle("stringelementc479doctype"); + + /** + * Gets the "stringelement" element + */ + java.lang.String getStringelement(); + + /** + * Gets (as xml) the "stringelement" element + */ + org.apache.xmlbeans.XmlString xgetStringelement(); + + /** + * Sets the "stringelement" element + */ + void setStringelement(java.lang.String stringelement); + + /** + * Sets (as xml) the "stringelement" element + */ + void xsetStringelement(org.apache.xmlbeans.XmlString stringelement); + + /** + * A factory class with static methods for creating instances + * of this type. + */ + + public static final class Factory + { + public static org.apache.xmlbeans.samples.any.StringelementDocument newInstance() { + return (org.apache.xmlbeans.samples.any.StringelementDocument) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().newInstance( type, null ); } + + public static org.apache.xmlbeans.samples.any.StringelementDocument newInstance(org.apache.xmlbeans.XmlOptions options) { + return (org.apache.xmlbeans.samples.any.StringelementDocument) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().newInstance( type, options ); } + + /** @param xmlAsString the string value to parse */ + public static org.apache.xmlbeans.samples.any.StringelementDocument parse(java.lang.String xmlAsString) throws org.apache.xmlbeans.XmlException { + return (org.apache.xmlbeans.samples.any.StringelementDocument) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( xmlAsString, type, null ); } + + public static org.apache.xmlbeans.samples.any.StringelementDocument parse(java.lang.String xmlAsString, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (org.apache.xmlbeans.samples.any.StringelementDocument) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( xmlAsString, type, options ); } + + /** @param file the file from which to load an xml document */ + public static org.apache.xmlbeans.samples.any.StringelementDocument parse(java.io.File file) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (org.apache.xmlbeans.samples.any.StringelementDocument) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( file, type, null ); } + + public static org.apache.xmlbeans.samples.any.StringelementDocument parse(java.io.File file, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (org.apache.xmlbeans.samples.any.StringelementDocument) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( file, type, options ); } + + public static org.apache.xmlbeans.samples.any.StringelementDocument parse(java.net.URL u) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (org.apache.xmlbeans.samples.any.StringelementDocument) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( u, type, null ); } + + public static org.apache.xmlbeans.samples.any.StringelementDocument parse(java.net.URL u, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (org.apache.xmlbeans.samples.any.StringelementDocument) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( u, type, options ); } + + public static org.apache.xmlbeans.samples.any.StringelementDocument parse(java.io.InputStream is) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (org.apache.xmlbeans.samples.any.StringelementDocument) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( is, type, null ); } + + public static org.apache.xmlbeans.samples.any.StringelementDocument parse(java.io.InputStream is, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (org.apache.xmlbeans.samples.any.StringelementDocument) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( is, type, options ); } + + public static org.apache.xmlbeans.samples.any.StringelementDocument parse(java.io.Reader r) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (org.apache.xmlbeans.samples.any.StringelementDocument) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( r, type, null ); } + + public static org.apache.xmlbeans.samples.any.StringelementDocument parse(java.io.Reader r, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return (org.apache.xmlbeans.samples.any.StringelementDocument) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( r, type, options ); } + + public static org.apache.xmlbeans.samples.any.StringelementDocument parse(javax.xml.stream.XMLStreamReader sr) throws org.apache.xmlbeans.XmlException { + return (org.apache.xmlbeans.samples.any.StringelementDocument) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( sr, type, null ); } + + public static org.apache.xmlbeans.samples.any.StringelementDocument parse(javax.xml.stream.XMLStreamReader sr, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (org.apache.xmlbeans.samples.any.StringelementDocument) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( sr, type, options ); } + + public static org.apache.xmlbeans.samples.any.StringelementDocument parse(org.w3c.dom.Node node) throws org.apache.xmlbeans.XmlException { + return (org.apache.xmlbeans.samples.any.StringelementDocument) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( node, type, null ); } + + public static org.apache.xmlbeans.samples.any.StringelementDocument parse(org.w3c.dom.Node node, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException { + return (org.apache.xmlbeans.samples.any.StringelementDocument) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( node, type, options ); } + + /** @deprecated {@link XMLInputStream} */ + public static org.apache.xmlbeans.samples.any.StringelementDocument parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (org.apache.xmlbeans.samples.any.StringelementDocument) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( xis, type, null ); } + + /** @deprecated {@link XMLInputStream} */ + public static org.apache.xmlbeans.samples.any.StringelementDocument parse(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return (org.apache.xmlbeans.samples.any.StringelementDocument) org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( xis, type, options ); } + + /** @deprecated {@link XMLInputStream} */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return org.apache.xmlbeans.XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, null ); } + + /** @deprecated {@link XMLInputStream} */ + public static org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream(org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { + return org.apache.xmlbeans.XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, options ); } + + private Factory() { } // No instance of this class allowed + } +} diff --git a/xmlbeans/samples/Any/src/org/apache/xmlbeans/samples/any/impl/ListOfStringsImpl.java b/xmlbeans/samples/Any/src/org/apache/xmlbeans/samples/any/impl/ListOfStringsImpl.java new file mode 100644 index 000000000..e8cf3f3a6 --- /dev/null +++ b/xmlbeans/samples/Any/src/org/apache/xmlbeans/samples/any/impl/ListOfStringsImpl.java @@ -0,0 +1,328 @@ +/* + * XML Type: ListOfStrings + * Namespace: http://xmlbeans.apache.org/samples/any + * Java type: org.apache.xmlbeans.samples.any.ListOfStrings + * + * Automatically generated - do not modify. + */ +package org.apache.xmlbeans.samples.any.impl; +/** + * An XML ListOfStrings(@http://xmlbeans.apache.org/samples/any). + * + * This is a complex type. + */ +public class ListOfStringsImpl extends org.apache.xmlbeans.impl.values.XmlComplexContentImpl implements org.apache.xmlbeans.samples.any.ListOfStrings +{ + + public ListOfStringsImpl(org.apache.xmlbeans.SchemaType sType) + { + super(sType); + } + + private static final javax.xml.namespace.QName STRINGELEMENT$0 = + new javax.xml.namespace.QName("http://xmlbeans.apache.org/samples/any", "stringelement"); + private static final javax.xml.namespace.QName ID$2 = + new javax.xml.namespace.QName("", "id"); + + + /** + * Gets array of all "stringelement" elements + */ + public java.lang.String[] getStringelementArray() + { + synchronized (monitor()) + { + check_orphaned(); + java.util.List targetList = new java.util.ArrayList(); + get_store().find_all_element_users(STRINGELEMENT$0, targetList); + java.lang.String[] result = new java.lang.String[targetList.size()]; + for (int i = 0, len = targetList.size() ; i < len ; i++) + result[i] = ((org.apache.xmlbeans.SimpleValue)targetList.get(i)).getStringValue(); + return result; + } + } + + /** + * Gets ith "stringelement" element + */ + public java.lang.String getStringelementArray(int i) + { + synchronized (monitor()) + { + check_orphaned(); + org.apache.xmlbeans.SimpleValue target = null; + target = (org.apache.xmlbeans.SimpleValue)get_store().find_element_user(STRINGELEMENT$0, i); + if (target == null) + { + throw new IndexOutOfBoundsException(); + } + return target.getStringValue(); + } + } + + /** + * Gets (as xml) array of all "stringelement" elements + */ + public org.apache.xmlbeans.XmlString[] xgetStringelementArray() + { + synchronized (monitor()) + { + check_orphaned(); + java.util.List targetList = new java.util.ArrayList(); + get_store().find_all_element_users(STRINGELEMENT$0, targetList); + org.apache.xmlbeans.XmlString[] result = new org.apache.xmlbeans.XmlString[targetList.size()]; + targetList.toArray(result); + return result; + } + } + + /** + * Gets (as xml) ith "stringelement" element + */ + public org.apache.xmlbeans.XmlString xgetStringelementArray(int i) + { + synchronized (monitor()) + { + check_orphaned(); + org.apache.xmlbeans.XmlString target = null; + target = (org.apache.xmlbeans.XmlString)get_store().find_element_user(STRINGELEMENT$0, i); + if (target == null) + { + throw new IndexOutOfBoundsException(); + } + return (org.apache.xmlbeans.XmlString)target; + } + } + + /** + * Returns number of "stringelement" element + */ + public int sizeOfStringelementArray() + { + synchronized (monitor()) + { + check_orphaned(); + return get_store().count_elements(STRINGELEMENT$0); + } + } + + /** + * Sets array of all "stringelement" element + */ + public void setStringelementArray(java.lang.String[] stringelementArray) + { + synchronized (monitor()) + { + check_orphaned(); + arraySetterHelper(stringelementArray, STRINGELEMENT$0); + } + } + + /** + * Sets ith "stringelement" element + */ + public void setStringelementArray(int i, java.lang.String stringelement) + { + synchronized (monitor()) + { + check_orphaned(); + org.apache.xmlbeans.SimpleValue target = null; + target = (org.apache.xmlbeans.SimpleValue)get_store().find_element_user(STRINGELEMENT$0, i); + if (target == null) + { + throw new IndexOutOfBoundsException(); + } + target.setStringValue(stringelement); + } + } + + /** + * Sets (as xml) array of all "stringelement" element + */ + public void xsetStringelementArray(org.apache.xmlbeans.XmlString[]stringelementArray) + { + synchronized (monitor()) + { + check_orphaned(); + arraySetterHelper(stringelementArray, STRINGELEMENT$0); + } + } + + /** + * Sets (as xml) ith "stringelement" element + */ + public void xsetStringelementArray(int i, org.apache.xmlbeans.XmlString stringelement) + { + synchronized (monitor()) + { + check_orphaned(); + org.apache.xmlbeans.XmlString target = null; + target = (org.apache.xmlbeans.XmlString)get_store().find_element_user(STRINGELEMENT$0, i); + if (target == null) + { + throw new IndexOutOfBoundsException(); + } + target.set(stringelement); + } + } + + /** + * Inserts the value as the ith "stringelement" element + */ + public void insertStringelement(int i, java.lang.String stringelement) + { + synchronized (monitor()) + { + check_orphaned(); + org.apache.xmlbeans.SimpleValue target = + (org.apache.xmlbeans.SimpleValue)get_store().insert_element_user(STRINGELEMENT$0, i); + target.setStringValue(stringelement); + } + } + + /** + * Appends the value as the last "stringelement" element + */ + public void addStringelement(java.lang.String stringelement) + { + synchronized (monitor()) + { + check_orphaned(); + org.apache.xmlbeans.SimpleValue target = null; + target = (org.apache.xmlbeans.SimpleValue)get_store().add_element_user(STRINGELEMENT$0); + target.setStringValue(stringelement); + } + } + + /** + * Inserts and returns a new empty value (as xml) as the ith "stringelement" element + */ + public org.apache.xmlbeans.XmlString insertNewStringelement(int i) + { + synchronized (monitor()) + { + check_orphaned(); + org.apache.xmlbeans.XmlString target = null; + target = (org.apache.xmlbeans.XmlString)get_store().insert_element_user(STRINGELEMENT$0, i); + return target; + } + } + + /** + * Appends and returns a new empty value (as xml) as the last "stringelement" element + */ + public org.apache.xmlbeans.XmlString addNewStringelement() + { + synchronized (monitor()) + { + check_orphaned(); + org.apache.xmlbeans.XmlString target = null; + target = (org.apache.xmlbeans.XmlString)get_store().add_element_user(STRINGELEMENT$0); + return target; + } + } + + /** + * Removes the ith "stringelement" element + */ + public void removeStringelement(int i) + { + synchronized (monitor()) + { + check_orphaned(); + get_store().remove_element(STRINGELEMENT$0, i); + } + } + + /** + * Gets the "id" attribute + */ + public java.lang.String getId() + { + synchronized (monitor()) + { + check_orphaned(); + org.apache.xmlbeans.SimpleValue target = null; + target = (org.apache.xmlbeans.SimpleValue)get_store().find_attribute_user(ID$2); + if (target == null) + { + return null; + } + return target.getStringValue(); + } + } + + /** + * Gets (as xml) the "id" attribute + */ + public org.apache.xmlbeans.XmlString xgetId() + { + synchronized (monitor()) + { + check_orphaned(); + org.apache.xmlbeans.XmlString target = null; + target = (org.apache.xmlbeans.XmlString)get_store().find_attribute_user(ID$2); + return target; + } + } + + /** + * True if has "id" attribute + */ + public boolean isSetId() + { + synchronized (monitor()) + { + check_orphaned(); + return get_store().find_attribute_user(ID$2) != null; + } + } + + /** + * Sets the "id" attribute + */ + public void setId(java.lang.String id) + { + synchronized (monitor()) + { + check_orphaned(); + org.apache.xmlbeans.SimpleValue target = null; + target = (org.apache.xmlbeans.SimpleValue)get_store().find_attribute_user(ID$2); + if (target == null) + { + target = (org.apache.xmlbeans.SimpleValue)get_store().add_attribute_user(ID$2); + } + target.setStringValue(id); + } + } + + /** + * Sets (as xml) the "id" attribute + */ + public void xsetId(org.apache.xmlbeans.XmlString id) + { + synchronized (monitor()) + { + check_orphaned(); + org.apache.xmlbeans.XmlString target = null; + target = (org.apache.xmlbeans.XmlString)get_store().find_attribute_user(ID$2); + if (target == null) + { + target = (org.apache.xmlbeans.XmlString)get_store().add_attribute_user(ID$2); + } + target.set(id); + } + } + + /** + * Unsets the "id" attribute + */ + public void unsetId() + { + synchronized (monitor()) + { + check_orphaned(); + get_store().remove_attribute(ID$2); + } + } +} diff --git a/xmlbeans/samples/Any/src/org/apache/xmlbeans/samples/any/impl/RootDocumentImpl.java b/xmlbeans/samples/Any/src/org/apache/xmlbeans/samples/any/impl/RootDocumentImpl.java new file mode 100644 index 000000000..8ff266f16 --- /dev/null +++ b/xmlbeans/samples/Any/src/org/apache/xmlbeans/samples/any/impl/RootDocumentImpl.java @@ -0,0 +1,228 @@ +/* + * An XML document type. + * Localname: root + * Namespace: http://xmlbeans.apache.org/samples/any + * Java type: org.apache.xmlbeans.samples.any.RootDocument + * + * Automatically generated - do not modify. + */ +package org.apache.xmlbeans.samples.any.impl; +/** + * A document containing one root(@http://xmlbeans.apache.org/samples/any) element. + * + * This is a complex type. + */ +public class RootDocumentImpl extends org.apache.xmlbeans.impl.values.XmlComplexContentImpl implements org.apache.xmlbeans.samples.any.RootDocument +{ + + public RootDocumentImpl(org.apache.xmlbeans.SchemaType sType) + { + super(sType); + } + + private static final javax.xml.namespace.QName ROOT$0 = + new javax.xml.namespace.QName("http://xmlbeans.apache.org/samples/any", "root"); + + + /** + * Gets the "root" element + */ + public org.apache.xmlbeans.samples.any.RootDocument.Root getRoot() + { + synchronized (monitor()) + { + check_orphaned(); + org.apache.xmlbeans.samples.any.RootDocument.Root target = null; + target = (org.apache.xmlbeans.samples.any.RootDocument.Root)get_store().find_element_user(ROOT$0, 0); + if (target == null) + { + return null; + } + return target; + } + } + + /** + * Sets the "root" element + */ + public void setRoot(org.apache.xmlbeans.samples.any.RootDocument.Root root) + { + synchronized (monitor()) + { + check_orphaned(); + org.apache.xmlbeans.samples.any.RootDocument.Root target = null; + target = (org.apache.xmlbeans.samples.any.RootDocument.Root)get_store().find_element_user(ROOT$0, 0); + if (target == null) + { + target = (org.apache.xmlbeans.samples.any.RootDocument.Root)get_store().add_element_user(ROOT$0); + } + target.set(root); + } + } + + /** + * Appends and returns a new empty "root" element + */ + public org.apache.xmlbeans.samples.any.RootDocument.Root addNewRoot() + { + synchronized (monitor()) + { + check_orphaned(); + org.apache.xmlbeans.samples.any.RootDocument.Root target = null; + target = (org.apache.xmlbeans.samples.any.RootDocument.Root)get_store().add_element_user(ROOT$0); + return target; + } + } + /** + * An XML root(@http://xmlbeans.apache.org/samples/any). + * + * This is a complex type. + */ + public static class RootImpl extends org.apache.xmlbeans.impl.values.XmlComplexContentImpl implements org.apache.xmlbeans.samples.any.RootDocument.Root + { + + public RootImpl(org.apache.xmlbeans.SchemaType sType) + { + super(sType); + } + + private static final javax.xml.namespace.QName STRINGELEMENT$0 = + new javax.xml.namespace.QName("http://xmlbeans.apache.org/samples/any", "stringelement"); + private static final javax.xml.namespace.QName ARRAYOFANY$2 = + new javax.xml.namespace.QName("http://xmlbeans.apache.org/samples/any", "arrayofany"); + + + /** + * Gets the "stringelement" element + */ + public java.lang.String getStringelement() + { + synchronized (monitor()) + { + check_orphaned(); + org.apache.xmlbeans.SimpleValue target = null; + target = (org.apache.xmlbeans.SimpleValue)get_store().find_element_user(STRINGELEMENT$0, 0); + if (target == null) + { + return null; + } + return target.getStringValue(); + } + } + + /** + * Gets (as xml) the "stringelement" element + */ + public org.apache.xmlbeans.XmlString xgetStringelement() + { + synchronized (monitor()) + { + check_orphaned(); + org.apache.xmlbeans.XmlString target = null; + target = (org.apache.xmlbeans.XmlString)get_store().find_element_user(STRINGELEMENT$0, 0); + return target; + } + } + + /** + * Sets the "stringelement" element + */ + public void setStringelement(java.lang.String stringelement) + { + synchronized (monitor()) + { + check_orphaned(); + org.apache.xmlbeans.SimpleValue target = null; + target = (org.apache.xmlbeans.SimpleValue)get_store().find_element_user(STRINGELEMENT$0, 0); + if (target == null) + { + target = (org.apache.xmlbeans.SimpleValue)get_store().add_element_user(STRINGELEMENT$0); + } + target.setStringValue(stringelement); + } + } + + /** + * Sets (as xml) the "stringelement" element + */ + public void xsetStringelement(org.apache.xmlbeans.XmlString stringelement) + { + synchronized (monitor()) + { + check_orphaned(); + org.apache.xmlbeans.XmlString target = null; + target = (org.apache.xmlbeans.XmlString)get_store().find_element_user(STRINGELEMENT$0, 0); + if (target == null) + { + target = (org.apache.xmlbeans.XmlString)get_store().add_element_user(STRINGELEMENT$0); + } + target.set(stringelement); + } + } + + /** + * Gets the "arrayofany" element + */ + public org.apache.xmlbeans.samples.any.RootDocument.Root.Arrayofany getArrayofany() + { + synchronized (monitor()) + { + check_orphaned(); + org.apache.xmlbeans.samples.any.RootDocument.Root.Arrayofany target = null; + target = (org.apache.xmlbeans.samples.any.RootDocument.Root.Arrayofany)get_store().find_element_user(ARRAYOFANY$2, 0); + if (target == null) + { + return null; + } + return target; + } + } + + /** + * Sets the "arrayofany" element + */ + public void setArrayofany(org.apache.xmlbeans.samples.any.RootDocument.Root.Arrayofany arrayofany) + { + synchronized (monitor()) + { + check_orphaned(); + org.apache.xmlbeans.samples.any.RootDocument.Root.Arrayofany target = null; + target = (org.apache.xmlbeans.samples.any.RootDocument.Root.Arrayofany)get_store().find_element_user(ARRAYOFANY$2, 0); + if (target == null) + { + target = (org.apache.xmlbeans.samples.any.RootDocument.Root.Arrayofany)get_store().add_element_user(ARRAYOFANY$2); + } + target.set(arrayofany); + } + } + + /** + * Appends and returns a new empty "arrayofany" element + */ + public org.apache.xmlbeans.samples.any.RootDocument.Root.Arrayofany addNewArrayofany() + { + synchronized (monitor()) + { + check_orphaned(); + org.apache.xmlbeans.samples.any.RootDocument.Root.Arrayofany target = null; + target = (org.apache.xmlbeans.samples.any.RootDocument.Root.Arrayofany)get_store().add_element_user(ARRAYOFANY$2); + return target; + } + } + /** + * An XML arrayofany(@http://xmlbeans.apache.org/samples/any). + * + * This is a complex type. + */ + public static class ArrayofanyImpl extends org.apache.xmlbeans.impl.values.XmlComplexContentImpl implements org.apache.xmlbeans.samples.any.RootDocument.Root.Arrayofany + { + + public ArrayofanyImpl(org.apache.xmlbeans.SchemaType sType) + { + super(sType); + } + + + } + } +} diff --git a/xmlbeans/samples/Any/src/org/apache/xmlbeans/samples/any/impl/StringelementDocumentImpl.java b/xmlbeans/samples/Any/src/org/apache/xmlbeans/samples/any/impl/StringelementDocumentImpl.java new file mode 100644 index 000000000..6c82e5c88 --- /dev/null +++ b/xmlbeans/samples/Any/src/org/apache/xmlbeans/samples/any/impl/StringelementDocumentImpl.java @@ -0,0 +1,94 @@ +/* + * An XML document type. + * Localname: stringelement + * Namespace: http://xmlbeans.apache.org/samples/any + * Java type: org.apache.xmlbeans.samples.any.StringelementDocument + * + * Automatically generated - do not modify. + */ +package org.apache.xmlbeans.samples.any.impl; +/** + * A document containing one stringelement(@http://xmlbeans.apache.org/samples/any) element. + * + * This is a complex type. + */ +public class StringelementDocumentImpl extends org.apache.xmlbeans.impl.values.XmlComplexContentImpl implements org.apache.xmlbeans.samples.any.StringelementDocument +{ + + public StringelementDocumentImpl(org.apache.xmlbeans.SchemaType sType) + { + super(sType); + } + + private static final javax.xml.namespace.QName STRINGELEMENT$0 = + new javax.xml.namespace.QName("http://xmlbeans.apache.org/samples/any", "stringelement"); + + + /** + * Gets the "stringelement" element + */ + public java.lang.String getStringelement() + { + synchronized (monitor()) + { + check_orphaned(); + org.apache.xmlbeans.SimpleValue target = null; + target = (org.apache.xmlbeans.SimpleValue)get_store().find_element_user(STRINGELEMENT$0, 0); + if (target == null) + { + return null; + } + return target.getStringValue(); + } + } + + /** + * Gets (as xml) the "stringelement" element + */ + public org.apache.xmlbeans.XmlString xgetStringelement() + { + synchronized (monitor()) + { + check_orphaned(); + org.apache.xmlbeans.XmlString target = null; + target = (org.apache.xmlbeans.XmlString)get_store().find_element_user(STRINGELEMENT$0, 0); + return target; + } + } + + /** + * Sets the "stringelement" element + */ + public void setStringelement(java.lang.String stringelement) + { + synchronized (monitor()) + { + check_orphaned(); + org.apache.xmlbeans.SimpleValue target = null; + target = (org.apache.xmlbeans.SimpleValue)get_store().find_element_user(STRINGELEMENT$0, 0); + if (target == null) + { + target = (org.apache.xmlbeans.SimpleValue)get_store().add_element_user(STRINGELEMENT$0); + } + target.setStringValue(stringelement); + } + } + + /** + * Sets (as xml) the "stringelement" element + */ + public void xsetStringelement(org.apache.xmlbeans.XmlString stringelement) + { + synchronized (monitor()) + { + check_orphaned(); + org.apache.xmlbeans.XmlString target = null; + target = (org.apache.xmlbeans.XmlString)get_store().find_element_user(STRINGELEMENT$0, 0); + if (target == null) + { + target = (org.apache.xmlbeans.XmlString)get_store().add_element_user(STRINGELEMENT$0); + } + target.set(stringelement); + } + } +} diff --git a/xmlbeans/samples/Any/src/org/apache/xmlbeans/samples/anytype/Any.java b/xmlbeans/samples/Any/src/org/apache/xmlbeans/samples/anytype/Any.java new file mode 100644 index 000000000..058836122 --- /dev/null +++ b/xmlbeans/samples/Any/src/org/apache/xmlbeans/samples/anytype/Any.java @@ -0,0 +1,457 @@ +/* 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.samples.anytype; + +import org.apache.xmlbeans.*; +import org.apache.xmlbeans.samples.any.ListOfStrings; +import org.apache.xmlbeans.samples.any.RootDocument; +import org.apache.xmlbeans.samples.any.StringelementDocument; +import org.apache.xmlbeans.samples.any.RootDocument.Root.Arrayofany; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; + +import javax.xml.namespace.QName; + +/** + * A sample that illustrates various ways to manipulate XML whose + * schema defines elements as type xs:any. Unlike its treatment of + * other schema types, XMLBeans does not generate accessors for the + * xs:any particle when compiling schema. Instead, your code + * handles instances of this type through any of several alternative + * means, including XPath queries, the selectChildren method, + * XmlCursor instances and the DOM API. This samples illustrates + * these alternative approaches. + */ +public class Any +{ + private static final String m_namespaceUri = "http://xmlbeans.apache.org/samples/any"; + + /** + * Receives XML instance, executing methods that + * edit the received instance or create a new one. + * + * @param args An array in which the first item is a + * path to the XML instance file. + */ + public static void main(String[] args) + { + Any thisSample = new Any(); + System.out.println("Running Any.buildDocFromScratch\n"); + thisSample.buildDocFromScratch(); + + RootDocument rootDoc = (RootDocument)thisSample.parseXml(args[0]); + + System.out.println("Running Any.editExistingDocWithSelectChildren\n"); + thisSample.editExistingDocWithSelectChildren(rootDoc); + + System.out.println("Running Any.editExistingDocWithDOM\n"); + thisSample.editExistingDocWithDOM(rootDoc); + + System.out.println("Running Any.editExistingDocWithSelectPath\n"); + thisSample.editExistingDocWithSelectPath(rootDoc); + } + + /** + * Creates a new document from scratch. + * + * This method illustrates how you can use XmlCursor instances + * to build XML that is defined in schema as xs:any. + * + * @return true if the new document is valid; + * otherwise, false. + */ + public boolean buildDocFromScratch() + { + // Start by creating a element that will contain + // the children built by this method. + RootDocument rootDoc = RootDocument.Factory.newInstance(); + RootDocument.Root root = rootDoc.addNewRoot(); + + // Add the first element, . + root.setStringelement("some text"); + + // Create an XmlObject in which to build the second + // element in the sequence, . Here, the + // XmlObject instance is simply a kind of incubator + // for the XML. Later the XML will be moved into the + // document this code is building. + XmlObject anyFoo = XmlObject.Factory.newInstance(); + + // Add a cursor to do the work of building the XML. + XmlCursor childCursor = anyFoo.newCursor(); + childCursor.toNextToken(); + + // Add the element in the schema's namespace, then add + // element content. + childCursor.beginElement(new QName(m_namespaceUri, "anyfoo")); + childCursor.insertChars("some text"); + + // Move the cursor back to the new element's top, where + // it can grab the element's XML. + childCursor.toStartDoc(); + childCursor.toNextToken(); + + // Move the XML into the document by moving it + // from a position at one cursor to a position at + // another. + XmlCursor rootCursor = root.newCursor(); + rootCursor.toEndToken(); + childCursor.moveXml(rootCursor); + + // Add the fourth element, , by building it + // elsewhere, then moving the new XML into place under + // . + Arrayofany arrayOfAny = root.addNewArrayofany(); + if (buildArrayOfAny(arrayOfAny) == null) + { + return false; + } + + childCursor.dispose(); + rootCursor.dispose(); + + // Print and validate the result. + System.out.println("Output: The document built from scratch.\n"); + System.out.println(rootDoc + "\n"); + return validateXml(rootDoc); + } + + /** + * Replaces the element with an element in the + * incoming XML. + * + * This method illustrates how you can use the XmlCursor.selectChildren + * method to retrieve child elements whose type is defined as + * xs:any in schema. + * + * @param rootDoc An instance of the XML document. + * @return true if the editing XML is valid; + * otherwise, false. + */ + public boolean editExistingDocWithSelectChildren(RootDocument rootDoc) + { + RootDocument.Root root = rootDoc.getRoot(); + + // Select the children of . + XmlObject[] stringElements = + root.selectChildren(new QName(m_namespaceUri, "anyfoo")); + + // If the element is there, replace it with another element. + if (stringElements.length > 0) + { + XmlCursor editCursor = stringElements[0].newCursor(); + editCursor.removeXml(); + editCursor.beginElement(new QName(m_namespaceUri, "anybar")); + editCursor.insertChars("some other text"); + editCursor.dispose(); + } + System.out.println("Output: The element has been replaced\n" + + "by an element.\n"); + System.out.println(rootDoc + "\n"); + return validateXml(rootDoc); + } + + /** + * Adds a new element between the first and second + * children of the element. + * + * This method illustrates how you can use DOM methods to + * retrieve and edit elements whose type is defined as + * xs:any in schema. + * + * @param rootDoc An instance of the XML document. + * @return true if the editing XML is valid; + * otherwise, false. + */ + public boolean editExistingDocWithDOM(RootDocument rootDoc) + { + RootDocument.Root root = rootDoc.getRoot(); + + // Get the DOM nodes for the element's children. + Node arrayOfAnyNode = root.getArrayofany().getDomNode(); + + // You don't have get* accessors for any of the + // element's children, so use DOM to identify the first + // and second elements while looping through the child list. + NodeList childList = arrayOfAnyNode.getChildNodes(); + Element firstElementChild = null; + Element secondElementChild = null; + + // Find the first child element and make sure it's + // . + for (int i = 0; i < childList.getLength(); i++) + { + Node node = childList.item(i); + if (node.getNodeType() == Node.ELEMENT_NODE) + { + if (node.getLocalName().equals("stringelement")) + { + firstElementChild = (Element)node; + break; + } + } + } + if (firstElementChild == null) {return false;} + + // Find the second child element and make sure it's + // . + Node node = firstElementChild.getNextSibling(); + do { + if (node.getNodeType() == Node.ELEMENT_NODE) + { + if (node.getLocalName().equals("someelement")) + { + secondElementChild = (Element)node; + break; + } + } + node = node.getNextSibling(); + } while (node != null); + if (secondElementChild == null) {return false;} + + // Create and insert a new element. + Element fooElement = + secondElementChild.getOwnerDocument().createElementNS("http://openuri.org","bar"); + Node valueNode = + fooElement.getOwnerDocument().createTextNode("some text"); + fooElement.appendChild(valueNode); + arrayOfAnyNode.insertBefore(fooElement, secondElementChild); + + System.out.println("Output: has a new child element.\n"); + System.out.println(rootDoc + "\n"); + return validateXml(rootDoc); + } + + /** + * Edits incoming XML to make the following changes: replace + * with its child; add a new + * element as the second child of . + * + * This method illustrates how you can use the selectPath method + * to find an element defined as xs:any in schema, then use + * XmlCursor instances to edit the XML. + * + * @param rootDoc An instance of the XML document. + * @return true if the editing XML is valid; + * otherwise, false. + */ + public boolean editExistingDocWithSelectPath(RootDocument rootDoc) + { + String namespaceDecl = "declare namespace any='" + + m_namespaceUri + "'; "; + XmlCursor selectionCursor = rootDoc.getRoot().getArrayofany().newCursor(); + + // Save the cursor's position for later, then use XPath + // and cursor movement to position the cursor at + // the element. + selectionCursor.push(); + selectionCursor.selectPath(namespaceDecl + + "$this//any:someelement/any:stringlist"); + selectionCursor.toNextSelection(); + + // Create a new cursor and move it to the selection + // cursor's parent. Moving the + // element to this position, displacing + // the downward, then removing the + // XML effectively replaces + // with . + XmlCursor editCursor = selectionCursor.newCursor(); + editCursor.toParent(); + selectionCursor.moveXml(editCursor); + editCursor.removeXml(); + editCursor.dispose(); + + // Return the cursor to the element so you + // can do more editing. Then move the cursor to the second + // child and insert a new element as second child. + selectionCursor.pop(); + selectionCursor.toFirstChild(); + selectionCursor.toNextSibling(); + selectionCursor.beginElement("foo", "http://openuri.org"); + selectionCursor.insertChars("some text"); + selectionCursor.dispose(); + + System.out.println("Output: has been promoted to replace \n" + + ", and there's a new element.\n"); + System.out.println(rootDoc + "\n"); + return validateXml(rootDoc); + } + + /** + * Like the code in the buildDocFromScratch method, this code + * uses the XmlCursor to build XML piece by piece, building + * out the Arrayofany instance it receives. + * + * @return A valid element bound to an + * Arrrayofany instance. + */ + private Arrayofany buildArrayOfAny(Arrayofany arrayOfAny) + { + // Create a simple and move it into place + // under . + StringelementDocument stringElementDoc = + StringelementDocument.Factory.newInstance(); + stringElementDoc.setStringelement("some text"); + XmlCursor childCursor = stringElementDoc.newCursor(); + childCursor.toFirstContentToken(); + + // Add a cursor to mark the position at which the new child + // XML will be moved. + XmlCursor arrayCursor = arrayOfAny.newCursor(); + arrayCursor.toNextToken(); + childCursor.moveXml(arrayCursor); + childCursor.dispose(); + + // Create a that contains a + // child element, then get the XmlObject representing the new + // . Note that the XmlCursor.beginElement method + // leaves the cursor between START and END tokens -- where + // content can be placed. + arrayCursor.beginElement("someelement", m_namespaceUri); + arrayCursor.beginElement("stringlist", m_namespaceUri); + arrayCursor.toPrevToken(); + XmlObject stringList = arrayCursor.getObject(); + + // The cursor's no longer needed. + arrayCursor.dispose(); + + // Create the element's value and set it. + ListOfStrings stringListValue = buildListOfStrings(); + if (stringListValue == null) + { + return null; + } + stringList.set(stringListValue); + + // Validate the new XML. + if (!validateXml(arrayOfAny)) + { + return null; + } + + return arrayOfAny; + } + + /** + * Creates an instance of the ListOfStrings complex type defined + * in the schema. The instance returned by this method can be + * inserted using either a set* operation or a cursor, as in + * {@link #buildArrayOfAny()}. + * + * @return A valid instance of ListOfStrings. + */ + private ListOfStrings buildListOfStrings() + { + // Create an instance of the ListOfStrings complex type. + ListOfStrings stringList = ListOfStrings.Factory.newInstance(); + stringList.setId("001"); + + // Add two children for the instance's root. + XmlString stringElement = stringList.addNewStringelement(); + stringElement.setStringValue("string1"); + stringElement = stringList.addNewStringelement(); + stringElement.setStringValue("string2"); + + // Validate the new XML. + if (!validateXml(stringList)) + { + return null; + } + + return stringList; + } + + /** + *

    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 literal 0 HcmV?d00001 diff --git a/xmlbeans/external/lib/piccolo.LICENSE.txt b/xmlbeans/external/lib/piccolo.LICENSE.txt new file mode 100644 index 000000000..57bc88a15 --- /dev/null +++ b/xmlbeans/external/lib/piccolo.LICENSE.txt @@ -0,0 +1,202 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. + diff --git a/xmlbeans/external/lib/piccolo_apache_dist_20040629.jar b/xmlbeans/external/lib/piccolo_apache_dist_20040629.jar new file mode 100644 index 0000000000000000000000000000000000000000..7113ab63ce6d0ca6745466019fc6b353ccb5b49a GIT binary patch literal 141219 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 AWdHyG literal 0 HcmV?d00001 diff --git a/xmlbeans/external/lib/piccolo_apache_dist_20040629_v2.jar b/xmlbeans/external/lib/piccolo_apache_dist_20040629_v2.jar new file mode 100644 index 0000000000000000000000000000000000000000..66f4e248443e2f74a881a723cb4ca5fd9e90f1d9 GIT binary patch literal 143156 zcmaHS18{BIwry36$I&olI;TX$T~3 zjp!(0p!tra+`{hf8Gn5T0kCMe&HxUm59kUE008p+8_54*hOoJTgQJO)h>4M% zv55nnrGbk(r|0`Zxyal}C}>98lGPzj$DQGdwt{yE%4OPCv%HDlJl}Bbo?FAN8-2@SU?JIJ191K zpF*PIaOg=CRGkQKjKV3-1bfPukQqw8TC-kA{gf3;^rv88NlHqjwWKj#7?p-Jc@{fg z$KDK?(hw~FvL)^xi({=ov>nzSsAb6C zOO>Z1`A6?&K}hMub2T=*5i7|kYc;ch?WH02+}hH*(H}fEqroV`izUidRMZM+0UNjW zaQi<}2D?QQ_QcDLw^#BuxQdxAN3wCuqh>avETv!XJ<4AxvjL|m9~|SJ?>~%V1`Wx9 zEz5U)Hu2{h(4wcZfAxagz61nShtcXuAh|+97zN?a%2OJ0)+C2o=i6a(RgPb$Hqow; zs4R96WYBr^9$klXKO*3gw%)B8~=TNk7~CA3_U2NLmvovu7qm=9O9_`e6T zfPvUtxR-_PP@G6f{$SlcPUhz&psxq157kUxv@*fLD>T2_oT#_xg;M?WzuCsdnBO+9 zdoGZAZMKRY@aj5`{6*j9i|6CdKASLt8TpCq;SB-HXb&*+qZAyUZAWvm>v|fx=kz|c zha0SiT==!sN@^+ZxBJtrNzm0K27!0D3pUvvEGO7_s{c%~m@C@nrSk@|_k$+I1stu9 zQ%v9?zwYlJpIp4J*ng43|HbYnK&fpW5CA|aC;$M>KVVnP!rDa4&cVjONz~2A#NO$f z-u?z~wbHiLCIf;m{ev%u5PrhmhUAli#Cl+A$y5~yLMgR((q&`eate=R4ED(9bG9|P ztOc0S6i9$~$L?x&*ZwOe%s!DsiT$KwS8|2E=_ihnMH|YMYm3PY+Q=0MS>e2=-NSsQ zm*4HO6H|ImX8^}cQ@PS@b@H&w`EMV2bLGFCv{ZsUc_J$IHlbCL#tT44U3($v$G@;$VbfiGTztgJ`88NF zYO#+{M`W;5C(lb%MNz1$>4=NTU2?QBP{P4F-~?I6?Z3+xPMn@#L# zSLP&I*r@H9Vgy@b6Z&H`y_>2v&1o+#n-wn8^KP1*nCcyvzN>Bj+=>BoeU%5@m$-%OIGwyF z&Yiuk9d_K^?Dp?hMXTJem$+{J{F$UXKq0Y=7l~BGGnh^K2*XzzA8~S3b2u-{ePOaInQz_SMNshAxpvki<=k?uq@$d*A4%U7%>_Nug z(msNE#CX+X)Vo^;gaNnsO8{g-$9OUkU10A^N2y>Zn3J)~*jJmMkz))>Qb|9UNW=qa z0YDlPUObL6U|sj)f83gHtyuO%UGeRB^#sy?Y;Jx&Zkuz2WNKk-Y3oH@iLtM~tdc&| z_70TJKZ;^=B!s5C7}1PD2c03;la&D&%}6tt#)l*iZQYyogu;c~Crxus5l?j?d<3LL zCg;k>A%k!(M*#UANs}!PX1GqM|2~5LBe;`V6f1Ng7m(yh6K_lPv6s|>s7pcuaMXG( ze${Vrgeh53`mo43r*Jk1)7%Gk4`{S^N(Bgi9^$S}+ZUw22@)9C*^z*RenoNJra}X@H@Gn&9lw?|5$f)52yUNj~!nV+hVyW`=)hL#q`*D=~ zLzX7}epmtYt(O^&)ltlvpHXtja($Ri(o9W zzA!;QzKPQ(fy-P>S|h??sBA(TY51a<#Hj`gGqGQ4A|e0wM6;f|7JX+imc%n0O7YBT zv)It?BdR52p&Ywxc}32#BYlyJA(~Y|7({CvL{^c!B%PP_Lx**+3)PIAoAe~eVdlth zro4)}kst}RE@PQaX5=mC3hQXR02~_5x^ptqjW2L2D#2Qr({#)&Qp`^brg+0o;U3Ml zZ?Ika;_wFj_Sl1O$jvR7%hEDJLko4JJwUg7_s}#bRe|o2q1(3%%1ZBo!^{PViI5}n zlO)_`n{uq{)AFRE#lcFdo4>W9bA=70bYzcbagz(TEuz50$CJt3a__X%X;r{2gA-bm zg4tz8<^FZ3m1+vi3+&z5nQVdSQ?U_hk)VuSB($XrcH0UYp4P3{WdG61O_bZaKXg|S zjYB$FQ#w)Ovf*n(6ICU;WD9xJi@QK@F|3=ZCIzz&?93VVL^qvtp(-5QEwnmobnl^5 z2{*Oir@rn{Jk=!qWlA+}bM-uy9rCzZ4HRj&%NpP!OUfiOe<`w|j^)ct!_gU+Q^lRj zAw^vBB@;14T@3`vskfW@`h-R`vc`k2W3#6C=aRBOv42G--fkMuO1UW#M5wie)3Gai zQZ3wwwx~PTu^QKwT}IMy{UR2LRSY`7eOhM$P1oP$^8swE#qRQ%3WKEZ=?}WB)I+)D# zW6kU;`Dm*~UZK0Y{NNF2Ca42c1?t6j*-!HQIBFuXr^n{!@{5PM6;E;Nq9jT_I^o)D zYOGhuC{LpppB0X=m`{NTS<3riI(NXlFzXzN5VchabI5(^`hLmyk_g|XC=V^@sV=t^ zeGoj<+DDPwjkO9dII~vrguA7SVnkE_=yv_&&S`zETNzZQ+n64iCE-$i5gchkr4k7-fF+1}d1 z=)3)uHgW&g!ZBD;$8JLa!HW**%OL0u0I@mz4G}U&JFg-cfnO4KKlbM~_^UAq3&`KNh7NfCY%$S5`d)~q)s;rJlZ3g})!XU6M4*ZV! z!#u9HOZShqc3jV$mqFSB8M5$jmo$86?PX(F17EH_7J50&5^gPEUh5xgN#OAY<&vB? zjWDvy0*Qp)d26rGquo&wm=OvUX)G5pd+0<5yX{Ovt_vZc1CC-RtFYaU(9l|pYTlQOa$bqmbN8cc@M%i^rU zl#y4hb**ZfniPwL(|GEW=a!I$7u0E6i@i~I@r!Z#C&A$4DIVSt1lI=9`C$eOr0+4R zdTH@j+#b}Zee2KmYiJRkoMPpIe8&_F008|zhL)Itk&~T+yON26i-nPin1$_s zX$sk@3XWLp2tKn>UxO**gZmq3J{z5f4~M8(1Lsa2kgY_H8`fgxs!W4gW#q3u-$0Xh(i4Z zQH9xO`>!<_%qdCaer0oSAp)BGgd$A@Xcag?BPy(|a|DAouUdlQx&;;S%0q3@ysU&W zE|gY}fTg(1Ym%T?7?3%Jcu6wY7oZw@Xc#M&#~je?2#!UuKY%)7%sUB3J|q|`&hu^j zqkwP~%)LI)e!wKTa_&sSbE%%`o}do<8WqM^roUMG%T<3ATGN2F2lDvY+Nx7~2+9Fd9@(8Rfke|1VE68Qp z|8_-zo2|l-yKsvi_{QjU1{b>h$#EI2&k&R;_$ACG2k!mH6?*%V_&xoJKMPRtmI8?n zHKdWCA^{pZ1ByXttB`RKl~zli%#5iJWVs8)F{oWPUm*z{#XM!fA(1vdOI4s__l2DmV}-Wd1bgb@fGzNiQ5LJuEVJO*J9-dDW7Xo+1zV$qT0B{ zauXvp)g-7%mI9_ivNX#;Jf6h%)H!{jT7rZoT9ls<26-bBI@kbhB;n%%VB|oYe3k2c zTrdHzLpI;j$o74cZ|2&>C|Pf?UfvLr@9%>+TWyP^M|Bv+#1XEF6d|~15}~@yxL?8c zeOP%!NqLV@!0ikdxM?po{TNz-`@51Ec zH0;d89T8%KWd|&0u=pnteXLC}j&`qbbymxuElT=x-CexpL`lBnt?k13GV!{ZtcZ3 z8dpAEp59kgJMr?6aMRLa{K<$xvs(15^jlhyYvuY^LZNSv_UddGG~j~ ztW*p;Q}nD^gs9Fk&n7OnAiNN_VQ5=Fq3}3S8``@8-UgaD*V=35x_H4k2w~Q+ILRJ) zJ%2oWf*NVjz2O!=lo8fh!Hsp_mnGtNzH{^fjMe+&ky9R&e6)vg&2n ztu*9b0j*$|-4MvF{1SVh?X<;W41L<_ifSLW8^DL`wnc{eC?+%)?vvs0m=k-fpWkw9 zIc)MEU5?oGz?l_g5zAbo9^j7-*XhbMa^?>E@EYT#;G=NVJL3lb^YL%prL3SR6T){I z&HPTI6#vL|lHcU!W@7xq(9*=n>2KY|Mp4!-QvijBUGZ~pY=SUc+x|qH{&VnrAOUKLmM3fKjYZn zrqoh2tSWc|4I-gf=1fJcN$$RrKk1b!U`)){qC#|#2Q-V`G2<9}64?}0Ai5xDa1B@l z3L`Uhjcc*2hwzdc%wg&ySjJ2w^K_(|gR9~yWObwzii1=)oLv|4emzpn21ZC#?E&?Z zvR>aAQ3ZKF&dhFXc$~f2Y#CoQenm^jSwhbt~+#t}Y&hw1i0X7~TuxW};f?oF!Y4iM|)7**?#KFrI>D26` zTdQ#DhZ6=hEMRAISl(n}EoMrkWLHOxrho|ENT_L}Un*i>Xd}dCOMet9-jblUe!kDW z>KJ@qM1FR-;?KhSu_iqcqG(XHs;;r)WS(f>lvO~Q4W09usTHdibAOc_6kt8d;hK65 zV4Xar4;NM_+1k;@S%Zh7k*D{eX5a@_bH*3*{Pu7N|F0SJOZLlS>^rI~zjcfMRnhxf z=lGYXlC-h6{yVa~mACCSz7@UPrLX;<3Mi@+`6mU)CUCKIv}&O8ITdfG1ZjJ-izyd~ zva_!qMh-h|CWPz~G+P1#pg^`nQ#AIF@dZSjiHJh|mkr7l?p+Z_^`;8>CLsDC<0rJ7GN7h< z-HV!_AV`rdps!Nm=)^sERPMtKKuTMn7FIx-(p> zvcUHr{J!u3gfHyuoOeQ$IcDe#ytVc~rU_V2+VSZ#{{zt*a4L%)mmx0IHr`YjQ01_? z=1~UVI1~~sqS7K0g80Kt1ayMMj8dp#rHphL6!Q#~-F7TQW&|~UkJ>h!mLE?=E#lP- ze@oQ+>(`6O{)C)PqD#cj+lxe0Fw@mMyZU37VHx*i|5ESb?Vwy2tuBJC$n! z<;H?^rjz;Gy7pwontu#|)vyr*_tZ`!aPG|${&ojnLQM`_v(@Hx#A;cq4cE5cGp~q{ zq&2&THg>#vR#rl$JngHkqi`|E!f65WbkKUHjl?a;#uWqh`KRE6ngs-#;))s`yd%%(MTHE`H=@TK^2j573 z3#ZlYmsF|4F$WKXGR)?$|0Qf!*zfZf4T9(7&9(U{(#ZRdBMbzPK3KT&ynrVkEB4Ld z3+#eDY*g>uuK8D)KvK7W5yB>6K?Yk%xX1XpLZX4S`H9p-WHHARENvOf7Nd>2Qn1rT zWMPXzMkzx5k#-gKPp5UoN@pCVfH>=T(h%NEwZuH6QwPT{m>g%x$wGXz*&vTEY%%qs zZznoBM5hkZ8aN)}Fk_VfwJwi)ifY=j8iqxehW}gJ=E?*8*0$X(o-Q^SNTFST#{|go z&_@u4dEIbF6fQW^X6GL}*GsKlaCCKo7thU+1}~uK%of?_omny$cC{c%*>CtVdTs&6 zc`AZjgBz&As9Hx_LZJ|dujVC+3yYy;+$NBbC{jqZh-gfLrQ+x)Oa=J;dJ^>p;?IYiI_u!{sJ5B5>JkJh8 z{UE0!AkcZpyxi8M8@5<8<;g{tPKU4ZBqLp3Z|Jnr$>vZhI>Xv#op3&7vN@zzeqCeZ zcEIx{B=-CzzfUH)Zl29?k*X z;af4aX5l%FEkwE2rseke{Ud=`DR$$T|Dns4XM1wv!FiK@^U(8|!kN1l;9qg+EeKk! z_l?V#Z(Nf6BQ9m^Y|Z{BFz5f;H1=ZO^IgMow?`6n@Unrg%RKPnL`Tio5J);FcS{ef(Hi8ns#bQGHSV%dgfOG^YnMA*3h9FqkHJHnXZ*eEQBZ<^P6o3m; z0zOGYi~FW>xT~kq43R*bb>6D-FQt>g+NoFiW!-r7MDC#rdhFgP9F|t1dZlV4IA4dM z4$vA=8D}(L6#=DD7t-TXJgeLGi5>+ehn8gWfi)d%Q1p^ZjCNxvHSE;|z?c97H9!nl z{GJ;rqIkgXDZAdBUvJ^~rfu!aB0KHz`tQ(cQX}E_b=tJ&diC^M+Cp~+hQZ#d^L?!+cnl^1Mso&7t_=e`-H#7%{ou}*a zcF&*39_i7hb?bU3q@&W=d@S7fnnyo$?T@{3{aZL&(WxL>h$<=HJaUI!t5`7Ww?kJ0 ztG9bSLy9qLnk<>!9U@U%J0O}Q0I~b z2Zdkq#+4zbf}VO=Sc<-AO}&i5aFKTp64G-2n;OFz?n2RAic}LSxBTMZ!2V#-C$fFS zwst(JD&K%tDZ)lLV&Yc=%j98q(b|doJt#qI2ykiLxMITOhBx1yx)AAW#uHbdL7`Z0 z#UT#eKDqe%tU?hP_rlRbR<6=3u=_VY7Zu2{&fjhjKCQjDK6+njrL6jOaK_pSDb&L+ z9bc}_HnBEeHttdZEeY{->tb3q_D0N}S}w>}!XNYxc?(&5eay)2*|nWyZaUOEo0V=W zgkzMPZUWXHX+sZi(mmq$zQ(#A71?WCI$Y*$ksIxN9P~0b8a zx!TvnS68Ju?B2eyMR6LY3AAXTQ0%lyqik8R4D^+SDX%Ln0`RwpnI7~|G^~{1J_>o2 ze>E!4NnBrhZb^`o!jzWD2_f4^?@}c1oGK$Pa@mS*Ga!R42KH32VvRY6>MLvE#L5;5 z*oJ5papM63*}M|LMO!MtC{%4BS`X7B-Z00J44Pd=r)F!3RAWsB?-j+Szq3-y)U}8VRkg#wibKX&e@>@V zKZ!|GtMG+TGH*i2@+we8FEiC#X1;t<9YN@_+xrO_?1@7Z0P?*lAVhm+{MP?)er+0Q z?A3hT=Ta9@uVK&&f$!&158-(O;@{fSLg0(~?ozHrLZw>i)GMq5d2y)_5WC~!le=k@ z6o{D9>jaZmiO3I+a+(bF$|SCfEa2Dc#+t~f4&^irI)|ZMw@t4eRo?8c__g@>49Mv$ zrGo0^Y)lx>E1ak1?;cUBp6)gp5v8eEIcmEY*kh4zkeH%4lvTT#Um@rjSSRsY5;1+g z;61<|w%nW3Hb+*o<~yHhdrqDj(_0y&(pk=lFP_1`At5;~@C(&PjrIyx}_03W6-MSoTRK z(Ib8+8UYJq(Cu}kF#-YyFND@0$ZN7vER~sZ+~E)IN0C#o#^l8jE9)x;+0Gz&D5Jsq zR}ameXj;7Bh!a)qOQIDp1%rwX8eolT7wCHfaRk;DN|1HzPnSVB-YPOF zf%>k-R#BzcSfYS1f)5|qYC3_Ke{5M4j~t2%GUU#Bt1dh-vqAb0~dUv zxKM&xQjgRIP*-F<7;^rUUW>zkW($=8%%mX69H)71KM47A=sz=JI)lQMhq$`bYha*y zsKrDIc?L&9kXW}EO&H<2=g1yoINPr+imnHqif+Hm%YXeuU!V&U=*WTj@S`x&e6F;W ze(q9lu(izh3^3svJlBpUl>`-AP+F|01Y+9xj59d2*+v7SJo!LJMf%7=l5E1H<#b~T zvh6LhDv_>@m-gRu$Q3U{X=0MW%d>9LM|V#J?~|W>U2+Yg)6(e-H`yfM1@S z7#IoNO<+?)zF=UnJuEUdslvEWvIHl@48gkN;w&-q@z^NL@mRy91S6aa&Yn&)@fCE- zVWTQ^#~<-E?HB&~1)YSPSo71x`1yJKBL!ssOHRG8zJTrQhDFz)@xB+6O|>vUJ$o?o*J`8}jx=^19}()*CG)|p5O&rd8OoMAJpr}y)w>jmrjHq!vmfo+3jJDl z+Z4f*xT|zwI<=DV5XP3yaC%s~nq{bRTA+FvN&{sx3?f&&1c{HG~`O2U$o>asHb)3$e{W@AUhj_~R8tv*4BazZ!} zYHv!|SH}>C+p0)WjXh!&E100szcf^}wxptG-|cc6(bGsnl-FFA!U^4O+}}+xGn*>$ z^Ll`m+F!(K&0)HDf3@a%qVvQV)pX5T&saKg-0ui9&cC$my!7n6!_CZSO`D!ibArS} z2;<7^JEZq9w%6B8Y(qJjG$Ol|8Wb( z=L{Ao_chXsGw=w|vHAi1{do0j5!LBW>rLWrZyBKY9RrdcSww?CSwPry1Qf$z7XWb* zT#B3o_lf_+Oe7E}%5v3f_8@N|Z$wQ2J8b^XUeHSyZGNANo_ z&?hm43E-0G)-2IA>@XQBB_70ubGh_|E#v6ibHM06&3x)#?N(jVo5F48N?m`-sg1x# zW_C=?Lm}-m%66NF;*6td@fnIi_La7Zpp+09S6Gl3;p=-gItG&RxleQynmyI^TZnrr8&Bo3;kPLdY>@-bom0j&lCIVL+J za11}QVQW_l-trEPcZ_r{$6itoiK4Mpd&z|~K^*1b8jJCXQEV`6*xw9u?<^861RHG0 z#HvakDkc=+)KFglZWRJ=9z3=%rkoX@PSrklGqq)H7Cpl8K;v+j${dE-0keiR$Mw$T zfVh{!LBlF7dxVf3L!kC{;yanBaEh1FP~OagTKJ_?5b^U1bj320dk8hA;)zuzpv>Re z&W^PFR5HEkj<>^R5(r%8pmiP$(5|s-?+}E2w}$XQp;Npg>3-d+48lrEs#*R&F> zTz}7F=Rd8EwfA1MZQi)H>-)LxgvIH|unMRRQ4v%#-yKwgZ!N@@=~!O}`U{q4RQh0m zpeP3{i zG8I>{;nqk!4%Uq?l%rs5fGCYA6-bAhWv`FN{#|sB>3|bOHEK37TM%+gMaxit)-xuN_vt|L6;1aj`ag}XvmnMn0+OM;qL?dLZH#YiNq-!h{Cm7 z^s{b^9q2oanY(o>SLYsmK{F}p*j$Xx;=-)XgEtZ9J!E?mTCm*$Afd#>fA??;YALJ} z?SnHt8PQ!3ZuajzzB$C*Ci<4@%i z!tG<;{Rx~$^N`YQHH(VM>I&Qm!{N&Uft}_a^5y|IBfeRL%nRq`@DSUZ<`kH(X}x(( z;)E~kcU5w`KjJAO=(bI%Bh*5o$phI`|6%uZ2cA-pQ;_9AHjun|Pk~48qJx^G&4}u? zttuUr=n&?=oaj4WX01;>ZfFo*aHZZF+rUaln7rXAtQ9Z4Gc#dK#9fj$=|gqBkfWe{ zwB15E#KHO44tpfQw4bt8ZH216OK6)*b2Iov<)dgY@MmglOIuE{v@aDb!IVmbA+~RH z5`~{kl3^mLsJW(tAB!~k)Jo2pE76>8IX_Q_mqeKMccE&rL;ACp*C;C`Bs3v-wjxJj zSeUgoSa*rvYK1--F5nT;g))i*qU8i0`d&K=VyE5^ll)G2tBQ&@buvAxjo2&vsZ8OX zhJ-tghrH7{!>G5Z9;@v7!k`R)Y+V5!COBIIE#0Ii z3jHLp7OLjH8{R4GeS+*er>#7_Yf**L2ES>j>_k0oV>#6N*rj8O66#xWO<=|4GyP%e z))L|1lS}fp^HS3yZYX-jN&5k>ecp4$6_~Mi;#b0o)fe!;Dq%3JkNY6sECntJ06_JR z#n^u_m7|26^?w;2F163?u-TEmbo0Ij`(WuB3PUf4X!m&Zmw(Fdy>F#lFdhdd@3}A@`%Je3L^7u1URPiOT(K9qu3WRUZSM3ES2970mfYhs; z16z((nKnisYRvK}=SG@ic$7aJoh8{r~y5v1EQpLU2E%pZVFT;6l_F`!_!)E4! zt?uf4+Qafc?slK+X~WOd?A_sJ>FRdjX~Wae-_)|t^}c|9^0v8cgT+h?=Dc`g%u~oK z3r5IBLD>(x3r79aA4(u}9a87u5b#B6gbbCmA0@^g1tpB-Asin=3dX?{tGNj>l;W?7 zl5<^oyMz7{>d{N+V|;Km7u`NsbhhJp<>(Q)02&X3;v_WNk+ALhoU_WG>wqpAzr95c z&cRm6_-e|oIWW?j_g#}=S!16mayY-0Tx{}r4O0S zp$ghq)eR2Z(fw0^ddb|q^DCL zN`l_o*GVc#V|1=#fcp?xya0B*8=GUQTOV&WXX~u@?shJ@OYxq;E;J+RwI;kX0VaKP zbJy`q7rqGvYiSqR%4S-j3K-Cm%uZ@nYhV;{KzhwL2A{s~=u<@Y_H#T@CzDpEEM^7b z*GH}4HAGI|zNg#kf<&*DwM1$z~4g!!d0lExq3u0StV@%Jrv>jQfS?=d^cbxK)j z>eYn`1+xOK!p5M^CC7-45y?nL^m-=DGgzz@kTwGbNY!4?Q+&D=n&1}n$7KrG=*$_=O$sG^MpbZL zxrAQp*-55iswsn+kUf4E99PD1hQmBQaxK{tF?yHbpQ$0&%&=aa!%87CSt;J7ilneu z)7{1xPdzyWHnI;>g}Z}=;_tv(j#&0lFi5wr0=HO9FRu8yqd0}YC~fOlwWTCLc{erN z${fa->h{-Nf%6?XW4e17s1j*U;B6+wDgflI4D~z3)L;!oJm4GL4XdfLLn+pt8&@#P zCX9!BP*G$b6E1#H!zka>`jRdbHL95$NL3q?(OY)9KJ@rl?$ec|K#x@em@8Bp*zijG z$3Csam7jB0HoFh6K!Ro1@O?V6@&712A)7RVWw-Q|VSsCi0fgl5osa$+{%95G{46-p1OC+vt_jO46fOY$)E{@Jo55sJK@kp0P7JK1hH;52e+f ziXP?#a?z@recJ(eXtZaCu|J|LT7Eqs9$AEeFeP^H`cYaOT0;EZdj~x9T`T#{4P4 zqt;Mp+ioGuw^>Cv8@LB{P-iVkOs&Z@3wI98QZom}=Qfoa7$}x#vw@Tj*)$Rth%SPm zGitOCp=n$W&uDWm5brk{b`#L#8V+;VGa zwmDrvg{0ha*PU6WE|QzPorl)P^)m+xYV883Vot>~#2zgYP8zyq+a;IW;FC;wWM7*6 z=pEB@N>e6$l$I-ibsb{9*W1@ZJ(I)ik>}~6G7aq-w)HzAtq6*Z-G$cSy zHDgXobhf~h?U=K?6~n4S%X+QHHko7^KnKk5J{~w){bd`~UteBQX-xP=0bZ;-$97CX z-iH{pkX3v?2wo86-TkPKK2}YxRfb zcb`WuL_tlyW_Uo0!T=CXqh}nuIO^7gM)cw(>Of1qa#ijnNP13*;#mGYisl^s=wt*>mHiWI9L}cU zT8+rvGBJ(z5G=xsO|(HvgRC5^MzcK zKC0Ap1Yc^G~!w`XyXSK@>%|m`@AxorgDIgWHgQPHSf-N@I zDS?Qv=7Lx#E^pfe$j#w+1Lk8yrD2?gX77D`d@vcL5cYJD5libr@c{Ex2QIK%g*q=7 zCbyEXwSM@v2@M}z-C?NKF&)Kd8z{N<7reApXmPI*O#pIE^3m~mIUi}CN9sG1YU(e$ z$8Zzf-nYf1H_$N6)F@#cu-rb{pD>^X1Tvo%ow~SzTz1xD$koiVGz5I+h>hK1+Rr%6 z^1~|Og-2+ULKd={8|IpeHFS9^ES1sau%TVTY)obh-_5X8+g{%e^pzVUTx?;V7E(Ar zQ{IQ{Pdp3JWx)>v0}ZZ1dUna5>suH0&89!pte&g|8@;+tA@TzuWwtZUE$L97J3JJA zRQ~9uUX&ZByj*fQ7SkP~l3K`?i|G}kiB?*P zEuzzKr_1DGd*#4(9cVAtuiIhSo^jkqerma-6MHyQ*U$#tWI0$@QTs+CuUOeyd#%qy zzG{iqoee6v=*6{CykmXYxdco!rgxdhR?!~h27bC9*t4x2S$+Q^3$)#}63X8os>XgVq zOix<1pwiYB+uSX+!0rCTR}sgadwe`69gDQ`%P)A?3R@2tjn&|CdJY~< zpoS#73GmyCYZYji6i6*_)y2l)ww$H+GJ#0V-m=Toor`^hvvK6Fht~_%*VVTJ4XTBW z(K1-GdT7J-Ipx=)h>IZ2<+&|e-r^ArlHO}q@;zfn*FMkQJRUa(?=ZT3_x3)Z>=sG23<|B`2bS3H!z)$2A*ub; zZC!0I7WTK6_OHxcUf#~`?vKB$!VG)V$4(G!bD7*~6krseJHS^hT2Q@S%UFJqPPN>S z>NR4J0VM*6{e&@93lIo5jK0?&g>&T@5IMlPGmZgTA|9YHLgc-W!{^J7QBQIz z!C+)C96zzyPXJQ#+_vDQO4fk|%bX_D7rP`tofOnYnC#ba^XAUk`4p(QUgslYl)8-a zb)Xw_xI>?mXbqc|_?2cufZCS=Wbva|^ErAif_##1%qgEuMjw#nw<09pWb*GGMI{G+ zX#qH6NGCBRh*DfP=8TXH_c(;Zt0FEBtNk`4}J*yG~ zQwuC&(2z;V5Xg5RXf$b@KO*?o*97Q{mt^iZYHXz_hIjc}6E`L4L^2K9vWwdCSCa?( z^OBdxV~K2|pp!<<*Xnvw>rbx8W z+u)1{Ne>bYud18e&@?m7NrzXzRixT=hV(_dNVOJfNtN0Wyv;#Id>XB)g{2idt-+GF zmYklX1b6@1^9+QMxxKe4ub-}w(sg!i8->`uI8gu%cOvdrsMmK%TH@7ohW@i}@ok%U zq)mVdK~qS+J9+W~NR9-#FohoAI$CYm!fNnlXCqcrQ!;YuzsSPj9_x>bfVV< zHth5<4zL6iRq)ec*YGx>amZ6 zFXUrdb>BY>`LUnlyy(W`p`Sx_(;ZQ~^%uLxyh$VCq2w;(!Ago&>uP9=J)W#2|5DDB zl8_E$ztw_ZML=BW!tuG8(p?-TV1xgY}>YN+qP}v zuWz3-#=(E~Mc(Dei#IbP){6Da8Kx>N{x?I#jl-QhZXb&Mj|&SmA@?@b7D62G@CrF| zdC`l|&Tks=&z}LK(pN}Ghge7j1Pl#tZC=S7o7<;avXS3dck_aq33iL~L%3)M16T!r zV}{;4nXsa0RcoHOOVy6K+?lT`DO01N%3BPlT^H#0>e=cPrPpGc_0oyfgx_B}_9P0{3duY&~Ufvs4}<8yL(6+*633X&CXU9df;4cY)J?PNYK1N23fG%=Ykp+y_Z zNtPvM_qo;1LpHqDPM&Zwbw2DQx5~B_=Clafw$bOB_RIC-_|`lt z8|o-Uu_KF&?^`x|(q5RS+p4P8vZuqMRLoZ!<0~rlIwY!#MecbjHmp0Yo7ghpj)2?> zUqN?#n+;bwEc)qnYyr$WZkx14pNK;sW5%WjDM>~)+2A@|>TnQhRoM%)&>+G!7kCc7 zct*fTAAFo9;lZMWu)G|)KAj&%*s(>-akJGjR5xwwaKa>Hjj~SpEbU}CNGEi~+A+;8 z!w|HSzh36KMFndvpAij?i|*^c|5vWe!%b#EquOx9!(a+^?PUNGHAO@Y+4>LoB36kZ6ptqD6n7)vW^C{m{04fqs5bb$`e6y&&jx zbfH7j>U0IuCxr*Ws?vLp>_qrcr#P+#jWe%Pv}$4Ku=~EkUfo58>X*^q>LCy7nf?@&}X3 zunuZ_+on0IrlC`b=Cj3a>C4%UBWq%a5B||&HH27n(%>UgQY1EBhmgo7Hw9^5&5A%7 zKMB%&s$jyaoLppd4kVLyLWP{#m#{Q4?tX*$V4dk-p@ST;9Huk@`tzRZe06$9sFdj5 z%k|R`%@_8zRt#yIfLrJyHam_?Es*A3CqdipUNZ-Uo&5z&(HHMGXs?I?_0K0OavT=03H3c_$a9?}tF2 zf_L4BVTz|C`>5QRArG}-p)3-YQbt))Mdn51rU51m&(AehQ>=<|uL; z{m&8(c7RU zw|sqfD-yyMy|*QTyBr%$q912n)*xWo6>d}yVOtqCla;7{0=$UuNOnomAnGkCb7l@G z{W$ks5~L}KW;`OUk#lkCc&-N=l};C@o=RBP*mmYh`n8KV)Yk~q$Ey87oXEKKm@|Eb zX8MwXf!>mpSFd-O>DwNOJ%CSEg0`vDi3IJ~O-9!}g<52nPQS|AS2My(a1F5h02?Gn zRZms=m2J|)d;hdxt$V9+eR4}cl$M;9R$K)$0&L#Ek_~Jc!bPjhZ>m+;l%yOEQ9x6l zTx(UxEYmcX<-hO(H_cO?P5ZC$SI7x-b@9Uaz7I)fMl$WkQ4g^OC3MkM$T(Vnz(}2u z20=e1ZGl}Y^Ev>?h<{>;OsUFhW8!|3&>(KZ{gO;PscKpJW}%52S(rZS+D2>AM{*q zVuVJDPGNsCv=R%JAn^F~GG6MZ6|44(wsuR}vbXEZM(LIy|G?Xc)Ou5!bKUIhUKXuD zaWK$1hxRA$IuJ|Royz54m-5FgTd#+8yq!zw;?1j$c0aWnW|muM&~j{AEvHet)pq}^ zvE?*VrgOk`dhLG4T0KBf%tA0fcsX|%Gv*Ss6j!=kyK%z=P$Y6Af6NPLf)RD8=(YJk zu!UeM2J?r($mqY7=8pXOI=e-CB>zDNk7Ic0uR$LcM zdoo}o)zG!Smj41zkI1SVh8sY=5B)2+r$%(%v?xJTL9t#pf@$@`8pPepk>DH!LKM|tNR1v2JPJ45UHW9?VC zE5vI&`?!+&tt^Yn`J{4RTAMs_$@c@n&n}*ccoB z6cSvhV(JD7TN>JT`DKhS)h)=7CJYc2DP$02;f#>ZbgX>!+2*;!lW)o8a#3_m4u% znBd=N#QtgA{-a_0v90Nw{-x_QW3Im8eJKp2ia^)3z*t=sKy_+rw=9Uxv3xTael zQ|Y$%naoqu3)FGn6)+zk-wh}G#ligv*75#z@$hibe%%W^Yn0eSK@^`!4tx~p~VTJ|f zAH*AyDTgIJx_1km6pbqBRE@5q=SnhUONEAUc70W z;&_maiQPRD7mm)%t%;j;IQlHF!0e*>aR56dT!p=8dqD;Ka(`sYNXVLL0| zUa{8cf;-&i-cZ=sMsj)ns>?zN;H}$|4vM@rm661D)jrKZzadhMETd?5O{Rpcd>RHF z^s=9Z>}L2}^>=^nCU9eP>i~|p!kgZ8rEq92ks!!->ICWiElNiJXbI3ozbkK7)`rXv zaV>LiXC%8X%uPQCr4rZ4in@I#XWU_46m^wPzH@>nxHZ7dty|0QK`u)Q81(oH7) z#yra-so*GA_Cw`%W)7NwViGZyxM)p$K970VyaK$Kj|W9Nr)Qs7|6NBn{GrtkiHLi} zHqC%aSGYiR4wdmBr>c)ng#5b* zQnfCaays#vc#0$6;;UDlBFmQ_Vw8__m$dC2o%LK8%0t9CE4)K8DI~!*%giFE?eMqg zh9SX%N_5rcWVQPc);n(L z=FZ6@7-jE>c`a4t^yP2t{9B4G=Lxzz=H5NZ$zcv7%$o~5(#@9KnW}3mW4D6PeH+)g z4*i|U)+Kkg7X$*yt&h>K`SDNb`>!98XT7p3N{JDs0jHp?xN*CZ@zZ^H)nwhh()^MyQxpOGO za#oB+)J4vs22H5+p0LwEb61*bXT>^sGZ>GQiI`@gcoUQV7)a*pCw`n3&@r);eKj-a z;&@X}E)?yP!tLe5T%nl-@}_y)t$=NUZOR>3E1l!4DeiMXo6-wHG{#tp`8 zi%L)wAT+i#sWpp&JQ)tSOQt3M_CjFrr+UG7{Xj_+XLEIX)Nh%>zjcMLNPiBml?_SwyZ&A*#`E z^=ynr$4_VtPBOcN&=(JNO(+6=O)5@d%4aC;R02bwDhZxXHN+DG_ac3>l%-Y&&`cMJj0&{Jp1oF}b4g&*3|jr&#a>?{SU6d0Wji#hkH>z$d0Dx_?I+Rw z8#C_#+o^COS5x#rp9G$`00R~jF6EUi*(wnr;H_JX$626?=ZN3}eG76h?V)Dz@wOn*_iREF(mpm8G6$`nTC-4$xLa?`aMSqMhCi&b_ z4$vJf(?U8q<#7F?#g@A=^O^5~Eu(B{I^Wm#0#9v2Wwk$E?iZf&t(gGk>6C`MbEnV2 zk;Bc(aG)h>MV`@k@=AI#E=<=*6|GP|!3REKsorosJpFW9Tlw7exW?Q?=SmFu{)mqH z#b-xrqiUx@|2iun5m7T+GMnjxSzB&FDD7YG^5V@*OV3rN3wq%h75y9mq;$Q~t( z;U-MClNQVGrOd*wxY)xkYF@UfECjQm?%IIGuFN5O;z?No^_@f-zpI;T%qY4D7PN5! zicJXYd+05`2?Q!_r+g}v5c4T3V_r@Nwfb&E&pYa#5{ImB?j1pXYN$H(=PfI0f9T)iPV2Mc+d@1c?oNoCXxaS)x0JWrIt2Wc#Q@*h=8t-p))9a5VNHPKN%aROJ<=bJHPHU6E;J zZ0pwN3*ic0t}21M7zN_ad!&bL4V>7(bei$AKvqwuIyU3SkwA_ZKZ9cn9HNS1LN26d z%Qn{Un`yrPhAF7ah%jVYTN>s5APSHe|3>`wPc0()BTtplw>EaP(>F9$bhfjzb@&fJ ze^Jf)pHR*hF8;SZC2*wCcwEIpl`4l#c|DG>nFUyqV<-L$n1rObm1?_YTzRt2=Qfv+ z!*(hAr)xO=-z27f(=4}LyLYnb>|ThD6ksCP{)8@LtSZE&oq1+)gHn&~I+}Bv-HvC- zADEQwvzPC^->2ubIe*vg;Y?F4(4bW*oMqzz$yJ~!qVq`^tZMH7f6$^*+#dWM$WyAB zI*@BLA2*^OexeL;6eU>`_rby0l?;_zf!miEvIV&Fh+b6bC0g^e&!`A@rcG{#D&TGd-FipuAo`117i(@6|Lx&>Zg0#)Im z>(ZE$e?_I6^c;n;>u?4TS0o&?<{9+2#dAd(&iuoY-G_;rg8_3JknfdLPsU>iL5u;2 zV?<^!W%U`Yd%K6{M;k0BKN#IyJ)U;~yfL=7qiyj>*%VvaL(1FN&qwfx zwT_@sTwjjYCS2r17<>`i<>*MD%jZXEoCbf)TNddf zQNetFzTyDi5^mmrpX*OHVbAmdBzc0#n}|Nz>C$ps^;t&<7ciRwkmRptP8dMPK-C_S zDxOM5lt(clYcmD8$*31rV3=SNhsAD&GC@Fo_f-u3iBmiUUR4qKyS2r$5kVf9$5%_PMsEKN1UQ?5OO5PvvqN=3 zNO{#4W|?65CxT|wnR0esrF=p*!Jr#KGB5<94f!4VigAdTvg0kb&^=NuT*g?}R=eKK ze!AKJi;WS7!Pb@ac#b2f+;M1GYS)K6JQ_(0@&O3h_#UuGEe@S>0+_n;CjdkF7`sU| zFJ#y0^R@Zs`|Q|!mNC_QLZa3CYlzEga5mR2f-wLSuD9;f3&GI;;t_6` zUsu1!8D@rf4mDEITUX4agfSLd0rm{0Xq*%12s*_gr>jA%u;Am5jRGf-NfJ2s3nXP# zMxr4-R$O+7h6IPMN)wm5&YVyPLzjal-_k>KEjVLroeD)nr%31~Q8RyZh)VPVLbXI( zkX4rN$^B~UGI&*k2AVU9AyP7E_PSaka0fJTsRq}oA-7SHj4V};mr_il3xv+G_=2~b z{oY`pcJ-zGElXPY$m{KX)i7WHmI|O6i=4a_Bp>ScVeX!6FFO|(;&;8ItUekchNI4w zWK2f{D7HuIflBG+T3X}!WZRF(3v^wj0PW7Ka2Y*foGyRum399RQ$?ssY^I zLxTVlkBAgG^6KtwX@W4miH@}UiCo1f>jxd5%dcB%UKL%QB&0N4qf^c!O7~J447;6^ z1WCbh$bP<}QB7{;Pwf0tj!Be$g-X0uFKZ_|E2&FA3sb=w46Q`k5n|RZx)-O{tLR@t z)UW}6L;*25aqGl@a3)zGFOksQ5AHEQ6Sq8$vo_W)ARdS4?*h*NiYKI}=|z$La5+|S zoh0?_RBwd1zq(DzZK)#xpHMs&>^U}-{;o;69kG(miH)B$NIl#wKUFy|P$#1O#FGTd zzih0EPxE6L@`%cVAhB%jo{#QWCzY~zG+%mD)j3QZW`Ko7kTEd4tZH8r#hHbnAISZh zvzbG3&D_|gS*QC=NAas*sa@2VT-AwH#&m=1T)D$L(<3YjD z{HvLq)H*`FiJAnXoAklMQ|-dlW-?$|75U~wE3>Y`#S>N%@kk?I~Bt-+y{>I_qudc5)Zf7r%*Ns1cB`qx{gQVI1I3wvAgd#d77*0?2^J*~nj$T?sIh`QLPul!dD~ z1ss{ICnwoGns35;yh%O5=g!#VYGbbR9}?zWU6(CfUMEyluYqi3GwuP8dtDTW&8sc) z1)sOX)^9fooVp zsxzN!+!pD)qg>y>q|MayR1$73-aZVOI8T47-M}}(h{U#xOUAOy3a1-wt3k7HHi1Ah zZf~?GzQ9?J4vuW$*@H_CMw0M86Uzw~78!2!-|QJ#1{#YVMB|P3J>ca$SLu~hV5cV{T-Z-2@o+K(7=EA+`LVWb>4WPwnJfmF} zH3%LjW4W~h)N^?;VgJyskritT5|Eh)8mCK};y=O((^kG3B`Pv>d~^jzWp11xyXdu7 z4K7vLz8dRwey6&Cv4q^S5Np>=DbstWr?f)8KAT3u^Zu7rvHmFzI{Er0sS34PL>fvU zdCa}6@{Xq^vEg>iUX>urpxi9-)K-<$1X*zk7dT-@C7_ z{k;+_2@vQ0o1)q;CPl#Ip10Aaa8XWIJPF>sH3nz}x6Q+TA^Z8Nbb=ui$76kLP27V( zR{gNST`fJ;-#rmGN&`&62+KG>8NmNmQT`*z*U(!GulgBE(f;su|0hfR&yP%8QI?&Z zg+rI&|6}gXZ83ktf7^_H_k*j$t^}&4kp?wD_BQ!TZ`2 z3h0J9QmEQ0*pH!J23%wSk;@n}Af{pj-31MAx2tc&AG}j)jx2`Y4(@19x}<1Pd{D7b zpt3Lnt^i+vIGfx}0ohkkJD-M*v^akF>ZyZ>>LPw>&tcbR-#Txj?E;oe2l1wHsfeyO zVe}CzCLN2UOGs#yg^sw#KOtZaZy4!hifou|X>P<$D_G&lgoc@!8ygXs)IVT!qDepk z$qEw6k04mZk#lgoBjh-Pi=3G{eR&?;DZ6~rx_ZslzI-_j@bETs=1jM?e5sS%Rh6^a z>4&$z8BT~F`#Z}H!92=8M}m}9nzH8?15m#ztO|B6nb)bj?=CxnVPI`qE-VFYsGO|v zgm@Ih!3YNAffA@7mA_w*8bZ=rrn4w-?Xh7?d4j9^j2=$4qWg>+!l zY(Y?W5|E8wBEMu1ld5ZSQ?S{*p3m^_!yk5vOu(2&3p0X4*<7=;!v8mFpy|l32{NtF zETkf{$||ykBxuciab^*6p*c9CP~O7Lx?h#v$77j)s<2xtA>5y93zdQw^c{c~da$OJ zA|G{#O#~gzWvKh&p0Dvz@ij8cFv&6=>`C2Jn-zD64_A^2QbXei63HV01k|?~_{7+? zwcywXV^Y+0`&G%{%{h=j^-Gj|m11gBn%{1CUI;^H5v>X{>aFtd2i%^Bb$zQT0z6xv zlIWOs2n;QNMw5(&2C7CB3^5!NP*cWkfK0zk7oee57Se(iNR_aztcpQuU%*gJ!tSPt z7FY1=q^^>1S3~iqQ9L|;qjy0gb(_`B=)9hL^?>vTi5O5asMx?nqCwqF=A-(kvAp5a z2>v8D`L)Xzxr2Fl8ZqckXZhj%_Ia}NB>f6gRMb?mRAuT{Sd#+e8!C`t8BSa5&EdYH zkufqa^vEw&C1;bKyG7-fF1veFZ|z-M670Jmr)KVjO-g{(ffrY}!w~1?Da)#-U004s z9uxDjC4h)KB#8p%6*)bd0mW61k5fU925|7b)(!^A zQr-Z)YAsO8PTZ~GX0AU|3^!BcABbdTZ}SM=HYwrOWs8aaaW7m(>IA&sl9B2-iH7P6 z-|j@fpm;cBxCIgx&X@&lR=bUa2UXOhn9uL#Ty}PQUie z|3=Q?0KV}xy?^G3oOG-!U1M4LQ_04 zS1IP5!cjSJhP6(sHGKOsQ4-yPK6B55typa>3#Oxq(tX=n>r8at)Q1rtNp`Hvs~gF$ z;9)1bv7i6nTj_rmz9ey;Hq0MX+4cu)`9B@%|15kG0%~%KKd*l-332#OyXU`BS&JIh zj_a(5Ut6hPA(5o>xe7rNUd!hZNQY&dPs*ylpVXq#J==20X9Oh?r~xFNobR@6(SB_U ztd1RU(r{y>1J_hf)4KFVWP81Wa0e9EFEV_1ynQ+Nefvw*T~LE3j$D1}`dibl^|5_5 z+db?JZV%IaG4Q^jcD-J`oSeMaZVRB_lgI61%3LeBN;EL@TpNLt5q3_$Tx!e?5vgtU zhj?NQ*u~ZkgqULoWF^Kh95fqKb#K5Pa~u6Nq8f=u8RxIWkebII&~-5ZW}}YRBDOo| z{uPZ1eX*eTG6&y^#$n~}Ar|Pb#aPfsBFt^lb0wHWxdRbs5I@8%CJ4$^wUicLxQ|7N zM~zae1YiShCmALy??nMz7KbyeQTpJ@y>;p0oiq3(;=&a*X~4mootZI(Ry-~LV6om# zY!Vl7t2xEAfPINlK(2{SEx*UU;x~fdGKoG#Ay9YCSmo-#1xP{I2*qduUfH6Ap?g%O z-zBKPEZ_xzNiU{HuiazC;EPujzG`4J^1MxO|WT!NOWJA6{kjafB1XPTy-PzIMjAWIHH0oy#7f?pY^Nz zE5%~!Fle})=k4bz9A=tK|QoMtz|L{V=4m$;DJ zP>_qIh?>mM1CAkbU5vP3Z2e%p(E`ekS4yu+pJ~F42A}?sflLI~VTKD5D8>nN@{U9? zvx^SM!LUvnvK&>z&oq47g_*Cb8fF9SX9qzBC`-Kq_`hNUwJQig+IDo&ks5@o?ww(; z=a&A*JY_Y0%t+v(&bG!@L}T3)gQp1H0?hhDNNZfkN$8@-_68x7U;;~V7??_XeRv0E%!Q&(y}trspoh2MFqSFk5@dvb zU#zoE!D)K6lV!O~#BC-9XiFWwo&~CwPD;*V(0h44KfTN?8rs#{8e6|lQPv&a&eibb zWUXI{UlH$%K>W{@`ne0$>f&ZnUvR{C#F)BBDmq~lLgAg=hEAp--fY15e&QvvS-hqe z;UtHJ@ZRu*Cg>*1s@F1?uQlHY&a6DT4b36~)LidjBhpQxK<&d_SK!OD4Uh!y zLo})bNKV6maL^G6>8Gz3lMn8!-^)I<)wHy-)m3~c(#)jv?D+Jcob4RwS!UJF1@qOF zp)QBlD7McI$Pk0Nn+;@=`<~QB=+V2G%wU#7tXB06$B{Z=y>JBYuWm~zksTph-;$!u!jK7uP}Sh za#i8_u2V+@CC**|Rj48F)a2dFkR)jIFxAL?1O4nx5DQJ?K?uyv<~laQALNB7oc6U! zs8GY!1HY3i%ZyztVvCi?7EMN|Q6foacFL=ERq z#=X+{nxNJDlIL7schnK^3`GfNYs3lU=LvC;If#%*Wsnlu~;nXZmx20NVFy6cRojJhew$sKtDC{4y5wYXr#Yc3~OcP4nsOiKWZ^s z|KQ~zb2P^ucDh^3^Lw1gRl%HB?of?!MIF#n#)CX{X?o;1su3HRF;gjA z#yA9Jo!hx!-w)bl1w3-IQ)XPT3-h_?uFl)xkz<1yF+8o90AA=rq>(+~CX+tS)OVWC zmu4gGve2BX|dUp-_XXabnPNO^cTUoJNe>5R{|kg zF~K2RlgS)`VO-pv*3juTo)r)(f;=S9Q((#U3qirXT~%2)OYfQlMZQp}vSgfwR@N1i z1Sz1k0eQTOeWGb|jqTW2DJEejPaNtUBwRV(yJeYB@BJCL{u{5~ymvXdy7{sd9XVQz zOc5|ojf5eJv4NSBTDuLAyA8tGg)@ZTrML6+N=wEiHsqYTkK9c8RpXS!?*f*NM5POvz1O+*@9xW!U}qlt6-dxGR&N?st6$dXE0afNy!qD>NJ0=m zVYmnpC+ELoY?@vFb28U9LeX3Dw!W|IUdU+8rslr8p^&rvru& zJ%G@ElWnio7@- zSU0@6`4cQ7+og$g)}esygEP`hXjrT!XW+9P(#qo%03seMOs2;*q+eJsizi17M#gP^ zA~>gTyK3tOFInxuXU(sxaMu6>TG986me1!UcT=H0yoc90$E_b5S~I8hUE_qesuTR72T~l^6d|& zvU$%<*5I<|u&3&KcJs@$bScxS?Z~ahg|DHIy+GhC z!01A0_R`L3Q)i*@vpjfVKg}4^Cs^z)V)G;$de0{#g=EY+`sBq2bn{zJF1hW+$#$$_ zsCTZz$(HuQOlEn$NhKe$Ek^~Z*}aCQ5heJ{>fH+v3fyBv18~XsK4FO(w=7TZlL5Qq4n*>=Y@o3Ub~+lf67=Ah1OW|;lHK+2V6?1{|se69{vQW zqyT>X`pJ*{-v*qYIgRB{ZiLp%$=b>~rq^NsA3pfnucN=F7}cMZ2Ni2&99IGgs`J1i zewCa!ik;}P%Zuf-7Qc@@yL;a>!|GfQd(F)Zi%3TWyUIJwj0Bx;Yu5tFkn!yVS@^o* zHSbkt%mMy;ch}D`A|Y`1p8H9AGkbSE9Owf9`htS~;j9!0%fyu{dRgHSB|r_)Qw_Jh zsg$P(=J|ly`_Uo9ym4X#k~TpvKX9i%a?YeMP*B}x->D}QA9g$fRjco3eDQYxt#V(0 zyeNZ|IvGs~K;-zXrc6Rc$fO;Ag82|8;9^&FT|gP+_N8@;1es`2fBggSzXCR%=9~0a zj}DWBoWFkQAOrmSXC!BCXlQF?`>*2r(#!JCK5N{`@j=E1m~eeNO)-gP!IlfR`mhS) z+O4J4v(($v(`_ut+EN2GW!{2~ZPE98B^W=dSWMiegvr%b>~t;({3E||ZrLxyo~fxH zN`lMTnJ;SL(iO2}mm8hhKeo+HVY{1$om*+krMTl>HvkR@#ZwD--V9p?1=(Fw*Q-^i z#>tjF1;%D5{?-6n*n%DtAeeO{walhHuM5t0=e?gDvKaJa(n{FKC2?D&co(dsSgDb+ zTxG#0$d3~TjDOLWBs*>Rgv*@%!;R|;yye>8oE{HO8JQcp2Ap} z-bEX{RRnGP)X5G=Ff6HFon4nbreUG?PG-@9mKZJo!Iw5?^Q>QwS5zt%QwCICsWUy0 zE#NPZZl(rA2ggk$p2__U(2X+}#)b$=V+vgG{;4)<__6|7KruG;M#Cuju9_(CFZ|&O~2OvLa*J6(}(io z_992X7_q|16~t-;T70pYT=S9bpVE7lz~;4Ezu4l-2bN5F>>Qp_V8Z6#o>X5ibWwhq zzW&ja4cN6~P4NM6DIePgyMOK_c3txyx_)WQw5e=(UQE7&lLJiTe=T$3#f9w`Z~0Vu zI~&Is(YFKJB=B76N~I3i#n-U%@l1hdW=2s{-u-|LZ_4i-zO;SH7<}#pCPp~i48|p~ z%{^!u)-N){q;8T0MM5^CcXzbkcxQ(eOA+S@pFT9;9>xC)l{>lZ`B?ZS`l;#DP`)Rs z%FADEL)EQfd9k3u<*n#;slB~j+1x8S+}u2Sqw~l+wa`sK-7B={-ndle&Z4YLX8QXR z@2!()0S~he-3o^pLAYSnwmX2-=h=e=(q?#`p-u+9V)_>}fD)H3c1S;fv%GY%XGC;zd3x3GcYYjS@7?S! zMR^}kl3c_4X3Me&6p1$#bIa&h?jXsN9$5=a+6BZ57X*(9--g^FMWsF~M$vTD=>0(+ z`8n4njB(9Kk`DEsTPr?D8zh68>&h^x5w~_7yVWLK{EDRmj;c7h+oc`?LIOmEz+~04JkM+2Y61y!rxh`v+P;JFhhnmJpreTKkKR)FNUnR$d6qc?g!Q*WQtdFTr46I$av z%oqy3lWlJ>oYDh*%1>E`3tdh5k=e%mGD>6_OxN{xdZ6aV2Uxygf(?eiD3nm*znk__ zQgXUO5XwL8*9L}-bbwRhXJ(s)j{7#F$DwW&&j2H^vvx0$9S*5W-Fj$v!_nLH6o;BXD(5|@hzVk$U7$PuW!{9!zU0J5;_rASjVIz2qSCL=6s9Ga*VmGAF1S?VmY7v0oEFQsQ zQ&Z$hUXS3betBG!TC^tPgMW57a!*bn?n2yGqXWPfdEjb1;FY8R0#ZbNmE{{lCp+F)K|P{RZRdZ~Zt1o3keadW#N zaw;j9sJhLA%ai*NgYyQW3)HQG&%y1w4xEf7@37|R!_97@mWt;xBsGRLt>DsT=ZW0Z zz-X*y30w{uX$-yX#PJy)*tt2|E%u-9;?cQ|6e2zh-?Rg|3XrBt+=|pZt20 zzd@)BuK|eYiGh+qPx(9SF*0mr6f-NdfNs4+nWs&nQE4)M(!~g6nmCJ1TaWMBjo?th zU5ArQ=WIb*pR>W-T; zKW$K|vV94mm&@1yuCQv?Mz02)PSM!bCXYM(=m^PM|g#SX$z?T7fk%@t9_W z(c6Loh##EgOUOe^3BT`b8p>++M(PByb{GNwth`9{C?M(?$ue#Qt|3K#0OJkg7Lf#3 zFN{0u^-@w~f#?ZN8Y^zjMh*vy10l{zaZ<8Ya&w%Lb{UFU=;aXfZguv410YWm;B|%2 zUbtMlPwt1j%eE2x6UvmL8{hw2+j`N=Yi9HQYeaQgu{x!INTuP$uv!tPmAY6U4+boDb2G-J5^dK`lLb$Yp>Tc7d9HU3ij#K#G|@oX|XqYxpSVVWSOGk z&sGTKW*=oS7+I%Rw=z|QlbiD_-zP$uThOArk3Xfieq#Oo)+tL39LjkR3S9Iwtw)!PN1y}H^xozIExBkeRCZ0%rWU)gWf-^)8FbX7SfwX}O_%gI0M>a%y-nRW&) zHjrAa1#R!?lT40At^3rrr_To8#`F3hWZTK-sq}Xq80svoiv0J%M~m!Z*yDrHH(8l- zMZx}kK=>Ag64la7P^n5q*8VjeKJ+91!KJ}rMnFccLamNF{7x@zlzYgqX#Ax?BDR(` z&NE&0-WnC>6b5w8yJ>NeyJ=9c(|*ggOIV|m6R5?tcClU_Lg?1Iq!(bT$?r1Q@5{i4>{Z=fDLPd*X zNg(fj8jwV@nvbo_{G+N9D`fbiMlCAbw2Vv*)Pm)pM#S+fT!dxGa@gYP_w57p#(5)D zom%_neE&Y%Z=RB7!A4<#G89WiKGrthFe=Z3T+~%aI=2m>SaCM>>dF%jblY5&+96n( z+^A;CN_O91*YX5s2f)jlpCBt4`cQ0fnaAK8JD;~BL}FOt?fmHN5sj=E2zl<8$xG3B((n3&lO#td3Suu)qUcwm2p~~6O9yA z&gWw@krEEprd2rhmtp1Axu0S8XQP%vT9$7TGjFQeTAhtm(3zd{QdQp4T0HiP8SfLC zmXVgfwbn7yS{||X*0g>;;G_KUf=cMV+Qs2fjLe(tcx_QN_=?o{QR8S0emSYdV(NTS z;_d9OrM8yW&%3P%Dou4)mu|j`H*k@pRG(5-ELPWA@kYAhmP1;Ktnb~NJHy&#HU-*A z&hC_-`m0LJbBy_HATc>U>AM&kF1{lt8fozlp3??fZ(ujh3!-O8;=Y4L+LLzqJQBZ( z%^SI7*W6TrHk-!gNLDQ+1w954lQNhZVog+z6oyx?S@G1jX`L4*_}d>Y(H>Le?YQ7X zsW_!4EkuOu`n#|sxu5RW0MAr#lJuBhiUXTRlh$WcQcqO7LdoA~&nqkKq0F9Igs1b_ zcVhY2GX9);q+cyLxdC3*`W%||WGO;qQ+TwReuxD-cGnC#KMhY5KK*gF0TXW&Xw;~C zoa-l6O?NzO+- z3M_Y!q8i^n$-8%+3i}HiO_FA`s-ejJ#;^}GRTX$yhi6Jr52nvIg5bv^`P;I%pC_0_ z)YD1)IbrnOh{`*lByP~7KwtKmEcz{Em|biMSA2vh{Fd{P5JKc3r&UaNaRqQbty+R= zYU|OfY~Gr5Mmg+2ZmBM}+&RH~v0q1#Ua`un;Cf0^(Q!tI331=Y=`Hq@jmqW&VqE&hM z*|T{Ia{)ChelcpHIl#0?-jYo9uFVOB1p>3azf9MVE+JQXHGVi%XK(gzw3U-(ah3Aj zhUZ~P%7%2~y4|8SO040Osu=t6*<5oAQnHg9aNMr!+!9SZ4QdKC`&fByvHe19YU6P| z9Py7U*t2O?R1`6?>1w-RTr_S_8EXo9ZjW*4Pg=iL3kqYih4N|$*@G3fv#g^`?O#z@ zosg;nj}DiXtWeiSosTj=^KQF9WlsU`?`9hpFg#qB>~igH&n9#&I4#D4GL>32E>4 za^`QH!x8>_S{-*%-|%E&)M5*;OV}ixt$m+A^`<&(Ow_EDG9BJkb7X+=h zEB6Mdy~E8jSMz!E7?v7n&orzXSK7jG?{Wdm3I$l5Mh`>f5vNFXVQJ~-V$ehV$0V$( zseNSo=B=ahVb)7U*3AN|>?2rL?!((qzau?H#JxryRj_Tm=bOdtPZOHw**m~(8y$lF zU|f@V=Ca?4jJ(q1=(o;$V+$M>bg_y|Y)QIRu0smsZ`FHA0jnY*Lj%DO+kk zPCog#GNvKk&Yk9Yui*~-w-x}37CM#X>Sf=y-yCvjM|CEn2KcFvS$XKx%1 z(=r?vV4Ruro<}-a;jSZ*CM7o^?e%cSTw_uYV>``Z-xzAukuYiN1L8MFu;+x>@T#MZF6LPU#1so5ZQd!PX`FQ5*_!C*%NvWHaZ*E3 zdz6Hz3vu_}Oa0&klevY-I`a*nwQzx|E0?3dykZb>F>kCV2}qVP~Qk8 zTXmTc(onb2VK#udp2HJ5pZ%XOAk zAIGty!dlIgmFbv?(c#lmAt3E@PFJB+DA+*T2y@9TwX&a8X(}7Nc}b*clQVv2xP0z@ zE+J=o$0fG=1iX8FmjWyrkMlkN8DO$sD;iJ0&B`94!PbaY2W0_XXAbKJiN*dlYTr+O z#e`sfhI^vFcwYr|#?Em$SAFuNV4=KsJ8K;0zW*~M;gzIuEYBL!FTIy>&(T|NL*hZY zX`mlq-=4y%PH?I$+d`jxF!*90xQ*;R&eRGg6uw2$ZAq7?Ceuc0Kc(2Ijqv=)q9|Cq z)*vIx%ErEqj}!l$M*uYdu-E<9P5p}B#uX2GyBa+pWg<#r`$(9+3A~n?8>5 z*iT`ySdC34r;<(VeUU8fVg&xoVI3U4p-C1Pn|llY8R-2(?5-s-2{k%S%h;JT(@DN{ zp%61NmmY+4um1;hK#RYr=3MKWvk;C@495|JrKv51Uu*Ici;AJOMJBYh-b7}qsS0@{ zoU=A~oFlZZvuTo7y(P*$U6Z6H{WWvmV0>MIpmuAY!Zu1cbdF+r0JoLpDdfobn%$VT z&QcBMbcekcXXHlOZ0C&(KEhPfSw>q(k|9`v5~9WQh>!Sn1dcjPgWAVln|+nmlCWCV zUYGlY9)mESLc6*y+ZyRg_BS3|VRUAVv1WvY&*Iif_wQhpRW9@WB4`taJYv(Kb z0#U9dPZrQ*-);QYYIzxZH2#V0oLWheWJ{2m<`}81xgq+Pwly9{b5t@tfUez)yd(u< zYt2Mn+CMb~?WW*a+exP)G{!X8h9%G14>3=CSN2d%yPbGmn>VH^uf~&eO@>b2QT&<@ z`wQlbA0YaIO9Ra#98XAFN~-0SplP>}R41-wdw7Z!H5dO3Ev$*lN|kLi$2Z0@7d9n%YYI%F-3ez5op?pt^R_ECXEKY5Wv-z;2X9Gv z#)5Ub^LVq`t#y@cw~jB_cJnwn9-o@NuG_71(z@4hL+e=;VJ+I?7;9U!oBOn*-J*(zh(Jhx>nM`9Y1O9&_@HE$1hC z4wvnVpz8%=khgDt=;PAcl&@;AVk5jQQ%zQZOA=!`mwEi&?5n zmy^k7UB3GAvr+sDty$oU*?a}Q>g`qF8*Od?|9OiP ztYyBKZB7UqZe@Z@r8g^qGHW{$Y^Js02x1i5gAg*uwjszTZwx|I;;lafK4hDC$E`Qa z|4Ty1Y#ILgy-Nh+EijUAmkIxjAlcA@kT^E2z)IO|DNu)*jVD-2a1X;V!oUtnZ>{1X5zDj+Et@)xWui2iKzJj0$WF1`v^e895>VWS{TdIhKu~21T%t(z@jL`8 zLEMg(b|u618${P*Iu8Nc8$16P2gww^nxYgB4!*QZQmEF3Gah`UP@T}C(Q!LDsL(fx zV!E-<#=|j5;K{}4vXKl%D^#rkB0D{e48| zGYlqc)Q11##nT!U2aCmI94*$UISnxigwqvOv5&07Anzi-qNXFF%lj*!9g+Vtp>y4o z#AVb(-ZvHe31&PUPL`vE^UL(6q$b=I1xW?w zU{`N2m5<2OGkEAX-F9)mn}5gI+T6VB*|On21Y|NfGqN5#RO$3Gj($BHtAo!A5MePU zlJWf)Vb(eQMw*+(_1Vp~5Wb}C#-{;+Q)|%kOzo_NCle5IkZG3;xb!z2yWki2o!e`= z>43Fs@7lXe8b(ab1k4w)roxt{;t7eDBX}9C)JBe; zS8$e$fY%XSEGr?y;e9wB2Jz2_a5TOh2lKUHqu}S~0p_vm)ZuV;JsZygW6MdgOMJ=Q zP2fm?(%6RK!^0qpZp~_j5>0$5XZ;i=-Lo@dmIGF+_6ohOgmdXM7s#Q{v@Dp7xF0wb zli!tMa2F-IXWJVv?;<7CQP6D(*kz)@&sN1)EW0Y1xpd#p^j>iGS^16V!qKq+nTk^-q$mU*&A|FF?%;PmFNIBSqRQBi-YMJ z9s8)yuf9Celf!?&)9&z?l+^Eih0kjM%hA~Mg{&IE;A1_C?{NjTmmPIThaoFEe+kAr zc(9^A*vK3N$tOF;dmZcI@|OBV@ey_3@QIubOz{z+5l9X#;dXqtoDbr|QTfn7bvOPH zBv9MRwxEhiY_g()#gLE4d>l_EbX4gLVxF0!Gj}qKnszLLhuH*AR5RzX+@6|4AR~~A zxxFol_tF*5=K&tPoKxT2HDEnG-u)3zX&y{SgX0u%PMtK0^T8ab!1qEVnOX*owwPip zd6hI0GUV-mj)zV}R2Jeg$H?4X1W`Eo5P;s^T=Z=s_N_gA*wbu2{(#0qXTjk4wu^GC zCeh!w;l?o?m{YFB2SsUh^Kone^lvB(j+**rLmx8D6Fxf$ z56gW3$Fm64O$Z&qIy4n4Zs@a1&F zIju+wN*suUAFYwSq$KuI+k8(G5H;9b_-T?XFxN3a#twaw(XWwu7ISp!za{VV^$M zCzL~%-r7ofFJa@fT_7x%&Zf}Id(%4@5QAswoo;CkB1NZ;E@#;3gHduoBqXoeK;kyx z@Bt_vhLh#P^psAqraV<21jic4RMkX%|nfID(H`#;QHoK9xxx> zmjkSC8el00^>{x9x6BZc!m;2Eq`uIo+b}sno*ruG9DfnM52i`_#pjh%G%zT0jwz2N zuMHtje5$NOBg~i-JM=cUh&W)10JLZNcfLYxj4(V*fn;@HL(upq7siM_2gXWPEjdNv z$DZhB=04(<^#Ok@JnTghUhQiKo%9;}wjT8+MHB(Kc5-mAHpnhziR`ZStcUKYDbJgNPN7db^~^j<;?@%@ zN>$1RdTO(IfR{zd@@2vWdrePORNioxNh~r^z|JA=L=IsE6e~x#OC=BjsZ1BNrBYO(F7-n&fJ%6fu^CbeweF*` zDp~#PlXfbp!T!EBff!NF+=s@RJE@VuQ#8B5Rb!bL7!ZeUnHig*xod};Bs{0#;?iUu z$zY9dTm-}LZaV%SaYv>_h|eTNrTfKVw!5=~(G#NR4p`F8trqM~+|Qzt%#*Zova?ZW zlrN-EooNLXQ%cQaJ)fX?(W83Dnym&}BTl--Q(&J#eP#^ex1~Q}bF69yy|X48E2iI` z&j+7kUgZ}z;hT%9@XF68FpjD?Wjh*7!fD{bp3F~-qszEvJY0W1MLkBUf+wvm=VP}Z zGgFK&qqU5JYWyrB@=Jn}Qh)!uS{u=a!DKw*H$GpC1DTm{p!y6>5DN#7&qR{2Vxch_ z5V6?~q1NEf?L$dHd1GLQ&#uHiosR9^lH=9i+{T2uL4@Wl3htvByIdSC=8{uWGfMBsykkM>}BZnWg=-V!IQ&goRwCEug z(|eWpq}@ffGnY#VQZHz*@;=`Z)n_#>Bx1?cfUq z1AdHee3~=+OWr%kBm>W+nDU@5YROv=ze?uel6^(1#+i8h;}jtcI`s$^$%>rA5Ai#{pHdMeG(9g1_{EjPznEt(_k;Og-zgXuAHp~5y*9e#z1wr}h_}?R zkW&leUu(F^e7KiwgjKClt9UVoPNKl-&GNQFPiDef{bdqN3t8d0W;tJM^?>03QX7BQ z?h>g9TckZ0LV6UHkv@_}s(Uuj%{&;q-%DZkQkc_EoS%>SQ`{wljQ(;zUhtS|9Sah* zKg*2V3>0hX#j46E>e))N6_ioW^HsA_E&S4nj@l2=U2*d=H&5@SYo zjOZ_OFjIP9I(&aM$LCA(EndExOc8E_pPb^OQ(c*4eU4?iW`ZXc7g7gqWBQ4;VCn09 zRr>E~Nxc>oK2anolJ#Pla=>I-z4( z^=+bjXaG0Sl|8`CJ(p=-z8}wKkVw!-&Dal*+g5kK$a<*gOZSs{hG$U;tasa-J?6Y` z^HMPnvC*%7hFe@Of+bH;`%@VEFNdUi%?WX^iD33wR6b?>z?&((0H~#m$$5?pXZSvR z{EOa1jDML`y{nZkUcbtE-sI-?GRv0chxyPGT=B~?{AOe&W+cDCr@D%4D$g_LH}pmA zO4K0QHI>wfY*BkeZZ3NtrVLkuyO{eZ<~F6XpL=Wc$~56BAWcfs$jCD*(d2#RU%5j%U-f=Tms^R*t&88Hp@HN5 z@HBVp^^~<6`76$k;MQEXuVl#PRCi zU!@*iqy?z?Og*r0i0}V_1_d#fE1E+Z((`+pwMSZn>$D0G;if4A}iS$I3H9NI&pE!<&!DKR+2H`R?ulurxG|x^aPn-6O*5bs$ zXmntnsU}N_O&|IBlzbtInr7*72{Zp31-FCcWWfby*vVyo&OAPfbyAUw#O!GloxALp zN)=uyfu!NrUZO?0G*foMxVqYBjzwHUxS#pnzQXN0r%`DOUmNZx&!!d5)Z>c*cDIzx z*=BXfm0A2H8hi*`0@P_-%vyy-nMhFz&=Q=nwX~Y_n=Sub>JqwILs7^HE|{1aMQzj3 z$Y;0ZSG%udHlq7>T#dV-m9X#)oFoG85S44#Rn5FI&aKvDWo8!8afOJQa2QTM1oH)T zd-_(E;1yz2B9UgcHXg$A+C%QDW&I<)CXil*_$AHlzM~iX)@GMS#@p_(+v})qE>)-L_46^Qe0@Yh}WhmiCE}$PzBkXXsWG``5 zwjLR~fM6gCc}Mxx)+<-dY%3&eW@6oZKG{F*>1F(^)o`&t`uc5uRdzPyAKzsBWO2LN zjSI8viixaTW**z*_8`HAlcwoSQ4llwm-1HH6*8GMd{qv=M~QRN91C}q_sBzjio0^b zHW8+ZPD#zrY};jWSGLjPlbaU>5ZWPTJqMo~Yf|w~zgcp$oK0XHwFv$gJXz1>exYSv zhFQqg=D`5>f&Vy;7SSH=!LDf2x`^I6)cf5oViH!}JWaHNsEjI=U|JiX-zJ z`@Patuiof4yLfXAMKF4Eacm3F$wwqwBM{1@ zB)OS_iRb)`R54sXJwd=Juig(LUQ{V%ga{Vl`#5T8WQITZ2{xF@yvUkNjm(WC{&0<* zZ`7Nq9^ugh6u8eZj=N~{lsf=RG^=-3$&B@h!+qYUDiy(5SKHxo!OwUn({kwwR|A{f zHKp>hzOn!upY7^Xn}Gg1_*H@^M};I5_`OxKJ%|h2e=jCHQ9;Kx=r^t&3A+(F-2e>& z#tN;s1_{z4WvrBXK&w){m{1`iMO5K_p`Ip##Rk7or{zv1er>7wEVoSl474Bn( zXH8>EaTzam)tg{ASVpv)8Er}S0bgR*5AdMFL7EUuhvFSlJg#~$SKsb~auQB6FT<4H zOoNXQJQo2X8zFi;3Qi4f7rNWClQ9yr9ak|r&POc&#az7;6Ke9$Z20H-ty;30sM7=>(^qX0IU|A0i^9c6ek(6&3@h|WtQ|F2-qb5 zALFKHw8)A58FKd{sJ*Ug2uPbXz?~(y)k$n6;C)BoG^nUxytof=3s5kI z;bQVs!S}fzcgSS918E0tgt9NzBLibHvD7_k5{5JAF3QwFg{afsPgm;Tkf$@qI_JTN zUwvW=)!h}7Sim^lN36F{=dZeb@Aj}1B;&jp$AdVwx_JZO-O_8gLeFL)(ofy_jpnEf zza&9b#vk-zn#N9<0*Ki{R?#GJt`Ot~X(Ro5y{{z!*&^J4a@h{7L6Pn1;QQm=W&i*55D)<% zxB)NIcbJE21WvOll2Iyl#RgpArsxoo+@>BzR2@b`UGwtl;HsCh8I6{Nm|)l=tH)>u zp>063F0otUkJ~xf-ibeug_(Mskr~FYP=(96qS2tQX z+d$nT^;ZF~Gkpb&Q^%{|3=7_z1`vJ*(-6I3f|NC2-23lM$KTl@TmS}6GyDK~D#CJ{ z|4wR3RjV<0%oSMQ7@(nbQ84)c{(lJYQYx{ln z(thjf&T4$<}Hg{vf; zsSDIrK0yKr6(l#3qhM_AqX+L?0r1l8S2QQZH<{t4=KJ(09?J$rb~AokRS6F7>uIMguCL39F@ zpOUy0t7WH5Hp@e805gMaiCk#Lj`J9&29CfT13+Ggb3ir^e3Mc}J33<1zc$^0z1(1m zb5Vl`#woa%7dkJ+-e44aPkgI&JYAYV4H?J#@k~but^;Fuo&Ha`1FQJML5SQj?f4nY zA8KkBr#$_@up2bUR9bR6W{cdnDo_xpccj>$a$Th$H?&HJcyWcCZzraSh z_9fT;S`u8vHH-s)ZLaGU*M+i<8Ps|=ERJn^*jBhwEw>9JdYOJ|Ih}uWdob}JuES^iRB(#dUa$7*k9jrPWzv~yZk%zr&Ckbg+CyRzA>_H&x;t-%PryJA*| zyBMfjv9P_4oo$!_D*(2e&tahcGN+kg!HQ;`v@;RsO6~FMAp6B8QrqHPd~G6D@afcZ z+le2hSWLyY3=u!;@|HlQnQX`?;n(t+Ec9j>tSt*`*NL?NV+Nn}6~5;-nH+rAd?>aH zZBv?o@8`Q9`6%DK)HGWzObkhc-Po!Kbye)wpnmL~_AU;Nr8+RTcD;RSt69DaXd)S- zrWXQpsOK4fQ`)6p&sVv7XC;>)O#a|{y`m!76Mb{FaPYI9fbb)QWMY4gkXEhFHYmj? z^VzSTrC%E8>$e#qBB#b96e6C|xT{Lp#>Ai3+{f{4r9FDdz&?t{!EHv}4XN%%V*~0o z8w?byyJM^SS^WY(xtkfRK>>07Z_}gYshjy>b2HBB{NUo?q<7W3*tokY{d?*4b6u7d zPvna;|45hR6cK(l=CsnH`v1#u$pMjHkf?6jakbZVT)76Y+I8jA_}}Qdtn{su@4C!~ zdAGK8$?1}5$vcR5E#mn}-a5ovTa}eLx;6O8=c^^hVSYCom%m_2BV4!;n5{pG7Jp>! zxpLl?XOYdO=3nf5qmIMyy;{!rk%mUQjVH}K2CqH@Dhh%rE{yv?ua+NNT^;u?uhb}} z8__fQ@uGtDClg%RiO-%RJiH2uX`1DW47c$>9M3(`%}tGBzCh3F0F3?X7f!VJN)(8Gt~RWLs) z%S|L(G8ohg#=e_W#Ach&u31gkSciUDkEpH1vWz+P#>P7FufeKsv6{{n?33=5d!Z*S zh04wcw(Az^bT?WHb^pkL*9uh4^x$YsycfM69H_0}k$EPuKI%&cZp*VbGjp)(;O?DX z^{?JKa9jSineOK6udoLl~|na z#S6OkB!&!e%MCR1F#pl&xOf%8$S6joclp&ew1)9jpJh@|&N>M0$khTKxX^ z%;NX;nAHsHe>UHie`&i1P^$%JO?8-Lym*i+{8z(INUZa*jP5n$Emw$K8E1AE^ zlXbUdQO=(rcq!#v!qOi$y!=-hUP$=wI9cP~<$~5z=S#%57|V|mn>K>3bde2z<7V$+ z!`EP=VX?9CPOvT;(%m)c`DydU)zGpCZ>mQKPmlIT=D7wl(iJueUi|q@nCV!|Y$_D2 zLD+JSnT+#AC~`Y zZ@jM*ScK&=JDakIQrWUdp95E3-12Ic$Lws}9tzrTxyWO>S&`>Suh;Z8X5+8(DS8&gjU~nT1f>IM`uPOShv(>`U_tx% z;9e>8GORra&5~(YWL7_udm$O=4x06Rqx?KF*6M<0ef7KsKVg)IPvsFXSiNquc()MM zJ3UfoKdiAJf++0l@Zt*oxue(phL0eD#j8j!wcOs`77KvaT5ib;u5e`}uJhOu>spjv z#rd~ov@lCKc?Apu>6I#oHz(LD1?L`I5Byl_e6H26-v0uC0h z^s+VRp=z+;7tUj(M*Xp|xTSqSJJ!S-C5YACVtQADO0dQ@yy$A@G z6zT0L3@(;QYSRUSE8cp6*M6z^AhNZ0VKA8Dy%=H?37A|<_ib%UqoEBtz}RrRkP5On z4RAU3z$`73kgj!nYwd9G$sq=^Gl}WPFvN{i#tT)3YJgQQE{wn~_NtOB`xuq}h_&Ll z4z60oouiM=PJ0IQ6E#G$$%W}fkv2ZMiwnchjN}USU-Dq24w7DjR#Zur`^S5Jyh{w5 zR~Fxy*%^m4J?AQ3w|`47sFlE@ zyKoWec4|4_h1fR4!O|&qD1&tzN_L^GwPIPXF%%9)xCpu51F1EntqV=^cVZ z$SnGZUA=y%=F2GnR;yLA(X0D8u0&mpgFYGs?jTkDuW1OVRLF03Jr4A4`EeziVWzs8 z0)H%q4?}(4SU8W?#-KkbhKB}KF592=F>HUz!DZ5)!{dX?%N0%e>dXHNP)h>@6aWAK z2msS!*)SOyD^*C9+Q^olovQqY9@bOAi42bCwTss~#ekAw$HolcnMvK9a>=5>x)BnQgdHZyf8TTZ zrEaN(v5k|v_pUzJQa{eSPoIAB^@pcV7M}msn^EG&^TuVkq`sGCjra5L=;@QEPlEX( zPBIcFGfZlv-uuS$BWv;%4Hq;?tFr0)OwaneckMNTxReypta0jv(>R&a$@%caeecsn z7Q|6r&Y*Ld1z`z@N__gH`TXe<@|^7UCM_}ud_NB3#>%-SFB?CQ!-Iown+M-F55FTX ze`p;Zw!Zm+_+c=erv4Ri-!I56)@Ajf=r{WZ-|xRXAp7L>tlN9lbGsyq$s&obg9#;` z@6$BJl>ht@SpM<9$b?RVC_vH~1mp3d2}v_A$xdS5%i=`gsdx5BCtj?QV0M)u)NIRVOEbPotDh$TFJHgk)Egv_Ze{Pvkh{H&7A~ zMGhMWq>cq@BCED{#DT2hC7F9G62%!=rWBwADVYW#C6sA{1Q9A>5e8o5Q*skzR}7PY z)8J6v2q^Jo=0ODysx07Zsuv|*meUT;RhBJU&F0O`O~YekH^79NAupUZPkJ4_x5nu?vH!!h@1^c z=d9oDjeBQ(_?S^!*}1E`Zbk1uK+F$cR#d3}_haJ6%vem;;%#u7{1F=S0_FQoY#FSwjpq5t+n z4>T*pi3uqM!T~NBfjLDpOp4-U8S$41y?(6J+TAdfpp?lkS}kPS9Du>iq$K zPX_Iw+b2W*@8qXpyYq`X*2o^X#D!K1^mN_MiNM$%k577|vH0qrjoa9i`KPKo6u?jp zqe>y(<#qBFl;#(HH zz^dX^*GjL?Wp$w!`=gwOaviu`Eh(1}e4r#Rn0n9q=69b_-#I%y)frXJuPp`Id)+?+ zcn9hi4lV8u>5tHxW$WYDq2lNF(hAdF||fyDDMFJu&8(a+N-GP7k; z`O!)lBm-e|zQ|ULoFfS#gXm2IqgSwV$Z8@zEg(^A-Z|CE4S?6lfZ5y~=%t_^^BG?P zBE&|{=0S9}*qCl1|@=JIT#OFd^LJWM5lgMA0maLsA`>M$;gpx4}Yz%|U>) z`Vb6}W3qdAbO*jhXu-&t0N^Z^m%Xl&uF_t2b1AR}4G=`LDJip6)~{$g50XZa&&4vm zav?U$R`uH70OOxE2mTHiNANO2rktr4!axclCAwEBDEe7}Lwm*i#9dzncQtL98@#;(yoHO4j||5j%I z{ejG?=4<-g^q@l7pF26%FNL?@)E`cU#o^}dPD9lyH>wYWRX%1-f-n%r zcDwjy??|%8qNi%h)%d`NBd7#w7G6iecY0yn(uAulg<>BKM=IVYY)X!IeB}a^c|m)g zmt|p)X7uQfs7B`%bB)enwDR#U>n2Txk6>oXNp=1P&DT92oB2yksmH6 z)WB&O5_7^TK+M1ZDB=Gm7q>vtt!{0f^ht}#C7CTX>J(nL*e2INR81bLX&^P3aSmEy zM0-aR7rd4g6N4)dS;S-=nqYmKNUI0r8!EsY?}&yZY@|G)0xYPG-stZv(Hxfr2YBj5 z-i$>onT%|}i#WUAIj)ia+U>i;_KEH>f+?w^W&e!xd^90n@jzhDbU<2(hU~mJXq^Az zxJurBEq|K@@L94dI?f8dWn?RC#9t-}l;JcwK%dqd+%6P+HWLg!x^N_0rf@j&gr;$L zO(8VM=)Bjh^RB7jzU8a$W&RbZTNix@-789k_kpjx3{WRYoYZT*=o-3-3HBX;jsz1F z*)*U@i`2?IsOJUmY~X+Gh}7U8ZOmwPO4AgCRku-lcYR|ro34`i+c1Fhh|RH2HZg$R z|Jck1xKt%%n@%OXy(1aW;`2|aM=?vgMgR1zv-^EP4TJU&z(XIrbq`hhy7q!$+{{ZA zx&6G}>f1Hm$|@p!w&t&dsQ!h0mZAMG?6|&N@3<<>q1ts7A^vl?uA@B2l7o&`VM*%l z;fH)UYkdLN(gPHwZ^#j!k85Zt4I1xDkbQvo!=5o1&mU82VjR~Z;zi89!555trWcrG zA#8`^WV<@3%SUc?F@o!=tsba99Fy1goKl{M;Ta_c>Q-TWQA!N4Hk;%mj^C2yf^WkR zP#dH-B{%fhH63A}E3@9B-p@yWvK7UkPSKU4X zk3{%dvgK0z7Zkf7;a*aIIQfr5_FAI(wuc+r?A+&;JtM^dH+@IBZ;yrTlfIVl&nxl+ z+tkD@qWwG)El{R8Y^0;b_q^=vd>}?O=r(MsV1?OS^v(`)*z4|WTD8|T>VaT3uL*^V zl}C4~J<_W4V0_c+ymYa8&mG;RJ`~p=i2XvFQXq<#0c=WwEUrNiJF!HhbrUBOBlHqG zv^2|9R<{w$YHQVz4k4#s?zaL|8&R@zPf8@BA{nd^C|n|Hkzt=Kx7kn^cQS@QEvHjx zs@`HjqX{&@k|!wf#rC?1_e~KO^7C)7%#A?=Z(wwh(E4!boJEe-#HlRiD5F zo1VG1kpjOu9r#ac2lU+|W2%ztLmOX}X#K^-B3MwptID%%W~k*pfbkl$xZUrn1brLs zoapURQIw4z&*xr+aJKDabDsIeW-A#FV%K5pep|_|9;=khyu58`d+n;K5kDqQYg>K{ zgq9|Kf9ol>V@-WbhGrLPZ7|#E&zLD4vfg2n&OvB++Z_XaSIMx}X1)l=XkS}qSDLBd zS)F{iCr3Y)*my`RQH~MtK*oKcy(mG`=8f+QRD&rRPqWF6UCP}r;uIuKt5dezL=p<& z5RH7A;sG{1H_1+h1b^Xq#AU`H1W}q%Z-ND`7!?z?DLIJP@i;!w^7P62y*tR^x=mv1 zce~4n<4S2Z7DU$B-d=Om_DNqW)A8E2j(sV-=9abXQemTElS3;8&E=CXdbT`*QcPC| zQf!%;6R~i|*UNst3Nn7IvAz*sEWFotaPf0UU2zUcHkwJ{o3|mT)E#$KnQT(ZW{adU zmFgd=NQV<5(|z+(6$^mY)O# zau2GlT+w36v7m%k*LKhH<liI=k6S#VABS`A`akVA5t zbO_CSew_Ly05^{A`4S;7V)ldOIKXOeAL3kytWbB*8Tr&vhJ3*j)%&U8zZ*rGShR8qKmRetL=5;0Fn=V8j!nfT#q85tVdj4gVu-yjDFPY%2`Y{_Wx-T;@s}}<|KHf-_h|7VT zC?Q0`MoWb<y&#U7Hy)+(>6J1_%qd)JvPb2tU!8k!8mJr^oc5-P@j6tGx{ zKggYWQL-wEsB1xPNuGMpn~T!c)9}_LI<%y2eiE?>HHRz(rtgFVD5}1yP=!v5w(CY5 zUgV(=m#^mng&fj)e%TUFAR+s=N1i^hTwWqEp>=&#uhFR1pzoHT`Z}+MZTdvqW&=%n zPaB*wXgqA!0M=_~cs$#UW?_(mXL0*`f`XKI33On~1vYv*sVVWW?R4VGCBYL89{_VF z4wv(&znou!q%clRC|>y@G*BwQ7P3tUCqYEl)Yr51+QQ94i2+OKO{~>LX1A)c*tl%3 ztadf?%DNoL%~b$ynb$~32vjy9^aZA-aemtn+aW1pd^WX_hhO}9n~`>#6{)zDMoC^6 zLY4SPooGzRTf4A9H#kR(0*(Yg;g7t1+|1s5ehyJs>YFNG{N$xBQ%2={9v@iuNYT)QfH@ zhvG(lJi+&MU}T{j&epr=!$xtg;cqNNr*Z=rSpe9@_w=23FDo?B6& zP`RVW=}&N{H{b_gaPD8B+NMc7XCcmyxDz>z9m0)X_S|?e9^QzDW%Fw?n9*uIFT@Rn zEhUBVwchFDQxQNEZzZURAfwU0RMxAoCiRMXP>7~@1rQ%nYid14WjSU2 z9P@fJj|q~=rzwyD}#TGQhsp`7w;6dL6{G3+mdg4Say z%wydhp**Ov&o9yo_o>i`74P~fum@mYNQ3yi_(N`v`@%stHzebh>9@Pnkut;H=LZYn z&4yL;%6CT)r29B!JMqFeqBiLH{6vtBR7o{lzdJ@TM%o8Yy1z^UyC6$bjQ7K}OzFN_ zi%1V^#scHVk7Q#&>^vEp^u9j~Bqrn?)dMI&D7^D{Ads9C1B}#w);F77s4@7n`%tE! zsxh#|XFJNLU*plSJ$=0T+1AGSivMje7d(wc~7D->D$sDa;fq1(c$J3<2=LXoYPXiw2ylpAxs zmIIahHO#r92T^S4LW^{Nbzj0cY(Bl^g*VFjS9&<{|KEXa)PZfu5M{T8#jV4~ z`}Tcjmw%@|n+6*s@q#AVsxV|R`a26$r;_Nqba)Gn9Gp-SHxzh$8DIJ|YxI}zJ17MM zcf?rmpf+szE{I2oJZ!ReglepT$Cp!tZqSw+9n9?@b#14}UMWiXl)s84zYb0jcf2%T zva{T(u!;KAO9m(W6|TMoOt^J=l_N5tp&MrfzP%`G*jgNzz6#v!T4TK|Izj z33iiz78AUizc9zjeng?L0=o6tU9sl`<=uf^&a0~hdfSSZUXaJ|KECt)DUO!Hrswqp zzHue@FLKT0%1i$CCxLNs2i}Z*Z7l2MpGOuNF^l+XDK#Me?ch%U>K~PvFp4<`&Pzq1 z6)BK~Tg2`85FVv<#E+;E>ycUM zGNInvqXOiY1<1t}=evXcq?&{#BYmUh?G~h!evld230SYGd#kFXs5>jkR8UDhcUR4= zYT=tsM6W$hXY1L=-o#iwFE63!*$wtl7haV8R7dVT0hwbg1v|#tu2Wb@c1jD=`d*ka zW7?LQ&A2O7LjoCd7GttPcZku6Rik2JEXj@o`aJxC~+Znpw@CS08?KaliL48c(x<2svUonh>gw?>m9Et|B0_Zm23ci zB?l@hK${wh>3ZaINAq#0Totag>Ku<@)ze)0zyN2_7Ck`bkAGh7! z{8D34@lba^g*7|_3pMt(SzFAYXVT)xMQrq|4{(c{^FeE6}1JOy>mBclMjjr*ftb#7NZV?2m%CR z5!diZs#LekJH`nHnmYlv#|+WrA4GmMnp8^f0rJwo-U7@jA7){E<>1s?EU+Jxje{jB z0WFi@Ar9YeP9|c35iwOaYEbAJa<@t%Eus=QO7bjAG~dts$PLoE)%!k8?p8o{U3?Bk zsbzn7k-E)V%EnAS;`|8i-UJbmLv{&h#C{O+>6Rx#noWdPm`}natF4Z^8~2X4ZXwp@ z*vh?Qo+)e&Fl#-dI`d$&GyHj?tzoD6?;RC!F_E}NxLcZ>-xRm*Td+v=VxU~~z)^BL zs~_wkjAvgzD=c0V1t{n&ELd2?_kVyPs;In$9i|~Mzqeg`WCw1oRska1Hb&sL8eb=# zGe0F}fBY*x=fkK}(?2+Qv^8>kh0#gHM3pf+wRN8uq&^KpFQRxs?p*hfa_yA;jNa|w zHhcK?U;S`m#XX5KAnY?=h@xh*^z6z+_Br7{f6Ei(u#>0#R$4w%Ix&7E)|^HWvCDC- z=J1mei27LFc)%JOCW)h&dLvZD$uXx`>({W}JDzt;YVYS^l-Bn2AJ+^1!sY6a;Kl&6 zS?cVF>+JQDS^OpSuBlCcB8*d{Ib4*v6mSZ@YZ*85iMFkZ@n&cQEIb1ziNHIg^#g3Ga$XtdR*jzn3TU8ph6V~LZ$%kbFvn212aQ_}F5w_Q%| zD$O2tZvM!CAVSPM1wU$Q68py|ORf(4tzSoV_S*JpU+yP{d4p` zxaQj+!mh(JhkQ3*7mHvq4PlPh4^t1cTHz;i9i}Bz968U?=Sq(qz2TExw7?7DPH8=c z7y}g?n_qDvM&EB=5`*<{qBVk{oRkbdCV8UIFGv;4b>Dk~Qys^Hh(VQ7M!=xkZKBm; zW}$xm(f7e*=7qf}P-H(0_J=6WKAM}BS9s`v^6C>WCPDC&2cKG3wEfB|xLFAQL%5~*LcG%nPdvFMR_2u6IfS;-8pC}Xr^wS!o#O=1* zlA{7v&>f$+dO_|%9Z(RTn0AkOHkQf=G{<)Plg)ATdFvCTz5gZHrO>gg|@0SH6*VvHw-E!-v0c9o6?X zJJ>SevH~2lN4wfUOYv$Y|M$(Vnu9|$GlV4jfwy{*1Wg2ar2M48@J!vsrGGg?O|!!= zi<{QIdgIwyVD=r@-$Q3;?mHg#q-27`wBnj(NAnS-zo=Gs!l5QVzW`860|XQR000O8 z(_+~$_dyqE7Eb^GX5Rq-CIA2cb8=%ZV{dIQVr+F~V_|c2FL-TiFHmV?V{dG4Ol5dw zaxP|UWq90Nd2`!Fvj0C-`3@7mq(a#e#hZd1Zx(05x4KrM<9IEV3L=LRHWa`IfI8yn zyT9&V10cXdc3zxp)x&Ov7)(#!Gu?B@Gk^4pf2GwZx~X4I=X&HPY5o3Y`s&LszWgG% znMHA`qWFqG)f4}|{`}S2&)0f7({WO6u3(&}!L;1?Z~xX`|1pU0>B}#6pMUvq!s>X%L0L zPR6>Q=}=9BP^)l$bIEEbsMhQ)Wk<7zIJmk_nTM9Td{FP^xBgTe#X77j zb2?RMO;oHC9pCElqPyA;MmkLNSk1#Rle*T*ocSaA$y&D6PehPdRIPeL)fnJe*7R)a zl^}VD=IX|OP+^p+d7=qRkf=#8)k@!w^ek0D$kv)o13w&Tbr+=9pp@aM3zl~omgq9| zse?~lW>lM$L6x5_c&Fz&O=mB6ckk}*>OR=6lhf=@1vuH=AK32Usk=k0FS@-6r)-B< z|Ia*#NpjMcKO^2o{v~ld_3y~>lz$a#Y9nJ2D|ay&DZJWNNi<3C{8$U3agd~Oa5+ya z>dQGL6_f!;fqtl-nWt)S`b=5o>ELu*(7YWCe>{3KRBz3b6Z3F5a8K3IiL#FloxyN$ zbVxN%nTPMxKL&@+w$h|LqNMLbWe(}vW+3)28x%j{7Wi<7Pwepyv zkL2q96mat}7)4`^_lE}>Z0U6z-F+aGl_7s>{_Mhihy_-a^8D1F9{c2t;Z@O6!SN`Z z+$HL@dausXv-m7Le~!VvtA0M%S57hFlI&~d-G}oV?&I(LYVQ22v144+U!LupzW|6E zjt>1B&F$1kAm`aH!PPGa>^Xzk*M7_{`I?LOXLI9hZl2AZvw5qrL%)5`JDai^y1e4TpO1j9R>Jq5Fl>FuDLxYY!<#hvMTceZ zqIv5@rf-k@F=SzAxN3Dx?nV>a6?L{V9hYf5yLd(<>;(};7_R+RzW)BzSI__J?_XbhbI$#R{(>LN zPjo?RFxJsk?9Z-)5s}NA7LG$9r@6yFU6ae6RQjmc4OE;S$~{y(RJ^Q0Ue;*BuNuvE z6J>P121-HTby1>EtJ&wWi#{!rv9&A<6`P5+_j)M7 zRC~`vX`^)U$pnL7@*RzJ1F~7*+Xeb1$~5>j%%S51W-Un6y5P?d^fsn(CK!2DDg?`)rA7O zf~M=TG+j?BUW>|J3t+uAxAep+y$&jUsaSoKrc_u3J+Xcd>goyVp3_Fjto7V3KDkWV zXrN-W4V3J;Mi;CbJywLVC+)C`vFD*;G*H4S2CQnBV8F1@Vzp5Ab4MA-Y)P`)fn9YW4b`Kt5 zLl9d8vEhHV2x3DJTLiIT5L*ml!v?n4z!r8eE!eK$gv&X?p#u&b;m`qxj&SIJLq|At zz?36QIbh0_8O3ceY8R$*#Z)fDaXSEZJFFacPk{GYC_5}qmR;% z3R}W81&ay%CJ>u|63JcDLg`2ajKMoy@lF?-ap91zOb{+6H&1x=I(?KN>GcfGH%v)8 z>@Js1mV?m1YEs}p$(ZSI;i~!1e)apn<)HN(-g1W_n!0mFWlVmWk5F zCmXE0=;DDzp4^+RWM{6y4X)_SMT;jbUbBmGPb!?!c`a$_prs=%9kg_%rQ1gdG+hg& zG(!bmAC*0UwK^z!Qn698ke&_cJsa(|wA*MGYkC|NsFW55WL#-+0p)Q?Xuy&&*$XW(9MDdF2i zbd<@(;9*4(8F9CbIm+mu(vcu7P+dl5^f1Pa9=gbUW9*?~p$qZ?15y|=_zm!HNM>Uo zvoR#IF>Hy^JRca6M;R_cTZ5%E!I6nH(QGqDQ)UpegXT_ODhQLJ9upj!eF5tunhKNV zp2SR`v>>F((+!n^#zq(w#!N6~iF&Mt#6*NFQIFNZCt<(>1C}sgbtFJa0Og@YF;T)G z7_fx21@8>DR^ZG*J!2m)liPD7#;IBbsKayGSZs(U;qi zkb!nf+A$DZ83-)N64&iTigBc=;XlMAN-Dv~e)%F67y?=D-vSt@=P)Gsb44v}( zg*hDV4^D>{?!J3Kn#jLh9GVAiQ5n8FmWt@=!g1|=)DI7aNB?k38t0Gp(LsS~@B=X` zeUIN*`vd!8P^HhTX1|$1^IFAROCNt8x+jO^EYiA+uux>7zJkJX%Su-va9YU99$0NV zHc!lhveyuf4_xx_;jKMC4tP&D$+q4D-rwa7c|T5QjA55jfU~X2yydkD=TknR;5Ii* zgY-d-=5egUG^Z@fL5TCI~7J zwY=YH$_E4jFYf}4_X5gHv(4z_$7srvjE@gV2E5#ieuXZ7(4mega~qKa{)i>IoKGe? z-d6Ku?oX!=*l6~19O~Ae&UL0;?(_a!ji^UP3twoN(K*j}3&IrbQymgWU-vuPkm;x!>uqJG8N9^;Fbr+eiU9USv%EblNSKB zZf^Iyuc)Kkn>S9Y{!&2HTI;)4#{naFUD9X{%X*o``c|O!^*#8^)KLb!jH0RbLlx_E z9)|+%hT|bj`&y;(TyN+RB*)~5H^q3I_|s$=me~+Vd6(7Ev-JA)CJur`P+6L!_T5}e_Y^KL+ftj7uzsk9hXtxn2 zPRoFKwy>hRoCA#X;8#5eXY=&+8k>||TPUpe>Bh2C=M*jYba{_t_Y zQ0sAW7{xdKH2BqDa*;J!89vO|YU~tQG^!sRyN4X^w%vnciuL?fxjyh`N>B9-S(RT!Nm)a6%3sV@`HY+O!z{I!>iIMW$GbFuxm%8; z^rbQ>FHJWY^qZ3bfjxWnB+z~|@~7D;(nmo5nSpI4T*&t{=>qIih!?=WgFNCEJI4aN zun^AKgDjdL0`g4(?v4{*#3WoB$PUpbL7b$e5Kf(E{cDVkSaKGyYrVY zy32v(7yipQFs}ER+)~&xL*>V@FDb%}AA`fYYmI~KJN@k~@v1e>#}{7ZC)6b29K6#I zsTUZBWx>fipG|`4luzmzl3Z0M&*YZDSWo==2wfWw4Y`*4GXt3inyxA}=~E zI?JHRA&VrYJfg$-%_5Ryn7ib_UfMp>vssl9}Lfp%6vEklMt1 z5I~FEAD^y*Tk<&x`gL4pDDiR|1!G*7No!e#AyIHk;hsUF21kp#395Wkp~7hVP_FVr z7>8Ljt8pO915(i?i(d5+`Bpgx&mZ!BG^uFL6Y&Fc8H_0fUyPk3OB%>&MBXZfEbZS& zp|p-D!IUBJ)mX=((Y30bXmT;W*s~azn(XwrGEID@C!ZT>LK**6bLXEY!~wyc{v#It}G#)$`>toaVHvNbJig5+_i&he=6N5g%b4+*{RIYOiWp%F642 z?F|Wk#WtnrK3J-_6yZ~8j&4M=QrV6R5T?nu#Es$!dD`;vqFQ+c!IV>w!boxW1c2q#VqyD z0&X_H7v{`VNbDV>=fGKFjYn5CSbrrG`BLo6`LDp%OL!{*kjK&5{-waZNyOwKN%hS_ z#Q2j%JVnpXFJg}O4~V#nbhLCuoCONPNt7>C`10y_ks~aNmfz9-%#sn+4D(^}XzO&`eH~<8?Hj^1b{F35_p5k<~B%WOSYv z=Lv+Q*vOL|KDnnYP=`^fU-Ck@*x{0VfflyBssKe^z$7WJZu9<`cNADgQJAvZ<0>t0 z$lqP_&3iCTn5KG?<_?v!g_DnhkMhi3UY;!PzE#&??H`SPx3EpPvRu>q=H zt{gU&4ad`Fl68N0NLJPv>^50@X;)SK_M2M$nxn5e!o$O*z6!!x!RSgT$RkXaILl^C z9(R%zFHV>!`xUsTPjLu9&Q4z&>zz4yRZf_*bA}+4lai#KMtm}1^5#ixSvNs=A*Uq( z&xozS%%Y^S?NA~^3&^Dt89{lzgoNPMVd0DM{5Jw2D_hps{#bT)f>hGB1+e&JP5AjP z<9#JzODN^wd2k`mY#np%`roL6*zTDJwmOjxIKG7DhYvTvpym;|yeJc;bAe=8R zllaNDkv5>cq_xj4OT8Ye)n$;%Qt;ChOSan5{P0*@HwO9nGJKr~1mG zTA3m8bf-8As|jD*jcwsF6(4TRW}1&fOUG(NH=4&QS7oG2e(nQD_0f44*_?>gWXfG#8!gg1wNu=Z`A#)g z{4-1JXs9pWwP`)Cpm{-^m#1=B#ny3B$A5W?4%>XMAj60EjQq-eenF4lR^2>@d7t&K z&W4Xq>r)O7|A=sVNV-zaBaR`65iSc5HpeurH$EbHRzA2JZw z*kmMrmZHomG16bAJE4^k+Rj;C;}NWw7q8XI(qv^XlCl?^X<-}Z;|9h-kXW~(@9GV* zfj-w+f+#~$HUDDsa|0_Sz5PC}O1JMwnN@(r9&Hg}`Z9LE~i4=nydp0BwSc(N_WXhH+#QjdHg=%>Y%QKFsjKL?>H z1&-!d*U}nbBXHu=j2NGvyQ=#A z*bgDu*imQJSV;Y>uBxu8uBslRW7z6!_LFuqI$`kYF#2Nz1CB#*_yhQGHV87lYGqL6 z9Fv@VUdXSpJOicyY7;t6Fu1F}`mkLW?Ay)|ZN4Lu@oF0>iy$`h7wGce>1fD?5~Kj= zpgAggXhArh=zg7mFKmT={iUuup8y9^yddD8pejJ&Qxk(6v@Aylv=NYVidO;Rs?~<) zr_m}|si}&_^6HAQ)iqXTcXEF}V7y}obtYG(VvCc8V6dqgm#bdEOCB~6_Y*ovuAF|M z2pa}g&bMQ%tmoJWIBcJJhJb<{Jj-dH3jn=@j0I4NO&J0^wIfe2mMm!f>E5V7@vPjV z;;uz4FhC}mL_Z`vlx-Bx3sVFjYeky)YS9^>buiSxvQQ4eIYHZ1=P0h1nV`6Fd|?bh zCXRREVPT%`V3onhBs#m*`CjTwTUm!F!8@ihCE!m*7l8c8Nv>9-SK;H%I=G(kj=)bM zyJl0+<|X?xn@Dj}#<^`p!XFuLgTVWcso~fK%!U?Xb`nK-C!~Et=`aN3=2eeKK{3Xe z2O8*g3ef|uo3z%Jku0OxbG9tFPFZ0e!JRqn91XK2zrg_Xh6pY&&q8G&xLwv^bWptfQ;meww`J$-|N!T}gv5#_&i7pC~kswa`3t$zvD1 z|HN_ZR?jDJy(4ht^d0M_JzRVYx&wGzYplbH4N~E-;*5BXonJL}I>NCimGRSaDnAHA z)mh`9o}`FkJ+hRmGRn0VN;eg!F4m1vri-uM`aIaDd18gWj(L_rq zu=llmq=qX@yh5TXAc}w?rnclvieHsV!O`7mv(9bBdGRZaaG?&Xtzu|ba-yKwoUg~kewK02xd z+v#FC;tC+TnsMFsovoMX)D4L6)sm4J0OvAu7#nX-i|6 z3)9mQrhV0+gsCdjVlGG7nTyd=qv^R2Jr|<&@(6_JPy;B_6QKk5 ztzW+oZJL?Il_pBHTCNdr^ctm*$gaav3JoGipAprV0Gal0FlkCs&P(S{f1{}@W~Hu< z#GrZ%zU^pgY6Rj06~8jN>J5iCI2yQ&W$8Er@ZtdxEp9E=BcwvrLMR1hJfO%u7KvB~ z=s8O%_>{^0boG6@wtWTwz3z@9a5@`BN!07If8lK)(G|IDEQlW6d#lPfT~OBO6&?2n z6Y|b2hA1$qox#f+s4Pl2+>A|y0oF4FgDlbbK7{RVMZr~i<_EiYp8m^oCB?Nb)$__q z5K2(QO<$1X70&9;>njRl3A@%W^3*=|Ajn5q&EArqyv*eObW$RL!W=rmEvoW`P* zJeBoQJkesG87ORMpv`R9Pa*xs6=R~^QD-Ciz1#jhy1)dBL%Lwi>!tMJPnC&3$;`fa zDmN6L^+GQmX~pvu(6dHtn>hqgdWLy3v+OIPFo6Fmqcs`Bg`@#7$i@+liAN8G7PxKk z`*WZn&#s~Y$58+o=U#xw_{QPu4M#mJc~*jX7`G3~tgkgaW82 ztaQ*G-ZJfIly+V);x5LFWeSg3YO_x<*?@f2$}{OU)0D}a}|D}iW2CeFfhq|RKd z0YfS++oTa_HKcdYnNj9M4AF?GZ&||l!I0@QBVEPXAQGqRgn>-y#E4Zj}V@@3F+vgZq?2uo=) zM|RUba`S~HD(RU7paeXsU7rzUj}5tvvQcaWs=qDr1X85^(YsAVaBZE zfAcR=3Bpx%*Eawj<@3C=fj-z*Jm65}hfz(7!}yH#LIPI7J`OK0vvj+C$Kth3n04&nz{o17JZx<-qWt&~{{75x7BJ!$jj{;Lt0+jUl<_X_Nn*PY*-dBO zIYFLZeBL5 zSDWx+G3Qc$A};`oZCLAzR*cm~^LqzagYy2oX6-_WjW@tm)3<5a>TD@*`+abUKlFQpERH^YED0R#tzOx>0I)&r z!N&x731Jl!=b#ag&A%D_md+dgkC^^i$O8xgRG2#^pmkPA1zJk))R*JeI`tZlR_D~~ z=4qT0In>P6RK3jA)VZ1(eR(z2{;H(tTUkZ*RfkelK@Ig&Nj>#_Jt3^-s;O1xswt|b zOu(3ea%z7yZN;<-8COd(lg|vt)N1_LnS`eb!?3Fq$T-8cXMsF_!PhralKv zgO(?9tVEf)h>Fc7Wu8c>=5smK+qs!|4q?Y%AR>0Eo=?6X+VJEKAEktQS!r)R*HcRJ zu0RXe>fjg`qz7)`>Kngj=!idfpw^lZ_3wtE*5ypTr8k67YqKJVu3p7d6ErR zO|E*_hpxvAmg2eDjzrQ8t(Kqp+q}tS_H>hI0seLHbx?U7udW^p#I16hm`kXiOb;ZJ zmE_(X6w-f%L(&EMa}Nz05Or>{EF+ulMB`IcClQs*A36G3m&7)4ff;XVAo8xn_D(qen%r{a^tb*dX#QG9fSlikI4*FvbYoTC4y13P$yD@dI&hU+x zj<8bH2jEP0i)G;d%AmTgIA%Y{2ervMbxL~2c~4F4qAChsy@j<5QH)6y zU%sgh4Y2bKv#+W&dBrwlXtIjWmcf9XFpa)LjSGaGNo*TA;*O~GKw&4+$`=uJ{7w`_ z!jAa(P(jB;z0V-(m;<^uiqz_BmUDtH4t`-l=gWBOOh?qQE6u=zZ_0uW4C3w1UmePy zS1z*3pGPFp|9lhzk-->qYLya+^pPqFL{UMRjyMF|zVYTreE~~xuzbsbINxM@MH*;b z1TH0dH8b)ENx&PV+tJ)*G%Fh>LmdpqU|f@u82YtPKSBz-7!G?WT)p_rD=4iPd&DQm zPN(+v*0T>ku0MIw-ee#Cb7$$}M|AXOJQY5{uRn-i|Idz#jlBA~hb%?=-DkZ0-jA}+ zz5n9hz5X%W@U^V;dMPr12p@#>3X*F2q20Ufq~wnS=I23q@UWAzGJqZ_Sn_deDp)mh zgrapKvtL~ljaTF+A4FA?XCGeuXXtkr`FjEL@BdrQM&E~=rux==76hFcZhjjOmQdz? zh#AA`WE}OAd$`_EQDnA%A#DM<;mNzIy`7UCNT({k`1NnilSb=kXSX3*haB@%M%L2d zcVgY`4m-kMp?IfD{2NvcWK>~+r1U+t3HdUyb7qS&7u6Hq$xY`*sz}tuEy7nIKIAAF0iQ5 zfYyz!B8r?%c<8<8!>>hY9#3*^fOnWUHyC%v_u#<`$Dqb7#Fi%kO^-EKm~b^TQf^|G zqm&U-I#7(q>7W{FG!9OhC;vEZyq+am*mw7^LN9O&@0@>P;7pXLu^R328(4%CSPGMj zAowuwkRuf=y}$|IS(IKS=YIL8bUcRX!bN%1XJ>N;ZsVRSXC+qINyN;ZG4#veuH@02 zoF;u#Cm-Zs=V)02l>@K689pvK=avc{=dk;dXO=p$*db*eTA%5>3LY8XBJZE@7?iOr zAs~JYEZ@7C-x&MO0nJ$mG#Et+v^BWxzhZ3c_jH_Xt@E(bDA#~l5Vf=wtrrAoRSjPf zrO1aLis7(FtWINHb;YFW2EcV#=UGRgko9h-4NS5yfqsFxL>W`nH?Sg&22n_9gn zBkWmTVq+*8{sd_PO1|5lag*@miQX$<)boN#xR%joua{mWJ+^=|)+0L>Glto1G<>LY z8^9LKwhW~V#?jQpiy4JpwNMPyD|-9HV>#E0FM>}mf#!j)CwDrmrpoExJuX?yD`zFq z=E5nSAE&FUs|=;0EJgY+lCxSVXA>30Er-XbpYkI3OUYM}RjNx^P>SDsDL8?kTo8?i z-lq}e0f!Y7pwKW#iph1-^9o8C4gy7qD(U-lbWh&9w>S7Wng}(0F5s2bnLOG~Zb^c< zXY7qK$(I^NP!29)RNMp;B=K=ihCiq24FkuUWPH8aXJXFty0#}pryCTL0=KNLOLX8l z;pOJkb%LJ!goje;l&1#T!j>mkSVd7G_W*}d;Sh&X_8^Cnf0#olJkZM!1v>qt14lgm z-b_GI0=9VP$9f9K)Z3*znz4S%;72eufL;m?dzqUFL7VsBjb6&$8-s8}N)kWaa%CeZ z6}TH-OWh?IgdwPC0UE9>E3)J!=ysH5?PQ>Mq!I++&;Tv;GEF-IrHxMGia6fixE4~pu1cJfL}35`=K ze5j{UgUxq$*hwRH-giJCAlt=nZ}!nq6OvzG){DiA$;rJNdG9r)vNr4Wy-C?3I*=hl z<@ZolW42Sc-VPaRy3!M?c!Y9gO|48$33cgA&H?6g)qT&-4~Bi|Xu$MJvKp;Mzh0** z;fH2UV$AOHw%5Doldt1%WD`1X9PE)zPBy&j_Ihx8NoNF92Q!rh0@QJCMq^4XR$#UjUBym(*2VyM<;7PttE#U(>W8FcD_W>8*;7ubM{<$LHgk z!vHvs+RfMGbbA-1gJ`^g~N~;jqdw$D@1uGz6}NP8bWp#88H$ftaU(igZ7- z5y!pZO=|0gP|zijYIL*afbcc&a3`FWr)QLvMp~VCWB6@nG)nHnFGb$p!){Q+n$}4@ zdREsvUG1U%ZFgZY_>eF`qp-bBlfGElRf@7#3Q6wVUVY$dskhNMArX}A=Ejc_8dfER zgorAH)VbJf;g+#$pV+yNy7Y0%M$Z^hDeQ7}d^+2V!;QClpDHUha8u4Ge8HH@VwV{p zTld*G?Kk(>k?O=^>Zcrh$R|M&5^#Ib+>?K0_Zj^4xmgTNf(D-|pQ*k`7yMW%u%b$k zkc?1b@0(oI;8ZicX@VI42ND!_p}zhd3Tp`8OA(L+1ZX~9fYdW z#35?^CAAjN!iEjruECq3aY!{WXhs;S0zX4RvAbb_>S*V9=S}0JaqN+K`BklOhZU1S z*re>Un3cntJ>&e;IA|R2>|3LR(vK!YGESShTgjay~uft!Gj80E`H_{%J4>~6Yp80qcKJTxWg{E z9`rKff>YbvBoAS@C^5V-M9=_0YdYF6s`vrT1V1bpa5Z<$Zt@(PJYOo@3cKMtHeAm~ zR=mepvf6HM1J!dPerQO6TE0IbgeFG~5*FQd_a=cEs z+x6Xbmq}vk;p3YmgQYP3qB5e^Woy>uzthnW@MJLLJ*c+ARFaoLmCQ-B;N$et667tJ zk(zVnr-|0}ASdLznTk!N4~DP}U?%ZdAIc#E(M2G9kk;{b@cUqRH;~KGO(~*Vy%iS~ zbrdjkV@p|4;t1u6+6qa;`Z$JEMHiT9$2ln1Fl!G+SB{iFRtBbyHExZ)5yG=n1&roh zG=beO;=A|QIvx+%AlM_TUC9hdc3i;D{zAjX;``=XPwF>FVfmV69ST$iCk>5=y_; z<^jW?gPr|zZVNqbybiBiMIAZ{pN95deo>9zsw~QyE#J{!lMJ3iy794gET)-|ss>kS z&p5yg_&?=%z9O%G-45X*g@TtoaW-uBoMJ^McS#1M-%HwH+-95|4?tc?cA!`}oYV)bwhWxI!j`Q(l1Gc7}T0Ix^CDc$DnpE=u%s7GAFzj4-XnGD_D zgNNY?-@$?nwANYfkPyfbAc~L?Fd$z#OmvLK(*pZ|N30xI7AQxie50s}30sUz;&_Sk z3WwcA594GuBg;8;M}hO!Wmgk%LSOfmj^+jtp9o`)sp)dOSYR@4e>h6%E-h1cXHqYi zjrYQ1xZ&5OoGBH#MzKD0(73oKUni!4WEpxP@r8n2nW^>{lwt;5HdY{YZ%6ji1}_hc zHsXE*zrES7EzQKCg8;!_a)J5ST$}9*)1xqz_lhC!;RKUT$B^7)>yW^v{Gxxs&Q21Z zRlH)hFg(sFCC45RO&2SKgc}?Xo%gtiSX+D-FV=z4|I#`+ZXWz}j_yC_uin0X-8gRS z#@x5I`w;OV6*Y&01T&NegBr>w_p3ZFOYby&tJT3phb#ieHw7p{F48A|aCrP? zXTSMBjS}wyK}C~DFw}iv;NnMLhtkHt zR%&2?r>;(hx``#*qK6DneNbCF2}Oee;7B}}bkHF}Ey|Gn|X zBKtWTGi+G(Jsx3x0l8b?X%&W${r*sk0L~yO3EQ#WJ?26lW?7dpj^HAJ10`u31|$0w=5n?dgL zw(2XCyBp?VYqjA2~Y3^l>t%YdFHQD9O32~aa9VysNbcRgp*5@5zSM}8%F6xKt`#1 z-K?FA7$Y6rgS^%4LAO3}OO%P^BT)p#`$^|4H%hmF7F3mddVpfmYtAl0sX{z?O(Y)d-zNz0FkLMt3Mcf@uyE2L0$~5?Sd4?RK7tT09D^IO7Z+E9Ln%?0hn-vZo!l3*{jL zO7hKU*tun&*Fm6quIU=Q4_Ci$4B+CYL(f!EL>?QJ^!ni?|Im}6K}o0k!PM}fCCS5P z@R)`=zR*M-XVe>S*_bO6u5{T?QJ0D9Y)HDHzVhpfiKs{$B!o5VZB;I7_H&oXVy}0`1kI`f-&|I7aTFpuR(ftj8+i165z3)yKr5+n`GnS*v}%Yw+68|;Rs$dNzsnU zAH5li{MpyZd+j1PlWlfEtH%@IB4w;0Md4J{i=aO|LV#}=q3Se(kMYqoc8C3&UiyK* zA0>md=uf)W02rt>`7H*K@}^T&J=Z(YRXP@98G~q0BX8qD3J(k?qx(AGU-#eqk{sfp z@oHR3_*~3liZs8ah%S4{m1h6&-!v@*E@lR|eQ7ty_PAR};6_MR+y&dT`;-Xe^`ebv z!2-6zH!D0q+wR~}2996{o8H-Zg{R<1+^oVqR!%98RPv$r{HZol-8+u0#ybM0dusXm zp<}Gt#Z&hza{V=-xK|TUd~#dKTOjAMRHr`DF55^mm>17-qtR#@pK!BD*`h#vL))Uj zY22cQaNBd2#6%s9j}+l~=HU24w;bIh^Y%Tc0ecn`;RAMRJ*>IsM2Eup93S}a+}@aU zV6}VNm%$`pFmI!E2RLx2kYnkv_yQWXyan9=)sS% zhBG3Y746y^YE$zK$@jIp6c9dCo15VcZ(}}N1Rp@{>3~T}JNJa5RCv-G*d~%E;Iw4+ z1o;}1{N`UphHzeQjMi`c;v+v6TlL7+M7O|Ma;IJD${2^iaIiwDp|IOJR24e$U^wb0 zJ+_-hcT9Usu9EIROCSwo3XQS@-h%Eo?0uCN4x(Qo{`Wp~cf0c(O~%m(lL&}SOa$jR zmG`KZ^vu?)5oS4$YeLca%%FoeZwdqad&&_)Ap#))Zm)K?p*O)Vj91&{a;lqK`7H1G06>^%H99&;k2j9S?U!dNZSuozV>Ju+QrB!IQfM%;l%W6#NhG6D4Dm0w0H;=Snj-J%Or5E@nc8 z>he%LFf3q~6e}?h@`WD5ovlU(LndC|wy%xu*cSG|OXz>Wok4Yo^JaYBnR}**W;`S& z!s#C?ggDgBkDPyXJ>qZb=JTm;rJOJd|*4;7-Y92#F0c@yN#183j;u+ zxJkhg4P3$SstT{gpsKojLXBndJ#Q&4^2WoP70iSn`mRS5VMsCTB-X=S@54u}hiD9-x)V0bC zV`D>J)V`w-sfjFXsZ|uQ%gwcTSyWz*x1-K5rHABj({Nii<7L@5tD?LUb>2}Nq*bo) z`I=F7`B7*yOb=Xe+lSh!XR}aT-deQZ{XLawm+8G{ zCS74j3y`FgcPL2>#z3nBuVYacug#y0j=Zs(CEOk(BQ3pg%kJ_w^YIh^0f&p^i<9o! z@;Vx1q0%ePU$DRPDL^4w7X6ySo2?g~5cf)m+6^vd&ipm}enh0C7@gt~GWA41yYejn zEYFeeG`BbGsL{PBK{S%^?EODU=%Zza>Zox zK2A6bUiTd*lJCBQ|7Q@&Z4&J_erxXT>_^9M_ZzL8y42}3Ve>RPzJ;7MeYiu6>oC#m?C&tLIu}gZ4$*gLwFiP z;NKO99=Hnbe~*WzrEc6pU>|^S8`z zp`poB;ArqZS%PfqZqyw!9!Sg&HQ}~Q-X(g$_lwy#MlWoQjIRUFPA@OJ?Jnb^y?gzI z)~81Gz_yEDO1%rJJs4>Av8E$R81)>A!z3OCmMLQMWX%nc%%@o#oFGsX9G-uf^6@zR zMSz!{ZY`w8Q|N|(`$+**;y*x2_$0N1o92kPs_!JgtiA4Am}2fK%R&4Zt+wqt)C?CtCy9yBH%u|yXP6lwov ze2*M@L#!WQm=A=4Rrx0vXoSOZj=(8x`~Sr+x0SSfX(iz{vk|IcU2<~S8#@kBPUr!h zV4Sotwa64&u{v?|H0&Nh+ng06MmFBx$*q{Km7Hr$Z!2;uf#hiIVW$gsjWYR&_k0r~ z7Q*px7h$QLqNWt@gI-IfauY)vaGZ3goOXxD=O>NdPW1Ml1OPqW21`dF^^ zyO>pf7aKyg2_B|UDfl=>e+w>(mFQwssc8>}Rc1XHR+zM-2UeeT%F)W4#$x;j!#6yZ z;16f|{#LQx%3OstF~JFg)8erS&a60dIk@fnC+2MzTkUeE#yPw_Gwey@$xyt^G0?5f z@>SoT1mnlx3Mu3?4WV-r5BzPILG*_v1uSjQ^!V@k?BvXpC?V!%C^JV*!!f8H%Nr*& zqiBN2!j_$s)=YB>{3mSkuz+#YG(dn$Fps=R7r-wZp6TMx^Cf*zlTUK`+S8X*KHUGn zo&bQRD?fT~fobA*2`Z(SRoe(A2bmhB=>vhBpMu>eW1)J5LF`0_Wa2vD7k57aN~v>v z!+&>9n7F?4rXl{=Z?;a(8~cqntbwd>@{c2`aPa2j@aM)s3;#HJ`)a?rd*0mRlcY_x zHv8AVHBTC?qn+J`I;m!1W|l9o&cu2QU{n^R@3>+SZx~!lw=r0cT-3bk!}Fzjqd57l zWtXrGe*|ypM|9(VnET&nD7D3$&yhRN)_Xb7x(Z$$Weo>D%+wzexg5UNYPz< zb_QI>#)rK_hBb}z<5$N!yFWKhkZY?ZbguZ?ISpolOU(|5>X-Lq$WwmjGeRj%Tb0PQ zK$L24fkwY<6P#0D{z%;^kS=hVw)?Y4-R)CUu=_hWJlQ#6=eP$)+)hMgrx!kKsZMxZ zdwHU(l@+^}-NQG0O=jGaSZW=)udW81cEJ007$ZFX$iwv!IN*tTukc6$1s&1`3T z>sHmK>Mfo3JlT+^wwlyA3}d}}B_Wj@{ybcK_IubHd~4hOovTQUE(+gwV7qh_*3Q*D zdS#%dyk{a)Lh19Qb4-{M2z@^u>{vnfx{9v-&q>eS19i~jaKyu80Z5}o$qW3Ug}1rK8}7)mV{Pm#cMbJ0f+0quIc z->03aP38B}F@$M(QN0?vTB*&C6BV6<0v&s_oT!7VBU7a>-wRRKI;5Pz9z)QaW;&>D zpG+b_oI@}~HTFlz?!%1wI3wV&=N5~`CmpK9DfF1RYfhc8xllESVbgdgQViTw@JnQz z5ZnrqBr-A|%pK?4s4c@(Gxm~|O19C&XqMdhG_vAnAbT&#MWYR4!9{o;$6j63am{ue zj+;xAewOPNtQCm`yYWLPDnvAM_Cey4hFsr{nAk~|* zIB<_g&{Nf1>ey0IGb-v9+qTw<8dr3aS3nvwt8|+nk-ytXuUXYX6;vA7x6j7v?@ph7 z?72`73OBMDO){g1?Z1oN7Cb=@FX+H-!rA_%E6}ec7mT1XqybhNNiP)>z5l>sd`Q7R ztR9XqI%LZR-C41HQP#RYPS5)->SX>cS{75^tBl;WVL~>w105ne7|A9jLBP%4|E*?s z+NTleTP=5G$;ot-XpDyQ(bb zxQPAltHZzvDhh=a4=3Hv!?Ty7=zf{(ABif;j zsLU!~-v7Br%1Nhkn?=V>iaguev@DrH{$r=SPHbmWHtTq9C^l!Wp|$@S0K>vwIH9oD z$nN*21rbzmNfFCkorVos`^;9;df!9LtVvy9x;*AB*>T;1xz~CBHZYJfgDB;!S1tfl>wz4;^`1%Md=<2}cO>r?K z$);*)6b)?N&-2Y4%Cn@CPeJ^)fw^<+r`A;6LF&`Gmi{q+@_9)mL$12|0Skr}zC#IQ zc^o(TRnz3I4u7J%p*ax0?V@OK z|2^^XcWY#LMXbzhQXH8z-YsxpO;*fw5^L<<#rpgQcC*QR9LU(i+;0$n4lJSGqya0; z_p5R7)7tz@hB16S^C>32U!xUQjl2^h$ULvo%*n=_QJwS}L%u8j4&EfFmS=#7qi`ks z>m9pr1v(jFBOLOfr6M}H&$G=wK;2+2T{u6?d>`LFKS8PZ z5SCk*2PhQ(XhbZt3RltTY!B+$5PQ)zSCtTQ->aB2L18@~?1cUfKvtVl_-7tuA^40b zm8f_|u*yOk1V54vnMxK1P|1S#@7=c03k@%~k$wLa?GQGP zJgdgM%wId^Fke+^7nYQ`a!`ppe~+#Pw{6S6{JXca!IT~eg8E|sJEG?zGooYTX1>Tb_zSF?-~$)ayzfwD}@ zi!L7DUW-i-*dS%oxe+=ljF{>CI-q#-kW5m!Uq4B%AR|S*aaI5D;N5L5>n!HeYid0D zWk}=2G!51}0M+O64NQP`^{I;$$TG>lx)x2JS!0Fh3g_8{sWT6ukPT!b;!ZJaAl-Rq z#K#X|idPe#3e4{>3wKtHJQ8I2ij^^;TfxvA|AZ_yDq>|;#o~^w-q(~r2A+Bdc{zlr zzCt*L98qnlmy&Q=4mjP>{Ybv;lCYb5@jcPuH;ei!?lGi%q&qvNTYK|Wpym`!V*`P~ z?k8@n+Zr)Hyer*T852*z=0agm!F_sb?d8;c6{oR%h?HWhRlT8aEd(8*bzBR?tsW5` zFso^Ymu@Z&tf^qQx|VX*K_65@(%wZR$gmfnvghZOLmyu4%d$!)LQXi{_<;2xn)cOx zBOz|ZA^z$F7lO)}(gcgZJZ+zAU$(y8)-FdmB?`68`Ei_ z--bO%FK^a{5$wQdp-5ktip!6L$2Jr^M?Jv5O!Lq9xKRO&fWB!}Ku2Z*lR2rtS{oxR zIfy#$^2#6mXm$&tY3WruW6tdlsP{AE+DqCP<-VAQpS7}^1$9l3pXbO9PLT1Ie2{~N zw!&&P>|fspg&O*vXw3P15zqTQ_MWF>r}G&thk$avjc0}hZyj=st8PN#03-B`uwqdmz@z}{p0KXsd_Z={! z%EEjQwD0r>5}z}k=gV(>4#ZDtQl8tjY7$S4&^gBy?mrsjFpJWp!w z9HTfiGca#R_A>AxtwM2X_+icDd@%t$egRAoCa34dPvDZ2=*{Z08y@^Uo0-;(^LEHN z{CX#X03iWXvxcmb3;$)|s@Zz9oX0tnjx4hV4m3aQ$&q!zOZ@MY<=I)-yIEHkl%3Ve z^Umxf5>>FOObR7fN^;wvT4=ms{rz*|9h(AC>V!3 znU~G-zdi%WCZpLF3dAK2tP;p`Rg4$QV%Ncghn&2h(|@h7==%`;pX}@38D3%)=ggJB z-&0`kpv7cuGv3Y&4D&Dmz7zRX38>D5XsYE|pIHUiW9Z|HngvEX9KsPg^E;MCj#p#q zN}+E_0}+9H1fI68+&C}uK>=kZB?2vQKaj(aMFpwDkd-SMHg zh%SDG$Ln|IzLQ%In>H51xI-hHIFd(>-05$nVpj+JyI4cWr#1%D9=@)X724&T3ib;Ncse7;oRKaqGtkB(YJvl-y8 zkp1bP?OUE^f6IqUbGw5IShc=jD@Jlji0Gh~ulj;-z5IOT1#G6STxu17gUni+q$2&k zrY;liz<=uKEx!vobrVtOxNBv5<1STN4M-;I275ze!39tU(O)PRse3}u;J&=$;@vsg z0cD*O*6T(WXUJpR!;=S4!P-7{)pzQY+z@Q)d*URH82vtdpnuFch5<3=#xQ(793|wa zgUml|a;{AT%HsU{6s%x%_ABzv-1Zd>Gtpxzf(Kk8gjt1u{5GW=C#02_#}jHW93wip zKx}6I8+~7_T}>91nIH%UG332Gh*WNz9DSCfb6=xR^KtNg5~}f;MANe9)yaDi)Z*vI z&S5K5W8h7WQ9u|%AtvdMptbLT=q+^~f5Q_?NZG*+%M>&z)l3UWj3JEYEV?&uYsno6+7p9dCc`&zn;J3h1;nY8`hz z#@yI7mE>!P_H*xDa#2%I(5AYbdij25wvt|E_6Bf}+vRYvdww%i^{ZL-m_rJrt_iB$F;xxAw)VEpE#bGunF? z^!r^Oj=0lhr*B!EKgl<0XhrfI#)%rn!F z$$yYO&3$cxwq7h@>8w?@exs+mr06VDP5dylmBzmtkR3W*=QG{%m~{?P2+nzb5y@Db z8e|2m@(lAsFpvjxsk%fJ(U5MsZl4q@h>5>ps+k4sy?+F{l!BEz(nbSp)1fOPPfCc| zif<30YZmB<=Ao69qIQgRG!5sdGOu2EbZ&8QXWD3lN@x{Pw*X8xOWNq{l)8%>X@MgG zb{W6~SQ$?$^THIfR<$4C{<{*E6g@-Ma5m^9MUFY$Uv?`X$l?1jg`=iHt(^Cmxx8}s z%-Gbnu=E~gf3X3$Juhnkk6IL*KeT+xr8c2K!;Ca~a&mwSjUj6Ucj?2CGBnt8uVoAb z2dN8m)_0B0V-yPyu5fzmh?9cs2-bP0;89N4;z9$+R<-2qZJtazs`%$`&dsp{7X6ij zI9g10rw#u+$=xdqgVlG7qt?O@70l}Ii5t4oYE<}fm;}uUu~NE~lls=Hm|7HcXM%cg z-kmA8CJ#Ic_H86Y#BPU%`G8h@-7B8y)L33jL8U@z7I&S?jr*h~)GzIap8~Yxg>2RH z)OqR~^JI zLOJC$li3>HhBd?jMJiQvm{5@VXHn;`7TFof;`yU*N1wze%3u~R1J!XcZie#V8ay(K z)$zZ+0yKhT=jJ`@(iDd!-KlP^IMZal31#EenB#~#e@_K}X8m>1zjvdfQG|5u^I}iT zdMnJc2^l01?+@=DtXXo&lh46>Hfo{}vjzF!di-?a>L#qr{91@+ECv(b?+J%HNxq!9 z3N`+<)Z+Ih_&4z@;j8y|Fywf(QLiAj+{+~5vFjsV)jz5q&5CrRcyar3Kvr`S;E`yO z;3&655GOBR`O!Agna0zn znc9A~grG>XpHC9p#N)mv7q0vWSbs+p^ITib^n?{lHVAz3yrV9~;rlUml5lEA&u`B4 zTwOhda7+h_2+=V5NAsULEON&3V^7v~>{yf!ZSuuNn)2I;z?r-&#LwflpqHF@NKG`h zPXspXuLwrm@!bL;A?9%o+;JWXP1O9A8v#?I)nqScEnUjPak@+mav^N>@png6isNuU zFLs$Q6WiMA`FgC^z{IeoR@J0{rt$xHUCB*az}PTj&fp5C<_jemR$KetyxDsEYa8Bw zf4ZDYBdnwxuDH+i`(wjr0?T2>E{TLuANx9^SFV{t8rb=IE{90GC3}BRkmy2_a1FD*!vEp{=rq?f^atB728Y=g-e0u*Lf(l>m%`eP_RHK5Xm1 zx$eKsdmWfT*el$)yqdCz|56YA7;1TqN0?7=)m7llAP>Jrv@|@#I`{MGbbDuLVQ`qg znm%X-&?tgg<(Rf+?e=Q&0NQY}AWW)L4%Xle=Vh!3dYBQpikQ5>hLqv zak@xUksIREon;USy}HH6&wqLO-Pn9_&hR{QpRG~ifq@!5?($L78a+NC21qJtjOe|h<1=HwQ2$icKm;KDt=A(fTKCa?VQCpp*jX-;7Ljbc!c zyW4soU)|+8Z^C0?0PKx&ni+VfnaQd;I6eisu!Z$)QFc1#t!!IBij@u@rcc8TEQFBf zjb`vbnPzb+!=wtM%wd60Ho@eB!naTG3Ffb68wYZE49ozF^FU<6@D}}0ccj0wZ2GA> zdm;@K6RECFQ4B>85suqXtQt|z*^y*11cfYaMl?<6xXKV9)&u{;#O!*EglCBf9%LCq zvV`7A^obqm+A+Em{;M}olUcvLD-aCde)p@S_;EfvOcFGf%6ifA0Dp($o|+7zGF>lA${B{J)mk{IrY?l+E`h&LN~D6Y7&WMwlmsyc2R+<;_k>i8fR7dSSU0SZRX~$MN`!N!9W94y{2X~>7o=}=E!wN z{Ad^wCmON_D-M;>vEw-%qC-UuBkGOS5_g(CHnOL!4&+?KhQ{zbdh`Yk1XM=e`wgrk zmAkZcag2GKq&RzAPS7)IbK)HVqn;!-l&qx_h~TQH9NgaaY~s``?UY&i+-x=_oXJwI zD7`H42r47(cU8)ytk}q5_pLP6-w+^F<3!cVd{!ZrXq7m}QK|MEb(2Ew=lF6u*=NYM zX@z1dNbj2**-ME%$V4D&k}$DXpmubX-nFRaWYAK^6LjNh@UGsUWl&>o=aSXJ7BmwU$Yyj%z8T^mWw55s0zx&gntW*fUnc1oUqU?_2VT+}Ah`^*5mPo^n>_ZPC{BY4PSjf!5(r zp)=8eO7j|_|KbSDrc=1Sg%_+ko0JZVuH~#exPF06Lepx+a#2BI5abt<`i8CR|9(|R zH7dP^=(qNOQZJXPZ^8XnQ?$NA4j$GzxW2DWLQ`wwm*!k=>C>XHCeacUtxXyBw=0tR zign9!e27^OC`c*yw=L(^lhlfpvePCtdTY1buv_*fjQWmb!(3NGZ0LyuEh)Y?kz+Zsw#hz)O=9cve|1-3w= zDOUjB1DbOWInht(DI>T^V3lNEEhcy!17qodi=$pHcGucO@$Cxj+!~so6I)Xn2*A;! zD@bjr4^U5=pRCF51VGLV!T_?g!u>iRRkb4`GWC@GE*Ch|g> zt!C+tP=R#m6Jy0r61PDB?)-jiQ|dFHD$}C9;gCbwaL=v=ro1O<&4+Q z6Exj<$kKAJbz2)kmdUZNU3nowg9M3QG%wtxlR9&gjzk`9yzNe7?F4n?7rM5|taj`Z z*&JGV8l1^$IAC~auxS8;Bm`(O#PLOKb_*bV@eulY3*g%j=OAxM^N8m`_9HA7&{pvJ z+c}Crwc%8**{bfXVjVzjgjTzDoRw_|R=`x*QJePOfLr%UfIX%fh_xb^RkWER!8^5G zN#y~frw}?wO>hUP-BAVm9%M6w>r(~$f;cVvFI~xOa_Km}M!1GMp&L6I!1e?@8c&7G z9%QQA#+p4c!ZzKqr<>AxNdi7I@Pfrt@B{=w1rNrj=xX2u#BZbnr{r7ma@5aqD^zyH ztQJMkenjg6HoMk}HhJ-S9z7cSPO)J(Rg((U+{%Gsf{@`~Yt z>TIE*w%%e?Ih)$L9FWPLWu$ort){jyrKBc&8e0Y9r>G{pnN(%$mdUXRKQVWs2%KA1 zrs2{lJZxLc141nBmePXruTMxd1(<OCej-DV1Q70L#DIHTA z&XefEmQ^#KA9M?;Yp<$yHd*%~u@q$O={cjPl=JR+(N?fgx|KdS?d%m#`*y1e3(Jv; zcoG6WAOA7g`KDZw>s(!C*fNRNuDyk-Y^TjX*I&|xxXn$ny8y(%s}^|XOAZ#Z$$rpC zeoJdI9Zu1Pa6%MM!{4ARnq}}G=k77-weBi|*2!$JxP2di4rH6#@||W!I~2&b_Q??* zopxfs;edh~=Rxe}5TiUH!0ZkbZg8>hP{i;`kj40ddngv`we9F_3y@u;cdd@ZZ{*93 z`0P$qbyt(^JXi1G@v7Cxk*;!M$^rA*aIk_ta543UcVs7++sr9365cO9lv=$sWlbec z=`QrlPShi=@GdJ!7Ejt-MQI-GZ88d$3kZT4q~?O z>sbeS$>m0c3~&CE)FEYf*%xv11JGT%J&V}dJQ6haR>o;_7p9aKxyP2{Se7%?Je3`j zV(nb;R>-iG#Qnz?42SE|3`JJvOws0!jY>T9Qq^%vPDfEQPI-$|x$(rre-Lv<`Alo@FX% zbIRaYrbC$Rsjvnv5W~TqHVdfv*G0~>a^b`tY-#whrL@57(6crU@dMM!Qq=QUGl8mG&T)ohDRU4iAd zN0r6_obZ~lyINo8C_s4zE{ulk zWX@iKLn97;ZEs5-&LE5>dEVTbkRQf+-z4*N5458XoNl>N>1!Jq!+GX;4$1g%{E3@N zyZ8-Vl*$6dnJu4fg_JpymjBislhVO6*Tl&RPZUsmk*+LVn!Erze_rZWw>2||JjQ<3 zjP{#18_X910iRApt!n%PoJ^1k{ec}UcP@aQ46>9 zJG$kD4XxqI79~Z^m{hex&KH*%Eb*Q3N<29d1e=Um<#|InV}nnnH4|)QTun5?UE7|b zaRYa!V1l?;5%c+P@Lj~J=x0^0j8U<%6dMY?m)ULUjHrn# zSbDt)(aD+_nSby{k1vLUnJs?-}&Q?N`*iA{#1K`K53&Xo}0 z-q4#eyD!Slvk=bF4M9=`bu3L?SgJg?1UEz;0RNV_2U^dfwkTebSEVt(93#u96+;Zl zY%-^yuba9m3l$m5l9s(w&+?$rn4C$?YG3Or{tVO69Godn7-wf`A0b{1aDfyHO0hAW zDoFyZ(ZxyM>I26Oq)00~A0rvd;`h)UmN^+4D>XRa3w_Y0Ov_w$`b#6s+jc**W4*bbgH5J1YqPf+U2YyQ&UmllV zl4EeFS>pa35TW{YT|(~gwRAOwTSif>$m@g!2@yv>pCmiy-alB~B1r<)vW+}T4?*gj?X6ihvz!|+$28gG%G6^M zg~Id2nM&TsF2>EFd|u=P%r0rFK?1; zWh+ajdrjIf53NJlaWxy7i9}W3s#HMrdvmm=_H0SL6u^#R*J-3J&l4%9L%N?Lyaqte zmBddHn~f8IILZXgQQV=n<$;0zbC^oV+GA6p6B?odRp)fjn^f-HU&_5*+Jcfq2%IuC zpL8z5&EhxgS;2xs1B(%U2rJXMSFP%gE}Y>->d}kMvc6=sq=5&1Zj#2D)Nu_BUTQWzk270Vp710SLPLojD2Tq7JVND&Z zAopJRAsZVU@2$!e$ZH4sw#$e#ZBe2sAX$Fj&cf)Gr(6l&XXZnpn{{qNts||2v_e_o zK{Y@nY$0^uS^<3mhm!u8MJ{(`w&Xn8BS}3oN$v}8tf-epyIJ*H+g;DuJ2jK=Syz|| zQcZOui4U9jR{5~By1OYXQ*m!u)o#!OLw`DKNQPo^*=}++&@=MSIrOalSm%;wW~ZlF zBe1JTOo&4jZ?BrO*n#eS#WRcB3i4eJ*s2(G<{e9g2ShMCD0hXQ^j4PsU&%$n5e=z)03TYKJK&8ztni_I4i9SYZeW`QnR60WJ@K8i@0)O$t%rM+;v+F?0D7RPHlmAM~ zC^vVv@j_Jm(yF;Mq`4nsW~DyMqP9xf{9Th_yR@&Fwy&AAaKk}^^AP|_$IR$^_L1gc zra{Cr?w4OmnW@Z$zZ2#}Vs3;LmKUw{0XoR@)UhJaZ3uFvOs8H~(~!)6;~WgytBOT8 zY$j(>H@?TEdZrH4iL#nOzvW1eN@BzV-i@|;=Ort|!o}HjDGHl}AwkW8p@+BhY@f)V z+*UcXCYdyuRR-Rvx?Y$A$<$%N+A~|L-fP&xcC4js)K9?_lzi273!cwq5y_*yLuNVm z(mBCEN1jJmDsQ*pa&evv9U3`v$tmY+4n)+nr_t+8xfu}S9K%2l~k2-e3o1vy;yp_0V;5@W1o(|piJ zplR8JH}+H<+Ygh~u1Y{wo6NJ_O8w)Q`PJT0a0o29q(M)iil0~0dYadFYo$v-!s1xnYF9(-d>xeMYh#pxb=O21{|xFt z9JhNtx~tFuPY4-OS>v;4bFI~|YD zDVJMTtzqT2IUNIe1gO?)?f)4WZLFq;%0GiEJbmPJ0fZhGKu#mhM$zaf`YP$^&Y<|uQTI-(&{vfvT!@B zEdJk=yi00*TVO#fTmlqUrbm%wd1q+tUe;uJr-;Z4wSMt&kh8ukD=DPyG7&gJR2VHL z8XRAkRNa6D4#}X3@#3RWt-b_nKy=NfCMLP+0nC&a)1=@ZLvHoVnQXBs8^BAiF*n$t zP>AIsf+S;gGVIg5kWoeVtGqTD!!#F#YVc`JZG>uEWFm-bt`#KY9NTGKG6yJB)-)HH zfio{@Y*|8MQ%6(VJGgPkd{6A%u=0zQ7M1*th>O(6-bk<2Mmlx3+sRa1s53rg)#%cF zmB`|Wnyz=#&|Pv5GczvwNIt}!eDB3x#e7@o{H&hDGDK#pD)?9`r4ZM@pQd{%7#ohl z`83wxrtC#XwX_vZDJuzf_r*hLdfUYnIZ)zmH!sxNs4ZE92bp+18yu*6X1p%wFV321 zahx-9GyGV-Ug|CB0;p@7&q9!* z3rXA28mPLQFXou*>n{yv>4`}o+r==ij6%oq=De{z6_BvGS^36n!Fx5_w(`m z*xZYX0uS{W5$6g{Te5q%e{goQER1qw1puBLUqSi;r-<_+tl2w*-rut1c`4n~T{iCd zm*jtEIW-S~%hNIsS;ZBXsLUfkw@FfCUi8c`ZP0Y&1HN{xZg6y9kQVwe^Hir&&fAQd zA3N7}(xT#t&=pLuz1Ni0$PUUe&19+aqQi$Wy*EL*}LnZknB^Y;SBX;Fj_U+UDc5d!vs+(t~s&RrpVcP+`S|bKWr?$A%ZKZsa!BTkV6plG?a{E#0@({^P?s=+!FoKoN zJn*Ar#)D{PA9WJhbR{RRb_mKI7pw*hN=}Iw0UAi-)q_`iZWo&bK@Cy&b6BPv@Vc~P zurRzA1;CqcR<@8!BfDE2SA2)C85w&k{AcAlKQo0+R%pMvh*c;gIORq4ctpwO5mu=e z2BAi$S`9Y#o0j!Fx6+}tM*B-_iT_RCG}%Nz~1A2_NdoPK=cPj_?h`J954so9BzMdi7h+Po4F zjr#e>eHA7_hny`P+U9o`m0*y?y2+z`Hs5XN8H9CJS=#!Ky2BhGQq|S^Wu-(8lL+ z#kM&Y^?ZmXUVfdLdA~I`L^{|m=AiNUpMMY4i z2t(xQUq-P}S6Jd6P$Z+!iOk{Uu&z-K(Zq(~(_ zJ{BV5nPzm;{isk^?IP>cNs)ylKmnPvXFr?Ye$Y_rfU#YET|fMybgMjw z6a~v4=1cYtRop)%fcE+D!6+*{;H{ERglJ^5fkVXwmhlZ|CI&m={WZ8y#(svS*_M%c zMg<;d)f~Az?v!r3IvupFBwL>QxU>mBBRsZ#MR3N)=$Vrqm_J(U;}#fJp2(chFB_m zdnjpqW;yx8{=Uj2oC(OUQ4T3u%Z3l|fFW%6J0po)GL)vs7B>FHeS{L{0W`?oi+$TZ z4=XuqGsq6qx-WIK0?od)c`Wp(L7!GjdP@a{SZ|Ny#8OIB%)#TJ-S`d5vP}!)#f+h{ z71L6R;TfZox#>plzGVC`>g)jGgKitESi|zuVz~@D#LF%}7YlUDE@xy_0dz}AUZCKO z?d$85a)hd5lc~^6MJ3m@sQ~2sq-=Z5ZX$J`u0iflK(2f0PTjWU7s{Vxb6sCd%j zvqj*KZ95enR{_HtRizr8F{tm-kYB8&`!H8|xjtUl#J@g-OB)(v-coK6rj!&~*+iZ@ zPQ^!+*n;pS`te9n&CEHKk5*KY!Dgm+2TJc7g^sYp|DZo|=PHC0s~iUR5A5eqFotV! zy;3ejwNyex#W9B}*}BYyTbs1{77fBqJBM<&J?ZeR%~3RQ)7O;`L=P~9MKu-l&?HQ| z76oc?s^FrZqSc?D2yo_fz7PA z43i(b@?=tcj~CQn1paPF$TyY$78H*2F^Vhhz3NV?%tplL(M?lR(*>fQ z`G=F34xyf*xSb%E7X!KbmAQy1A$XtI6hx^X@1NgAND6a|)}--m%*Rl!d$AEF*-R<8 zcnLY~^Yw|4Wb%%QM@UhI|G#dw#p zE5$-nhDp$O@w%_ZgipbWkcRRF?Y7M=Ah7lO1>#wmpA2SPH|Vi-vi!AfH)fX2dw zZxiz^4e`}C1k86}oX~DQxPLsUO4dYpv&qKOB-LCo4dKD()Mi7Cu{7<(cXfefCj&jmxyp?nHUjTl{#e;3erLLbI2%>k??6K{v zD}M>mQ@xOrm+$S?$eJYlZokHuYybIAgJkT&wa!Nu4UENU=p=tW6F8TzP)?3zVvCGr zp|~-(7Q|nwiVRi!Fj&t>2abuIs7Ge>j|fPce2=1g}AnpVD-(gCtg+_Wb#e z;RWCSsXltKEiuNIL+B)bg=UMaMZ=ksW@>m&oRVdxE&tm|f;Am|Z#u(~_h+Lt1fq-> z?q+#LM~VKscLJILb9T*rD!exba$sTLBt6p@?sPU(GZw(%whJ|F%ZgBvWiIw8F3KVo z>ow4yPT*jl_Rx~`XN3Gip@y$2^!?h{bzly|icAC}1T^@0-uT9>zI8F^_oC--hdmsOket8qtKJiO3#s)bdZ9qkI-`cwR(Se0Bfz04E&)6X+QeW`ZT1 zVuJNfbSP>w^{0di>7emIS-ki1;OXT@r5NQDc!G$$&{lDd|3qQ8XBOhKOTLLVSEXbuH$Q=brBT8zUc)18sPK(-&F6I8sN5l_YT&9%MkyX+fJ}`BM zy#8#c;ORG%5?qMQhyK@81ESssV}=7*v`5=eysmHx2CQn!$Q z5s&1(z}nA0n|EVw&=u_1wNNGIdB~cagyKk7+07w}eeW1|T!i(drlJhL!66g|^v?&$ za%bwQN=}IWpnARqTTj)*`h<~(yz$=}UUCr>*;PefHw~lgJh@k3syx}rt|Hs4ks%Bo z*ivHUHHI5_<*3#Zks$<_7l5b|l#0nro=RaG`3sk7c{*>o*qY%?9()^4(%d6eT5Ky% zFa8#A5%L3ZRunCf2V{SNEF4G0ILb3yTxUk`4GV9=iJo|Uj*En7B zhANZE@%M8>S5QIg zm1`z_w&)$bdrp@+IQvw2C+^=LO+yZb^Ay)3+w#>IMF3xwAqZfuJuQC#Zi1A9c%Mke zI_MYjwDO7wzGFslR14xOU(<@MZ@yr3eLtUuyc2bo^oCHqy`t8I8l@IFI*LhV6YhLJ zU$MGl>YdPC0qOO6d5u(=P(S9BSBOzs_e*F@BDlK*iOf$}qg78`262q$4r*#e= zY>fH6ECKqe2ke;39f3F_rW&lJMHK6In0Cv0pul^EW}o$P=H!vS(S0~+!3Xh=G2}lD zSV!AdUhJ6*^)9dLGxzc=Sn|M3QRo}NefUY0dMLCL_GB7^8V_P}>ZS!>7_xNJi4Xc?AVh;z zIQ#g9)`rOvdlyfq|M7+_7b=L|iPji(IJ5Wod#r?bYb?j^>E)-Z%ZKoIFe~=_BIcBu zQv86TjqZ>sc@SLt(A<)Qqj5w^U#j+vg$2{GJ4vfpa+q0M@11k31x*U+&XBT$D?`nD zAztF=+XgwlvSN*Tt?)4nwf@^_p*PC(K1l8RBKjW#ms*!xztHodHG$jJd0B)l1S@JM z#9Qbr+kf=RJ3yWz_YNrsu{yaz(fA)n$^~CK=~QgfUT(tXmJV+?^6CS>Oy(5A&-c zWR@StnQ9nSa3-9;=sV3{vCs9uKbS1_|D`Gq%)er2=4g&% z=-JbT&k!sTLG+F-J}=8UaV1^R>&6wRLncRCSHS1F3QJ}&Nsl;PI4D#9bRPr<&YXk9 zb2Bkilc07Ga~#t`2KAYp0&amm$aen_5mzxa18Yze*3B;=`ZI+i@WI*VTdbXvdT%ea zxYgU8=42!`dFH}f0s*Lyce_X3aTB*yJJYTdD2FJixNyHL@)%|>Ust6Dy0i*4l0Ts< z5nZ|_j7c>kZ_TLI7IBv7rh692_xNYw;;6(?B;eIwR?yn~*fSh@Lb4L`LYT)f-^O!M z5cY)00-^Y|glT=o=zC@0O(E_dXO)pU9VPZ)p)7AruBWHfL$GJrl)*4OmE)cJ0T9K< zDP`)yp)k{5+}0sLQqO570KVpkS{c}M9%q?7MT+lM&*2f$m)A4RUlgAe4l;%hAIfR; zBsD{8D>bYZ$Hy7v&*oJ60;iO=X>(syY*%uq(C}1D$uMk5s(&SGSqowY017Li<57nJ zu@U_a&9U>meV+EYk4iMHn6H6>Tj3MUdrhpwQY-(6VzEWQDCpPdG_pW|10r}F03@Ga z3jv*2o7`p2a9 z(#+rnQ~KkCXB9-HjJ%HT)Yt8%34xS|RX zudOlUoASp(1AocXKgD8XtSV?hNauEev+z<5bzmF>Xu*+U+A2Mtq6Ld`2$y_7fRy6+ zUhYzZAe6+hHfBG9XvI~NUnfNbFPlmcW@6XDlD83+rJp~c!i=r-<$gp zppr-n6@2+pVM&(rQ{e-HOIIg%L(e_yCQOUukiM}#98?b8{Hw>Wgw3FAUIn)b`PcX_ z?(x%MqRm>7SF5Y3oHIf#$h+`=tRF@RBmb%gwPNpoWF0`Rpcm)W|hz9=c9>&VC>1up3?ly9o*tgBP zM#IEC=UI;PEgk6(i%|FRkNlc@G!wj5o~$+9>NMSIb%v`SGTr?fanL{sD*UjWS9U97uJ0Rhe6N_op_VmuR=KD+Gw{J#vv5Xnz( zw*ZKp+?akc6w-?XxPxZA&b?=cl_znXE#phkT@KSDaSvc?Mxyd|7 zlQH{;mpiN#-h;uPggKV99Nw-M%|x7UKaVf!OSy9X4EK}{EGHJ%wz@RPKew+6C%3My zN}LWgrq!U_$$aXC%5WAr??a4QQ0C*wE*fI%taAOakv8v=`zlK2QIdN6DGWOhbvM=~ z`@sTp4>G%|oJX;nG*j1~TwPO!4U8)g@aSF?@A>mpd3fiuxlHq`$Zu=IkM;EA$-_^f zDhBVo-H=0y>5Olg7#_U^jh=wb?h?4JIRen+wL-fHD4~A#lNyN7h&2*kPA}sZ2J{oO zxJgD$c?kOfoUR$Ti2qu9YLmwP=&A?NzQrm3~?a` zdA!Eh)fwiTE(elvY|^@#_TI1nSoqkHXY}2mg7jw)lz=3Ju@$_u7+Z=%6Ud58)NYG~ zKsj0z1UVbKNuAvW0}?>&=GV^82r35MR>R7Oz5`;~3~a^V5g7NQ3dr-Av9=lN2DK&dPql1r{?EG74o^!^Y6o6Y}{^ZN+Oeq`IWA*|g{c2V_A8o|ti+$S+XC@c3oJ3_d{(q;)|gK0znIOQ0qTIXH3x9mq$(!70H3 zkQiD$41AhyvX`2Z7%Fc=E4B?omAOE!ug9P}c4*Ax52>JX$`MQ}wam%Ypy8!Dn?%G3 z9TyiKT)dFApiVYxH8Y8Zy$1Ol<)ir7Gsq^^f_XDB^|K-zrO zE>cR2)#u>|^lgc&2mCN;BQJ>Tx?W{?-(1IcH|#LLaYJIP%=^{M$3k=W3prB&JQ_^UR0Uw#b4iE^faXKp~WQER3DB^G2`7h0#o^dR%mH9K!D}NG)>b}Nf zJtYx~na^xVTII=`9LU~^W{Zj8bTZqiMFomDI~;KYLNtuzk$IJ+IKZU>UWRFj7qjI0bG>$YF&SgL-`o4Y&4?Ay@Y*nM9vDqJ|?R~^OxB`{t=QiI7kjMGN6tLXX~U}*&Noli!i$$Kz+ z&#n>DT3F@dwR8=FlCYxS-Ph4yj&NOx1GR+n3Wtp#Mxkh5!EeBjNj# z*(XZv4az?m$IIlP`g##_@p5KNolZ8iShboM&FuDe>0-L8PVqT6&TU640zq1 z2_2bl{nt05Z8x)=(j=?a*lPp>y{08@WH%673XR1^w_re)mshlDO0is&&j0!uO>fSk!;mrBu@=Zn9Yk{H@tuu?q)_LOg93X!pxk>b zk!u|ga#ix;Q`}RTroMmOdh#0*^zCq#V9?o=wrz&rVx&QF$i{aPqCao7@=ONI&R z(;Lfc$zIvK79+YiW(F@P8fCMZT$Z@~#|0?S;dJmY`F+^`J)uLpK%QxWwGPVCoj)gL z{e+vN{B39db+2y7jaSHfVO{}iCGZO6*$}ozH3G3ThIN=Z{uOxv!GBS!H9_IxrU7ec z8}sh=)b;Sv0zWUkKSdb|v?@7pya6C+?(cAAJZ}H&4G$M;g!mdyyjT?0Ze0jTLH~6= znUy%Aq28$0ErXXGUiY00ubYL)=w6HXOJ1zPbR#UIC+>V6>KuWnj{Z$(^i9)$BBIM_ zdf%Dz8Zfvj`?wT9ufj4;HhBQTy_hrZ@$#6veYjg=A5bXS@=ChTdwGDyituG^O>i|K zn6u|#0(rPN1;&Q7&`47p)$q83`;29J#F&iO<1NP+KbXLHW@-+x9)>6 zGYS)LHLLh$b{>ntlb95InrAPRPz>E12f+>efc23y)3Tb3-sw%}UQNsM;Ri8A7WLjo zQ2rd=y_Fs3H}&0p{qFS`S4M;TmgY*V97=>~6nz%IcnD4q%YR$x!RwO+Wl7MhJHu-L zGer-Mgx3&Y*XxMzheZz5&!R&-z_&%1$mj;If9ENLm?BzvZz{Z&R#I^jaFLCAi*o{a z#Sy8uL6@^VAHYCZS(7!kn{g}L7mlf9?j(R$B%<1n8PWdOSlCF73wP=Ge~H#NC+=-J zaU=6G-`u$0+_-`3n;SQ9eRJamQTXP@#p|0JHd0H}|c$zPWGd`d4({@`JTg zY$&vIDVMA%Cri(VIfrtI6K3o*;WPgdy+OE6?#Bk;p?raJHYf)BLM%Ac`@`t0i! zSG3Yxs`;s63=nVQBio_AnasyiY)H9txmXTkEDUk3n{l^y{-eC=csneAU;FYS{Q%@9 zAyL$znNj`y^Y=Q261WxlM^^n|b!GYB7FGg>#X0%@dq>hDy9$`smN+I}TN{93QsF8- zFubaGMn|T3U;-ntcjXk!#mzq7X;0Qh9F%*RdS!)d>$dv6d*6gpH;}AXbQYKhl!)V0 zE)6rUI-TU{lQ4_nbpxk>HCb-*M?Hx{%6kd6P-E75=tyfEyl3l9D=g9Q7P;2VX1eD9 zyIa@%A-b%6xEzhEwd9XKmL!gGR~kEQ!p@YVQ}icy6u7KDq_6y&@?($ z`8JmQLStFyT6GwETRQ*SAU1q`t%KNTKN<%6Z4CP#;>Q@p%FUXJq>o1#@Poy zpEpv<8kf^)tQ=B`9pzb>ye+2@@~c zx(7VU`9lJuq1kY3E>R{b-`K^a@_tH!r<@*F5^^E9}m1xGVg( z4*g%ZLk}gFm+tL?k(+K9slv+N)lIgt=b1!@@Xw>CgR1FxJ@sHQ?kcm1wSxN5jzF?iN$uRhLit~z zlk|z61!UNws5g`4IN8h~n$S@7CZ>}8QLwKwN$d(2y78uEHIrgxy7Wv8>8%?B;T(r< zmoLn!cz8v0zme6xprIgL#<4R&22#Pu!Z+eR%6po$(nllVO#qkHopz zESAOppKT7yo|!T~-Myc#HZxTNDgq}mHx-MstZOkaE9}!gR^Sjf(Xx|aELV#r;KGVS zUJeO7(>BmAn4g&dkAgEDH(s+J)q@7IUYaGN`cE?`7I;LHn*otyYJYRny(>JyEf#JIkQsS^&OSY+(T+fOxg zY}We|OdY#Ge@2mW{VUr!(Gv&1u%Yv1qIGV^)NvDih6uh}HgvF%Ah>XHy#DvvMb7oV z$0RZzzY2rMQj9gJmNJRVl2$T^k_Ff8m_w-TdoNz;7g!aK%O86b7me)J$RMrHz)P84 zdlg576c`OM92ns;hL?>tLmf|M=v-5l7{#?P9BGA}O(vrfr(Qzt6|z>WHWCOz@6>g>KO1lUdr(+WS;Qe$z}3Ypxh$@6 zdPA=wbK?uS2{;T-%~d_yIo`qTROO3be%?Fo9lhGw?aAD+z&yPp>(a~bWWDi4aL`~5p_mbFJ zBaq)in(!r#VIIK+E_%0JYimV2>uP%&){b-KMclAojxT0!J##$0yWGN}l?rrbbhS{_ zG{UFOi+=jFDC6;c%?$7km~-RVaCVImyx0vI+CnyY5gF-0cFhSF6Kl&&0y!-~n98wM zJRX46Sfh7vym$QOu=o6PvV}W$k2MSucj27#Pe9H>n;M(Ru9$%(N};E)sF;GEMjj5N z!m2L_!uKj=CaIZU{;8bJ5M7)oPcETvt}tvoFy*YxDt8kxyJf8LWwcf5WKN;Ux4P%U zJ=g_XuH%q{roDk5?|S`~UOX;n_a*x*-DN>1Wp`SCQhycgGX5QP{|&oAwU#AD#D4{q zA8gEjGxc3Vn%`oip;e?PTjTlVQ&3~Sm$T||DwdTdwGPY$tCk)o>4HUCt1e%X*Ppz>pJf!UhKWw>7$ZdxPkrxcb}Jhp_+~6TA+H}%bTe+FYSc= zt!`suybS({$^>5ZVSm<4!uQ{sP?4ju1xWaw(Y?{AyeLLcf!_ckbc+>mcAp#{y5B~! zMR!}qYZ;DX)a8j83!`fBvRH4?*(U+dxp{?F@R?U6d*t=agAP|4%9-!JE?X>UXBEk# z?|!BJ5pXyfdFJ)gP&b7LQh1cTqUKaE~c%89~ z$Ihpb*C%vVc%g*GNwQd6Z`xnswTuSAOPea?yK;KX(Yy02Ivh08)HSy?ZUsW&n2?{)lc3U|tJ4d$l(ck+$x@8}nLr-WZJ|9wdq0 zt=2ZeYX$8_(^Bt?3YQ`1)dF1HvZ~0jn-J`@top@R>qu<~V5fnj(DSk!)P$+Zi^B-a z4(aAiRr9I-Xr^V(k6QNZsO87kc-7;z__(NL4M4nNCTo4*1oz@vJ=RIU?Qwk6R2SH( zDJg9<-qIzC`XT87zPpn_nLvL(K!bpN7k_`TPl1}a`33EIai;=1d32@by>98+`rP$< zQ9>mKxI>2C-$Q$ip{1z419sF5RV3Ep5|+ERbj=h>G?uOu4v5di@E!CYzD!G`beZZ_qdP37z&1p0Q6(Wqdyzjd1po`v^>qZYqNWG{%`v zrx>FsN}xP)nUlGX2;cHRWL~}Paq@NZ1mHxxWKbK%EHn&wip!q!n$g0AiHNn3w^d?% zH6H6!z9`o&&Msx6;mxamzA9~ysR4b-{Ic9HKO7k+9IjH$+4S1&4N+@R5XN`WjiD?{ zgE-G16_5SwOoI0&SEV~P#EU`_ImNKr8#BK~4(`O>^4H&ZR~qGY5}EPa&U9K_$4`p9 zzQ)$zjOzxFjij+*0^J538h!SRGPc|F+TTgR_7-2y(_gB8?~uW z6rshK_hc&rA&;)BS$Vnl47yZrEvDJa;Z3~=$|V8wv%P2Psk*N4>CaX%j06{ct9oYj zO8VrdYXw!b5+#%(RNVWb7#9~HhS1nguc4tW9ycjvHodR2SLJYoVuz<4@tJq;OJT#< z-6{0#)Ysusbw(Ult^dfmCABDHPvq-~Y~&o$SuB~6j;hFKyvXeCS)_WkbGY-OcicM+ z*t}w@R))h$WQaB;+)J!H)f_12r`|#DaA)5sC2ns=%KoVwms3rTsGW+pwyV<7WP+cW zSO>)LlJev7{a#pj;mhHY@*5UeF54*7E6Xb)Ah#=4><0B>;Z&~|n+j%iM-x>(9w@OzWAI<}vO%d7nH%sTV^0+=>_oHgE(+EEcN?7SF`0i1sap#_MT8L@Idz#%o{nLc zV={_$M#YU)fe9tlO2!fr8_4~I&u*CGi$5%y#RRR5?cSPM#xdG%q%jpF9WIPcNbYAHysoO!7-AP>G z!}8oQCnARInO(pt>+yR0`*`wxtg2(W zQY2V2moODg7O=*~&R|8GBfMACxXY_xDvQz*N%}08V1I!!Nq=KVe zDuz_ZikcAV?3Z$yfh9O@`S{)jyY?I`!Ro&DE6p&9&ISl5HZ&7jx5$xG@U zM@59H{aviLi?rNy6t*@?bqzOadoiUofi1=7KbL^3>;EV6T z#=V?OOP))s^xT;m7kr-Rg|A_T-?VaW=~8u+^`iidvuloZf)PknQ52G>DEgIQXn)3A z%uvY2ecZZtpy2c|%7a!LiMWBkzt~^D`&j}ym=NM57sSWa+R!R6j-su+?_2gBAy^Cs zmgS~$#|$ zAMPFebV}hrr%zu$f8IOnJ*(@W9N2pxwI9mC%d>x!{aG?Wv(Uv0O+%4P9of2WpDE;a z4p_fQ?LI;(KhaO@>%2zQSbOLv|0ELNwd5?ln6gs!Ji03T!}DP|_;sSluzvTq$lxYP zR0l(zRRu;9^De<*a)ai=2StHkbOQMoMb8s}$Lm6)ai}Yj8Lv+!HC`Y6S9MXAK{P|P zHOa-DED7A^fTF-MR=@| zz4P!oG6iagXC8>PWC%uWdLNz)xsoxsbOefmBD~z7ysG)t)d*M^1CG}iY&oFO;o4%0 z$zlXPX@tY)Nd@xI%z}A?@F{lDUkP&%%-6{rZb$EElL2u6AIMuVu11KQ-Z;YoF&txT zx(Z9~Pp+=fVg$Rt@D}DF)-(m6w%t>K)(_1=-Jf+Hi(awveR%imWkTF(esC8`4C;{r zMvpi}ND1_65=DlM&@yoOF$7Tg7@(#W2L#fZVraUUB1_bH$hd?C*K~UnrkfwI7}67Z z#qOg!U=_fan9h~3MnmxP&pQ{;g!)EC42>S)@-GWD}07G70PK*`66>drb zEjGHQy^tqWH3Y>Gt>lvg)$om&!^6p@ohi^aWF}Um-C7a zg8|DMX}^)IJz2wU&O1&EFA8~!SVeKI{OECHmt(xf$-EtK49H9MXW=A^ zSGf63T)hQgayjIago|^s5$#?pxQsH$fFP;QhE>0qf+8JXqrEj8A=r?)C9fOVNAi*! z9~Pb8YFFtlkOiHjULNqW<+Y|2@mfWI@TzB4yp|CpyjDVUS;@m|HR;1^aitb>G+se7 zPhJ5X9Aw*=t!Te+tVP_>`=*vom|gFu=oA2s^f56XT|CBNJQlUza&7kMnBIUy_JCPG zfO-jUpEAXLF~n#WtvDF+jZ0o^D&EqVkS#9_FFe{=JjyXi5gFkuGqO?VA6jEyk-&5j zY-!hkd5#^8;>lRP49m?kBUUAno`dbc75JlCP$d!5r>WG^jFTtRZ0dNeOck%lgHm~1KRFjSBegWB7z{tyBYe!s_OQKp%wV0+(nPV&Xf%85a<1BNWeA^= zA(-n>Jlx#77qHD4297BB?gz#&xkq^MZjgiF#c+lV^($29-te~#PU9&s6iWf`3GO+Z zrVY5F!6j&+M=HM_vW7kI1f36mI7SYqt+TWHZWBiS9Y2sBJN9TVn7eNgGHe z+yNQUSm-ivA$$+FDXkf4;P5TIE1>O$papb`PaFyP5rD}WI72R8e8(EweKYmmj6-{k z{PBlPcdW0G5licZ+Zl428J|CY-n$Vu_<8VJQygjtF{l6$uR?3=6)$*ZTzCW-Xfduq zWJ*A+{oKXr;@zT}EnfS%i0hp~98EaI6HQ9;V~Rs>W^(`Rx5YbSBDhj{c5zfsJ-}HB zs-Yy~RHsW29(5t8H>{=VTtZ0kF&ev*%d1iOL7X3@7HRP#&ubtJbe+N;gG5Ku>7;?_ zo#djN$+E0M461Ro@wmhThKuR-2J+wVpJI|6*F)3PxU%qtnFRxBF-wu0kBSS!{}G;P z`YtjtGoD{6zd`j(goQ+AgjB*^^iBImiQv9o+z>}tfyeQg6|q3u1#qqwju3!HLF|IY zQ?w-ERuK^^zw$m(#fSCm2cx8oU^(tE-ZL=$UMmELyRp?Ko`%0Ae!M1L{?r6sA-iqK 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
    MWC$miw4I!Is*fv5jc2ZEGQ# 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�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�S_r0BPj7xK?jkhy!>XIhk;?h>=v3QX<84XISs)l+_6+)6Wqe*xu%yT4I{!Wf+ z8amKCp~*eFHC-#!o(>`Ei4x{e=LqK-*nL42NBl0`Kfl1!2PH6^CG;1MZB$)S^QY0H zk}7*Ex!LqL7V?o^egB=4j+{wb=hU2wpFKY^p*=VQh>vWGG^q&3djrw;HU-Vp;FGu5 zL3G}O)CCOnC1y8hg*8<}(q#Xboz_nn+b407in8fno9b*Z6Mex&9pA`obTX&|?DG01RLLlP96_G_t3Y5ovh(YtB^f zAfJTiz`&V0&PgqoIh&C_U1XWLX$JRClTN%rS!s?iizH@1ORkc$dB%pOah;ejzhiJl zw0MM31oXuSK{q0vc#eSk;a|p)7?=lwX^7bVAx3cyt9fc&1oVUwcv2CxIf?i3`)^bpM4&sy{Uuj`0s1|CDk$8Locx84jaaBb%62$nC zX~Nddmhg3`;AA_CoV;c|SEF$hi;Bd3hUjmAROwdnjZ|7b zO)&3TmlrVtdKIZPYDv1C=X96{qSQnk=| zW{q~1vT$&&B6#!7-j*KV6xJX1=qhB%vDQm8_6Dgu~m^UU)SZY5n1SNq(rY%sl!oV4&eV|N7Y zs!1H<;5p<>?2dImzOh~DE?qWMAK;ix9?X?&chHMr$F1M`LsE{0-8Edst8B*#HR6-5 zOW3}YPv<@7x;43b!A--~oKIu?4B9L|uGelF@oL`1)7(Ub4|ae8!K%ioJRw$3C#E$L zK35N3#5F5#KF{>4DpE_V+d;NsY2v;HF&Ww-K#Ecg;VeCAI%-3s_rTW!Rk%aHF6!i; z6>0N!pJqJA#3^siW~}q>Bw(iyyFrV$!*0fX70*03G}zLSvdpNKc7s;rxeqy2gi0}d zqX;rG_$WT_iU)(Z%-1TJx!)QhsTw9r7%qm3Lx6nd1FDxcw9SPm{yGVK-EaSMK!Y@e zYbAvR1jG{epAKk<{#~hvy`izSp}8r&g_8}yCa%wFkPs>4%D;18YK=iy>QIL?P@4i!S7$L$$)DNBh^|P_? zL5!+>LCWGxa@tf36=2c7ueIe;a>8aEgp;g?@PX&MV(Wsc;5W~0TV!Y?i-zm(|2oui z9nN_;{JtYH!2fm6V7{+`{x2J;?^CaT*+>B_jTruY1@bq0;s1=X`bUPA&e7TwVCrON z`|T`fY-|Ux+tl&2BWa8O68PB->KZU1Wv%%rg8;m@oIP^3x_EK!X5fi5X#*i9onNWf zk}f3xI7@iBR9E#vUj?kDk%kh2xQL(9{}?k`tidOx8{Fd9^GI9XOBE#|a6RME92HC6 zD~Y@!wI1jJx5tLN+3#iWtxm`lr>{ku3)sbwPbuVwN>N$aHbEv zV~#nUqM1B}tr^}%t4d-$M_Uwks8b4lO-0IveBC5scF{O$o^M+Z@i{gj=JoF8b0dZu zxtSW8?WlJoi*Vrl*@N;zI3ZNl0ibH&iZZG5`;5D~ysSRdIegM25nke`5$JSx^l@i< z$#Fb3;>B;^|B3Jd_vQz|Xf;9S!JiLZUEgFwX`)&tHTh?Q6-68JdUrGSivIKY^635c zb`NE^*7sQ@a%{cj?{-diS6e%O*RW!bSN%{&WJZo$&5RGwp1M3r&zJqfz}Z3rft_Ag zwihCu&yz`H1p&ns-GeW_n1jYx`?Ref8tk+GL?L*h>|)mjd3Htd_=L8Jd_vpH$?02; zfFPuA-w&bAXN9e@P?S(Y8i3wReSMHbcy8xhTz$FvM$R5@r2q^FVF)#Ihte>6=V~Q1tj22dO`C z4Nip@CDkcGnT=Rkh8r7f)5Y{cnZDM2D(n z>MBV_Ed!K-$EBMS#gn3$3C+1_L1K5y6pqbUw&6=ZP;ZA1V4h|K$&_NlQRHDYHVbPI z@Ip2hYP-975%q_>dvNg)igtqiI!3X1DM$qa zT4IH2nH?z954mJ&6SaE!Qb=+u58)eS-@nDug=_uzdZ_x{VT4rnL5xC85Q{i|?LZOm z(c}K;qX1RwI52PWI*Lw>^@E}32+nxXV>Rp|l7PNilFdvrrof^~JaQZndW?tw1U_2v znQsC8a$_V^PtI$yX3Slr4=}FuXX8lF;blBnW5l+(yAf=bfly%Vy1%$3tNTcZAF#%L zpZ*J~ULyPunJ}(Y&%AA)&jEyr?77^cdHWe!u-?^u&}``yu9OpuIDJa^p3X*h1acUCseMQ2pJk=k9%vc@ar{*JgRX0vc(46fGiM)AF zG9iph^kP<-_4`;>nH2X4EJ1j5_lSJY6Y?rO0$sau3P;U6p!E8j>NBq{%UmVyf83V;;=W09@-LWnwf0 zrpVS&aTqmp=5(FRH+`kj((AQG@B7Gcc@u!Oj1nXxQ>}3}~euJZ} zX5Xn*+pjEVp6z=u>zy5Gln6lg#=Q7cqYk9(2-%;_;|b3#tFNbb;+N~SHMT%J1x_{Q zsTY2n-xquB8i=^J4ned8Vb~t@Ok&VZN;HmRN)?YQKKGV#CWN~ULhYvk@6sz3Ov! zy0Gh*WaWFnHD5FR-1;Z_XN)&aHMi$pquVGuTU97@1I=h4osNP;vjs3|A<%I-(QvdH zE!wtZ=7)7M0mqg#Zy^xX2sBK^-E0(z_E;BMRq(61Rodl-f*7-V z$51I}2O>Yq;mm1(o)jA z?4xWTT#|p;8}9Wpqh}WdVZltu<+BzN!1iyDj!TP#(Q==x48uO`6(_|`je^(RFC5o^ zI}-2_Kpx=>ddZiu)`I53p`_{U8&@}Lle5aFRlu=C$Son+7hrCOUeHgLlr>;HK6Qhu z*lQAK{{;O7yt&7}T(S9)+VSR#wCYt23&R3Vl77NGMq7b=IXJ+aLq|nv62VRin^|#t zCe}GCA=TtV9+yEJKg$)r-ZJURrE#L{a1jXED3hb3iR7KEMSG8NP5!lYddcP;nZVLB z>dYI4+A2kI#A0g7y|Fm1VJS=(9PB1_=6P-kxqNxG{Hx}m@XxOr$s(^9HCuR?1Rv23 zN+($jHY>C{_ipA2sdvP!Y8&{KMsj^DcXWJlg{o_>CR=tDMknOpyr!IuqgE0wobv4A7|8{5Jdu|EylMKEl{G=%V3$1b} zcx{218>NL9g4a=iXkxQ3i&o}ZZc=H##D*a@ueepq{v&0g{b-akINYOz_y_tJuciiE z@N-A+Pe zDfK|dx~pv0T1qomEqFC^Q-boKAFvw4gIs<-kX&v0qBIXYZpb2lvS4tH36YRZgHrm8N__jdy!-F;*Or&T&C?__=~6z)ae zjLm9*#1X81P^NyI^fBK@HtQajdu8a1?K?6$1E;K=Q&r0wH91hh6Zi7OYbkGv5)a*|Ee_K37~^oVKg)0Kl7Dd;)uGyDfoYI* zPe?c*G*Ib0fa9kr;7akWR<7Tf_2i}RaO>uX5Iwhy+Mz`>$JU#Hk`rRB8D%#J&XP;G z_>ZR#f>4G|tRe)HY(vtjwsWBXK~-M@PT0F3Cytc&zTQYC{?!YI5?OcRDc+$~rWVwv zW5P^3@l$y;p4}2TMjpj}@RUk2hW7Ex#~nsbN`DhJnRuV8g@yFxPAIh*Ep_eDu)fP= zmx2K@wDZ+v!xh$G5FuVgiv;D&p_x{^XXAz$GRQye(v*zHy4;^ zse{~?pN%UMhhc5-&C$omYq(Pf(Jn54yrf5cIQiR^zRP4oA>-|4yM6fs2}ZpR(4v-R zL_TC!^RcYj625$N;Cs~bH1ZKE$aGRKDQ0g^Y2T9eunMnal3|eQ8!`gHR@1XqQQ#^& z?H$k*M9aCE-gf7=c#BPs13RKXTsVP~z?5o064B@`un;bMac~xDdWh^^(x8A^n)AnU zsS}063h_q_D334_>s(|8TtDQlf|29NSQUR^L44YsT2d$YxISq1bczYq=i&FCnyxlg zVpxqarJN#vr^oYKYu=OgpZ)`!9D8adiC-TO0Wk`oWlCQUIpsBo{eSVbpqX7=5R|Vv z`b<)XMT=;kk8-HMqFtXi?6x6=X?|JwEzXT(=>Q!Kpb7rzhz{=vV)6l?3hHy{3OZ2< zJk9WVv7|;;(xo3X=CBnQ@QxKZ3jHkGPQFZxIu_T zFt;hos#zWdf$Dd`gTwgpFwoH_ws?;Rf^>~hS+nSvsNn=B;`!w)z( z;}c4bKEai~$ljC^bGtsbN=bHFvhTfW zPYXMPHejMsKP3h=@n1*La4cO}0jT@Wms$FTbg8Khxa3p*&TB|?Yc>w2FfSe4(CmlC zS9FgP1+M4>(b5jXPl7QNuVNK7?(TQf~^z zJ$0<6S*1;uosn254K0ISx#vP7rL(i<3&$|WvTX?@J@tYq6fik!qSe> z(Esr4a-V&6e)r7GIcM(NoqLW%3YVyL4O})_DcfK_nh(8TSifkBdP+vGCo~96tbwjI z<#J8a#Ud-y=iU;nN~vJO$}JIs^hr@wG@1E#l-kZcY`!z)h|s#^6}jx|A?i3a2^CLz z!}$iP%RHq9<*pckpNqq+?B&5IJtLYNf{IUt=8{gez;p51F ze8D5IR?w)}8VZF5(#}mHa&VXeaD&;`CE9oHCb;r2@J_8*0qZAQvqOYB{^NCUgM9D7 z5Q(4>z525^5Y-mxx!c)kpC}26Cvlp2QMqnlXxX*b$vJE+Ps!%Gvrcknv<_Ef4!0fJ zV|av5r!L^FI#W-8TKHK*%{g4ub!QsJ#*hcxQSgAw#1cB1;v zCasflSt4=O(siG@&5n}ng{(c?!F?+Cry0tZ3j1(%Mx1>oy`-?c*1&Y|iM=HqV=n%b z5Nm@G2&}euuHJYpL692kqo^yf>%?k2&n`hhmEcL4@GW|?(k(hCrpEN$EZ;>(_Af2T z5;dVNi1x6Yd&`sNQG@pB;mJB=NkQTia+Ncxw`N5?Xim9Fm!v)GlxDS5$JSK>L(af~Y{{*mkdm6U?v|K-X5wq(*Rl-#<1*y@7gOL6zR=wx(M8rz7*GmhZxi{$q`i*DZXsU<;2co}Ywmo8dqNuGobxB)~ zqrkOAsZ=svl4^X<{wh7Y8A7roTmk}L0P;pfId8^fk4PpG2zz64c~I0g9)Wh(FLvOY z)me;3nUqe382TARMMAR^E3{siVX^f@cZ;RJ54GUM&uG5mZMGd!mk<@sf*2cd6wEP29{Ek1*Hef)KYs+#;D;~M(d z6D-8z2i z4qI5?RfNfWNEA9muPPS3w57r`D0^Pne{D+Pxflm{eCo zGHLwWBR3zmR^J2MNwWdVnWY`so45H4tO&%RyxI#g$$VuHZ)>GaSV->q|6?;)lu210u*n#l<)po9e2IS6kdGEJ%M4QqgNG z7D{#%%=dwb7sW^sTQqD1r*`PY3lx$?1DB6Rj}Gr7#vg5QiZzdJkEp z3~uDf0cG@};*#Y=&(9M{+(hs?CADcAceUQkzL|pyCb!^urlpOgnJdkTi@JawYkOtq zvkxQT!aOt!RBN)En)zHVliaWSv*pu4YZ#4|d>ML`gKbcZyhaD%;WUo02ex@Lw@M64 z64A5mzI~L>M}sipWh^XtIC?Ngj8@hKJk}c0`=;a^Sh-VZBpw{vBKptiHnFa_Nn-N1 z525%ol=x|e>90}7^e|dslWnOGa>flVE%bfwX{PPDl1^)~u4~Y=gd45wC=wHS9n&VC z;(?!***lbF^NPAehyESaH{lk0o+0|gb-9?mMbK6YnnPPEt6T~zN(o!uL*Xo|b%#QS zQrhkOg?Z`%_W{LzS#*Ci3Cl$ib+2moM3l0l`|v=U3rukzB9rq6v9lDo%K2r*yqR9#^6d^*CFTL6tI^g)$*I03Eo|MA@x1_l+e7d+~7*M6UE!y!=>w1oz}%umW(~q zKFtA#+)0IwS|!!5Hfi0a<%PMI&{jA>nPv%zc0soq9UuuhWxNeXqEqemX84kd2Nlic z&qQ+Wmp&fJmgFFd++!qJ_A&zWL#DEL79L%<2kP38|$QE?Os4#P-1=*isp$j1~f z$9y=Tq`|F$ONa+OE-amXW)!}mH{%sT9C8G!S6Us7kmJSwa)ihaJe!e?+@B+kl_={dpn0$%Q&R_}SqbDqeSeh_w$szdAzm z&0xiW5rnlkhH0qG@ha}^A_PST=vHsECMY+)LYXR_afATXy9Vab$K#Mw^EPRI#QjN+ z>Wr{fIseux)WG)mQr*XS7uKhQN|m%tq_Qc<>9uo-?f!}D_FMveFQ?qXSQ|q>D)2>f z!>uUFDjkY1TN3HI5yE!p{3+oox`@B%wCnJ_LOL?|{diYGv?NQs(&rw3Bh-=)#HyL;3q%cOUA54y?I65ARBTe4i{vAG8?N_IEr$_s|8;fpZ42o@9I zPt+2VmMXlNf7ksO+qt}sxTK?A^d%N9tE>snXJyU74SYgNkcxQIr}^FMXfN~o=@~@B zxfDyt#LdTw5}($`b8Par+-~)DNuNDlPC!Wwt_74Z{!$GU;m~+d9G20cWY@x!$JUB3aGakO>)}N0yU0<&~eOS4`M7LNr z4DQF5(e0YrP@?mD;OJK^hr0TYi20@7ux^)qNY+8eUX2Z8kpr$kXR*O==vpT9%BjkSf;-gWi zOot{Yex}8M&H^02gU~sKE*(SMEO^rdL_^*lG7wRHrJWSI7QK|0;)H>DG>ov(qS zE_YA8Zpc!dF_=$l^;j%V#~3xM@wh#!YEY3~%ZeCQS;M9iL6sr6xL&E->jR`2*1A@T zsZCnat44W~X1ZR-YK&2>E{BPeOR|Z2pWCed*5x=y&Ua&b-3_k{TBMhB?|!>rnw*~| zx4SpAsWW;J)+j?r$n7$Wz^n5_2SmI#ANevT%oM(%eY6u#Rl1aPDd631lS{A zC5fo{ShuJwu{^2^OoVY(Wb}qv-KF^J=uii~dzs!<-V8EUF|Zlyb0M}Pof$j!Fp{ES zgDyzCv1o;wj(yu|is5Xl=SzM)fr`)>Tu#4W%7-Q<2rI_S4F6ymm#5d6DuyTZK?0k@R2q;jj^Cy;!rsJ3aLf01Q(?4qxCOab^)=XYDg zy&}($@Y@LjB(W44{``R#ToNunz886%aPi3(mYi+W3xW_HtkG46+;*9{kgT*tI)Y-q zi1}m?xg%OiIc~Pxw9)H|+p09G``mZ9Mt~hS7_m+k|8&)uFQH=pSep+yaHpaKtbQ(J zygKwc^DFo44%meqZS$)@DT!x4QQ@7v8Poc%keS@@2HxUNX`PH^p{Cnd4mrJf$LwrQ zcF}kmUk>I$O)=R?7#1~O6yok>KP*#NI4-RoePZ5D<>Ero#pNt$xSnpfVD??On4f$~ z$exx#zX*PXYktXCoA-D&yLH(L39*U zlc5c>Ii<=Fa=O~REuOp5tHxN?owJ5(PV0;c<409RD6(2k4D)Fu-8WSQWc+ZAX&*7$ zsx{PHmU9#BWJ|9CB@geDj43S4muZ+h0arZs{wO8=T9dc&Bgq!p>VdXak{q5 za5_!e+Jk4-#Zri%o!Z!v6gMn9n@#s6#wYi^Xi51B<;WjFXGw2&37~EaM_3d1g17kh z$G#aC7sbkWRo=;*5Ddk7Me=}oN|}x)#6z>}1>FG3t#pBMDA+r}H%R$Ey|VQNcBwaxBg(^QGvBG&1~PdS>N zLECypunUg+q^yp@wpJe1T2hhd)W8NQQp6y*;Z3wNK2@zI_I9jxXWG8fs!Ez1R#cb( zy;4!19RB#_c%sYn)KKdHzG*$4aE-Xt{^Z!(5gU)882ajhup0;d`>>6#@1E9fJf)a} z4Bu(gG@A0j5UpIxzj@2vYp6?rj|j98rxSH^{&-Ny*H)beaoyM7@+H3w+RkudcgUU8 zlGI=yuX|x0c~2N=ePI=MS8Rlqwsl__I_chiT9SVpMb`6KgRjiANf@!AL|%Ne^DZl4 zX3&^J5dA^$HoP)5e(SQEFu!o%h5a{%*sH9*B`Crlmz1(su6Bv#LL(Nw5qu0r_t3#i zA8URb;xkT`Gf~;Lu{qy(vUVTc;}P;C0G=%uJ6XGEBvbaCfM+r5oap)qiQ|S=C|A{~`R_%O_&9^lZht15wd10hv#7l>RKv=Md!W zPZDk;6rk4s3%h!H=uV)kpB&j90b`dBB=_d}Nd%6>fKPsF6(E)p3=UOtc6GEwD0*2# zT@Wx}^VCT$)L+S58}^n$0C@utnH!1B2Q=U;G6W8X+F8O+r2ZZK?~wmGfaFN%MnErq zL%Snj@ZWlq)21|`8OR0uoD2lwL1OHj%Q%q?h>!qtvXggq@_@P`fMn)pHQi*n!Vw>6 zdM40xBy9r`5}zlZg1ZYGW^IXpszJSfZ~bXKAo;M)oB?P$8ZHRLizK-ppjc0aRo|&}Tc3r~|cjcXb0y>(8n%!zu4T1YoHE zVFA{uQVk5=*`xJCfsw^M&$s~FI92F@q5F;L<@md8&4`e;qyZW#hYtds#6A02w9iAx z>dHePK;Xtd`6>c!E<0lY8-@34N6PV^Bbh7$Fjp&g1XKZP3v+^<>#S^e=wcQDd%}T$ zKpa2C1&;Qw{0;4<;tW5}obuiJHYxx|8UXYpvN;LLpTkvfwsv=fIw2ID5HQ4#NVvZm zsl6pzlp)X&EaIC19suB=BdA^T6ke8EDOs zpa}SSF2Hb*CoE#^KhiWToq%o5XZu$D;akzwfV!Il?g-g$zc4xnsszl(nwE}GH(>uX zRM*|b#o6_2H^u4roRb1*eidL+$ey*?@?18;60QYIv%sYAXIs^OeVm;S44N5W6v%Gi zip@E2i0(B}(JNx+{C_cwK3^k4a$we)22>ZhPsCy8pjBnBYv}^7lM4jb(@~dy)is60 zfcMklAkY>y3WyO&C0@9l!`Aw-mHJHg3bG@SSEU7fbs`9KvK#wn87uk=&ihx; zCtm}BG#62R@qX~$KeN<<`O1~&WCQrGOs*^?<$K;B(Cg=@zc3AHP|h~3|2Fpr^Q_B( ze3JLBZh#$J1Uvw;6A*oH4pU!GN%Sv+?pdnu00vwO3oz*;4?0T5c~mFZ$(5iS%jTc7QDjumRV4s`%&pnXL{(AmGry;3JB&Qf~n+CJeZaMs^J7&(FdCApXbF&KbGW z=?RdbJ;nbo=vhN|IC9ggiey)a3Rwt)_8J z+&^|k`Ih+a&eHrc;v&L|O0?1Zv#^phlv5Ma4GQ!NOgje-v=Y+P;?lFu zf>GW1QoSIh?XH_ z3?COaQuDgqeRJ!8#VPN@Hdmxl74#w0Bl7=zD91pcje+UGKZy*J02WihJ32MqHqGrc5 zNrlRpt=LAP6rZP`*h@}Qq`U7xPTycsVre1earzc9*l)(~!sC~(qEnBoX3*gr zv{Q1N)?B(^Yuz9&CtHx(r6sGeLqK(U3+5-z{<$=J}dC zZ;w-|%GPY8;;Q367lDr2s_n{*2FL8gSEYpB$?&Q%&JV7q`SuJ36`;B-tB4@|_D-Yr zX7{H8P?A(wp{^N}tWHCjAXr(?i)M@@IKwo<%a_Md@s}l0obX)8#-+k83Xk0Gf?~|7 zN|Jz-t_mv!fVa5tWOFl9PtY0yt5hi7qhV&h;3{X;6se5eIdvunmcCS0RyQTKqBDlt zSS;2JZ*X*SKH5f049$_7W5fs@pJ0A!SOhY~Pz)wN;?Fp1KwD6uYWNtNoKCiG*yT0v zZJGyH;3nzB_NXI58(G}pbUS%TmMyVc<9eNB#)~x7{o>o+{>w3KPzhQf0s{bGg8$1O z{NEs>{zs6B+ZY+U85_wOSQr~RiCf!Q{S7s5rK`W7_Q6y3H2|rMs>Gb9U80=pt(Ry% zOBoBLy%;0o0C^diwF(EQ{ITsS14I(MNN_N`+4Xdph5PmX2RU=V9N~#DmZ6#S*6*OhbwDt6%`eRGA#}&9M!{@5r_XCvmB^(lT-x;g~t~kgdhLc`lRpib| zUwd^ixFXmNSe6#Q7^?_ekT6$@A$K-cNB{hSekWR#9Cj!+ffUxopMFA3D1~z_c)Ju< z6{)%tuTfi|0GF-MP-uub;(3}v+kM(Wp@hmaWi2LzU8exr;Ma5njB3VWKUx>FU#1= z0A)mB*G}5|_99!SOLE1=qGZ;ana752CORI zz-Cp8_*cZ7E81W=9#(u*bHOIV+f!V)(b6MY*sdEI)`)A+)J0mDPMjWlb+&EfXCQqz z#u5-9@Kk1lKfnHtnPzcxbYtJq+ZyaYVTAr4F(Tw_XJu}v?_?}#>@MtPXl&-tv zE|PQNYy0$9Z-prs)>ql>m1(qpy7|>ryNIAs9qFT+;zbO?$#&y22~zTDC7Wqd!>BW2 zj|KMNv?gFuNOD*tCHQM1?nxNEud9YU%M8_vXn`QUcIUOwJ%BCaj>;^nMc^j7l+rLn zG^&lo^Hm9o1xwYew#s4V#n~)oHy%N9CYNwW=&<(z^u>m&jxSdsT;^uwBsngU!(Ee;}6wnV7W}W|0>5F3qVcD_h&^2CamVTXkruL zEDI;B)M*#NI1O_!&x(s!>-u#SqY%C03=B?=;$a_7e6cH;NqSOS;4XEzZ36H3bLi>m z#wlA$Vd9b@TiQ0>oiXF~lxpt;*(Tv+65;pmjd){Kq-&o-5xfhp5&?+^kzpB^dUL)M zt?>|;vV25<+%YWXV7FYHy5w1?mAcUuVv++*mfgi6@8#M+|31-|!zC{_zAU?1B8zc< zd#+1;r%lB}K!LCdl*-%Xfhk?Il8ya}I}gumEqFKd3H&vTX2a#@4i??lnT$J>m7{e8 z@D!Z}xo;2PU;bF@pvfBU+tzZwee(ZL6#qBrA^%5P`+xlL-!^8g&}Wmuhw_t6;Zxt} zU`GfJflZm{NC;O|_?Hz0dz6FL4yJ9mdV2?krt(*pEg)N+27B%JL`D{y?MK8svepju z7-`s8q)Q@AysAXi6J@hO<6zPg;yyv^W8k!pUEq!hl9qHeufDFWa31}-GP@&E)r6f# zbXobM#-Zie*icF}+9)1fbWCvZoS+(t83kB6%n6P0mM-kikwghWOpC_?{pFxqBnn>- zqoAw8C?%319ltyx7!NZ$pY>no%281(1xjd5geq}hRO$$3DGJ7fl7$wEs0xV`d2ueA z*$ZcGS!0ql`AAf)e0Ji49gCinLEd*$(`#!MdvDV7Zuw0Y6j^V=qO6~S%vqEBt0bD= zK9~}kkv1}?X<>uoh=lSnIXnm#J>P#0p^bE?(qRjmri%IwF;Zhy#OySP(Y!KQ+&X5D zi~Rs%3z?ly-T+}JY!9$I$Q~tzGwsOi#rmf4x8w6O##G8I_0S&T{NOvShDZd*Rrim~ zo*ka_?I=DRyd0qpi4NM8a;LsWK~RHyB5bO~RYuez2NFe_+6l`zWQQgaZ3o>_G26m# z4{XJF76jE6r?T>R#JkxP`cgu6d9dNj&YfMGg2GbNuU6As-)cR}xogHDEa^ew_9}{w z--B~BfDOs9n#|yoat2_PG@%C(MR|Dd(#gLCzCGK&9~m1V)9 zt|5F|S@wUlGP-}XG7)`4CtC-1MPmmSb3cGW<^shl^3a<2buo2ZUSb85zdub?q8kKcD6aF5je8uXnVMwdX5!#? z1sb~L$k6So7|CQzLQG1SxKS;lNWUvr{vL(m`F&)!bdpJym6I?9>O@P+g-<)}8z9|= z)E2U(2zZ4#S|H43-8wrsH1g7Kzp_d(+;0RNa}Ez2NEu?29q3x8H>04EIm89iN(48y zhazzZXyZRaBP7z(pMdPfXIP|ShvrIP5US#~V4QWR(Gg%rw=s$~g_uTx{VYd*X- zk82ulJtO9K7u$y`pjHVa2FqIV2f$A#1d~bwi z>lU9%G3_olFKSb!LTyGNFc3jl2`+g7!HI%QQcZxPrY{ z4l!iq2sB$Rd(NE_X|4K5S^ru~Z|PfSu#$J;?X>Kn-##TSdHI5O;V!rIkWFXpT)2?sDb#h zmO9_t#PcM2y0g6Gzu`}NQ`iQbiTPK6MLshMrPHxsU=o0 zc+1|u!XxYC~_61YCfNl47D$!sF$Y3LzZ$punqz^!cy5XRP2-UN zqH&y+FxOccYA}Hi-nuhf)DN^*TnSy(b%>ti7jl{g=;n3tB>rn~gs6;NWfBxhB4&k} zEnK)>0aFJDJNYRxwS2XOd$Xt36hU0|cTFzUSi$=9%>HI|z}Dfl=i%1RsgY#!P7agD zqN@p%qp$Qni*t5InJJ~IG{};qw8FsF1WYcbfn%uQM6h1WL=n%M|EG6fi_t4R zfW2EM@&)C7hn~_&AU6(WEK=8i+6mmaO5$kJL@U4YLOubChop$TZs~|s;X|kuCgWA4 zL|dFptIKU+hfBlt`^0wUo9xvv84mS$I-|a}9GCi5OT|O{Uo@_m`{S++QIxWUeX6sb zO&5H(tT4x+RI00PkVHq{a_H)QDu=}pUar=LJI?VHP4m+LZ5xK7(y&a%@wJ^t41Cj1}+!x(U*v5bc>8uVd%Ro6$* z;ubYBV(6rr&l0zGL~h3dybyf9hzZ>K2h(LYH^8)B@Zgbof|)ZN03G`B@R{IwCuFcc zcYfRyAn3Gd+llS;TH!W&tc|cr=npm{h#<`c6`=C^r{UY}#Nfq{JQKRjQo?zmdEl^i zYn3KM;;L%CSX2rjkIMPyNknd&G?UY->kT)>GV+``v1UY#qgb&a-O1zzCrmAx(Rbp( z%OZH>J#xUf2^e`vdi!S+=~9bW;bjo)`B@Vn^&ST7XGcQ3i990>EQS!LkHR8rVW+=B zhSN|rVa6Glq=B)i zrW0{3$gq5Of&4hDxi)w5o&}5kvn&42fc6Je;Nh1VvXURe5eY_v*not=m)ENc<_qhf}mu;w!x%Rc)VFFNRyYT<^e~J{}qjJ>d##-_A}o zZSn75t}!k;y^(P!#jrVY`6Uc$wfb1f-c&iG!%sjN9*pncWoW&ZJgyXkL1%~pFHo%T zlQl6FVGIk8W7mm!ZW!pxwj-CPUWqpLHXmrc-GldVf?X&sPpdmHM3}0mC#r4P3(=O-QPL@Vfr%<@9p8BI6UZGqn1x*>jc3 z(wzUDrAx?%NPbmBmrzP|0AczNa@7n$txl9^rdIsDMyO@SBI@wE8c|Lj%uRevc zz(kj6?su@D=nJ6=6*Slaf>)dMa;Bwm=IpI$q4J!c<8iW)*=TSWD*)kkFFC|>Ca5=q ztm@B1!Nq-guPOi4Q35|x>g+!LRgLE83Ny_vf$Or!dOJUW{->*C$!kEFFMOl=U>4CK z1R9`*=QV%Gw(Q#=k7JAofQEo$TaM_x4rTkwd8?R6VvVmc*a72B9T?Dsej(f192rKAQ8mglDNd}F(@&w^OMH;B6|7S4D!|Xbg_hSo z4n{k=$Owo+OcnEr8)&*haq4`TAD1^fSW0-i*($qMSwqM~^{vjXbKGngfoj~)vC)f9?moI3fPgpFI$>AzT6>lI9zdH*A79)BZYtb<2!7iL(&2%w37Oo<} zU&Cq64)5HTDB`B%+w18Z#8HmZT_jiGHpv#SY>~#-XrW4YT+{*=n^UKlR+k_fXj?o_ z)gPR4I+fqL{2`A`x?m(CudRkaIq~+|SnspQ8p;34s95B@Ehz?~gjL$Se;z`qm0?NX zV>gm4VCw0}^Kzy?BpsV)=$YH~nJ=VX@L&;J!l4654&_)Z$~HU=563@h27caoZcUC- z87(`0ZrUI>u-a2ZUd_2mMs6CCtClaP9$(Z^9Hnd&a_NI1l_49qxO4_d!{vI{ zl3>-aE0IQa9_?w&(L$x9WNTaQ*5${PXTzTa^eM}tht$JSa9dbotEt7(jkkm)dvf7~ zBz!Ck;qrMvlykx`T^Tox1)dg{W0v-dgm=|ml-{KjEM3UVc+zRe?(_ZG$l^!N1rblE zQw?qrdOtYmxsSrn6?NqfJ=R|9=X7()IM(M@UYAua?nioDMrZi#)?My8VXysiKQbL(YGLtWq zT4=q>VqC|SkTcWfAxSFfIRup&QE0d0!utpowV~LZgwi*H2HIHKaoQ7LtM{c_^N9f` zi3sdsG3pTP2!I>ltBs%hS&YPr5%;K^;{nNz<@H5L65S z-ppujc8;X@=RO4_N=0}Tf=ayzi5Plf>5|sE;F6HTi62z=VMyBJL0r3w+RW91=bu;A z2ov}fT@=(}DeNA`&eW9)A3Ao&ZqZ!pg$sYEfT~eK{d?MQTXkcHA06Y>M-E?)kVzt~ zbL|m-Mq!sWwxZT$j|vTw?D-Lln{ow%8}&dcneiUewMM}-rs5Q= zkQK%74wKSMuZTfKWY=wTDzV@)yIF7v)FGh$iY<%p76RmUQMHD+nQh1 z-8lW;OfwUrSX&>{xGCREosqa9y2xT5cU4Usd?yF}LAMB(T&!6-k7EiF&%HIi4rMh6 z6sPyz@EL0~W#QYK+b(bGEq$DLi+rxW&sxDDY;M^!l)l+(=zlyGBK}8^O402#hm(#33&m0nrTR$(rgZ}nJcOEP5DX<1LQkV6km52NC|k;$0yOo3 z5YntSV*?va24_Sixl&65VV=7nMy@3|<_OX$TT9;yO6;KcC-WCb-XW)*q*D%`rbjttX#V z9E8V4=~NI}f@pr(Pg%r5t!NNlV4Alrhhx(&;hCkSr&BobQB_Cnjn6rquQQN9!$FVm zk?PS$5r%_b`(TOI9qE1JvxkmntM};S;larVdD1{lYv91(ld%04nxn@nZ1J7uGf}$l zHNfc4^q{BUdde`$mZ9cQCSON4Q@8%1W4Gs(6VNQ*0!|6h{G)>6(<5il zwUQaLZZmY*vCsDjLXt_#e9`3g7>mm0YG|^>abZrPjUX&vYpzTno{91FMl;a2G)yJW zZ7|aC=3pu=!>Of}UQUeLKM)n<5w)fJyx!cXuEScc@)T@na$6QpgO9c}?SSD6JH}P( z+~HEouXoL!le{zI{LG9~IcjQ66<)S@Ri&IlZ-xJe0>=8N1|7kL^<2SBf)%HL|#FeGhzU6ohSZQ#pXFunbMId(0>U@2V8rfXnjHi$}-lq}i9h;Vu z)OEXBN0Z`BzF@SX*R}u0NFK3haW?TYcw39k>CmFgGVPkR!Q&+S<<-K~2lQWX?T#T= z(f)>O+`r-auc{94|5cmv9dQ4GQ*{N|KXnndaWZ#um)5t@H~n{VI;ehT zyU&XB)!q9EKc9O%Rz_v|1gE-ztlEASUI)bMr!^FuL9CPL*= z{7Dge%W~hdtKV^es|WlT`Bh`M#ubB>hL}GT{()B8Wn7W)+vN02c zvIpaG07Q@!2K9IIz86V@zr|^2d*^fn={H}uV7~uy*k{66v5yT6f?^_1YzACe zJd4$b3YO~c8JfTGa)PzpF<6m)@nOc_jINxj3bI7NQ%-B#3-bdAU31Vk6;D)bwQ+8Tyn4r8j^Wy-kzz~8Wt!=*ZdFj-`FhGam%Ku-_WppjUdzx3gT+LA`TrZU2#k*`%vvQUj8E}eR@ z;54*G-cF~-8&fyGooH&b?<{EqU$dwdtX4POQjm0Tq(U8P@Wlx1B}HXwbZYuMcbj&Q z3HYQXf}llfvJ6$;+HPx@a0w5Fphi`g(d_3Ibm~08B8g9B1#F4)|w-Sa{98k1ttlt|LJwTWC|OAP^VP2{r-IjPj&x8gr)juuqq^@F1e zJd@OLL*!-Se91u$NktGzxDqn6OTexUm$QHEX4h<(lXvRi6Av32 zDMp8&9X^0Dx_iIHP)H5pE#lC^P$d#@>SzF%8;3n5S2i%-<27 zrToTdAkfi|V?VqZ2k)5GbXB`bgeFXep^7gHdLc4tBos%aMks+jNi$ElF0}c0XLVpE z+E`WbjxG9SyAmtXltsk^sxp?M@2?3 zCt`_$508a0G5-$~;nSD(3wR^54rJXKWRATf&RoJ)ZW99Rj!pL9Y8;w%%sr7L z-Cxw1ZEoDcRt3-Ik7%zC4STccY7&%!TPQ=I)>pOs#bRt8ALSWD$rD+d4U?vR5$cUQU52h!QxPp{9G1BzFs0ufac5FFHvl6P172ZW`@{1bV zQsaXsb>GL&&8T8|{Zo-gYzeIQR)Qnwnf-jaG7(&|n};^A4kOaPG(lP6mD$#I-Z$p5 z2T-*`Bg;vXPlu0j>ZcwUUQi-uO3;!_f4~A!{^pE&eeuxtUMRG1P7AIj3qvmx;^>vw zKU2xjp)Vy*R95@xafF%q06Y?XI0=Y5`<#*fReBmEOtm79 zXb3wayS`fA>dEK%l8fjUzI=0>CN;yCAN25}2E|T#a8g-Y9V@xD6*GB{On4FXY{^DV zmVvdni|LDR7cmu^;#UjB5zGU1r)7xhoI!o>pVMGJOG{{Yzk^zV0u}1T2a+=ecY>Yx2Jp+H`*>apcrk#Ij`z1;J_2YY?1XKbji$J;Dl^Zi`zsXaPB z+IG)1YxQ*oXL@!fkU|RWuBy zt9ovV(hr*S+EIB`g||F4Y3k^S;m!Gv4 zb|E{DCc9+Ds;=oHrC#*7$=0UDiQ46a3A~KmxMaLTxxknx#b5^vxgFXuV@6j>ltDc)@LM$tt9(`S?Yk{-wNxQ4$C z(-{`Cjt2aMCexXT^*~pz;3oc(%uXwt@u6qLPM^lQz|6)?V3T7PB+{i~dI0nufL-oE zeb!|VEE!kjauy7kG2!9B_3g#rBFWnfZcN8f%0OR`cBJ~(-n*L{M<;uzEm@`KXIvM4 zHhxMP>{MXyt?a*E($L?ZnZ=SWUfT zWdG_M5S@BPZwIiZ$&$m%$f1iLSV!~pL7sX=6S$0CgQlhR6v=i#x_lsY#L&B?85=u4-<2`fo4eIE*YgSJ zG&rxMDjg2GP$la!LfKrU5}JQ5gq7=*FMfN4G=c9YE^%*@2GRBG%|E8v-T zCytb-Dj8YejT7VhG@$3?+Jnr#aXgqn%tcx#(9zyD3V^V`>a67Fh|W`A$^qAz<-2Ei zUlIx$02kHeys7%a$|Ku2z`er-xKF_iM=%%##%MFN-E(Za=Y_i@b~?V&5kn1`C(lZ> z);fGN7jHBrOYndg;DgC>MzB)Em&4MBHB@vu9{g*`{O9_mTfE9W)&}73v#=3g@n!z> zkg36bk!;;Ve6Y*TiK1)W>One=p_MHl0l@kKp!2JSmMvf-%_oL%_Z)6MyA6+w1DuH# zw_8nhOWi*Ssy%!W)hZP|@7#E&pm9mg;44}+i*6CoOtQHoVSI87%_HwWI+OU5T@+P% z0w>~(KAG;IN7krQFj@M+itKhUj<#gp(c*=8`p-DdfB~L&&YUuSPfe|Zr0QSd!mxu3 z0)NfImFMAXf!lbMT0(bNAJ+uV(RMTwF0LYU@xj-en`&KmB%0Xm`Moz@GFamKPk!Fess-CY|7A9$Ft8V&?(9l@SsM z2;FZ`SDTjtyT_2epXoWB23_RSOGljYyKC20uUGzH@UDM=x!9l#D(b>{fo2c&z`k_= zTOmEc+M~v?gRzqtH(#Xj++-*E+;m5g#>E$HE64oGvYwodBx%$TCiN$^{m#s~o_8{k z*^~Vj-xrG(pX4o6yT;)F8`%W79S5|ELeiKIQdh4{r-p#+S{#?n zIlvnVPOlzF1y_f@Y^>5aWcCaFsND?dxq>!FoS%*TlpLI&aN)c|^)RfJTT2vc$s#>X;Sdg&{#d(um zVRf9>+mO#%^?VsJh~$D5+qi5+F+2B>30cwd)3N1wK~$Es{DVys+pZZ34fM<<3rODzeOK z(Rnj?j(JrxxZ|JY2^ft|v&A6l?O|4g!(Zs(l1a_QRvkKT53Y&u=~n@{;^KDpODMRZ zrBa9Emk#M&#t2>AE~1X54Y}krUU!7MsT9%`qlqMZK)F)l4)Q1`Dqwq%Mxqb{LZ2t4 zc~SmCl|xfKYT3!TPpM@<{GZx;@bl4|bKHsY*%7}`#V54SD->12aFjz=%p5$ewp{LN zf|Wby+5l125sC{vNIl*Vm9X{EyR_5wIA;0d%$Z-VY33Ybxdzjc=INjH;Xn?SY?S;{ zl1I(>e#@}q`y26p64k3JpBIZRwm@1I494H1TVnC~Mq;q4K?&hZoVQXUbx~Z^O4E zJ>h{~sRA94q|&(R4FcEzS31ywbqvXCc0_ z=^v7=24}hKvGeWuys#(^4n|Xw#XmT%k$>{_gb-VI4szBa2$pn}l}S=l>U^2Zd>A6;!j zRXjCdC$j0Dk@`y61^3a`S8~)%*>+K9sPo#B^|5f==vQY;$UCNcNDa1$M0u$vJ-;8K zNKv*!lSygC{gx+g+Yeu92HP#)dBrsdA)oPODkA(0;1IS;jMX&RP zMJI>EDdNf%9+odHrc2@Q#(5KxpBNIvfbJDea;nw}4u*%r=E^u#7cd?l`}#d|_{!C! zT*l4wx{GkpE_)}2*d^OVj#IKHneZu2Q#YP{<~WE>9l4G&A>s3^hf-ipQ*y7lv(=c6 zV90~!SdLrwC`U6J;D)0osc%(W)zAtJ`ZhBeb$d7%j$3dj!yAy?qa2lKXG^}4N0D@3 z-s(zkBbkpk;ZvA0C?z%%ZHbqc3loNUTsC3~UF5CyY57|MPOXQHsJxk4N~cXK4a#k& zvXoKG_Sj9HJeV@RT&1j34>B3(t6BG<0|7vwLkJuAxQ)?~eaP|W`d5_#v2b=!SR0%; zs*znlZaUz|K>ARTr*`i#=npa_He*b5yA}$BFAZ#7j$vw_w(`>Qy+r5v^zWjB-pal} z4??|n1i85s?UAQVB9gf;WWbB!FiP1Hxn&@^hj9UH(wX8UvDe<$v-VXwwoAmIyr?4Z zkkj9#17TPcM5lyBrB4VVsryBU#6a>y#zI7e%#o4w!;(Z|Ao(I=VS%v<%pger<9DV) zl&H}l#6vf8kY9WYVwmjKM+_HL>dJo>;sB+|2^7oc`=I1BeVaKorR+i z-Z#+?;`lFVCjp7!5eUal<^ZAGq-%XQAFmsIg)%lcW%yq?k>U@rN()4TVo~1>@NY42 z!ZPyxA+gC=rNmu>!h!Eb-k?xLjMAcyVNU+LVPH_;B1UaV8;Wzn_MykvLb}GtU}hIi zL!=cIubs^d@Iy~m+(9uGY3(KH3q~boW*dT@q_7KTB+@cL-syi}&1>Vxwv-7_OvKzZ z$N@ozGY&c&a?9fYm610Il8i>u`bl-vA9W+(2$h*XQ93J+y1)>D=GdvF?#Wi(d6n%d zt-hgiCtyZNC_>`jkE&~4!=Pg(C{STIqtQN~4oimw0 zWVsm@sO9FhP{M$+A|Ebadv5fn-Ixe&8)`_IMu46C1#O;9EH_NHaZYX;^ za;-p$#nA8=hM;5Qc0imuiX4>33C59nS1KB@N;b!LU)K3;e?IGtp&VkN|DI$KY0(6S z(&(h*2aMok`TKtPhti;|SmMane@(TYO^Z^=9OE$@q@I4^zg4_Yk>roa5tHlf7c=an zj|U<%*ExwsZEYnJilk6WHIGC$QTSfxezs-+t#>{EhGISaVg{X5@xRw1LJdgkStNO8 z1816rtdC+W^4ggmlJzWY^4|*!u}!zXvxh#}did`tM-<$R*5E%up*xBcvuiUL0Y}f0 zFt%gqrY~|Bn3UWrFbgM4=u`H+|9t*)eyi=ez>Obw`;4YMVcPn{_%7@Fgo~L>G|tRYE+{0WO2O-c&l?^_(#O{Jr?*wh~BlVFiGsr z^QBI~l9|%$(TIP|Gi)~sD}=unZ}jX=guXd5R^yR}DAL-+z|;c4ycDh5`w|6nww)P? z{v07=FE~Wyj1uyd+R~s0jz3FLinD}Z!Y0n543P{Iq_Pc6+90kfS$*++y^Oh8J@}7d z+~4NG^VkRMj1gSbf=1FO##wVSM({$>mP6*jn+Xm$X~EGI%VCuiU6qPh>F53<_8&3( zyC-F8m8$3c?z_nBdDHM^)c5WU;(zsZ9^TZME6!ilaCLBz=O}NY$Q-%5zXkhfpzS^r z+70rtl~+H08bXZwRtwer&!ii@8-5Ae=VGj#SjKOTuGUN!EMhoy1{nfW#HD$}q`|W? z;lD-|en6>`qO_Ua2$_QTnDxP`U@W|yi2+}jD|W&q;w7C^+?@+#tP(W70a+vc`^m%~ zXSfk$WPUrF=2E76Tyj6)5pv_rCY0U0Cu|+e4+{Len0*DxJ{lF5j_;&9C z)cyl8o`QU`FQ)JFt-y}mc6<7wD=M}NTzjxTrdZQk4SMlhCOA4V9Nm0xKMht6nUvq@ zY0`^-lp4SdgF-UE`|zINH^T_6z@leT>x3Uk6D%Yvh$+YL3q zvt_&{41Y2+t?+&vLVFY0)4`l*y0mKZ+!?#`KJs`8^EJMjs(Q$jjA`x?DBUomY`U^? zh-kHoKr7QSNI~4t<@?NTpb1+O=ChG6_eo~#p{??>wI_gHm39L_k)NyZcWu&GJ?jpB z6BzUkp%i0yy(mls141#}^Re(KrB*t!-q4+VJdnw9n8vgP{6y1aX&7AV*mp&rT7y?p zw1P&wwFh?mj99S@v;A_nZpey?*mhlMVtEUAvvxDcIa_Hiddpn(H!<10G%&lixj5VTBYbPq zxgz^8jlmDKezqGz_%1@^zAx0FimNk=Mh;Fl|J3V=ys;0_mA>|>K_`V-`B*oe-)-tU zCZgp3rNHCyc)ALWi@kW{aemi>yVVk?o>rEqFmyWH!)9v|A+sRMt;x%Y>*HQrR%{)v zwa*&+*w94N@*@!5OLfGHLcfUY?6DMA<&}R=Z4JvG)X<+ zJ^<+i_KdmJdsLHAQJ_gz-i^FWJkRL#ploTnHO)_ni%B61vXX~ZMP-`dpse91h2Ix^ z_5_6~iSv}s8I7kj=I?RIe{4uPgg1HffCo}n@LWpdSF+$Hh^()DY36FTUA|mJGd9kj zw{h%d^iPg4?2etR(=8V=z&p~tXZ(XqXQ+knzhGJ}jJqNl99WG%2?eW4?weQ89DaC8 za;l`zw&$QgyB!F-z60%Yhuue6VjQ`lM!GtDIK&^Ny#Kkmx*u2mftB+I4)xD&9}ZfM zmOx^Dv8yHvtacgZY?sGv7+j6*HaR9H)ci#DYv-Wg%z~dkx0(+*WC+}&2dp{JxKM?h+Jx9b^LO!W z;2!si{gKYFGtjWcqsNW)MM4I$Am{`4)0R#|k9we5^><1#b_;BEb?YYGJ)u2WUMkL_j!Gz=!dSh?s}_5mGiT>cJ`tM(*pIIk z#5H!;KK&%QWsiB9ZraScEH0=iZ2??kwv!=+oZf%e5hx~BuaZ;pI5@q)sN-`Ul+sA% zs%T*}9X6ZE03f}rLsyx02-2xGAer@=J6T9~x0{M=XeyM7gBX{j;?*yhjEuKjd(ap{ zO~uJztjUnZeLFasxq1h4lc=JZsbH~VI7tzD{`5y@pOfVQ;qFfKdT*L+Ku3(F;r#N= zt*j3;d$m4dMi!~3<%t6|)P0<`_=3HiDu813#TY(aswJ?|+#@hdgkqo>x_qIfd9;cp z*@F2`pmOV~n+thy>IwtM&D)H9<~3Q(d+)(QTJG+^>alz)#$l>RRQ23}-0oZgR+f4n zO*TY4s=Nr%O~o8Tdm`#4K>IQ zoa9%DAit@BI??%EHKgmZ0YwMgBu>8=eA~pM;Enot?bYNq`;|Wi#a-1OKs2FUD>@J9 z9BK}k+CO_`lsMPNml>6akrNL#ZkpO7hgQ=97_U9Bvg>)Bj3yH3c@Lq{W?wKmtTHT} zwZ-z+SUP;Fyu$Cw7ykwH|DJ0vscT+cs*n_XCC9aX z*VH-=$H(Yw$7`P>Nndx{t4q|4n{(!m5GdbEVx2WEyBzhSqLeO2pwd_{hZIh^lQEMN z*3)@MN7=ODl6@jEyb2YJ9i@ApBB}dtXJ) zdJN)dvT?~>A}BnAlF^Q2>XNSAgT$s!Uytq>GtyZ|!_Kr0&BOBu6*v9ToI$g=cOO|}xvsr+++9yV7p~%Ct`By$3GzGakyD7JM z0KP+*Jxg(?NUdGmcPS*-Yo9w(nJD9qD-Pz{YLb!B$6hNJVCQ0Rx>pw!C)dz+=TloV zu;L&negNUGGDo@Ujj`(iZWZ zC}Rk=_s!8<=oPs2xez2x?f7z?Bm1D7nLU5p$vkpMyuSW_Y+YlFFffx|+qP}nwr$(q zeb=^a+qP}nw)b7{-h1Euxm+%3(l*m({!H5GGtW$qw9aW3grb7%<1*Ndx+C{iKXTdB zV#q|wG$ma*82={CGRLMMT#eu_fghjFMf|o?G8)cSWT}#w``KwSPkDcQ*jZUY?334A zV$Jl(lDX`yY&87B{&(!fJ~()q6cYe|F#dnXUj8qU5eSk%JA{2dG!U4d+Sb4hS8;OCFwtrV#;}B-_Nj~Ap=*hVOwF#l0X`#1;j)C zzGr_U&fC>V8X%hvBjwOn>2|Z(qTh1W@~P|a(F!qZo-}d&?cs$8V_rn$k(V|g%1C?q zUWfr|zBcg7n~j1WXhFVV3EE^izZ+Ay!vK2-E=le2!}4bL+V^|)uTkOuBGxOVF#Xm)?FippwT&ECrl*~nLmxUZ<}Ul<%uUPx zj_;kMJijF_eZTtM_`dG_qI#o$*=&fD<=rw%lEGVVZnB}w{AP8#SXk9_GeE;0m?9~m;zidxf` z5mU%Bh|05+x8JAT?AsTr1ehb-1rMN+v=8OoZu>|G)S6H2GxfohHi_2LKm(fUfSnyl zBBJ1jj;s)2$QN|fk{x+-q1dqLb&n)s%)$x2XB14&qIHbNN71MsUTn)?9Ye=-z4hqQ z)Z$&=_WJ$$l8ZOHgGk@VQ8;#d9+&fT@L_JFmtWcN%aPAxJRRmuJ!HS}^dYswJ~0P8 zkoeKBGmX=qhP;t!$>cx!(rHmlSXwChZdnNNj?@7WXGRntCA8-=C7Ysb@&`MIs}*p=|ziNQCYlmc>gR@}_Ezs8MD( zDdO?qrk{Pi#ejW-N9f5>Z1{7=c$p*K^=`b#n?6$HH+$A3UF8%`=Y*HisKFB&2Hy1z z-X%Y3{^af3^Xbj^DbA>q+@((Px9h~aox0swohnI}u%HVy=iWjc;7AL40rgN6l@%H6 zml_GAO9rBP?)x##NQnkSO^P04Q>cFJ{Y_W_t&kK%WR!wKTQ8YgM&F;D@{sj60-BJ7!Y-Z^0-~qtBxC;~KbQ>%icSxN|Ca}$x*2^t4$o@5JVfNt>8nl% zYRiP}lhjZ9xUeVn?5vOn`qukPuDJyEZRRH~EG!6}T>O_A0aQeDQ8I=J1XpBBh9RoI z6LTtPDTuwS2Y)v^`>$R$)IT6vJFolqcw+*98A5UcdDvD4wm;67!}l-Hd^C5AWgdP6 z%Y~Ff_?5oAoIVcjZ@&pb49&eAt67MR-xcq>qj71TA0HQ5W#g*|$xboY z+#h-``I^AQzf#xnQ<<3HQk=eCAJ_E2MiVQlYG1@0PnLHP$%QE;Jim_m>Fw;|{q~M+ zjPHASd7UHtZaF6y3U5yYPPA*O#=6`o;&5DeB zg}a=eZ>*O&YeP7XJsg-1!mbBvoT|o>RnE$xb_xr$K$AgLX-M%*rdS54#HNf@N$)NW zP7lU&!fX`;xTOp=oVr8*>3ef_euC;OkQ;aNmA{^}qEe_=lP?jD`T?e%K0N(X75n@M z^6nO13i7rms%YJyI^xe-tp3Pbd{5*BStvhbuhdAMn%7zG9>fhzQ3*&8?#Nj%>O{5`n- z06z2@ibG@r0R^#OHiG8(4$!vpTarL0Nkb*13ZOsZ;pQQe5VzHkpV5CNW~m8`y<4!DcC1l+YVLNHs*A$Zj}@t<~PK zs`l9sJ7F1O%y5_4z&YKj>Y2%ZK^eiP{RJjS#38Eb*ly7A^3Zu&{j?BZ*mqVR+fO;uji%gqA zp6iax^URtOg+nEz5fZbZ7FsF?Bg%-14VfGD)cgz=0~4G}DjID%YR1k;z!{_a&=~ke zCs1B(s>{uF`R?}3Q6avJwrRG;a5O60lV-u~z< zjdnWVjgmGWoGt$uuI6yz*}M&#MUjtrVUTJCGe-X^ih3_vGZIKiBPp5 zGBZv85;90l^j?x;KQy^Y#RQdTI^KboPUW9CAf z`XZ4#2>q#Om|GF8-at1+B$?V9@F=uqCfZ^{hyvQJg*-*0Rwws3c_#wVrrVaVpn+{0 zaUn1RQ)}A^sJ!b}SL{=i&*ppmQM6S-f7%d}vJcn%#qg%h??m;zRlNNl2*Wez2?*iN zL7_1uv_ddkjzQ^wW|afd`W@)s^l$Zs=(j`rG_mOv69-A*h`UX2+esv$=`1mhNUsJ< zQcN5s22HdFCO09fatNyB!t1$ggI8n$QqO5x?-#)|6q5m}Dd3p9n^|cBAo?R0>toW` z`XjX{`y(3>3{C$nl|xh`7tzRJ8@w#VN-c-&NAl(Ek1Rqlfc!)|D1ogHRsgQ%h%xGJ z22|UYVs=fapLP!vPz+3yJ1>Plbc-BuC8DWa8aV8<6d#Zpgn*JAghR;`p+w0XRt!yp z6F@5lAD6`X7vht21(d8pwbalAd68&@3$$rNFd-L;&w(qwYXvB_5Ch&|xdu2^iB}tt z0=3=G>Bpoi#Ay$2^SDrvKrXI9(`&?l9`7s&U9ltllFL3UiHh%{_1}g%N(Ebl>QWG( zwh{!a;TTPGWOuZr=YXf0mpWq8>jaYpA^Ina;vSuSu_Z_CzK%lpL(zgcxC6vXQcF^sLX(BxClVgBu?6hkte>dTpGuMsHFo6}1xtpt0!_h{ zlp~4H6t4_{!=a# zE{H2ygMgCI?td8(>;N>b22&}nBk&>;h#_f=J3tQk07Q%4qLr^sWEfiS|DU}y`N)QV zIjyG=YHPyug4ZDQ`8twc8#bxVc`wv&QoX|Mwl0F#!GH;G*4IGblHPK=BmVJo^ar1cwa- z7Eo!$mnPw91cyRcg2Tp!)<&>ZDVB!FSd0VDHw=tUZCeEo%aZl&cA~8#U2ZD_4O*%| zfLA6wqK4M2G;jA=WnrXT@;trge+!Pii-U&r>RnUj&;>o*Zvv!mmqJdYE<{UT8!WC9X+X327Gr#W!p(vkeZKXc4@0kHVUL_E<}s^?%8Wu zB(nI&M-djo4KYRe$dN^&NJt4$iKQ_Sv^}li&4;lbQmOh0h`S}Kb?!5nDDZ-{lXCBE z&{H%lJ%Y<>8f>g-bRom_7s`oKhJh7rMOUpf)Y-?j0D>x+k1DcmpaY9?br0f)u_l-ml!D#J}d(#tYQHhaRYilyN zMZj~k0T(9SZ`7IwzDPGmlR}mxaw5GLEH|1K_ZyuDm^GL{2$B!X;*&3dV z9l>~KM&aq|mytHel*}T^wocb9(i2A|6vLL=(=Gs8P%@*m5(OEYDP0=H5~*$?t*h*a zPVVFyY%FU4+aFNeC@D|rVTz2o2gU9w&!lc(ZpQ3D(3fto_Z-$cJwy`LzhH~&2w$M( zB2q+qZ#qDa;3YFEzTk_3t-e_tR~CFGy%*UVb;0h8oF5b(d}u9H%)I-f-QpD58N)-6 z^)-k(X;LU-iV7!-Q?s#pGfzg@9lvZ9mfOn4l>c(tY8Mu%;l>6zNyYe_VyC<(1|u-M zg6>u{A(9J|n4aKeODS`cD{33WCK4~g8hlYkYDQGmGlD&@bxs=5OU1vwMByN(1M{@2 z^dhkIvuT^AO(kpYYrbss>?X2SmCz@WH(i_kfVSW!h5XGbiX>42VIv9a>+;y5FDW&~ zp+|m4{Ds~3*aGY=sbW2hC@Wz@X>vrtd`o*qHL97-D5oE73>3HF$ycm-6WKHLq1+`Z z(}N+?T#elh(GXK{Z{R3rlARx!3ePd4#7B^6(J;~zLNmR?qTKwCX$E~D_%GjwwH3y; zc(>Kij)>pi^%y*XHiiPb)Xl6!sI^rl@i5*tTP!i-h$R(I-6qpg4Z^W<7{spRPnlE8 zwN64t)HZiF{LY{dcb*X0!Z-<5mY>|y$J@nI83x0B{3b@sU&WLf{$ibWO_`?FqvIR9Z?pE+>N#M{*hq17cA=N)6Y+MFctIk&$jRTN= z*dS2M<|@-oBjqxvNS7o`+=l)sM9PvOPEcJ3<&)+r;Ie6Z*CSGN1g9wIR$gyLMM52- z=2rqyG+bJh;0Wo*BLATFq%x$Fy`NQddL)*CIKiRKm`x)tRSy;~)YLEwI5cv%BIu5M zR?iL22#)xiiJwp@Q`9d&7inu}qOwtiHUf;}=*6t`w-`TA(2g*@q!t%6u5~lpCZ(HT z63vlWXs5lQ@?+!Nn?+>2VUiuKE~K=Dq0wQ%K(FHZXDGd1Zw`u_iQ|@EGA-gLlA%#X z7fY&@g$=PN!^f&Bq=h@tFRb?~yZ_81m!Zcsd|v&fwOp(7}ts$O$CK1^>&e0JY+U)}@^21!PBL?yyAfLkcxYm{SY3Uz-+xYAyY? zq}GTO+d&g~)K8_wiqea9M!3h9>50SrfJa8V$4DcfQqXWj;h#gx6p;iDMINi3=xkRI7Ba-j z0w@!PSf+CK+yhwVFsw}i6Y9T+Vf@i`jX(`VB2&sKDyl3iE%GH-;z2|yG*pJtCw3Y1 zxL8m9;YsmCMUSc<#YL-Y?Gm?qHccg5U-07;`mRSBqHp#bh$t@1ff%_K$R|B;Zxr_3*2IQEmNx+i#9s)X$c&ehZ?dtr4fqMoTG z(`M~ob94<*3j#Hr^uX%DA~o|To@_$V^M;SEYq409f^p>mGs@Ph5Kas~m^N5$I|UE9 z&8QWqD7K>}Goh2}r>Z7msW&YX6ge^gqa$UscD^#j)o@(JFTmW2^%0|D4IHTWSU2@) zr({B5aLq2aq>xQN_ehGiF^Rz<{S7Iu3DO2qg?u8@oRk(o##@B7Tu&k9sLzONDUbzv zIE_Xk;rW@;To1E*vNe(=v^~&v!(c9qq z`GzNQYq&)f14(|9sWsC<1?#q+h~Z%AmU~?BQXx(;%qp1cfblGTtPr38dXR>{WrSb^TOA5Y&*zL*YOU5sddXu+rq0#>KZJm0yjfXW`X2xBhKHE4ZJhj+P>o z3~!zL^qWAacACl6B{QNAlQ=MG_B76=dW}GIGQ=wBtz`~f;j`h*&r_ZRT&H*OFWrln zkS%#v_`$W$C&D+$>S1F!f`&A#Ow~>#VezOhL_<*GscE#-GRhPy1ahQtvJ)D;D$7YH zVWYxKilWFh4j1%*?f-#F$f~EAx8ND(l?c^?ZOhE@z91*k>nl1Co z1QM{8-YDG#2WA=Q42&ptr}Nq|A2I@BitgzA;p!9Fn=w&GyIEkr^NAlDN?W;3}edpPZ?F3 zgw}F0_@s?k`>Du|0Y|+3exgt@N8z7B+l6`Klo9D6G(jld%EHI-;@XyDkb(zC=-khUD5#PWVC{d-~`_Uss{-u)*hf-ofjHnQ>M!jV-2QxQ;|6vwYEZY ztXNd`r!yUDyT6kVX&sC#+;*w!j`f!!`KnQDRD(qE62e6^#CBvs#!T}kAVVl8L``i* z;sY!L+sIf}MrL*11&vT~m+6>ct@T(5qgZ#yck9_WR>yyK{+;-Tsu5+XPZT^$Kt-0z)JbjE;U_5H|y<3dYu;9wsB9y*CZ51EMHO}u?jCXil%I322mM3R2YmG#?*Ji&Xt28eet+MvdW01|Y zik`F-A#*n@V0w(Hmekg;n`}>3moikE@tI=^S-S`D6n*Ywh!romG}fbGY*>(bdH8H# zNUmu>x*5Evo=>;Wu^h3g!l=6hsjPR3L#*iJ&Bup_Z%|Yntp*>r<4)dZj68b_uTn!k zL<>~}&@h*18`~T4MV@ScR>m4wwkI_~P`~NS5yx@-qcWomUm~wLqwUZ|{vum_;GpW} zD_5V}s<;F$+(6QT(5SDXUSXN@OT(J~8?4OwidL(0eb$C=t~Ynrw$RJhSl@KMdznD9 z*cNZp!D_Eff)~gUo5nH;=d`jqacm}4OU574PvVM*>|3S;G#Zp)6>%3fTb^xpY+6^w4v zpf4`1_SIdP%A(>@rki)=76hZ>Z61=^?Z|Al+VgoStwnwz_jG=|`Mc3<$+OhWWo`!E z20ZlkVF|)LIT02(m}vLo+=RXZD{HYcu0p=EUM0{Oal!7U+`*Jh!p3^LbAxzpD;*-m zEw-4R0yyQqwo@tF(_HH3eo~LWb0rvCyW;b2#_g%nR;0btEJs+Fk2QmJ+36;vughJq z%>dfi$a~RRW8)R*+h!~kHoL|uzTef6UC>uhXC4gHWnSm&hbbr$s#ns`5UoPFhnvxp zYiB64a+Ql6N(|oTw@HJgk_gHYzb4uJ~ zSIRay=QvoJ^|=jkI~YXuNfW%Jdn_z6cKJUi`|3K>-P971OSU)JL&j*Jh30Po5W6D*0U5aj#xA8 z_;o$Av}^f0N95Se^zei)|I@v9^?M@Q?e`oso=`pQ_?T97#^m}jUod2fq zZngRuxNIv2F_P`3@Jgf8t)OP^RD>NTf~4VKla zFs7^qLrNA?_9P2uzTZ{%Z1a9D9su86bj!EG!OCp^@bL=EV?LwlLq*nWuqvzbYX9&M z&CBsYP=gSYHM1as4R4a0_NGX<4NQyoZdK56%idMGZV?VIXI(&7pBDK?9loSi%vI;C zEGlbAy*7Y27b#QaoM`Itpjl}4%29J-Om){)c{xQJxF*znCsTBE1$bs(7vDXL=XkQ? zz4uDPxB2qi9Hi)Q$3ug|>=XaJ%iEl1%Tw`~_+T3%&NhLm zK`p*XH9F9n3u=@U84EeB>BPJIlGxim!SbrMA68cwyW?OB=R!E7P?(u^_vk8ZaAo87 z;ojl?@c7&htPYmtY2PXok0f76cHoC7U;{3dH2aYg`c$+deMU4;^!~?|5tTH89n^qW zDjn)~bvTQfuJL3^U_Y9Gd~HC1Wml*_OExM8>v`%Q9fyg!pz@dnWB$-;R5!yr;Ev3* z1LEbd%0h!slNA*M0% zVw@6k0ysJzK7f?Aed|z9;i2YSEE_fOR{&Nbl{;^aPBX$o`YbWJv21FJSuwCYK0aZ> zgX#l$M8(C=|5MbOrmmQW;IQ#fNx^yxl7RE3NLmS%njeeLzx+AVN?NdyqSHy#deTgT z3@ld;#h5XRhQ17y2c+O>{_4@=bG-!t`LYJbB}`9O!H*b0E24|^c`j-*5+Ox=K^3#qz|bY0YEi#2b-Dgo)uBQQ&yjAqX&Z4i%DFFH^|Amn_G!uemwlVRw0H)LI+=5}wBYBjixk zBZN&119hpm|BwCW5V%Ujh*15kiI8J-VmKes2?$P1G4UoC8)Vz1McYlhZI@7kZJ5TE z(n>}j)I}?`%GO_mY3M4U%o`}xR#+^1?c<&*A##Z%TvbJ{HuVFn962n&l-W~~90hGM zxpSwqgyfjUKuhOrxpK-eNNSz(C8|WJd^+>XVz3%Y%M@)_qt;9;%_wG9u0=aBu89gY zrsey9glPnblyIyW2@}W(`}2YrAABKOi})wV=37?G(?elK zoxmjZD&we)_pF8K`eX>Cqe6HFbm%?1`!;XBPy*KoIbF?ILIYZqJykyX61L*uxiMiy z=oe9ol@pUeRxBCxqmhhPl_CKrRCgYZAXmVmPoHm`6p z=li|GJ9hCO3qoQH2rT2gS$cvG~n<24jdQo<` zPN#KglySj0SO>Kn*wQqU5Avpqkfr9RK^y%PgDO&N&C`;Ptd6*+sX;Ti6eH@t=4}~x z02~wkDC$p#xTGFR-W&(L4H*)Xx7`{vXUbAs>9KMJkk*N@Q)huQbd)t^GL;LydT8K< zO@CX_pa9qDMRaq4oue<6vD^X{N=0prtxGlEv3nT;XPDfU3Vs}P<1n-*B zqeqE(Sf^>tM* zp+o2&q4gaC*Wlz zOGO!};>@3>yqSK|;`DU3maeF+3A z%0ERxb^K(f+2@_A3o=sDi8l4qA_nrWf2dkRR~&NSTS3;Smj$8+*K~CwLD_WvbG-c< zaZm42|LT#g zl7SlLzwtJ75q=2g>ChAF1fRT=3i9QhnFJ0rfL!nO(Sme7?fX33a4W*!*F07XNDMxB z&5RE+>ZggR&irh2Mqf2?_($op4f-foUDl+zp zgxYZV=*IZ!!HpTSRTf%;2us*DOQs$rwJ_VN1&7vh6|p}Z-S)c=AX=c57%Tv$?b)5T zU9kjSl0)6mLL@k-l6!-v%|Zb8$p>= z^j5MHOfOd|KaYlRrejKyDR@`sh4Xf0^d%=r_)5fGc`!HGn;9+g2RhoGBlzR1Zjv*% zn>Mh}Gyo1GKUcanAbEFpIZ-+BwdpPLff}XUx`}p31)X)7Q(!>6^pwV5fPAmapdBdM z2}UzU{I80SGu8M>fCb^|T4;Yx%qCLwZdAgkOn^Q3CUPywd}=FP;8GZMvERRYm0OcF zUkyX;9XV&W#vWpKw%yxJRi^EBw?<5XV+5v8{T`5DIG+0~6Zoz(28O?6+s(s!WZ;Y) zym75tEkNH zI{dS@qA!;P$W8elB`NxPF#4_5yN-^6fX}9id8fgWtqcA?k4H;K>|^|VJNVrko=?|r zb|awW0{0ohGA86p1+1rP2-iUy&)NqIGG^6<9H5*KPeN}110D@WKtw-AqdgR8C?zP{ zwg!K*6qXo}ZLUNKMe0y)N>SAa-(K4yKe`L@8Wjuk-aD?BZ&VK}?vKril!-o6TmJ#>?eo43LqvWooqLOU5!sdZNdB|F|#uLaE;Nued30i;k(6Xl`SS+Fza4gpb9xB~Tp}bX}M3{L4>RSkJ zrf~wXLefs)PHcza!>%iXv|5smq_5|3#tBBGHA@-niGsbeD^C< zSXq7Ku~P>ntuykerOG3a)4n$n>6To@5q-x6k9FQzd)B;B`}4I-K6srnY@%j!4~oT& zU6)yrO8Dok(~<;S*%0#JC$xb?yb(k4EpOP0-w_2kh>S-T6v#*@3Hsy>%{)5~6$XS% zFy)wfKy*WX;|f_o#Uu5wb;Lrvge#Xe5}buQf;jt_K6(nkOIw4;<$4lySjfcp6b=;B z%o=d34^>0Xz~lIP>mj)G37}Zgu{R!ubYakuA|$M0W5zBE+oy%Q&P)QW^xt=4f}W^- zXnAeNuXiukP5S}8e$EchM)Ulv*ml*WV*~N}niqb6Tlen9Qrh=db%HN7Aa|X~99hQF zgj$TCi-Qhjfrp-px5=nK zLD*hzd7u423324p?C4>9aa^ha|B!v~^|82T?2z%!dYu{HOuv*mx2l=@I+VMqCrFw#pDfZ!4k z?+YbFDDf(NtNECmf@Hn9ib{>R?RJQ07r#joe5)Cw3;)8ex`=6QA6P|qwX*ny-541I zxYtfow_*u)abNa7M>}Z2wL>;TtrE`#81*HHZYc>IaDC7x*5RP!`^vyUJQ?ZGQIzZu zHXX2VBlXsR9DLxBDqHR2TnJh)AH{F*Wa}F+h*6}lO zys457`)V~-WkB(ARqglaU=*O9%%MF?iIB!Y*#~4XS;k?`oBh}iw@sL=`5V*x2Yp)| z@Jw7#wUe=DE1wRK9>}y3(tQwhM(J#41|a+#dtgi#Y}lI&X*6LD|_O-$$g20VOZz zyBN&MhNP_ED+Ka`@ur-H&O*CThnd02p1#~gma0MGpl4qLKh#l;odGUh@k;A?HHh(G zsM2fagds7TSMUkaX=9?ubgy=n!5mDs^?mI_R#ZD_9vIiiS=ICU#aqM1E{#>#2J$jIRBh*q)S*dP03GQUbVNRYYY#4fcnpPt@KD z+@2olCxgDuY7Ci*00tTeA{pt|p6~&LuQr%{)WnM1Ju=w|D_Z;l1o-6y#?r}*JXHtJ9|)HJ%4TpdLhj=o+5ogQNj zE&cA|8Y39coO8j#8P+PyLrD3-_W=)o*f`PaF@rByyFkBgJ~{QJ-AJKuIQ#P!t2VN` zA135GG7#|6bpIRhI|4Qd=9(6`il*`6ay|GZ>yMBE*1YW?Bx!xT+(2jWDOV6`4|DYU ztnG+3OYw)KVN)N#xF70M28C24P<;@i>ozfTm#S>g7m?NZU7t->l9K?iXBYEnH|!P@ zvsGjK5wbZD#3+QtVr(1mur9UxDG;i(qLq|UdAF_cM`yvL4#C=*asjv3x_PBrg~*8t z0mj-)Mo^XBm^3Cf=fEXPUwMB>UbLaX;VH-HcR8V0f3qvOv1l>ov?WS1zW> zyBRN-d4OAzuc_mcJ2lO}kgCp)qSOz(yR^Cu!r*dO{%8P4gl zLO=mF&i4_ydVTv_oFP;uf^>4lK`$#{deFJq!fn|O4L~Djo(S!l1GF6n5WsZ>QL57B z0ijOfWYiGbpnO43o>>B~M^14v2N!5&+^w&%>b&(q4ut{;EEXY6U$MEV&XJNiD( zL^;FTyDRXz-U?{{sQ@|cq2=(@Tq__IPo-mq416-s6J)GJFmsvv1p0V6kL%R~LoYm^ z^l$PRM^?`!|15ul$f~*OU$q3Kw-q_?dzl)?XjGY2ojr{PqMyl}-_>nR$Ji5l?)y7CavM;`8TM~_kqj0x*e)zw3QG$=6A zW8&s-HD=`@1Tr{6MI;AN0)!^lwm=m46soa>BX2<#462u#BYSJy$`t0Blj1&he`q-d z1XxAjax=MJe&Da?Yj2IEy|4-)e2Z9LA3STiN-zh-{wmt<7Q9IFVI<#{C);iOKltPr zlLn_um=$b!7tO@v0T>q1Z95q)Th;(Ibi@xON>`fxvse3-YXI%kg4Rp|pW02eJXKuB zai*rS^FJ`h zcfv6MY!&`-^H}#)?rdsIc&VjpNuDi#?OpjaoXg54q?SFyub5E3)aFJS9v%bUsah(GQlyrOoax=ww5YtoME!1pp8970<>rSd;FS_9O zeO|k!t7V-ggJylDb|635{6?|#IZ-E6PujSKk`B6XZC`67pvOwv-|De%15Oqy@*CDg z{c~et`h@1MgVwBo?gl(&2}JLX-v<`hi%Sobp3go8J2t|aXQ9B-bAk=Iz-{W&q$pTR zv0U*nQ0i?uJVvv!ODX>XlO;M66-iKC2C+_rZ2ARBdif3rtG3 z1C}-aRr7j0Ca9ba;M?mF{r=>^m8(7v5}MCvg;3hUXfrq+fiaOs@Fs7iTCK2J&pCv9 zKXD-g&Z6BMT$G8v*9Z9i)JzpxOtqs_@X{B63t_PIBvs~G!d9U#4b6{~%$=v{ulVxo z%BhVqKUetg7Xin3-ie1S-WKges5oTbs&@Gw3C>G0E%7n$&p-3GBH{1H@InK1Xs1V1 z516zvtj#Y){ri;|gG%r{ld~M+=K%^-RUMajw0@o3DDLhQM5ofNy^a`*dbC2ytM@L( zvIZ^X4g+%`TWSL%%r$MJTRFn=(H~OY`6F1V?Q*@_C2wlrhaO}f2F^{|Z}S=i!z~Bj z3ApTj%JM%)-pWXcV=dSP+eX<-Y4O}ea^pwDg@rTBC8wgCS=~$8aC~{_XGicnD4N`G zkC?_e*zkhhHY86|_~qqC8=Dn5?88j}V8s(I$9AT{2cehuVJSSrx5^v#+S+Kqg|O3P&@vCRqnj%p0jzjE+v>V zW^*3Aac_bS;-BqTGaF|Hu}A$GpX&W}W_W(Ca`CY?YqHQ*5TSKFmm-BPtT?_&2lttX zwRM0Gb%2igxV@p&$9L8OU&;($SO~vZ2x)!)B%OO}{_Xe;zcA2GtOP$LAj2_Ey`e)7 zub&_%-V+C}tQbH4X?EYfejQa)&n04itOs^&5WeD=h3;7qX8Y;_?tjMxICwRpDsjQyW^uNppl>-hwH(V}1dYjf4Dhy18C~;c#BElY*{*=sYZIclRo=*zC1d4VKZ_ z6jCeCHr_ooX{wL7_tNZ+!HC)5cbZV|&tjI>Ew@dZ;hGfF%iRws0w=jk0L8@VZoVnW7-Aws+O)eQ!H-9UGSkcW6OZ z<~!h1^*2T?vuO5#V;MF_Ce3O^1-teyFtI_L!!^hhC60eJ9RI$m(Wn>Y*{h?F5~q;b zPo~H){iyy&CC}99;(&P~7RU6rCTyO5+Hyt0T)v?HM&Fi>HGlg{$+xd7;@5?IEXkS; zqtTB@*Ia3m^-uxQ8#pOVE^4o-X5PXA=CVDq>%RoW5bj-Xbv{1S_IdC(+V(>qSpgpA&O|Hy@Gd;Y>}#M{(u|pHV~DRt4P; zvvUFKaNA*RIqK?#d$f+$X|v8VfUd3OFTT$0cL&alRQEuAKiwpbQO857SE#{Nw|H-< zR6kc8(*q*djAEN7g*W_(T*~8%R<}+JB#RR(>ADf?UzWRUm zQg++!-F@4BUcHWcYkFVFtc;F!-EG~kt=+%fFKfB`WdB^Un=1GIU0N%fN}HG8bI4p< zv+LZDJ&Wz!2BU)yb;yUY4RO1??ThwShJsqf9e#4o>$Ses<$0W>AwggzdI&DJ4%awZMeZQjlep!9Kr*3{y)uiOA z*8Dku{j3rMmeon%Dx3nZUX7=K{kJ;%?SP6(`)O&vUifWj^Qn5}8s@4Qe=Dft0q{_M z9&C14N;``c?$o;wYO|k4U3-;X#+Fsv^n5YGD-*fRTla6=18|RB7IQ~`ia~hQY?KqB z=~{F{CdQ$*`!4JawyHA{&YzGMWiKmsk-|zRSZvT zLu%`s2ie4FRpUzE6=mVTNbcUldahL0yZse$`v=7;Nmvu?G0(MF(k`FW(S_yHB4cWa z8a#PdvfxQ@I|ldX2E&i)1EqH$!NB$Rjbe>|9)xoyAgbmP-G~?etUB)fsPriab>wQZ!jad)lY_u=0IbCi+cDN{qpsy>? zI`5bKV}LC9eGspAVz>fL#WCCb_?FfSKNe^3)3f^*&Rdh}?cQ}lj&>$(Vqlh4Fx{y| z9ep_RVh)q$|Ip2~_KaN{Hp)lKh(FrsNs{$6L4I^&L;As7Nb6K}RVbPczbg+E?Z9kL zu@5o(LwM;&1wFOW27K2kLl18#*=ih^OBO9Sd>XrG5ChE~^bKB^zTt!O+305zPTq}f zr8AKlfVyY>o=4}=w;}au)d++VBzAW@RkghT1))G*zpK{ZQg&(r$ zPk$Od5;yJM-Cuvj#Yw`D!5w@}<=0lPVf2IZy=mGIO+xI44DldSr5tql-C?!{ghQ43 z@NQ5&o7dZrO@zShdciEh3~(bAkM&0CzT?=JRXeGv@Q*TU8paB7#XG!ljf|QNUDn%FBE*fdilg8UDEx zFBWfe+HaeXoGvfV3R;P@c#B9EFvsF;p+JELps9nl1!z*>Q3)cUsN>?>5{A%38KM#} z>o{MCCK9Gbv{TSgkcP8MVe7}`j7*ZM1>?Z`fRmF<1u3*5+_}{QDabGK@w7At(Fk@dYn1W|vvfLZtq@2Nq6AIn8?wTw*kDDsgR6;fK=RRO43Q~d#jz0R<<{gBHv-@k7m>=9eKgKIE)^VLB?=vXFd)tb<$X3w3%0#~aMSgBP+WQ~(mY1RO7C zqw)E;7=822H+GzneLNwSqHUlSFJA{w2B)Wk7jItlj(-@uIXUgUI29akcs=2VP{sCPNIo%qnO~Z(<^gV6ybBmw5ls@gZ`AYbtTuwURbccjjE1~?YR+p|BKXdxlAzibW-e*jg ztj*Vb!aM78x&wJ_(RD!AZphb!=+|vg`P~k`?;O&#OLXb>2yS;j<}1;&%k=3UaC*kC z$MAb0z3)W?rxz2PUJ~<_(hqQJF+TguKl@$I*X{C^(|7qh^Vfc_!&iR4Pkhm5 zy!y;X{fOZ88LvLmsh?3j`dogW%kOjfeWpX7>)&U-?Q{JPxSRtn=YY#O;BpQa{($*< zknl6pWsvf7hrf4HzP9<=<15i^(B(yO~K1ge{m)J4*M}*`8~J8;Q>Dn`1z329pd{qisiM(*8yFr zoFoj}bR~V4gehN%j}mUzlk}hA_3bD28 zGF`fCJ-bZDE^7sCg*g8K=O1wXL%Q}twh9qjrI@V@Yqeg&)`PWuFOk-#&sS-Mh86Rzh_{wzJXFl3zI_-DaDs|<1 zX@%Ho^-{j_ceWDyjAx(m>N8$_#;ecx^ckN%m*3}h>T~&hrbD0W-sF#H3CKOk*jSRsNtNZERH*g7aH)ZwdZh1kk49R_TTt5#^AuUxLOLY!V%Au8`M zrF@61-NQa<^N_TgVTIT#gsjDt6=E$Ou{GG(3bFN&R*2}fh81EsZBDn+3bA$D=l9YI zvDUA(LS1@4;OE1r#aFf}DL<#u%Cz}fV};s$-B0=2=c}|r{JzicN$-d&!x`}VLr!;y z&xRG+=c}|rSU!(>)}9I%xM2+X}6=MaR#M->lIuie>+V`$q}; zYYF>bX@@wq#hR(boZjMoP-~wgpv4xc#hje6Kb57FE@QY^TlOC^zLErFtjV$gYkam0 z8C$|G`;Xm(H91?*ZYuj5{5@k$p0Pz>i`Cudd~8X&jCYs)zb^Nuy4;`Y9`G~w%erh~ zdZFxRutsM*dI|R*xZXXMH5;AW8W&2J{wDX%FkTReky%9mf%cA z5;z^V&py|4pW$nXKV*q#-zrV{%03sv@3ThfGyFco?=v0y48PCt`>fgf4F7=PAEffi zz8S;U5`XAOJo{WJ`%c_<&=N17`;Nr3Pj$c&8SyoilD($Hvk!R4KKdd1!b;*fvT(?K z6fN=n8i_w-iEq_N{D38Xpe0_8MyU`jZ4*-R0L`fQAO|F9phS(T(;g%93mA8i6V3D} ziyk(i(Uuv-gkkn(ep$d=935Lew?;oo1w{?f!1+}3U^2cOFSa>qTrS3wNpLa4g-SEE zP|XPqJHz!behs57M^LT9*?fz&8pq{vc$MF51v^qh}}z(?{)B4 z)x!J{Vj_W)**{N6*2qq8OlM(=o9O&z%)&S-DO{iPd0EKgkUFGr$gHL1+F`-j*)l{t~~l#36;$#PVXaKQS?>Bi_BpKOE> zjy`)((sX&e4q5#3eyfP!vU{ATWywj^&EF1&o+WiOZPRrSUJ8h>{gZXPZ1Q;+WKG_< zUA9=8BW{ZsnyIi=KV!VIQ5rUY&p&)=v68>n2<+sth_p?4V(&+F8|-mSdAO4*>>Pj$MJxm( z==!8~>v-H-sPRfLx@LU@hjla8q}SJOttAPHz`&R-d1v;A;XmM?5 z|1W;AKcV@jIxIntPlcDZ7%#5nya+?hNoLGzrpk-#nny2Y)`89la$X26P)xPP{3Hsj zJXLvce0p^H^NYdZZ8DX+*#!{5OZ$}@E&L#;oomlyC+PFG14u~dW#lCh_*SV$TOI*r zR&3%~sk51+Vb6ship2tI1Di(#mpCi>y>}Z1?S#2UN!ks!-Y(@$06g z0)7Vn)XD_>n)m;*7P9{7PbO60sCWeu)fII|lSy%rPecV?3y4FI>-lns@g41O0NE;w z>|CT*aU7xk&0g^H&x2=&EBDKT-&)6v$Y0IrDe~vrx_pi7O=q%vgkyWdUGEx9zW^W8 z>p$kfqip$87AUrp40xA`|_YoD_(35Di@9^8e#=~!2I}g8RTW=R$ zWAE1y3fwuTm{z>!bU3tr24Z)+~4|aCg85aAGJrOn7v+;N1JXge^z)&Y)D>x~j;t-}JmFhjMH`H#a^)qXAvq^P(6v z?DZypv^#}qkUqYt8a~zgU+`PiX@}oB9e4QMSm%8;+Rd)x=EyYGtIi*8-pzx20Igh` z$^0fBFR1Xu=9>JWJ@?Qh3=Dy+ZVc ze!I6_zo&($#0Zz?s#BA6s9m%a)^|ifqOsZ@=%(=4^~`%Zp(CLr4tmCu;J#uGb08^V zwG;eguAwzTSwdBwFDH|0MjqD|2NZC^d6F11R2kpH1g5isEes@w5Sc*&>>(}ZbC_7g zC14)8A+os+mTsvVvn<~ZDESs|nFmuRwgY}iptglkn;>u zQP0uN#Jo4VD%_r>ERj=;%cCjr>z02rG@kQ@XML%V7H5WUxETd*g70-^udkssDC3p^ zWE&>G8P7aXu3fw*rnPtwQyYOAvPW%ML)=VnHG*yV9~m`Zb3H9|nP%`$GB?_HrI=%7tmQTVoP zzZYmio?MrU;_~P~nAFOy?e0z`%_1mw@q{)| zMH^8*-*Y)bT2{28?LFoEFgPB(=sj^t zsrT?}%Ko947IRJFTGtnO#fqIe%8^Bch=qr%sK%TY?~nZYKzw-lv{F{3 z2#+e*uwoxkFOqlldbRgqR#$NFg|=^tg64_CH%wrgJH_7to9Zk*ys6tJv~^<|(jVm*SZHHkqUHQ7LBL<l&d9^hJ-7?umNJWZ~htxXD&1p3^ON?3KyDOW*%@|?EsF_)DVCAlp_wi$pdKThC zYlefjfootS5`<@?@d{V_yEyL2TkKPKC1zcju^Z6F%aPsSu}d-szp_}I@_AZYX!Dzm z0B%oZbNBx?=p9VHRc%0Bi)xA*Ms(!VWjfbisWM7ALFbjxm!_kxDMCdReo>q|eFMi0wQRWIt#8+ALMw>j_uujCDJsq=sv-sw zM9ntYRF5C0zf5QEr>Z(;bVhWw zkzu%t_*_pf!y%nr4)Chwg>K}KveVXd*WbjT0nm~MXEI8=6_v8(SS6>Vc>uat9a-v1< zyc{h?ukXOt=l*V`Aql^KJqLf^q@HddjS%`NFHe3MUtRgMJ=MwzMpDw+T2^9$e*M6g z^~`{lxPLBZFkD0X_Is9g3GC(mk__a14%^^fP4Xdx(1o%`o5+b203&fp6|7VEQk{{q zd@^3B4)K?!`z4I30(RX3Eyk;KvZKxvL}r_f%nc;@M(IirxUFxRf--n^gu}5y1lJns zdtt^vm(x*kKAy_qqw5F3o#0+D^)RnrxvmZdDXp@has)cLY66Sd2Dhu`SQzU4C_;V@ zMg>o}{9EtIj|0{W^*w0(JqX+kwDGm4+OCT5Rr{Md16bcOxP+!Mn5H*{hBjJJi97j1 z2;bRqQP4mG47iPHLa8r+ZDG8*uE)7uW@O!uxoC`FLR!M#a87I43f*mkPvaGC!4(bY z)N?%}A(^8_DC**ZH7;jGi7qgnx*}xY@iZ43`(^uoXEC(Up2g&fMVsW`4?u!=#8W zVdB8&m>7ZcKF+Rb0+#57lynvVR}^B)qI-Wv$0^}Vko$1%xZbjV2$M%}X%|mN`1{i* zTX%0|o(K_wCSB9M<&K)h{k%uB<=LdTZ#j5~U_KgIuA0hS=b`Dz+J8l0r#YS39&C6H zpmDg=0SFCl$6o8r=-J`y6K;L`>dv>@pxOU=a{A)v_=h(*tLV-CkB5hY7lVT)i{!w@ z%@K;xv$KB`!$mLyKhVVsd_hjulLXpQr24DRGl%-k8qds9`H_BnDE%F*hI;_4Mo8@;cN58L(e%~UBo|p#Bu?G5Q|Snq$R9s@@wE5k=zj)l;9Wgu z(XcVN2@9RdK&M=QdenM`6i~eeIl5lO^353L<{@_ zB3E*1FP?{^pm3xcw&h%2T}=cF!#w6Y1hyDqcks??kI7;LI`4<(^rH%-zL*8`BW7h$ zm|iaQ7Vhh8DQ+k4a7PCq7Eb-2=hJcm$mu;!ED+-U7!xGQ+ayuAb!DR99Tk*ME2xi%-tQ4rsJB3|%@Z_-J?DBFpwa%6-1JPoWYdi#fR+eL-S86Ny zH~=ku8@yAUDr=F}R0p@kx*Ul?I@j1-{Px7Nh|FTtir~p6fU~f$bBSl5;dt+S!77{1 z!GfcpetdD{Sz-hgRK-6EQV3j+OLZvgfgTgAnYKhe=Q@WED`}MF`NX4s)t)Q}j_zdR zxdOIFQH*?UprFjQdQfMxZrg6+sv~BrP5@63_swtTmOI96e$;BPOE|?0PoqQHZwGfC z-vJwXXV){o8Ryj1xLoxrA9jtb^|z+07k6&x8BI4_mF!(FD(9k3SFGapZr7(j*KgSe zzgt-R)ric$+wwU=d$*aykDDvC=6(}`bDy1y?rD8LMgAIgo`K)$C4bfUvfcqRxEzIUY%FV1N<7-fP3`6m+9-g+(tiF z@YHQNVSZV-A3-ogu=_^txL_JDnyXs>Mq2#SD{?DNwsC9qYyCUn%wdZYjuC)+Dmu#3 zf>!?WTkJ`bOR3@cJAtb^f6j(FzK-8I9X{F7vm*xf03%mh1yr*64!m)I~)GQy4BA(azSiJW`ZO(U93W-%Qjx zt$Z~8V8=xuCpr4|NPXZR~6yJBbp_V@P6%>C@$dnpn1DG2xF?bwA zAy57P`qZ+n6g*X~>UR=S^+7Kn?<5d=N2Yfu@TKV6l%G1Xau0c4?it`y}zBba~QQc^2 zK)+b~3s4C@1xaZ1XO~x#;=_Q_sbz5VNTWvfUTFT1i7`1*C-n@T!4d4TEUOTMYBZmF zS`3S_%;(qJz87Hmd!~@kyVP6l9h^H~2;Czx_7y%&vINmok!(P+nr3##s2R!Mf zX1q-$>_g#+R8R{Wh& z(zdr8H;z&9a;w(O2ZzkvX2W{p*PiLGhKM=0KKF0UF}BK3v?+bmK^~&aEaYw?#v~;} zreT1iBFc^g&Va=o3A~9h>N?)`jMTv?Nm`Gr;`6e?_r{R9 zS~4=7P4ClwUI=y@lFGjGbT+@tC!#fNuVE477x{R)W9vuAR338<8sKr;RgJhvxFr1V zeC%EY=P^x|X{429Ubjj3-*T@8^}V_;teWUloTtX#%O>vB zhCP;>^~2c4evB8!yD=ZE3&G!C@%nNSX1xnn>xjt;`Q5OMTrj_4*~kIAb?58G9j{eR z*Cun|)G8U+ptWapg|<8`v6ET;|d3`;B$)>=6YIU#L8`3dz&3l}|*wWb!rM)Q18O}e%Q5Pm3jytG=uh>gckugQ(g0QA_ zMG7QL&NL!4R{%SQK>F=J|6PNl56cY0Nik^#=->

  • + */ + public static XmlObject newInstance ( XmlOptions options ) { + return XmlBeans.getContextTypeLoader().newInstance( null, options ); } + + /** + * Creates a new immutable value. + */ + /** Creates an immutable {@link XmlObject} value */ + public static XmlObject newValue ( Object obj ) { + return type.newValue( obj ); } + + /** + * Parses the given {@link String} as XML. + */ + public static XmlObject parse ( String xmlAsString ) throws XmlException { + return XmlBeans.getContextTypeLoader().parse( xmlAsString, null, null ); } + + /** + * Parses the given {@link String} as XML. + * + * Use the options parameter to specify the following:

    + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
    To specify thisUse this method
    The document type for the root element.{@link XmlOptions#setDocumentType}
    To place line number annotations in the store when parsing a document.{@link XmlOptions#setLoadLineNumbers}
    To replace the document element with the specified QName when parsing.{@link XmlOptions#setLoadReplaceDocumentElement}
    To strip all insignificant whitespace when parsing a document.{@link XmlOptions#setLoadStripWhitespace}
    To strip all comments when parsing a document.{@link XmlOptions#setLoadStripComments}
    To strip all processing instructions when parsing a document.{@link XmlOptions#setLoadStripProcinsts}
    A map of namespace URI substitutions to use when parsing a document.{@link XmlOptions#setLoadSubstituteNamespaces}
    Additional namespace mappings to be added when parsing a document.{@link XmlOptions#setLoadAdditionalNamespaces}
    To trim the underlying XML text buffer immediately after parsing + * a document, resulting in a smaller memory footprint.{@link XmlOptions#setLoadTrimTextBuffer}
    + * + * @param xmlAsString The string to parse. + * @param options Options as specified. + * @return A new instance containing the specified XML. + */ + public static XmlObject parse ( String xmlAsString, XmlOptions options ) throws XmlException { + return XmlBeans.getContextTypeLoader().parse( xmlAsString, null, options ); } + + /** + * Parses the given {@link File} as XML. + */ + public static XmlObject parse ( File file ) throws XmlException, IOException { + return XmlBeans.getContextTypeLoader().parse( file, null, null ); } + + /** + * Parses the given {@link File} as XML. + */ + public static XmlObject parse ( File file, XmlOptions options ) throws XmlException, IOException { + return XmlBeans.getContextTypeLoader().parse( file, null, options ); } + + /** + * Downloads the given {@link java.net.URL} as XML. + */ + public static XmlObject parse(java.net.URL u) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return XmlBeans.getContextTypeLoader().parse( u, null, null ); } + + /** + * Downloads the given {@link java.net.URL} as XML. + */ + public static XmlObject parse(java.net.URL u, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException { + return XmlBeans.getContextTypeLoader().parse( u, null, options ); } + + /** + * Decodes and parses the given {@link InputStream} as XML. + */ + public static XmlObject parse ( InputStream is ) throws XmlException, IOException { + return XmlBeans.getContextTypeLoader().parse( is, null, null ); } + + /** + * Decodes and parses the given {@link XMLStreamReader} as XML. + */ + public static XmlObject parse ( XMLStreamReader xsr ) throws XmlException { + return XmlBeans.getContextTypeLoader().parse( xsr, null, null ); } + + /** + * Decodes and parses the given {@link InputStream} as XML. + * + * Use the options parameter to specify the following:

    + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
    To specify thisUse this method
    The character encoding to use when parsing or writing a document.{@link XmlOptions#setCharacterEncoding}
    The document type for the root element.{@link XmlOptions#setDocumentType}
    Place line number annotations in the store when parsing a document.{@link XmlOptions#setLoadLineNumbers}
    Replace the document element with the specified QName when parsing.{@link XmlOptions#setLoadReplaceDocumentElement}
    Strip all insignificant whitespace when parsing a document.{@link XmlOptions#setLoadStripWhitespace}
    Strip all comments when parsing a document.{@link XmlOptions#setLoadStripComments}
    Strip all processing instructions when parsing a document.{@link XmlOptions#setLoadStripProcinsts}
    Set a map of namespace URI substitutions to use when parsing a document.{@link XmlOptions#setLoadSubstituteNamespaces}
    Set additional namespace mappings to be added when parsing a document.{@link XmlOptions#setLoadAdditionalNamespaces}
    Trim the underlying XML text buffer immediately after parsing + * a document, resulting in a smaller memory footprint.{@link XmlOptions#setLoadTrimTextBuffer}
    + */ + public static XmlObject parse ( InputStream is, XmlOptions options ) throws XmlException, IOException { + return XmlBeans.getContextTypeLoader().parse( is, null, options ); } + + /** + * Parses the given {@link XMLStreamReader} as XML. + */ + public static XmlObject parse ( XMLStreamReader xsr, XmlOptions options ) throws XmlException { + return XmlBeans.getContextTypeLoader().parse( xsr, null, options ); } + + /** + * Parses the given {@link Reader} as XML. + */ + public static XmlObject parse ( Reader r ) throws XmlException, IOException { + return XmlBeans.getContextTypeLoader().parse( r, null, null ); } + + /** + * Parses the given {@link Reader} as XML. + */ + public static XmlObject parse ( Reader r, XmlOptions options ) throws XmlException, IOException { + return XmlBeans.getContextTypeLoader().parse( r, null, options ); } + + /** + * Converts the given DOM {@link Node} into an XmlObject. + */ + public static XmlObject parse ( Node node ) throws XmlException { + return XmlBeans.getContextTypeLoader().parse( node, null, null ); } + + /** + * Converts the given DOM {@link Node} into an XmlObject. + */ + public static XmlObject parse ( Node node, XmlOptions options ) throws XmlException { + return XmlBeans.getContextTypeLoader().parse( node, null, options ); } + + /** + * Loads the given {@link XMLInputStream} into an XmlObject. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XmlObject parse ( XMLInputStream xis ) throws XmlException, XMLStreamException { + return XmlBeans.getContextTypeLoader().parse( xis, null, null ); } + + /** + * Loads the given {@link XMLInputStream} into an XmlObject. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XmlObject parse ( XMLInputStream xis, XmlOptions options ) throws XmlException, XMLStreamException { + return XmlBeans.getContextTypeLoader().parse( xis, null, options ); } + + /** + * Returns an {@link XmlSaxHandler} that can load an XmlObject from SAX events. + */ + public static XmlSaxHandler newXmlSaxHandler ( ) { + return XmlBeans.getContextTypeLoader().newXmlSaxHandler( null, null ); } + + /** + * Returns an {@link XmlSaxHandler} that can load an XmlObject from SAX events. + */ + public static XmlSaxHandler newXmlSaxHandler ( XmlOptions options ) { + return XmlBeans.getContextTypeLoader().newXmlSaxHandler( null, options ); } + + /** + * Creates a new DOMImplementation object + */ + public static DOMImplementation newDomImplementation ( ) { + return XmlBeans.getContextTypeLoader().newDomImplementation( null ); } + + /** + * Creates a new DOMImplementation object, taking options + */ + public static DOMImplementation newDomImplementation ( XmlOptions options ) { + return XmlBeans.getContextTypeLoader().newDomImplementation( options ); } + + /** + * Returns a new validating {@link XMLInputStream} that throws exceptions when the input is not valid. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XMLInputStream newValidatingXMLInputStream ( XMLInputStream xis ) throws XmlException, XMLStreamException { + return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, null, null ); } + + /** + * Returns a new validating {@link XMLInputStream} that throws exceptions + * when the input is not valid, specifying options + * for the root element's document type and/or the collection object to use + * as an error listener while validating.

    + * + *

    Use the options parameter to specify the following:

    + * + *
      + *
    • A collection instance that should be used as an error listener during + * compilation, as described in {@link XmlOptions#setErrorListener}.
    • + *
    • The document type for the root element, as described in + * {@link XmlOptions#setDocumentType(SchemaType)}.
    • + *
    + * + * @param xis The basis for the new XMLInputStream. + * @param options Options specifying root document type and/or an error listener. + * @return A new validating XMLInputStream. + * @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API. + */ + public static XMLInputStream newValidatingXMLInputStream ( XMLInputStream xis, XmlOptions options ) throws XmlException, XMLStreamException { + return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, null, options ); } + + /** + * Instances cannot be created. + */ + private Factory() { } + } +} diff --git a/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlOptionCharEscapeMap.java b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlOptionCharEscapeMap.java new file mode 100644 index 000000000..91ffc7320 --- /dev/null +++ b/xmlbeans/src/xmlpublic/org/apache/xmlbeans/XmlOptionCharEscapeMap.java @@ -0,0 +1,142 @@ +/* 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; + +import java.util.HashMap; + +/** + * Corresponds to the Saver and XmlOptions. + *

    + * This class is used to set up a map containing characters to be escaped. + * Characters can be escaped as hex, decimal or as a predefined entity (this + * latter option applies only to the 5 characters defined as predefined entities + * in the XML Spec). + *

    + *

    xMLnG+)u^Yug&9M4y+2`2I+H*3c-d|ArgS-8 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

  • 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%0DNn`R%%Zm5D=F{di@n$oq6>`$D>=6*HYDx2FMkR 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