summaryrefslogtreecommitdiffstats
path: root/xml
diff options
context:
space:
mode:
Diffstat (limited to 'xml')
-rw-r--r--xml/MODULE_LICENSE_APACHE20
-rw-r--r--xml/MODULE_LICENSE_BSD_LIKE1
-rw-r--r--xml/MODULE_LICENSE_W3C3
-rw-r--r--xml/src/main/java/javax/xml/XMLConstants.java97
-rw-r--r--xml/src/main/java/javax/xml/package.html8
-rw-r--r--xml/src/main/java/javax/xml/parsers/DocumentBuilder.java252
-rw-r--r--xml/src/main/java/javax/xml/parsers/DocumentBuilderFactory.java405
-rw-r--r--xml/src/main/java/javax/xml/parsers/FactoryConfigurationError.java126
-rw-r--r--xml/src/main/java/javax/xml/parsers/ParserConfigurationException.java47
-rw-r--r--xml/src/main/java/javax/xml/parsers/SAXParser.java390
-rw-r--r--xml/src/main/java/javax/xml/parsers/SAXParserFactory.java283
-rw-r--r--xml/src/main/java/javax/xml/parsers/package.html24
-rw-r--r--xml/src/main/java/org/apache/harmony/xml/ExpatAttributes.java154
-rw-r--r--xml/src/main/java/org/apache/harmony/xml/ExpatException.java28
-rw-r--r--xml/src/main/java/org/apache/harmony/xml/ExpatParser.java794
-rw-r--r--xml/src/main/java/org/apache/harmony/xml/ExpatPullParser.java964
-rw-r--r--xml/src/main/java/org/apache/harmony/xml/ExpatReader.java335
-rw-r--r--xml/src/main/java/org/apache/harmony/xml/dom/AttrImpl.java177
-rw-r--r--xml/src/main/java/org/apache/harmony/xml/dom/CDATASectionImpl.java49
-rw-r--r--xml/src/main/java/org/apache/harmony/xml/dom/CharacterDataImpl.java93
-rw-r--r--xml/src/main/java/org/apache/harmony/xml/dom/CommentImpl.java49
-rw-r--r--xml/src/main/java/org/apache/harmony/xml/dom/DOMImplementationImpl.java78
-rw-r--r--xml/src/main/java/org/apache/harmony/xml/dom/DocumentFragmentImpl.java50
-rw-r--r--xml/src/main/java/org/apache/harmony/xml/dom/DocumentImpl.java298
-rw-r--r--xml/src/main/java/org/apache/harmony/xml/dom/DocumentTypeImpl.java110
-rw-r--r--xml/src/main/java/org/apache/harmony/xml/dom/ElementImpl.java446
-rw-r--r--xml/src/main/java/org/apache/harmony/xml/dom/EntityImpl.java71
-rw-r--r--xml/src/main/java/org/apache/harmony/xml/dom/EntityReferenceImpl.java52
-rw-r--r--xml/src/main/java/org/apache/harmony/xml/dom/InnerNodeImpl.java221
-rw-r--r--xml/src/main/java/org/apache/harmony/xml/dom/LeafNodeImpl.java70
-rw-r--r--xml/src/main/java/org/apache/harmony/xml/dom/NamedNodeMapImpl.java176
-rw-r--r--xml/src/main/java/org/apache/harmony/xml/dom/NodeImpl.java191
-rw-r--r--xml/src/main/java/org/apache/harmony/xml/dom/NodeListImpl.java63
-rw-r--r--xml/src/main/java/org/apache/harmony/xml/dom/NotationImpl.java64
-rw-r--r--xml/src/main/java/org/apache/harmony/xml/dom/ProcessingInstructionImpl.java74
-rw-r--r--xml/src/main/java/org/apache/harmony/xml/dom/TextImpl.java70
-rw-r--r--xml/src/main/java/org/apache/harmony/xml/parsers/DocumentBuilderFactoryImpl.java106
-rw-r--r--xml/src/main/java/org/apache/harmony/xml/parsers/DocumentBuilderImpl.java436
-rw-r--r--xml/src/main/java/org/apache/harmony/xml/parsers/SAXParserFactoryImpl.java123
-rw-r--r--xml/src/main/java/org/apache/harmony/xml/parsers/SAXParserImpl.java91
-rw-r--r--xml/src/main/java/org/kxml2/io/KXmlParser.java1440
-rw-r--r--xml/src/main/java/org/kxml2/io/KXmlSerializer.java562
-rw-r--r--xml/src/main/java/org/kxml2/kdom/Document.java129
-rw-r--r--xml/src/main/java/org/kxml2/kdom/Element.java335
-rw-r--r--xml/src/main/java/org/kxml2/kdom/Node.java366
-rw-r--r--xml/src/main/java/org/kxml2/wap/Wbxml.java49
-rw-r--r--xml/src/main/java/org/kxml2/wap/WbxmlParser.java1075
-rw-r--r--xml/src/main/java/org/kxml2/wap/WbxmlSerializer.java512
-rw-r--r--xml/src/main/java/org/kxml2/wap/syncml/SyncML.java192
-rw-r--r--xml/src/main/java/org/kxml2/wap/wml/Wml.java233
-rw-r--r--xml/src/main/java/org/kxml2/wap/wv/WV.java593
-rw-r--r--xml/src/main/java/org/w3c/dom/Attr.java134
-rw-r--r--xml/src/main/java/org/w3c/dom/CDATASection.java48
-rw-r--r--xml/src/main/java/org/w3c/dom/CharacterData.java171
-rw-r--r--xml/src/main/java/org/w3c/dom/Comment.java24
-rw-r--r--xml/src/main/java/org/w3c/dom/DOMException.java130
-rw-r--r--xml/src/main/java/org/w3c/dom/DOMImplementation.java105
-rw-r--r--xml/src/main/java/org/w3c/dom/Document.java382
-rw-r--r--xml/src/main/java/org/w3c/dom/DocumentFragment.java52
-rw-r--r--xml/src/main/java/org/w3c/dom/DocumentType.java99
-rw-r--r--xml/src/main/java/org/w3c/dom/Element.java314
-rw-r--r--xml/src/main/java/org/w3c/dom/Entity.java82
-rw-r--r--xml/src/main/java/org/w3c/dom/EntityReference.java39
-rw-r--r--xml/src/main/java/org/w3c/dom/NamedNodeMap.java168
-rw-r--r--xml/src/main/java/org/w3c/dom/Node.java454
-rw-r--r--xml/src/main/java/org/w3c/dom/NodeList.java53
-rw-r--r--xml/src/main/java/org/w3c/dom/Notation.java49
-rw-r--r--xml/src/main/java/org/w3c/dom/ProcessingInstruction.java58
-rw-r--r--xml/src/main/java/org/w3c/dom/Text.java61
-rw-r--r--xml/src/main/java/org/w3c/dom/package.html12
-rw-r--r--xml/src/main/java/org/xml/sax/AttributeList.java193
-rw-r--r--xml/src/main/java/org/xml/sax/Attributes.java257
-rw-r--r--xml/src/main/java/org/xml/sax/ContentHandler.java419
-rw-r--r--xml/src/main/java/org/xml/sax/DTDHandler.java117
-rw-r--r--xml/src/main/java/org/xml/sax/DocumentHandler.java232
-rw-r--r--xml/src/main/java/org/xml/sax/EntityResolver.java119
-rw-r--r--xml/src/main/java/org/xml/sax/ErrorHandler.java139
-rw-r--r--xml/src/main/java/org/xml/sax/HandlerBase.java369
-rw-r--r--xml/src/main/java/org/xml/sax/InputSource.java337
-rw-r--r--xml/src/main/java/org/xml/sax/Locator.java136
-rw-r--r--xml/src/main/java/org/xml/sax/Parser.java209
-rw-r--r--xml/src/main/java/org/xml/sax/SAXException.java153
-rw-r--r--xml/src/main/java/org/xml/sax/SAXNotRecognizedException.java53
-rw-r--r--xml/src/main/java/org/xml/sax/SAXNotSupportedException.java53
-rw-r--r--xml/src/main/java/org/xml/sax/SAXParseException.java269
-rw-r--r--xml/src/main/java/org/xml/sax/XMLFilter.java65
-rw-r--r--xml/src/main/java/org/xml/sax/XMLReader.java404
-rw-r--r--xml/src/main/java/org/xml/sax/ext/Attributes2.java132
-rw-r--r--xml/src/main/java/org/xml/sax/ext/Attributes2Impl.java320
-rw-r--r--xml/src/main/java/org/xml/sax/ext/DeclHandler.java146
-rw-r--r--xml/src/main/java/org/xml/sax/ext/DefaultHandler2.java185
-rw-r--r--xml/src/main/java/org/xml/sax/ext/EntityResolver2.java197
-rw-r--r--xml/src/main/java/org/xml/sax/ext/LexicalHandler.java212
-rw-r--r--xml/src/main/java/org/xml/sax/ext/Locator2.java75
-rw-r--r--xml/src/main/java/org/xml/sax/ext/Locator2Impl.java105
-rw-r--r--xml/src/main/java/org/xml/sax/ext/package.html48
-rw-r--r--xml/src/main/java/org/xml/sax/helpers/AttributeListImpl.java314
-rw-r--r--xml/src/main/java/org/xml/sax/helpers/AttributesImpl.java618
-rw-r--r--xml/src/main/java/org/xml/sax/helpers/DefaultHandler.java467
-rw-r--r--xml/src/main/java/org/xml/sax/helpers/LocatorImpl.java214
-rw-r--r--xml/src/main/java/org/xml/sax/helpers/NamespaceSupport.java840
-rw-r--r--xml/src/main/java/org/xml/sax/helpers/NewInstance.java79
-rw-r--r--xml/src/main/java/org/xml/sax/helpers/ParserAdapter.java1046
-rw-r--r--xml/src/main/java/org/xml/sax/helpers/ParserFactory.java133
-rw-r--r--xml/src/main/java/org/xml/sax/helpers/XMLFilterImpl.java715
-rw-r--r--xml/src/main/java/org/xml/sax/helpers/XMLReaderAdapter.java538
-rw-r--r--xml/src/main/java/org/xml/sax/helpers/XMLReaderFactory.java206
-rw-r--r--xml/src/main/java/org/xml/sax/helpers/package.html13
-rw-r--r--xml/src/main/java/org/xml/sax/package.html299
-rw-r--r--xml/src/main/java/org/xmlpull/v1/XmlPullParser.java1116
-rw-r--r--xml/src/main/java/org/xmlpull/v1/XmlPullParserException.java76
-rw-r--r--xml/src/main/java/org/xmlpull/v1/XmlPullParserFactory.java349
-rw-r--r--xml/src/main/java/org/xmlpull/v1/XmlSerializer.java326
-rw-r--r--xml/src/main/java/org/xmlpull/v1/sax2/Driver.java469
-rw-r--r--xml/src/main/native/org_apache_harmony_xml_ExpatParser.cpp1530
-rw-r--r--xml/src/main/native/sub.mk20
-rw-r--r--xml/src/test/java/org/apache/harmony/xml/ExpatParserTest.java839
-rw-r--r--xml/src/test/java/tests/api/javax/xml/parsers/AllTests.java48
-rw-r--r--xml/src/test/java/tests/api/javax/xml/parsers/DocumentBuilderFactoryTest.java1121
-rw-r--r--xml/src/test/java/tests/api/javax/xml/parsers/DocumentBuilderTest.java733
-rw-r--r--xml/src/test/java/tests/api/javax/xml/parsers/FactoryConfigurationErrorTest.java139
-rw-r--r--xml/src/test/java/tests/api/javax/xml/parsers/ParserConfigurationExceptionTest.java55
-rw-r--r--xml/src/test/java/tests/api/javax/xml/parsers/SAXParserFactoryTest.java547
-rw-r--r--xml/src/test/java/tests/api/javax/xml/parsers/SAXParserTest.java1171
-rw-r--r--xml/src/test/java/tests/api/javax/xml/parsers/SAXParserTestSupport.java492
-rw-r--r--xml/src/test/java/tests/api/org/xml/sax/AllTests.java45
-rw-r--r--xml/src/test/java/tests/api/org/xml/sax/HandlerBaseTest.java226
-rw-r--r--xml/src/test/java/tests/api/org/xml/sax/InputSourceTest.java254
-rw-r--r--xml/src/test/java/tests/api/org/xml/sax/SAXExceptionTest.java131
-rw-r--r--xml/src/test/java/tests/api/org/xml/sax/SAXNotRecognizedExceptionTest.java55
-rw-r--r--xml/src/test/java/tests/api/org/xml/sax/SAXNotSupportedExceptionTest.java55
-rw-r--r--xml/src/test/java/tests/api/org/xml/sax/SAXParseExceptionTest.java276
-rw-r--r--xml/src/test/java/tests/api/org/xml/sax/ext/AllTests.java39
-rw-r--r--xml/src/test/java/tests/api/org/xml/sax/ext/Attributes2ImplTest.java464
-rw-r--r--xml/src/test/java/tests/api/org/xml/sax/ext/DefaultHandler2Test.java234
-rw-r--r--xml/src/test/java/tests/api/org/xml/sax/ext/Locator2ImplTest.java153
-rw-r--r--xml/src/test/java/tests/api/org/xml/sax/helpers/AllTests.java45
-rw-r--r--xml/src/test/java/tests/api/org/xml/sax/helpers/AttributeListImplTest.java270
-rw-r--r--xml/src/test/java/tests/api/org/xml/sax/helpers/AttributesImplTest.java608
-rw-r--r--xml/src/test/java/tests/api/org/xml/sax/helpers/DefaultHandlerTest.java278
-rw-r--r--xml/src/test/java/tests/api/org/xml/sax/helpers/LocatorImplTest.java172
-rw-r--r--xml/src/test/java/tests/api/org/xml/sax/helpers/NamespaceSupportTest.java434
-rw-r--r--xml/src/test/java/tests/api/org/xml/sax/helpers/ParserAdapterTest.java468
-rw-r--r--xml/src/test/java/tests/api/org/xml/sax/helpers/ParserFactoryTest.java170
-rw-r--r--xml/src/test/java/tests/api/org/xml/sax/helpers/XMLFilterImplTest.java678
-rw-r--r--xml/src/test/java/tests/api/org/xml/sax/helpers/XMLReaderAdapterTest.java414
-rw-r--r--xml/src/test/java/tests/api/org/xml/sax/helpers/XMLReaderFactoryTest.java154
-rw-r--r--xml/src/test/java/tests/api/org/xml/sax/support/BrokenInputStream.java50
-rw-r--r--xml/src/test/java/tests/api/org/xml/sax/support/DoNothingParser.java55
-rw-r--r--xml/src/test/java/tests/api/org/xml/sax/support/DoNothingXMLReader.java79
-rw-r--r--xml/src/test/java/tests/api/org/xml/sax/support/MethodLogger.java95
-rw-r--r--xml/src/test/java/tests/api/org/xml/sax/support/MockFilter.java89
-rw-r--r--xml/src/test/java/tests/api/org/xml/sax/support/MockHandler.java147
-rw-r--r--xml/src/test/java/tests/api/org/xml/sax/support/MockParser.java68
-rw-r--r--xml/src/test/java/tests/api/org/xml/sax/support/MockReader.java128
-rw-r--r--xml/src/test/java/tests/api/org/xml/sax/support/MockResolver.java47
-rw-r--r--xml/src/test/java/tests/api/org/xml/sax/support/NoAccessParser.java55
-rw-r--r--xml/src/test/java/tests/api/org/xml/sax/support/NoAccessXMLReader.java79
-rw-r--r--xml/src/test/java/tests/api/org/xml/sax/support/NoInstanceParser.java58
-rw-r--r--xml/src/test/java/tests/api/org/xml/sax/support/NoInstanceXMLReader.java82
-rw-r--r--xml/src/test/java/tests/api/org/xml/sax/support/NoSubclassParser.java54
-rw-r--r--xml/src/test/java/tests/api/org/xml/sax/support/NoSubclassXMLReader.java79
-rw-r--r--xml/src/test/java/tests/org/w3c/dom/AllTests.java110
-rw-r--r--xml/src/test/java/tests/org/w3c/dom/AttrGetOwnerElement.java156
-rw-r--r--xml/src/test/java/tests/org/w3c/dom/CreateAttributeNS.java229
-rw-r--r--xml/src/test/java/tests/org/w3c/dom/CreateDocument.java317
-rw-r--r--xml/src/test/java/tests/org/w3c/dom/CreateDocumentType.java222
-rw-r--r--xml/src/test/java/tests/org/w3c/dom/CreateElementNS.java251
-rw-r--r--xml/src/test/java/tests/org/w3c/dom/DOMDocumentBuilderFactory.java94
-rw-r--r--xml/src/test/java/tests/org/w3c/dom/DOMImplementationCreateDocument.java177
-rw-r--r--xml/src/test/java/tests/org/w3c/dom/DOMImplementationCreateDocumentType.java208
-rw-r--r--xml/src/test/java/tests/org/w3c/dom/DOMImplementationHasFeature.java147
-rw-r--r--xml/src/test/java/tests/org/w3c/dom/DOMTestCase.java230
-rw-r--r--xml/src/test/java/tests/org/w3c/dom/DocumentBuilderSetting.java281
-rw-r--r--xml/src/test/java/tests/org/w3c/dom/DocumentBuilderSettingStrategy.java158
-rw-r--r--xml/src/test/java/tests/org/w3c/dom/DocumentCreateAttributeNS.java313
-rw-r--r--xml/src/test/java/tests/org/w3c/dom/DocumentCreateElementNS.java169
-rw-r--r--xml/src/test/java/tests/org/w3c/dom/DocumentGetElementsByTagnameNS.java150
-rw-r--r--xml/src/test/java/tests/org/w3c/dom/DocumentGeteEementById.java72
-rw-r--r--xml/src/test/java/tests/org/w3c/dom/DocumentImportNode.java699
-rw-r--r--xml/src/test/java/tests/org/w3c/dom/DocumentTypeInternalSubset.java76
-rw-r--r--xml/src/test/java/tests/org/w3c/dom/DocumentTypePublicId.java97
-rw-r--r--xml/src/test/java/tests/org/w3c/dom/DocumentTypeSystemId.java95
-rw-r--r--xml/src/test/java/tests/org/w3c/dom/ElementGetAttributeNS.java89
-rw-r--r--xml/src/test/java/tests/org/w3c/dom/ElementGetAttributeNodeNS.java139
-rw-r--r--xml/src/test/java/tests/org/w3c/dom/ElementGetElementsByTagNameNS.java122
-rw-r--r--xml/src/test/java/tests/org/w3c/dom/ElementHasAttribute.java123
-rw-r--r--xml/src/test/java/tests/org/w3c/dom/ElementHasAttributeNS.java139
-rw-r--r--xml/src/test/java/tests/org/w3c/dom/ElementRemoveAttributeNS.java80
-rw-r--r--xml/src/test/java/tests/org/w3c/dom/ElementSetAttributeNS.java266
-rw-r--r--xml/src/test/java/tests/org/w3c/dom/ElementSetAttributeNodeNS.java276
-rw-r--r--xml/src/test/java/tests/org/w3c/dom/GetAttributeNS.java187
-rw-r--r--xml/src/test/java/tests/org/w3c/dom/GetAttributeNodeNS.java121
-rw-r--r--xml/src/test/java/tests/org/w3c/dom/GetElementById.java102
-rw-r--r--xml/src/test/java/tests/org/w3c/dom/GetElementsByTagNameNS.java381
-rw-r--r--xml/src/test/java/tests/org/w3c/dom/GetNamedItemNS.java135
-rw-r--r--xml/src/test/java/tests/org/w3c/dom/HCEntitiesRemoveNamedItemNS.java102
-rw-r--r--xml/src/test/java/tests/org/w3c/dom/HCEntitiesSetNamedItemNS.java86
-rw-r--r--xml/src/test/java/tests/org/w3c/dom/HCNamedNodeMapInvalidType.java103
-rw-r--r--xml/src/test/java/tests/org/w3c/dom/HCNodeDocumentFragmentNormalize.java108
-rw-r--r--xml/src/test/java/tests/org/w3c/dom/HCNotationsRemoveNamedItemNS.java110
-rw-r--r--xml/src/test/java/tests/org/w3c/dom/HCNotationsSetNamedItemNS.java112
-rw-r--r--xml/src/test/java/tests/org/w3c/dom/HasAttribute.java119
-rw-r--r--xml/src/test/java/tests/org/w3c/dom/HasAttributeNS.java172
-rw-r--r--xml/src/test/java/tests/org/w3c/dom/HasAttributes.java111
-rw-r--r--xml/src/test/java/tests/org/w3c/dom/ImportNode.java604
-rw-r--r--xml/src/test/java/tests/org/w3c/dom/InternalSubset.java92
-rw-r--r--xml/src/test/java/tests/org/w3c/dom/IsSupported.java272
-rw-r--r--xml/src/test/java/tests/org/w3c/dom/LocalName.java132
-rw-r--r--xml/src/test/java/tests/org/w3c/dom/NamedNodeMapGetNamedItemNS.java229
-rw-r--r--xml/src/test/java/tests/org/w3c/dom/NamedNodeMapRemoveNamedItemNS.java342
-rw-r--r--xml/src/test/java/tests/org/w3c/dom/NamedNodeMapSetNamedItemNS.java451
-rw-r--r--xml/src/test/java/tests/org/w3c/dom/NamespaceURI.java153
-rw-r--r--xml/src/test/java/tests/org/w3c/dom/NodeGetLocalName.java107
-rw-r--r--xml/src/test/java/tests/org/w3c/dom/NodeGetNamespaceURI.java111
-rw-r--r--xml/src/test/java/tests/org/w3c/dom/NodeGetOwnerDocument.java128
-rw-r--r--xml/src/test/java/tests/org/w3c/dom/NodeGetPrefix.java108
-rw-r--r--xml/src/test/java/tests/org/w3c/dom/NodeHasAttributes.java171
-rw-r--r--xml/src/test/java/tests/org/w3c/dom/NodeIsSupported.java216
-rw-r--r--xml/src/test/java/tests/org/w3c/dom/NodeNormalize.java209
-rw-r--r--xml/src/test/java/tests/org/w3c/dom/NodeSetPrefix.java314
-rw-r--r--xml/src/test/java/tests/org/w3c/dom/Normalize.java106
-rw-r--r--xml/src/test/java/tests/org/w3c/dom/OwnerDocument.java88
-rw-r--r--xml/src/test/java/tests/org/w3c/dom/OwnerElement.java118
-rw-r--r--xml/src/test/java/tests/org/w3c/dom/Prefix.java337
-rw-r--r--xml/src/test/java/tests/org/w3c/dom/PublicId.java91
-rw-r--r--xml/src/test/java/tests/org/w3c/dom/RemoveAttributeNS.java147
-rw-r--r--xml/src/test/java/tests/org/w3c/dom/RemoveNamedItemNS.java178
-rw-r--r--xml/src/test/java/tests/org/w3c/dom/SetAttributeNS.java353
-rw-r--r--xml/src/test/java/tests/org/w3c/dom/SetAttributeNodeNS.java237
-rw-r--r--xml/src/test/java/tests/org/w3c/dom/SetNamedItemNS.java248
-rw-r--r--xml/src/test/java/tests/org/w3c/dom/SystemId.java94
-rw-r--r--xml/src/test/java/tests/xml/AllTests.java38
-rw-r--r--xml/src/test/java/tests/xml/SimpleBuilderTest.java162
-rw-r--r--xml/src/test/java/tests/xml/SimpleParserTest.java289
-rw-r--r--xml/src/test/resources/SimpleBuilderTest.xml21
-rw-r--r--xml/src/test/resources/SimpleParserTest.xml19
-rw-r--r--xml/src/test/resources/hc_staff.xml60
-rw-r--r--xml/src/test/resources/nwf/staff.dtd17
-rw-r--r--xml/src/test/resources/nwf/staff.xml57
-rw-r--r--xml/src/test/resources/out_dh/staff.out45
-rw-r--r--xml/src/test/resources/out_hb/staff.out45
-rw-r--r--xml/src/test/resources/recipe.xml24
-rw-r--r--xml/src/test/resources/recipe1.xml24
-rw-r--r--xml/src/test/resources/recipt.dtd17
-rw-r--r--xml/src/test/resources/recipt.xml24
-rw-r--r--xml/src/test/resources/reciptWrong.xml21
-rw-r--r--xml/src/test/resources/simple.xml34
-rw-r--r--xml/src/test/resources/simple_ns.dtd45
-rw-r--r--xml/src/test/resources/simple_ns.xml59
-rw-r--r--xml/src/test/resources/staff.dtd17
-rw-r--r--xml/src/test/resources/staff.xml57
-rw-r--r--xml/src/test/resources/staff2.dtd24
-rw-r--r--xml/src/test/resources/staff2.xml13
-rw-r--r--xml/src/test/resources/staffEntRes.xml60
-rw-r--r--xml/src/test/resources/staffNS.dtd45
-rw-r--r--xml/src/test/resources/staffNS.xml59
-rw-r--r--xml/src/test/resources/systemid.xml24
-rw-r--r--xml/src/test/resources/systemid/recipt.dtd17
-rw-r--r--xml/src/test/resources/systemid/staff.dtd17
-rw-r--r--xml/src/test/resources/wf/staff.dtd17
-rw-r--r--xml/src/test/resources/wf/staff.xml57
-rw-r--r--xml/src/test/resources/wrong.xml1
-rw-r--r--xml/src/test/resources/xhtml1-strict.dtd65
264 files changed, 55779 insertions, 0 deletions
diff --git a/xml/MODULE_LICENSE_APACHE2 b/xml/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/xml/MODULE_LICENSE_APACHE2
diff --git a/xml/MODULE_LICENSE_BSD_LIKE b/xml/MODULE_LICENSE_BSD_LIKE
new file mode 100644
index 0000000..b56941c
--- /dev/null
+++ b/xml/MODULE_LICENSE_BSD_LIKE
@@ -0,0 +1 @@
+For KXML2.
diff --git a/xml/MODULE_LICENSE_W3C b/xml/MODULE_LICENSE_W3C
new file mode 100644
index 0000000..3f41106
--- /dev/null
+++ b/xml/MODULE_LICENSE_W3C
@@ -0,0 +1,3 @@
+For org.w3c.dom code.
+
+See <http://www.w3.org/Consortium/Legal/>.
diff --git a/xml/src/main/java/javax/xml/XMLConstants.java b/xml/src/main/java/javax/xml/XMLConstants.java
new file mode 100644
index 0000000..88fcdad
--- /dev/null
+++ b/xml/src/main/java/javax/xml/XMLConstants.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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;
+
+/**
+ * Defines several standard constants that are often used during XML processing.
+ *
+ * @since Android 1.0
+ */
+public class XMLConstants {
+
+ /**
+ * The default namespace prefix. Defined to be the empty string.
+ */
+ public static final String DEFAULT_NS_PREFIX = "";
+
+ /**
+ * The SAX feature name for secure processing. Turning on this feature
+ * might result in a parser rejecting XML documents that are considered
+ * "insecure" (having a potential for DOS attacks, for example). The
+ * Android XML parsing implementation currently ignores this feature.
+ */
+ public static final String FEATURE_SECURE_PROCESSING =
+ "http://javax.xml.XMLConstants/feature/secure-processing";
+
+ /**
+ * The namespace URI for the case that no namespace is being used at all.
+ * Defined to be the empty string.
+ */
+ public static final String NULL_NS_URI = "";
+
+ /**
+ * The official Relax-NG namespace URI.
+ */
+ public static final String RELAXNG_NS_URI =
+ "http://relaxng.org/ns/structure/1.0";
+
+ /**
+ * The official XSchema instance namespace URI, as defined by W3C.
+ */
+ public static final String W3C_XML_SCHEMA_INSTANCE_NS_URI =
+ "http://www.w3.org/2001/XMLSchema-instance";
+
+ /**
+ * The official XSchema namespace URI, as defined by W3C.
+ */
+ public static final String W3C_XML_SCHEMA_NS_URI =
+ "http://www.w3.org/2001/XMLSchema";
+
+ /**
+ * The official XPath datatype namespace URI, as defined by W3C.
+ */
+ public static final String W3C_XPATH_DATATYPE_NS_URI =
+ "http://www.w3.org/2003/11/xpath-datatypes";
+
+ /**
+ * The official XML namespace attribute, as defined by W3C.
+ */
+ public static final String XMLNS_ATTRIBUTE = "xmlns";
+
+ /**
+ * The official XML namespace attribute URI, as defined by W3C.
+ */
+ public static final String XMLNS_ATTRIBUTE_NS_URI =
+ "http://www.w3.org/2000/xmlns/";
+
+ /**
+ * The official XML DTD namespace URI, as defined by W3C.
+ */
+ public static final String XML_DTD_NS_URI = "http://www.w3.org/TR/REC-xml";
+
+ /**
+ * The official XML namespace prefix, as defined by W3C.
+ */
+ public static final String XML_NS_PREFIX = "xml";
+
+ /**
+ * The official XML namespace URI, as defined by W3C.
+ */
+ public static final String XML_NS_URI =
+ "http://www.w3.org/XML/1998/namespace";
+
+}
diff --git a/xml/src/main/java/javax/xml/package.html b/xml/src/main/java/javax/xml/package.html
new file mode 100644
index 0000000..5a4621d
--- /dev/null
+++ b/xml/src/main/java/javax/xml/package.html
@@ -0,0 +1,8 @@
+<html>
+ <body>
+ <p>
+ Provides a utility class with useful XML constants.
+ </p>
+ @since Android 1.0
+ </body>
+</html> \ No newline at end of file
diff --git a/xml/src/main/java/javax/xml/parsers/DocumentBuilder.java b/xml/src/main/java/javax/xml/parsers/DocumentBuilder.java
new file mode 100644
index 0000000..6fd6550
--- /dev/null
+++ b/xml/src/main/java/javax/xml/parsers/DocumentBuilder.java
@@ -0,0 +1,252 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.parsers;
+
+import org.w3c.dom.DOMImplementation;
+import org.w3c.dom.Document;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Defines a bridge from XML sources (files, stream etc.) to DOM trees. Can be
+ * used for easily obtaining a {@link org.w3c.dom.Document} for the input. The
+ * class itself is abstract. The class {@link DocumentBuilderFactory} is able to
+ * provide instances (of concrete subclasses known to the system).
+ *
+ * @since Android 1.0
+ */
+public abstract class DocumentBuilder {
+
+ /**
+ * Do-nothing constructor. Prevents instantiation. To be overridden by
+ * concrete subclasses.
+ *
+ * @since Android 1.0
+ */
+ protected DocumentBuilder() {
+ // Does nothing.
+ }
+
+ /**
+ * Queries the DOM implementation this {@code DocumentBuilder} is working
+ * on.
+ *
+ * @return the DOM implementation
+ *
+ * @since Android 1.0
+ */
+ public abstract DOMImplementation getDOMImplementation();
+
+// TODO No XSchema support in Android 1.0. Maybe later.
+// /**
+// * Queries the XML schema used by the DocumentBuilder.
+// *
+// * @return The XML schema
+// *
+// * @throws UnsupportedOperationException when the underlying implementation
+// * doesn't support XML schemas.
+// */
+// public javax.xml.validation.Schema getSchema() throws
+// UnsupportedOperationException {
+// throw new UnsupportedOperationException();
+// }
+
+ /**
+ * Queries whether the {@code DocumentBuilder} has namespace support
+ * enabled.
+ *
+ * @return {@code true} if namespaces are turned on, {@code false}
+ * otherwise.
+ *
+ * @since Android 1.0
+ */
+ public abstract boolean isNamespaceAware();
+
+ /**
+ * Queries whether the {@code DocumentBuilder} has validation support
+ * enabled.
+ *
+ * @return {@code true} if validation is turned on, {@code false} otherwise.
+ *
+ * @since Android 1.0
+ */
+ public abstract boolean isValidating();
+
+ /**
+ * Queries whether the {@code DocumentBuilder} has XInclude support enabled.
+ *
+ * @return {@code true} if XInclude support is turned on, {@code false}
+ * otherwise.
+ *
+ * @throws UnsupportedOperationException if the underlying implementation
+ * doesn't support XInclude.
+ *
+ * @since Android 1.0
+ */
+ public boolean isXIncludeAware() throws UnsupportedOperationException {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Creates a new, empty document, serving as the starting point for a DOM
+ * tree.
+ *
+ * @return the document.
+ *
+ * @since Android 1.0
+ */
+ public abstract Document newDocument();
+
+ /**
+ * Parses a given XML file and builds a DOM tree from it.
+ *
+ * @param file the file to be parsed.
+ * @return the document element that represents the root of the DOM tree.
+ *
+ * @throws SAXException if the XML parsing fails.
+ * @throws IOException if an input/output error occurs.
+ *
+ * @since Android 1.0
+ */
+ public Document parse(File file) throws SAXException, IOException {
+ if (file == null) {
+ throw new IllegalArgumentException();
+ }
+
+ return parse(new BufferedInputStream(new FileInputStream(file), 8192));
+ }
+
+ /**
+ * Parses a given XML input stream and builds a DOM tree from it.
+ *
+ * @param stream the stream to be parsed.
+ * @return the document element that represents the root of the DOM tree.
+ *
+ * @throws SAXException if the XML parsing fails.
+ * @throws IOException if an input/output error occurs.
+ *
+ * @since Android 1.0
+ */
+ public Document parse(InputStream stream) throws SAXException, IOException {
+ if (stream == null) {
+ throw new IllegalArgumentException();
+ }
+
+ return parse(new InputSource(stream));
+ }
+
+ /**
+ * Parses a given XML input stream and builds a DOM tree from it.
+ *
+ * @param stream the stream to be parsed.
+ * @param systemId the base for resolving relative URIs.
+ * @return the document element that represents the root of the DOM tree.
+ *
+ * @throws SAXException if the XML parsing fails.
+ * @throws IOException if an input/output error occurs.
+ *
+ * @since Android 1.0
+ */
+ public org.w3c.dom.Document parse(InputStream stream, String systemId)
+ throws SAXException, IOException {
+ if (stream == null) {
+ throw new IllegalArgumentException();
+ }
+
+ InputSource source = new InputSource(stream);
+ source.setSystemId(systemId);
+ return parse(source);
+ }
+
+ /**
+ * Parses an XML input stream from a given URI and builds a DOM tree from
+ * it.
+ *
+ * @param uri the URI to fetch the XML stream from.
+ * @return the document element that represents the root of the DOM tree.
+ *
+ * @throws SAXException if the XML parsing fails.
+ * @throws IOException if an input/output error occurs.
+ *
+ * @since Android 1.0
+ */
+ public org.w3c.dom.Document parse(String uri) throws SAXException,
+ IOException {
+ if (uri == null) {
+ throw new IllegalArgumentException();
+ }
+
+ return parse(new InputSource(uri));
+ }
+
+ /**
+ * Parses an XML input source and builds a DOM tree from it.
+ *
+ * @param source the input source to parse.
+ * @return the document element that represents the root of the DOM tree.
+ *
+ * @throws SAXException if the XML parsing fails.
+ * @throws IOException if an input/output error occurs.
+ *
+ * @since Android 1.0
+ */
+ public abstract org.w3c.dom.Document parse(InputSource source)
+ throws SAXException, IOException;
+
+ /**
+ * Resets the DocumentBuilder to the same state is was in after its
+ * creation.
+ *
+ * @since Android 1.0
+ */
+ public void reset() {
+ // Do nothing.
+ }
+
+ /**
+ * Sets the {@link EntityResolver} used for resolving entities encountered
+ * during the parse process. Passing {@code null} results in the
+ * {@code DocumentBuilder}'s own {@code EntityResolver} being used.
+ *
+ * @param resolver the {@code EntityResolver} to use, or null for the
+ * built-in one.
+ *
+ * @since Android 1.0
+ */
+ public abstract void setEntityResolver(EntityResolver resolver);
+
+ /**
+ * Sets the {@link ErrorHandler} used for dealing with errors encountered
+ * during the parse process. Passing {@code null} results in the
+ * {@code DocumentBuilder}'s own {@code ErrorHandler} being used.
+ *
+ * @param handler the {@code ErrorHandler} to use, or {@code null} for the
+ * built-in one.
+ *
+ * @since Android 1.0
+ */
+ public abstract void setErrorHandler(ErrorHandler handler);
+
+}
diff --git a/xml/src/main/java/javax/xml/parsers/DocumentBuilderFactory.java b/xml/src/main/java/javax/xml/parsers/DocumentBuilderFactory.java
new file mode 100644
index 0000000..4e186c1
--- /dev/null
+++ b/xml/src/main/java/javax/xml/parsers/DocumentBuilderFactory.java
@@ -0,0 +1,405 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.parsers;
+
+import org.apache.harmony.xml.parsers.DocumentBuilderFactoryImpl;
+
+/**
+ * Provides a factory for {@link DocumentBuilder} instances. The class first
+ * needs to be instantiated using the {@link #newInstance()} method. The
+ * instance can be configured as desired. A call to
+ * {@link #newDocumentBuilder()} then provides a {@code DocumentBuilder}
+ * instance matching this configuration (if possible).
+ *
+ * @since Android 1.0
+ */
+public abstract class DocumentBuilderFactory extends Object {
+
+ private boolean coalesce;
+
+ private boolean expandEntityReferences;
+
+ private boolean ignoreComments;
+
+ private boolean ignoreElementContentWhitespace;
+
+ private boolean namespaceAware;
+
+ private boolean validate;
+
+ /**
+ * Do-nothing constructor. To be overridden by concrete document builders.
+ *
+ * @since Android 1.0
+ */
+ protected DocumentBuilderFactory() {
+ // Does nothing.
+ }
+
+ /**
+ * Queries an attribute from the underlying implementation.
+ *
+ * @param name the name of the attribute.
+ * @return the value of the attribute.
+ *
+ * @throws IllegalArgumentException if the argument is unknown to the
+ * underlying implementation.
+ *
+ * @since Android 1.0
+ */
+ public abstract Object getAttribute(String name)
+ throws IllegalArgumentException;
+
+ /**
+ * Queries a feature from the underlying implementation.
+ *
+ * @param name The name of the feature. The default Android implementation
+ * of {@link DocumentBuilder} supports only the following three
+ * features:
+ *
+ * <dl>
+ * <dt>{@code http://xml.org/sax/features/namespaces}</dt>
+ * <dd>Queries the state of namespace-awareness.</dd>
+ *
+ * <dt>
+ * {@code http://xml.org/sax/features/namespace-prefixes}
+ * </dt>
+ * <dd>Queries the state of namespace prefix processing</dd>
+ *
+ * <dt>
+ * {@code http://xml.org/sax/features/validation}
+ * </dt>
+ * <dd>Queries the state of validation.</dd>
+ * </dl>
+ *
+ * Note that despite the ability to query the validation
+ * feature, there is currently no validating parser available.
+ * Also note that currently either namespaces or
+ * namespace prefixes can be enabled, but not both at the same
+ * time.
+ *
+ * @return the status of the feature.
+ *
+ * @throws IllegalArgumentException if the feature is unknown to
+ * the underlying implementation.
+ * @throws ParserConfigurationException if the feature is
+ * known, but not supported.
+ *
+ * @since Android 1.0
+ */
+ public abstract boolean getFeature(String name)
+ throws ParserConfigurationException;
+
+// TODO No XSchema support in Android 1.0. Maybe later.
+// /**
+// * Queries the desired XML Schema object.
+// *
+// * @return The XML Schema object, if it has been set by a call to setSchema,
+// * or null otherwise.
+// */
+// public javax.xml.validation.Schema getSchema() {
+// return schema;
+// }
+
+ /**
+ * Queries whether the factory is configured to deliver parsers that convert
+ * CDATA nodes to text nodes and melt them with neighboring nodes. This is
+ * called "coalescing".
+ *
+ * @return {@code true} if coalescing is desired, {@code false} otherwise.
+ *
+ * @since Android 1.0
+ */
+ public boolean isCoalescing() {
+ return coalesce;
+ }
+
+ /**
+ * Queries whether the factory is configured to deliver parsers that expand
+ * entity references.
+ *
+ * @return {@code true} if entity expansion is desired, {@code false}
+ * otherwise.
+ *
+ * @since Android 1.0
+ */
+ public boolean isExpandEntityReferences() {
+ return expandEntityReferences;
+ }
+
+ /**
+ * Queries whether the factory is configured to deliver parsers that ignore
+ * comments.
+ *
+ * @return {@code true} if comment ignorance is desired, {@code false}
+ * otherwise.
+ *
+ * @since Android 1.0
+ */
+ public boolean isIgnoringComments() {
+ return ignoreComments;
+ }
+
+ /**
+ * Queries whether the factory is configured to deliver parsers that ignore
+ * whitespace in elements.
+ *
+ * @return {@code true} if whitespace ignorance is desired, {@code false}
+ * otherwise.
+ *
+ * @since Android 1.0
+ */
+ public boolean isIgnoringElementContentWhitespace() {
+ return ignoreElementContentWhitespace;
+ }
+
+ /**
+ * Queries whether the factory is configured to deliver parsers that are
+ * namespace-aware.
+ *
+ * @return {@code true} if namespace-awareness is desired, {@code false}
+ * otherwise.
+ *
+ * @since Android 1.0
+ */
+ public boolean isNamespaceAware() {
+ return namespaceAware;
+ }
+
+ /**
+ * Queries whether the factory is configured to deliver parsers that are
+ * validating.
+ *
+ * @return {@code true} if validating is desired, {@code false} otherwise.
+ *
+ * @since Android 1.0
+ */
+ public boolean isValidating() {
+ return validate;
+ }
+
+ /**
+ * Queries whether the factory is configured to deliver parsers that are
+ * XInclude-aware.
+ *
+ * @return {@code true} if XInclude-awareness is desired, {@code false}
+ * otherwise.
+ *
+ * @since Android 1.0
+ */
+ public boolean isXIncludeAware() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Creates a new {@link DocumentBuilder} that matches the current
+ * configuration of the factory.
+ *
+ * @return the DocumentBuilder.
+ * @throws ParserConfigurationException if no matching
+ * {@code DocumentBuilder} could be found.
+ *
+ * @since Android 1.0
+ */
+ public abstract DocumentBuilder newDocumentBuilder()
+ throws ParserConfigurationException;
+
+ /**
+ * Creates a new DocumentBuilderFactory that can be configured and then be
+ * used for creating DocumentBuilder objects. The method first checks the
+ * value of the {@code DocumentBuilderFactory} property.
+ * If this is non-{@code null}, it is assumed to be the name of a class
+ * that serves as the factory. The class is instantiated, and the instance
+ * is returned. If the property value is {@code null}, the system's default
+ * factory implementation is returned.
+ *
+ * @return the DocumentBuilderFactory.
+ * @throws FactoryConfigurationError if no {@code DocumentBuilderFactory}
+ * can be created.
+ *
+ * @since Android 1.0
+ */
+ public static DocumentBuilderFactory newInstance()
+ throws FactoryConfigurationError {
+ // TODO Properties file and META-INF case missing here. See spec.
+ String factory = System
+ .getProperty("javax.xml.parsers.DocumentBuilderFactory");
+ if (factory != null) {
+ try {
+ return (DocumentBuilderFactory) Class.forName(factory)
+ .newInstance();
+ } catch (Exception ex) {
+ // Ignore.
+ }
+ }
+
+ try {
+ return new DocumentBuilderFactoryImpl();
+ } catch (Exception ex) {
+ // Ignore.
+ }
+
+ throw new FactoryConfigurationError(
+ "Cannot create DocumentBuilderFactory");
+ }
+
+ /**
+ * Sets an attribute in the underlying implementation.
+ *
+ * @param name the name of the attribute.
+ * @param value the value of the attribute.
+ *
+ * @throws IllegalArgumentException if the argument is unknown to the
+ * underlying implementation.
+ *
+ * @since Android 1.0
+ */
+ public abstract void setAttribute(String name, Object value)
+ throws IllegalArgumentException;
+
+ /**
+ * Determines whether the factory is configured to deliver parsers that
+ * convert CDATA nodes to text nodes and melt them with neighboring nodes.
+ * This is called "coalescing".
+ *
+ * @param value turns coalescing on or off.
+ *
+ * @since Android 1.0
+ */
+ public void setCoalescing(boolean value) {
+ coalesce = value;
+ }
+
+ /**
+ * Determines whether the factory is configured to deliver parsers that
+ * expands entity references.
+ *
+ * @param value turns entity reference expansion on or off.
+ *
+ * @since Android 1.0
+ */
+ public void setExpandEntityReferences(boolean value) {
+ expandEntityReferences = value;
+ }
+
+ /**
+ * Sets a feature in the underlying implementation.
+ *
+ * @param name the name of the feature. The default Android implementation
+ * of {@link DocumentBuilder} supports only the following three
+ * features:
+ *
+ * <dl>
+ * <dt>{@code http://xml.org/sax/features/namespaces}</dt>
+ * <dd>Sets the state of namespace-awareness.</dd>
+ *
+ * <dt>
+ * {@code http://xml.org/sax/features/namespace-prefixes}
+ * </dt>
+ * <dd>Sets the state of namespace prefix processing</dd>
+ *
+ * <dt>{@code http://xml.org/sax/features/validation}</dt>
+ * <dd>Sets the state of validation.</dd>
+ * </dl>
+ *
+ * Note that despite the ability to set the validation
+ * feature, there is currently no validating parser available.
+ * Also note that currently either namespaces or
+ * namespace prefixes can be enabled, but not both at the same
+ * time.
+ *
+ * @param value the value of the feature.
+ *
+ * @throws ParserConfigurationException if the feature is unknown to the
+ * underlying implementation.
+ *
+ * @since Android 1.0
+ */
+ public abstract void setFeature(String name, boolean value)
+ throws ParserConfigurationException;
+
+ /**
+ * Determines whether the factory is configured to deliver parsers that
+ * ignore comments.
+ *
+ * @param value turns comment ignorance on or off.
+ *
+ * @since Android 1.0
+ */
+ public void setIgnoringComments(boolean value) {
+ ignoreComments = value;
+ }
+
+ /**
+ * Determines whether the factory is configured to deliver parsers that
+ * ignores element whitespace.
+ *
+ * @param value turns element whitespace ignorance on or off.
+ *
+ * @since Android 1.0
+ */
+ public void setIgnoringElementContentWhitespace(boolean value) {
+ ignoreElementContentWhitespace = value;
+ }
+
+ /**
+ * Determines whether the factory is configured to deliver parsers that are
+ * namespace-aware.
+ *
+ * @param value turns namespace-awareness on or off.
+ *
+ * @since Android 1.0
+ */
+ public void setNamespaceAware(boolean value) {
+ namespaceAware = value;
+ }
+
+// TODO No XSchema support in Android 1.0. Maybe later.
+// /**
+// * Sets the desired XML Schema object.
+// *
+// * @param schema The XML Schema object.
+// */
+// public void setSchema(Schema schema) {
+// this.schema = schema;
+// }
+
+ /**
+ * Determines whether the factory is configured to deliver parsers that are
+ * validating.
+ *
+ * @param value turns validation on or off.
+ *
+ * @since Android 1.0
+ */
+ public void setValidating(boolean value) {
+ validate = value;
+ }
+
+ /**
+ * Determines whether the factory is configured to deliver parsers that are
+ * XInclude-aware.
+ *
+ * @param value turns XInclude-awareness on or off.
+ *
+ * @since Android 1.0
+ */
+ public void setXIncludeAware(boolean value) {
+ throw new UnsupportedOperationException();
+ }
+
+}
diff --git a/xml/src/main/java/javax/xml/parsers/FactoryConfigurationError.java b/xml/src/main/java/javax/xml/parsers/FactoryConfigurationError.java
new file mode 100644
index 0000000..f5e0c03
--- /dev/null
+++ b/xml/src/main/java/javax/xml/parsers/FactoryConfigurationError.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.parsers;
+
+/**
+ * Represents an error that occurred during the configuration of parser factory.
+ *
+ * @since Android 1.0
+ */
+public class FactoryConfigurationError extends Error {
+
+ /**
+ * The nested exception that caused this exception. Note that the nested
+ * exception will be stored in a special attribute, and can be queried using
+ * the {@link #getException()} method. It does not use the facility the
+ * {@link Exception} class provides for storing nested exceptions, since the
+ * XML API predates that facility.
+ */
+ private Exception cause;
+
+ /**
+ * Creates a new {@code FactoryConfigurationError} with no error message and
+ * no cause.
+ *
+ * @since Android 1.0
+ */
+ public FactoryConfigurationError() {
+ super();
+ }
+
+ /**
+ * Creates a new {@code FactoryConfigurationError} with no error message and
+ * a given cause.
+ *
+ * @param cause the cause of the error. Note that the nested exception will
+ * be stored in a special attribute, and can be queried using the
+ * {@link #getException()} method. It does not use the facility the
+ * Exception class provides for storing nested exceptions, since the
+ * XML API predates that facility.
+ *
+ * @since Android 1.0
+ */
+ public FactoryConfigurationError(Exception cause) {
+ super();
+ this.cause = cause;
+ }
+
+ /**
+ * Creates a new {@code FactoryConfigurationError} with a given error
+ * message and cause.
+ *
+ * @param cause the cause of the error. Note that the nested exception will
+ * be stored in a special attribute, and can be queried using the
+ * {@link #getException()} method. It does not use the facility the
+ * {@link Exception} class provides for storing nested exceptions,
+ * since the XML API predates that facility.
+ * @param message The error message.
+ *
+ * @since Android 1.0
+ */
+ public FactoryConfigurationError(Exception cause, String message) {
+ super(message);
+ this.cause = cause;
+ }
+
+ /**
+ * Creates a new {@code FactoryConfigurationError} with a given error
+ * message and no cause.
+ *
+ * @param message the error message.
+ *
+ * @since Android 1.0
+ */
+ public FactoryConfigurationError(String message) {
+ super(message);
+ }
+
+ /**
+ * Returns the cause of the error, in case there is one.
+ *
+ * @return the exception that caused the error, or {@code null} if none is
+ * set.
+ *
+ * @since Android 1.0
+ */
+ public Exception getException() {
+ return cause;
+ }
+
+ /**
+ * Returns the message of the error, in case there is one.
+ *
+ * @return the message. If an explicit error message has been assigned to
+ * the exception, this one is returned. If not, and there is an
+ * underlying exception (the cause), then the result of invoking
+ * {@link #toString()} on that object is returned. Otherwise, {@code
+ * null} is returned.
+ *
+ * @since Android 1.0
+ */
+ public String getMessage() {
+ String message = super.getMessage();
+
+ if (message != null) {
+ return message;
+ } else if (cause != null) {
+ return cause.toString();
+ } else {
+ return null;
+ }
+ }
+}
diff --git a/xml/src/main/java/javax/xml/parsers/ParserConfigurationException.java b/xml/src/main/java/javax/xml/parsers/ParserConfigurationException.java
new file mode 100644
index 0000000..49875d6
--- /dev/null
+++ b/xml/src/main/java/javax/xml/parsers/ParserConfigurationException.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.parsers;
+
+/**
+ * Represents an exception that occurred during the configuration of parser.
+ *
+ * @since Android 1.0
+ */
+public class ParserConfigurationException extends Exception {
+
+ /**
+ * Creates a new {@code ParserConfigurationException} with no error message.
+ *
+ * @since Android 1.0
+ */
+ public ParserConfigurationException() {
+ super();
+ }
+
+ /**
+ * Creates a new {@code ParserConfigurationException} with a given error
+ * message.
+ *
+ * @param msg the error message.
+ *
+ * @since Android 1.0
+ */
+ public ParserConfigurationException(String msg) {
+ super(msg);
+ }
+
+}
diff --git a/xml/src/main/java/javax/xml/parsers/SAXParser.java b/xml/src/main/java/javax/xml/parsers/SAXParser.java
new file mode 100644
index 0000000..73cc0eb
--- /dev/null
+++ b/xml/src/main/java/javax/xml/parsers/SAXParser.java
@@ -0,0 +1,390 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.parsers;
+
+import org.xml.sax.HandlerBase;
+import org.xml.sax.InputSource;
+import org.xml.sax.Parser;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXNotRecognizedException;
+import org.xml.sax.SAXNotSupportedException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.DefaultHandler;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Provides a wrapper around a SAX {@link XMLReader}. This abstract
+ * class only defines the interface, whereas the {@link SAXParserFactory} class
+ * is used to obtain instances of concrete subclasses.
+ *
+ * @since Android 1.0
+ */
+public abstract class SAXParser extends java.lang.Object {
+
+ /**
+ * Do-nothing constructor. Prevents instantiation. To be overridden by
+ * concrete subclasses.
+ *
+ * @since Android 1.0
+ */
+ protected SAXParser() {
+ // Does nothing.
+ }
+
+ /**
+ * Queries the underlying SAX {@link Parser} object.
+ *
+ * @return the SAX {@code Parser}.
+ *
+ * @throws SAXException if a problem occurs.
+ *
+ * @since Android 1.0
+ */
+ public abstract Parser getParser()
+ throws SAXException;
+
+ /**
+ * Queries a property of the underlying SAX {@link XMLReader}.
+ *
+ * @param name the name of the property.
+ * @return the value of the property.
+ *
+ * @throws SAXNotRecognizedException if the property is not known to the
+ * underlying SAX {@code XMLReader}.
+ * @throws SAXNotSupportedException if the property is known, but not
+ * supported by the underlying SAX {@code XMLReader}.
+ *
+ * @since Android 1.0
+ */
+ public abstract Object getProperty(String name)
+ throws SAXNotRecognizedException, SAXNotSupportedException;
+
+// TODO No XSchema support in Android 1.0. Maybe later.
+// /**
+// * Queries the XML Schema used by the underlying XMLReader.
+// *
+// * @return The XML Schema.
+// */
+// public Schema getSchema() {
+// return schema;
+// }
+
+ /**
+ * Queries the underlying SAX XMLReader object.
+ *
+ * @return the SAX XMLREader.
+ *
+ * @throws SAXException if a problem occurs.
+ *
+ * @since Android 1.0
+ */
+ public abstract XMLReader getXMLReader() throws SAXException;
+
+ /**
+ * Reflects whether this {@code SAXParser} is namespace-aware.
+ *
+ * @return {@code true} if the {@code SAXParser} is namespace-aware, or
+ * {@code false} otherwise.
+ *
+ * @since Android 1.0
+ */
+ public abstract boolean isNamespaceAware();
+
+ /**
+ * Reflects whether this {@code SAXParser} is validating.
+ *
+ * @return {@code true} if the {@code SAXParser} is validating, or {@code
+ * false} otherwise.
+ *
+ * @since Android 1.0
+ */
+ public abstract boolean isValidating();
+
+ /**
+ * Reflects whether this {@code SAXParser} is XInclude-aware.
+ *
+ * @return {@code true} if the {@code SAXParser} is XInclude-aware, or
+ * {@code false} otherwise.
+ *
+ * @throws UnsupportedOperationException if the underlying implementation
+ * doesn't know about XInclude at all (backwards compatibility).
+ *
+ * @since Android 1.0
+ */
+ public boolean isXIncludeAware() throws UnsupportedOperationException {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Parses the given XML file using the given SAX event handler.
+ *
+ * @param file the file containing the XML document.
+ * @param handler the SAX handler.
+ *
+ * @throws SAXException if a problem occurs during SAX parsing.
+ * @throws IOException if a general IO problem occurs.
+ *
+ * @since Android 1.0
+ */
+ public void parse(File file, HandlerBase handler) throws SAXException,
+ IOException {
+ if (file == null) {
+ throw new IllegalArgumentException("file must not be null");
+ }
+ if (file.isDirectory()) {
+ throw new IllegalArgumentException("file must not be a directory");
+ }
+ InputSource source = new InputSource("file:" + file.getAbsolutePath());
+ parse(source, handler);
+ }
+
+ /**
+ * Parses the given XML file using the given SAX event handler.
+ *
+ * @param file the file containing the XML document.
+ * @param handler the SAX handler.
+ *
+ * @throws SAXException if a problem occurs during SAX parsing.
+ * @throws IOException if a general IO problem occurs.
+ *
+ * @since Android 1.0
+ */
+ public void parse(File file, DefaultHandler handler) throws SAXException,
+ IOException {
+ if (file == null) {
+ throw new IllegalArgumentException("file must not be null");
+ }
+ if (file.isDirectory()) {
+ throw new IllegalArgumentException("file must not be a directory");
+ }
+ InputSource source = new InputSource("file:" + file.getAbsolutePath());
+ parse(source, handler);
+ }
+
+ /**
+ * Parses the given XML InputStream using the given SAX event handler.
+ *
+ * @param stream the InputStream containing the XML document.
+ * @param handler the SAX handler.
+ *
+ * @throws SAXException if a problem occurs during SAX parsing.
+ * @throws IOException if a general IO problem occurs.
+ *
+ * @since Android 1.0
+ */
+ public void parse(InputStream stream, HandlerBase handler)
+ throws SAXException, IOException {
+ if (stream == null) {
+ throw new IllegalArgumentException("stream must not be null");
+ }
+ parse(new InputSource(stream), handler);
+ }
+
+ /**
+ * Parses the given XML InputStream using the given SAX event handler and
+ * system ID.
+ *
+ * @param stream the InputStream containing the XML document.
+ * @param handler the SAX handler.
+ * @param systemId the system ID.
+ *
+ * @throws SAXException if a problem occurs during SAX parsing.
+ * @throws IOException if a general IO problem occurs.
+ *
+ * @since Android 1.0
+ */
+ public void parse(InputStream stream, HandlerBase handler, String systemId)
+ throws SAXException, IOException {
+ if (stream == null) {
+ throw new IllegalArgumentException("stream must not be null");
+ }
+ InputSource source = new InputSource(stream);
+ if (systemId != null) {
+ source.setSystemId(systemId);
+ }
+ parse(source, handler);
+ }
+
+ /**
+ * Parses the given XML InputStream using the given SAX event handler.
+ *
+ * @param stream the InputStream containing the XML document.
+ * @param handler the SAX handler.
+ *
+ * @throws SAXException if a problem occurs during SAX parsing.
+ * @throws IOException if a general IO problem occurs.
+ *
+ * @since Android 1.0
+ */
+ public void parse(InputStream stream, DefaultHandler handler)
+ throws SAXException, IOException {
+ parse(new InputSource(stream), handler);
+ }
+
+ /**
+ * Parses the given XML InputStream using the given SAX event handler and
+ * system ID.
+ *
+ * @param stream the InputStream containing the XML document.
+ * @param handler the SAX handler.
+ * @param systemId the system ID.
+ *
+ * @throws SAXException if a problem occurs during SAX parsing.
+ * @throws IOException if a general IO problem occurs.
+ *
+ * @since Android 1.0
+ */
+ public void parse(InputStream stream, DefaultHandler handler,
+ String systemId) throws SAXException, IOException {
+ if (stream == null) {
+ throw new IllegalArgumentException("stream must not be null");
+ }
+ InputSource source = new InputSource(stream);
+ if (systemId != null) {
+ source.setSystemId(systemId);
+ }
+ parse(source, handler);
+ }
+
+ /**
+ * Parses the contents of the given URI using the given SAX event handler.
+ *
+ * @param uri the URI pointing to the XML document.
+ * @param handler the SAX handler.
+ *
+ * @throws SAXException if a problem occurs during SAX parsing.
+ * @throws IOException if a general IO problem occurs.
+ *
+ * @since Android 1.0
+ */
+ public void parse(String uri, HandlerBase handler) throws SAXException,
+ IOException {
+ if (uri == null) {
+ throw new IllegalArgumentException("uri must not be null");
+ }
+ parse(new InputSource(uri), handler);
+ }
+
+ /**
+ * Parses the contents of the given URI using the given SAX event handler.
+ *
+ * @param uri the URI pointing to the XML document.
+ * @param handler the SAX handler.
+ *
+ * @throws SAXException if a problem occurs during SAX parsing.
+ * @throws IOException if a general IO problem occurs.
+ *
+ * @since Android 1.0
+ */
+ public void parse(String uri, DefaultHandler handler) throws SAXException,
+ IOException {
+ if (uri == null) {
+ throw new IllegalArgumentException("uri must not be null");
+ }
+ parse(new InputSource(uri), handler);
+ }
+
+ /**
+ * Parses the given SAX {@link InputSource} using the given SAX event
+ * handler.
+ *
+ * @param source the SAX {@code InputSource} containing the XML document.
+ * @param handler the SAX handler.
+ *
+ * @throws SAXException if a problem occurs during SAX parsing.
+ * @throws IOException if a general IO problem occurs.
+ *
+ * @since Android 1.0
+ */
+ public void parse(InputSource source, HandlerBase handler)
+ throws SAXException, IOException {
+ Parser parser = getParser();
+ if (source == null) {
+ throw new IllegalArgumentException("source must not be null");
+ }
+
+ if (handler != null) {
+ parser.setDocumentHandler(handler);
+ parser.setDTDHandler(handler);
+ parser.setEntityResolver(handler);
+ parser.setErrorHandler(handler);
+ }
+
+ parser.parse(source);
+ }
+
+ /**
+ * Parses the given SAX {@link InputSource} using the given SAX event
+ * handler.
+ *
+ * @param source the SAX {@code InputSource} containing the XML document.
+ * @param handler the SAX handler.
+ *
+ * @throws SAXException if a problem occurs during SAX parsing.
+ * @throws IOException if a general IO problem occurs.
+ *
+ * @since Android 1.0
+ */
+ public void parse(InputSource source, DefaultHandler handler)
+ throws SAXException, IOException {
+ if (source == null) {
+ throw new IllegalArgumentException("source must not be null");
+ }
+ XMLReader reader = getXMLReader();
+
+ if (handler != null) {
+ reader.setContentHandler(handler);
+ reader.setDTDHandler(handler);
+ reader.setEntityResolver(handler);
+ reader.setErrorHandler(handler);
+ }
+
+ reader.parse(source);
+ }
+
+ /**
+ * Resets the {@code SAXParser} to the same state is was in after its
+ * creation.
+ *
+ * @since Android 1.0
+ */
+ public void reset() {
+ // Do nothing.
+ }
+
+ /**
+ * Sets a property of the underlying SAX {@link XMLReader}.
+ *
+ * @param name the name of the property.
+ * @param value the value of the property.
+ *
+ * @throws SAXNotRecognizedException if the property is not known to the
+ * underlying SAX {@code XMLReader}.
+ * @throws SAXNotSupportedException if the property is known, but not
+ * supported by the underlying SAX {@code XMLReader}.
+ *
+ * @since Android 1.0
+ */
+ public abstract void setProperty(String name, Object value)
+ throws SAXNotRecognizedException, SAXNotSupportedException;
+
+}
diff --git a/xml/src/main/java/javax/xml/parsers/SAXParserFactory.java b/xml/src/main/java/javax/xml/parsers/SAXParserFactory.java
new file mode 100644
index 0000000..ebf0531
--- /dev/null
+++ b/xml/src/main/java/javax/xml/parsers/SAXParserFactory.java
@@ -0,0 +1,283 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.parsers;
+
+import org.apache.harmony.xml.parsers.SAXParserFactoryImpl;
+
+import org.xml.sax.SAXNotRecognizedException;
+import org.xml.sax.SAXNotSupportedException;
+import org.xml.sax.SAXException;
+
+/**
+ * Provides a factory for {@link SAXParser} instances. The class first needs to
+ * be instantiated using the {@link #newInstance()} method. The instance can be
+ * configured as desired. A call to its {@link #newSAXParser()} then provides a
+ * {@code SAXParser} instance matching this configuration, if possible.
+ *
+ * @since Android 1.0
+ */
+public abstract class SAXParserFactory {
+
+ private boolean namespaceAware;
+
+ private boolean validating;
+
+ private boolean xincludeAware;
+
+ /**
+ * Do-nothing constructor. Prevents instantiation. To be overridden by
+ * concrete subclasses.
+ *
+ * @since Android 1.0
+ */
+ protected SAXParserFactory() {
+ // Does nothing.
+ }
+
+ /**
+ * Queries a feature from the underlying implementation.
+ *
+ * @param name The name of the feature. The default Android implementation
+ * of {@link SAXParser} supports only the following three
+ * features:
+ *
+ * <dl>
+ * <dt>{@code http://xml.org/sax/features/namespaces}</dt>
+ * <dd>Queries the state of namespace-awareness.</dd>
+ *
+ * <dt>
+ * {@code http://xml.org/sax/features/namespace-prefixes}
+ * </dt>
+ * <dd>Queries the state of namespace prefix processing</dd>
+ *
+ * <dt>{@code http://xml.org/sax/features/validation}</dt>
+ * <dd>Queries the state of validation.</dd>
+ * </dl>
+ *
+ * Note that despite the ability to query the validation
+ * feature, there is currently no validating parser available.
+ * Also note that currently either namespaces or
+ * namespace prefixes can be enabled, but not both at the same
+ * time.
+ *
+ * @return the status of the feature.
+ *
+ * @throws ParserConfigurationException if no {@code SAXParser} matching the
+ * given criteria is available.
+ * @throws SAXNotRecognizedException if the given feature is not known to
+ * the underlying implementation.
+ * @throws SAXNotSupportedException if the given features is known, but not
+ * supported by the underlying implementation.
+ *
+ * @since Android 1.0
+ */
+ public abstract boolean getFeature(String name)
+ throws ParserConfigurationException, SAXNotRecognizedException,
+ SAXNotSupportedException;
+
+// TODO No XSchema support in Android 1.0. Maybe later.
+// /**
+// * Queries the desired XML Schema object.
+// *
+// * @return The XML Schema object, if it has been set by a call to setSchema,
+// * or null otherwise.
+// */
+// public javax.xml.validation.Schema getSchema() {
+// return schema;
+// }
+
+ /**
+ * Queries whether the factory is configured to deliver parsers that are
+ * namespace-aware.
+ *
+ * @return {@code true} if namespace-awareness is desired, {@code false}
+ * otherwise.
+ *
+ * @since Android 1.0
+ */
+ public boolean isNamespaceAware() {
+ return namespaceAware;
+ }
+
+ /**
+ * Queries whether the factory is configured to deliver parsers that are
+ * validating.
+ *
+ * @return {@code true} if validating is desired, {@code false} otherwise.
+ *
+ * @since Android 1.0
+ */
+ public boolean isValidating() {
+ return validating;
+ }
+
+ /**
+ * Queries whether the factory is configured to deliver parsers that are
+ * XInclude-aware.
+ *
+ * @return {@code true} if XInclude-awareness is desired, {@code false}
+ * otherwise.
+ *
+ * @since Android 1.0
+ */
+ public boolean isXIncludeAware() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Creates a new {@code SAXParserFactory} that can be configured and then be
+ * used for creating {@link SAXParser} objects. The method first checks the
+ * value of the {@code SAXParserFactory} property. If this
+ * is non-{@code null}, it is assumed to be the name of a class that serves
+ * as the factory. The class is instantiated, and the instance is returned.
+ * If the property value is {@code null}, the system's default factory
+ * implementation is returned.
+ *
+ * @return the {@code SAXParserFactory}.
+ *
+ * @throws FactoryConfigurationError if no {@code SAXParserFactory} can be
+ * created.
+ *
+ * @since Android 1.0
+ */
+ public static SAXParserFactory newInstance()
+ throws FactoryConfigurationError {
+ // TODO Properties file and META-INF case missing here. See spec.
+ String factory = System
+ .getProperty("javax.xml.parsers.SAXParserFactory");
+ if (factory != null) {
+ try {
+ return (SAXParserFactory) Class.forName(factory).newInstance();
+ } catch (Exception ex) {
+ throw new FactoryConfigurationError(factory);
+ }
+ }
+
+ try {
+ return new SAXParserFactoryImpl();
+ } catch (Exception ex) {
+ // Ignore.
+ }
+
+ throw new FactoryConfigurationError("Cannot create SAXParserFactory");
+ }
+
+ /**
+ * Creates a new {@link SAXParser} that matches the current configuration of
+ * the factory.
+ *
+ * @return the {@code SAXParser}.
+ *
+ * @throws ParserConfigurationException if no matching {@code SAXParser}
+ * could be found.
+ * @throws SAXException if creating the {@code SAXParser} failed due to some
+ * other reason.
+ *
+ * @since Android 1.0
+ */
+ public abstract SAXParser newSAXParser()
+ throws ParserConfigurationException, SAXException;
+
+ /**
+ * Sets a feature in the underlying implementation.
+ *
+ * @param name the name of the feature. The default Android implementation
+ * of {@link SAXParser} supports only the following three
+ * features:
+ *
+ * <dl>
+ * <dt>{@code http://xml.org/sax/features/namespaces}</dt>
+ * <dd>Sets the state of namespace-awareness.</dd>
+ *
+ * <dt>
+ * {@code http://xml.org/sax/features/namespace-prefixes}
+ * </dt>
+ * <dd>Sets the state of namespace prefix processing</dd>
+ *
+ * <dt>{@code http://xml.org/sax/features/validation}</dt>
+ * <dd>Sets the state of validation.</dd>
+ * </dl>
+ *
+ * Note that despite the ability to query the validation
+ * feature, there is currently no validating parser available.
+ * Also note that currently either namespaces or
+ * namespace prefixes can be enabled, but not both at the same
+ * time.
+ *
+ * @param value the status of the feature.
+ *
+ * @throws ParserConfigurationException if no {@code SAXParser} matching
+ * the given criteria is available.
+ * @throws SAXNotRecognizedException if the given feature is not known to
+ * the underlying implementation.
+ * @throws SAXNotSupportedException if the given features is known, but not
+ * supported by the underlying implementation.
+ *
+ * @since Android 1.0
+ */
+ public abstract void setFeature(String name, boolean value)
+ throws ParserConfigurationException, SAXNotRecognizedException,
+ SAXNotSupportedException;
+
+ /**
+ * Determines whether the factory is configured to deliver parsers that are
+ * namespace-aware.
+ *
+ * @param value turns namespace-awareness on or off.
+ *
+ * @since Android 1.0
+ */
+ public void setNamespaceAware(boolean value) {
+ namespaceAware = value;
+ }
+
+// TODO No XSchema support in Android 1.0. Maybe later.
+// /**
+// * Sets the desired XML Schema object.
+// *
+// * @param schema The XML Schema object.
+// */
+// public void setSchema(Schema schema) {
+// this.schema = schema;
+// }
+
+ /**
+ * Determines whether the factory is configured to deliver parsers that are
+ * validating.
+ *
+ * @param value turns validation on or off.
+ *
+ * @since Android 1.0
+ */
+ public void setValidating(boolean value) {
+ validating = value;
+ }
+
+ /**
+ * Determines whether the factory is configured to deliver parsers that are
+ * XInclude-aware.
+ *
+ * @param value turns XInclude-awareness on or off.
+ *
+ * @since Android 1.0
+ */
+ public void setXIncludeAware(boolean value) {
+ throw new UnsupportedOperationException();
+ }
+
+}
+
diff --git a/xml/src/main/java/javax/xml/parsers/package.html b/xml/src/main/java/javax/xml/parsers/package.html
new file mode 100644
index 0000000..7e0921d
--- /dev/null
+++ b/xml/src/main/java/javax/xml/parsers/package.html
@@ -0,0 +1,24 @@
+<html>
+ <body>
+ <p>
+ Provides facilities for parsing XML documents and building Document Object
+ Model (DOM) trees from them. The
+ {@link javax.xml.parsers.SAXParserFactory} class serves as an entry point
+ to event-based XML parsing. The
+ {@link javax.xml.parsers.DocumentBuilderFactory} class is an entry point
+ for dealing with DOM trees. Both factories are usually configured
+ before their factory methods are invoked. They then try to create a
+ {@link javax.xml.parsers.SAXParser} or a
+ {@link javax.xml.parsers.DocumentBuilder} (respectively) suiting the
+ application's needs. If none can be found, an Exception is thrown.
+ </p>
+ <p>
+ Note that in order to cater for resource-constrained environments,
+ Android's XML packages currently only provide DOM Level 2 Core support
+ and a non-validating parser. This means that (a) the interface for the
+ various DOM classes might differ from other implementations and (b)
+ requesting a validating parser will always fail.
+ </p>
+ @since Android 1.0
+ </body>
+</html> \ No newline at end of file
diff --git a/xml/src/main/java/org/apache/harmony/xml/ExpatAttributes.java b/xml/src/main/java/org/apache/harmony/xml/ExpatAttributes.java
new file mode 100644
index 0000000..ed6cb11
--- /dev/null
+++ b/xml/src/main/java/org/apache/harmony/xml/ExpatAttributes.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xml;
+
+import org.xml.sax.Attributes;
+
+/**
+ * Wraps native attribute array.
+ */
+abstract class ExpatAttributes implements Attributes {
+
+ /**
+ * Since we don't do validation, pretty much everything is CDATA type.
+ */
+ private static final String CDATA = "CDATA";
+
+ /**
+ * Gets the number of attributes.
+ */
+ public abstract int getLength();
+
+ /**
+ * Gets the pointer to the parser. We need this so we can get to the
+ * interned string pool.
+ */
+ abstract int getParserPointer();
+
+ /**
+ * Gets the pointer to the underlying attribute array. Can be 0 if the
+ * length is 0.
+ */
+ public abstract int getPointer();
+
+ public String getURI(int index) {
+ if (index < 0 || index >= getLength()) {
+ return null;
+ }
+ return getURI(getParserPointer(), getPointer(), index);
+ }
+
+ public String getLocalName(int index) {
+ return (index < 0 || index >= getLength())
+ ? null
+ : getLocalName(getParserPointer(), getPointer(), index);
+ }
+
+ public String getQName(int index) {
+ return (index < 0 || index >= getLength())
+ ? null
+ : getQName(getParserPointer(), getPointer(), index);
+ }
+
+ public String getType(int index) {
+ return (index < 0 || index >= getLength()) ? null : CDATA;
+ }
+
+ public String getValue(int index) {
+ return (index < 0 || index >= getLength())
+ ? null
+ : getValue(getPointer(), index);
+ }
+
+ public int getIndex(String uri, String localName) {
+ if (uri == null) {
+ throw new NullPointerException("uri");
+ }
+ if (localName == null) {
+ throw new NullPointerException("local name");
+ }
+ int pointer = getPointer();
+ if (pointer == 0) {
+ return -1;
+ }
+ return getIndex(pointer, uri, localName);
+ }
+
+ public int getIndex(String qName) {
+ if (qName == null) {
+ throw new NullPointerException("uri");
+ }
+ int pointer = getPointer();
+ if (pointer == 0) {
+ return -1;
+ }
+ return getIndex(pointer, qName);
+ }
+
+ public String getType(String uri, String localName) {
+ if (uri == null) {
+ throw new NullPointerException("uri");
+ }
+ if (localName == null) {
+ throw new NullPointerException("local name");
+ }
+ return getIndex(uri, localName) == -1 ? null : CDATA;
+ }
+
+ public String getType(String qName) {
+ return getIndex(qName) == -1 ? null : CDATA;
+ }
+
+ public String getValue(String uri, String localName) {
+ if (uri == null) {
+ throw new NullPointerException("uri");
+ }
+ if (localName == null) {
+ throw new NullPointerException("local name");
+ }
+ int pointer = getPointer();
+ if (pointer == 0) {
+ return null;
+ }
+ return getValue(pointer, uri, localName);
+ }
+
+ public String getValue(String qName) {
+ if (qName == null) {
+ throw new NullPointerException("qName");
+ }
+ int pointer = getPointer();
+ if (pointer == 0) {
+ return null;
+ }
+ return getValue(pointer, qName);
+ }
+
+ static native String getURI(int pointer, int attributePointer, int index);
+ static native String getLocalName(int pointer, int attributePointer,
+ int index);
+ static native String getQName(int pointer, int attributePointer,
+ int index);
+ static native String getValue(int attributePointer, int index);
+ static native int getIndex(int attributePointer, String uri,
+ String localName);
+ static native int getIndex(int attributePointer, String qName);
+ static native String getValue(int attributePointer,
+ String uri, String localName);
+ static native String getValue(int attributePointer, String qName);
+ static native void freeAttributes(int pointer);
+}
diff --git a/xml/src/main/java/org/apache/harmony/xml/ExpatException.java b/xml/src/main/java/org/apache/harmony/xml/ExpatException.java
new file mode 100644
index 0000000..da3db9d
--- /dev/null
+++ b/xml/src/main/java/org/apache/harmony/xml/ExpatException.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xml;
+
+/**
+ * Used internally to propogate Expat errors. We convert these exceptions into
+ * SAXParseExceptions before propogating them to the client.
+ */
+class ExpatException extends Exception {
+
+ public ExpatException(String message) {
+ super(message);
+ }
+}
diff --git a/xml/src/main/java/org/apache/harmony/xml/ExpatParser.java b/xml/src/main/java/org/apache/harmony/xml/ExpatParser.java
new file mode 100644
index 0000000..60d74b8
--- /dev/null
+++ b/xml/src/main/java/org/apache/harmony/xml/ExpatParser.java
@@ -0,0 +1,794 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xml;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.InputSource;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.ext.LexicalHandler;
+
+import java.io.Reader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.net.URLConnection;
+import java.net.URL;
+import java.util.logging.Logger;
+import java.util.logging.Level;
+
+/**
+ * Adapts SAX API to the Expat native XML parser. Not intended for reuse
+ * across documents.
+ *
+ * @see org.apache.harmony.xml.ExpatPullParser
+ * @see org.apache.harmony.xml.ExpatReader
+ */
+class ExpatParser {
+
+ private static final int BUFFER_SIZE = 8096; // in bytes
+
+ /** Pointer to XML_Parser instance. */
+ private int pointer;
+
+ private boolean inStartElement = false;
+ private int attributeCount = -1;
+ private int attributePointer = 0;
+
+ private final Locator locator = new ExpatLocator();
+
+ private final ExpatReader xmlReader;
+
+ private final String publicId;
+ private final String systemId;
+
+ private final String encoding;
+
+ private final ExpatAttributes attributes = new CurrentAttributes();
+
+ private static final String OUTSIDE_START_ELEMENT
+ = "Attributes can only be used within the scope of startElement().";
+
+ /** We default to UTF-8 when the user doesn't specify an encoding. */
+ private static final String DEFAULT_ENCODING = "UTF-8";
+
+ /** Encoding used for Java chars, used to parse Readers and Strings */
+ /*package*/ static final String CHARACTER_ENCODING = "UTF-16";
+
+ /** Timeout for HTTP connections (in ms) */
+ private static final int TIMEOUT = 20 * 1000;
+
+ /**
+ * Constructs a new parser with the specified encoding.
+ */
+ /*package*/ ExpatParser(String encoding, ExpatReader xmlReader,
+ boolean processNamespaces, String publicId, String systemId) {
+ this.publicId = publicId;
+ this.systemId = systemId;
+
+ this.xmlReader = xmlReader;
+
+ /*
+ * TODO: Let Expat try to guess the encoding instead of defaulting.
+ * Unfortunately, I don't know how to tell which encoding Expat picked,
+ * so I won't know how to encode "<externalEntity>" below. The solution
+ * I think is to fix Expat to not require the "<externalEntity>"
+ * workaround.
+ */
+ this.encoding = encoding == null ? DEFAULT_ENCODING : encoding;
+ this.pointer = initialize(
+ this.encoding,
+ processNamespaces
+ );
+ }
+
+ /**
+ * Used by {@link EntityParser}.
+ */
+ private ExpatParser(String encoding, ExpatReader xmlReader, int pointer,
+ String publicId, String systemId) {
+ this.encoding = encoding;
+ this.xmlReader = xmlReader;
+ this.pointer = pointer;
+ this.systemId = systemId;
+ this.publicId = publicId;
+ }
+
+ /**
+ * Initializes native resources.
+ *
+ * @return the pointer to the native parser
+ */
+ private native int initialize(String encoding, boolean namespacesEnabled);
+
+ /**
+ * Called at the start of an element.
+ *
+ * @param uri namespace URI of element or "" if namespace processing is
+ * disabled
+ * @param localName local name of element or "" if namespace processing is
+ * disabled
+ * @param qName qualified name or "" if namespace processing is enabled
+ * @param attributePointer pointer to native attribute char*--we keep
+ * a separate pointer so we can detach it from the parser instance
+ * @param attributeCount number of attributes
+ */
+ /*package*/ void startElement(String uri, String localName, String qName,
+ int attributePointer, int attributeCount) throws SAXException {
+ ContentHandler contentHandler = xmlReader.contentHandler;
+ if (contentHandler == null) {
+ return;
+ }
+
+ try {
+ inStartElement = true;
+ this.attributePointer = attributePointer;
+ this.attributeCount = attributeCount;
+
+ contentHandler.startElement(
+ uri, localName, qName, this.attributes);
+ }
+ finally {
+ inStartElement = false;
+ this.attributeCount = -1;
+ this.attributePointer = 0;
+ }
+ }
+
+ /*package*/ void endElement(String uri, String localName, String qName)
+ throws SAXException {
+ ContentHandler contentHandler = xmlReader.contentHandler;
+ if (contentHandler != null) {
+ contentHandler.endElement(uri, localName, qName);
+ }
+ }
+
+ /*package*/ void text(char[] text, int length) throws SAXException {
+ ContentHandler contentHandler = xmlReader.contentHandler;
+ if (contentHandler != null) {
+ contentHandler.characters(text, 0, length);
+ }
+ }
+
+ /*package*/ void comment(char[] text, int length) throws SAXException {
+ LexicalHandler lexicalHandler = xmlReader.lexicalHandler;
+ if (lexicalHandler != null) {
+ lexicalHandler.comment(text, 0, length);
+ }
+ }
+
+ /*package*/ void startCdata() throws SAXException {
+ LexicalHandler lexicalHandler = xmlReader.lexicalHandler;
+ if (lexicalHandler != null) {
+ lexicalHandler.startCDATA();
+ }
+ }
+
+ /*package*/ void endCdata() throws SAXException {
+ LexicalHandler lexicalHandler = xmlReader.lexicalHandler;
+ if (lexicalHandler != null) {
+ lexicalHandler.endCDATA();
+ }
+ }
+
+ /*package*/ void startNamespace(String prefix, String uri)
+ throws SAXException {
+ ContentHandler contentHandler = xmlReader.contentHandler;
+ if (contentHandler != null) {
+ contentHandler.startPrefixMapping(prefix, uri);
+ }
+ }
+
+ /*package*/ void endNamespace(String prefix) throws SAXException {
+ ContentHandler contentHandler = xmlReader.contentHandler;
+ if (contentHandler != null) {
+ contentHandler.endPrefixMapping(prefix);
+ }
+ }
+
+ /*package*/ void startDtd(String name, String publicId, String systemId)
+ throws SAXException {
+ LexicalHandler lexicalHandler = xmlReader.lexicalHandler;
+ if (lexicalHandler != null) {
+ lexicalHandler.startDTD(name, publicId, systemId);
+ }
+ }
+
+ /*package*/ void endDtd() throws SAXException {
+ LexicalHandler lexicalHandler = xmlReader.lexicalHandler;
+ if (lexicalHandler != null) {
+ lexicalHandler.endDTD();
+ }
+ }
+
+ /*package*/ void processingInstruction(String target, String data)
+ throws SAXException {
+ ContentHandler contentHandler = xmlReader.contentHandler;
+ if (contentHandler != null) {
+ contentHandler.processingInstruction(target, data);
+ }
+ }
+
+ /**
+ * Handles an external entity.
+ *
+ * @param context to be passed back to Expat when we parse the entity
+ * @param publicId the publicId of the entity
+ * @param systemId the systemId of the entity
+ */
+ /*package*/ void handleExternalEntity(String context, String publicId,
+ String systemId) throws SAXException, IOException {
+ EntityResolver entityResolver = xmlReader.entityResolver;
+ if (entityResolver == null) {
+ return;
+ }
+
+ /*
+ * The spec. is terribly under-specified here. It says that if the
+ * systemId is a URL, we should try to resolve it, but it doesn't
+ * specify how to tell whether or not the systemId is a URL let alone
+ * how to resolve it.
+ *
+ * Other implementations do various insane things. We try to keep it
+ * simple: if the systemId parses as a URI and it's relative, we try to
+ * resolve it against the parent document's systemId. If anything goes
+ * wrong, we go with the original systemId. If crazybob had designed
+ * the API, he would have left all resolving to the EntityResolver.
+ */
+ if (this.systemId != null) {
+ try {
+ URI systemUri = new URI(systemId);
+ if (!systemUri.isAbsolute() && !systemUri.isOpaque()) {
+ // It could be relative (or it may not be a URI at all!)
+ URI baseUri = new URI(this.systemId);
+ systemUri = baseUri.resolve(systemUri);
+
+ // Replace systemId w/ resolved URI
+ systemId = systemUri.toString();
+ }
+ } catch (Exception e) {
+ Logger.getLogger(ExpatParser.class.getName()).log(Level.INFO,
+ "Could not resolve '" + systemId + "' relative to"
+ + " '" + this.systemId + "' at " + locator, e);
+ }
+ }
+
+ InputSource inputSource = entityResolver.resolveEntity(
+ publicId, systemId);
+ if (inputSource == null) {
+ /*
+ * The spec. actually says that we should try to treat systemId
+ * as a URL and download and parse its contents here, but an
+ * entity resolver can easily accomplish the same by returning
+ * new InputSource(systemId).
+ *
+ * Downloading external entities by default would result in several
+ * unwanted DTD downloads, not to mention pose a security risk
+ * when parsing untrusted XML (http://tinyurl.com/56ggrk),
+ * so we just do nothing instead. This also enables the user to
+ * opt out of entity parsing when using
+ * {@link org.xml.sax.helpers.DefaultHandler}, something that
+ * wouldn't be possible otherwise.
+ */
+ return;
+ }
+
+ String encoding = pickEncoding(inputSource);
+ int pointer = createEntityParser(this.pointer, context, encoding);
+ try {
+ EntityParser entityParser = new EntityParser(encoding, xmlReader,
+ pointer, inputSource.getPublicId(),
+ inputSource.getSystemId());
+
+ parseExternalEntity(entityParser, inputSource);
+ } finally {
+ releaseParser(pointer);
+ }
+ }
+
+ /**
+ * Picks an encoding for an external entity. Defaults to UTF-8.
+ */
+ private String pickEncoding(InputSource inputSource) {
+ Reader reader = inputSource.getCharacterStream();
+ if (reader != null) {
+ return CHARACTER_ENCODING;
+ }
+
+ String encoding = inputSource.getEncoding();
+ return encoding == null ? DEFAULT_ENCODING : encoding;
+ }
+
+ /**
+ * Parses the the external entity provided by the input source.
+ */
+ private void parseExternalEntity(ExpatParser entityParser,
+ InputSource inputSource) throws IOException, SAXException {
+ /*
+ * Expat complains if the external entity isn't wrapped with a root
+ * element so we add one and ignore it later on during parsing.
+ */
+
+ // Try the character stream.
+ Reader reader = inputSource.getCharacterStream();
+ if (reader != null) {
+ try {
+ entityParser.append("<externalEntity>");
+ entityParser.parseFragment(reader);
+ entityParser.append("</externalEntity>");
+ } finally {
+ // TODO: Don't eat original exception when close() throws.
+ reader.close();
+ }
+ return;
+ }
+
+ // Try the byte stream.
+ InputStream in = inputSource.getByteStream();
+ if (in != null) {
+ try {
+ entityParser.append("<externalEntity>"
+ .getBytes(entityParser.encoding));
+ entityParser.parseFragment(in);
+ entityParser.append("</externalEntity>"
+ .getBytes(entityParser.encoding));
+ } finally {
+ // TODO: Don't eat original exception when close() throws.
+ in.close();
+ }
+ return;
+ }
+
+ // Make sure we use the user-provided systemId.
+ String systemId = inputSource.getSystemId();
+ if (systemId == null) {
+ // TODO: We could just try our systemId here.
+ throw new ParseException("No input specified.", locator);
+ }
+
+ // Try the system id.
+ in = openUrl(systemId);
+ try {
+ entityParser.append("<externalEntity>"
+ .getBytes(entityParser.encoding));
+ entityParser.parseFragment(in);
+ entityParser.append("</externalEntity>"
+ .getBytes(entityParser.encoding));
+ } finally {
+ in.close();
+ }
+ }
+
+ /**
+ * Creates a native entity parser.
+ *
+ * @param parentPointer pointer to parent Expat parser
+ * @param context passed to {@link #handleExternalEntity}
+ * @param encoding
+ * @return pointer to native parser
+ */
+ private static native int createEntityParser(int parentPointer,
+ String context, String encoding);
+
+ /**
+ * Appends part of an XML document. This parser will parse the given XML to
+ * the extent possible and dispatch to the appropriate methods.
+ *
+ * @param xml a whole or partial snippet of XML
+ * @throws SAXException if an error occurs during parsing
+ */
+ /*package*/ void append(String xml) throws SAXException {
+ try {
+ append(this.pointer, xml, false);
+ } catch (ExpatException e) {
+ throw new ParseException(e.getMessage(), this.locator);
+ }
+ }
+
+ private native void append(int pointer, String xml, boolean isFinal)
+ throws SAXException, ExpatException;
+
+ /**
+ * Appends part of an XML document. This parser will parse the given XML to
+ * the extent possible and dispatch to the appropriate methods.
+ *
+ * @param xml a whole or partial snippet of XML
+ * @param offset into the char[]
+ * @param length of characters to use
+ * @throws SAXException if an error occurs during parsing
+ */
+ /*package*/ void append(char[] xml, int offset, int length)
+ throws SAXException {
+ try {
+ append(this.pointer, xml, offset, length);
+ } catch (ExpatException e) {
+ throw new ParseException(e.getMessage(), this.locator);
+ }
+ }
+
+ private native void append(int pointer, char[] xml, int offset,
+ int length) throws SAXException, ExpatException;
+
+ /**
+ * Appends part of an XML document. This parser will parse the given XML to
+ * the extent possible and dispatch to the appropriate methods.
+ *
+ * @param xml a whole or partial snippet of XML
+ * @throws SAXException if an error occurs during parsing
+ */
+ /*package*/ void append(byte[] xml) throws SAXException {
+ append(xml, 0, xml.length);
+ }
+
+ /**
+ * Appends part of an XML document. This parser will parse the given XML to
+ * the extent possible and dispatch to the appropriate methods.
+ *
+ * @param xml a whole or partial snippet of XML
+ * @param offset into the byte[]
+ * @param length of bytes to use
+ * @throws SAXException if an error occurs during parsing
+ */
+ /*package*/ void append(byte[] xml, int offset, int length)
+ throws SAXException {
+ try {
+ append(this.pointer, xml, offset, length);
+ } catch (ExpatException e) {
+ throw new ParseException(e.getMessage(), this.locator);
+ }
+ }
+
+ private native void append(int pointer, byte[] xml, int offset,
+ int length) throws SAXException, ExpatException;
+
+ /**
+ * Parses an XML document from the given input stream.
+ */
+ /*package*/ void parseDocument(InputStream in) throws IOException,
+ SAXException {
+ startDocument();
+ parseFragment(in);
+ finish();
+ endDocument();
+ }
+
+ /**
+ * Parses an XML Document from the given reader.
+ */
+ /*package*/ void parseDocument(Reader in) throws IOException, SAXException {
+ startDocument();
+ parseFragment(in);
+ finish();
+ endDocument();
+ }
+
+ /**
+ * Parses XML from the given Reader.
+ */
+ private void parseFragment(Reader in) throws IOException, SAXException {
+ char[] buffer = new char[BUFFER_SIZE / 2];
+ int length;
+ while ((length = in.read(buffer)) != -1) {
+ try {
+ append(this.pointer, buffer, 0, length);
+ } catch (ExpatException e) {
+ throw new ParseException(e.getMessage(), locator);
+ }
+ }
+ }
+
+ /**
+ * Parses XML from the given input stream.
+ */
+ private void parseFragment(InputStream in)
+ throws IOException, SAXException {
+ byte[] buffer = new byte[BUFFER_SIZE];
+ int length;
+ while ((length = in.read(buffer)) != -1) {
+ try {
+ append(this.pointer, buffer, 0, length);
+ } catch (ExpatException e) {
+ throw new ParseException(e.getMessage(), this.locator);
+ }
+ }
+ }
+
+ private void startDocument() throws SAXException {
+ ContentHandler contentHandler = xmlReader.contentHandler;
+ if (contentHandler != null) {
+ contentHandler.setDocumentLocator(this.locator);
+ contentHandler.startDocument();
+ }
+ }
+
+ private void endDocument() throws SAXException {
+ ContentHandler contentHandler;
+ contentHandler = xmlReader.contentHandler;
+ if (contentHandler != null) {
+ contentHandler.endDocument();
+ }
+ }
+
+ /**
+ * Indicate that we're finished parsing.
+ *
+ * @throws SAXException if the xml is incomplete
+ */
+ /*package*/ void finish() throws SAXException {
+ try {
+ append(this.pointer, "", true);
+ } catch (ExpatException e) {
+ throw new ParseException(e.getMessage(), this.locator);
+ }
+ }
+
+ @Override
+ @SuppressWarnings("FinalizeDoesntCallSuperFinalize")
+ protected synchronized void finalize() throws Throwable {
+ if (this.pointer != 0) {
+ release(this.pointer);
+ this.pointer = 0;
+ }
+ }
+
+ /**
+ * Releases all native objects.
+ */
+ private native void release(int pointer);
+
+ /**
+ * Releases native parser only.
+ */
+ private static native void releaseParser(int pointer);
+
+ /**
+ * Initialize static resources.
+ */
+ private static native void staticInitialize(String emptyString);
+
+ static {
+ staticInitialize("");
+ }
+
+ /**
+ * Gets the current line number within the XML file.
+ */
+ private int line() {
+ return line(this.pointer);
+ }
+
+ private static native int line(int pointer);
+
+ /**
+ * Gets the current column number within the XML file.
+ */
+ private int column() {
+ return column(this.pointer);
+ }
+
+ private static native int column(int pointer);
+
+ /**
+ * Clones the current attributes so they can be used outside of
+ * startElement().
+ */
+ /*package*/ Attributes cloneAttributes() {
+ if (!inStartElement) {
+ throw new IllegalStateException(OUTSIDE_START_ELEMENT);
+ }
+
+ if (attributeCount == 0) {
+ return ClonedAttributes.EMPTY;
+ }
+
+ int clonePointer
+ = cloneAttributes(this.attributePointer, this.attributeCount);
+ return new ClonedAttributes(pointer, clonePointer, attributeCount);
+ }
+
+ private static native int cloneAttributes(int pointer, int attributeCount);
+
+ /**
+ * Used for cloned attributes.
+ */
+ private static class ClonedAttributes extends ExpatAttributes {
+
+ private static final Attributes EMPTY = new ClonedAttributes(0, 0, 0);
+
+ private final int parserPointer;
+ private int pointer;
+ private final int length;
+
+ /**
+ * Constructs a Java wrapper for native attributes.
+ *
+ * @param parserPointer pointer to the parse, can be 0 if length is 0.
+ * @param pointer pointer to the attributes array, can be 0 if the
+ * length is 0.
+ * @param length number of attributes
+ */
+ private ClonedAttributes(int parserPointer, int pointer, int length) {
+ this.parserPointer = parserPointer;
+ this.pointer = pointer;
+ this.length = length;
+ }
+
+ @Override
+ public int getParserPointer() {
+ return this.parserPointer;
+ }
+
+ @Override
+ public int getPointer() {
+ return pointer;
+ }
+
+ @Override
+ public int getLength() {
+ return length;
+ }
+
+ @Override
+ @SuppressWarnings("FinalizeDoesntCallSuperFinalize")
+ protected synchronized void finalize() throws Throwable {
+ if (pointer != 0) {
+ freeAttributes(pointer);
+ pointer = 0;
+ }
+ }
+ }
+
+ private class ExpatLocator implements Locator {
+
+ public String getPublicId() {
+ return publicId;
+ }
+
+ public String getSystemId() {
+ return systemId;
+ }
+
+ public int getLineNumber() {
+ return line();
+ }
+
+ public int getColumnNumber() {
+ return column();
+ }
+
+ @Override
+ public String toString() {
+ return "Locator[publicId: " + publicId + ", systemId: " + systemId
+ + ", line: " + getLineNumber()
+ + ", column: " + getColumnNumber() + "]";
+ }
+ }
+
+ /**
+ * Attributes that are only valid during startElement().
+ */
+ private class CurrentAttributes extends ExpatAttributes {
+
+ @Override
+ public int getParserPointer() {
+ return pointer;
+ }
+
+ @Override
+ public int getPointer() {
+ if (!inStartElement) {
+ throw new IllegalStateException(OUTSIDE_START_ELEMENT);
+ }
+ return attributePointer;
+ }
+
+ @Override
+ public int getLength() {
+ if (!inStartElement) {
+ throw new IllegalStateException(OUTSIDE_START_ELEMENT);
+ }
+ return attributeCount;
+ }
+ }
+
+ /**
+ * Includes line and column in the message.
+ */
+ private static class ParseException extends SAXParseException {
+
+ private ParseException(String message, Locator locator) {
+ super(makeMessage(message, locator), locator);
+ }
+
+ private static String makeMessage(String message, Locator locator) {
+ return makeMessage(message, locator.getLineNumber(),
+ locator.getColumnNumber());
+ }
+
+ private static String makeMessage(
+ String message, int line, int column) {
+ return "At line " + line + ", column "
+ + column + ": " + message;
+ }
+ }
+
+ /**
+ * Opens an InputStream for the given URL.
+ */
+ /*package*/ static InputStream openUrl(String url) throws IOException {
+ try {
+ URLConnection urlConnection = new URL(url).openConnection();
+ urlConnection.setConnectTimeout(TIMEOUT);
+ urlConnection.setReadTimeout(TIMEOUT);
+ urlConnection.setDoInput(true);
+ urlConnection.setDoOutput(false);
+ return urlConnection.getInputStream();
+ } catch (Exception e) {
+ IOException ioe = new IOException("Couldn't open " + url);
+ ioe.initCause(e);
+ throw ioe;
+ }
+ }
+
+ /**
+ * Parses an external entity.
+ */
+ private static class EntityParser extends ExpatParser {
+
+ private int depth = 0;
+
+ private EntityParser(String encoding, ExpatReader xmlReader,
+ int pointer, String publicId, String systemId) {
+ super(encoding, xmlReader, pointer, publicId, systemId);
+ }
+
+ @Override
+ void startElement(String uri, String localName, String qName,
+ int attributePointer, int attributeCount) throws SAXException {
+ /*
+ * Skip topmost element generated by our workaround in
+ * {@link #handleExternalEntity}.
+ */
+ if (depth++ > 0) {
+ super.startElement(uri, localName, qName, attributePointer,
+ attributeCount);
+ }
+ }
+
+ @Override
+ void endElement(String uri, String localName, String qName)
+ throws SAXException {
+ if (--depth > 0) {
+ super.endElement(uri, localName, qName);
+ }
+ }
+
+ @Override
+ @SuppressWarnings("FinalizeDoesntCallSuperFinalize")
+ protected synchronized void finalize() throws Throwable {
+ /*
+ * Don't release our native resources. We do so explicitly in
+ * {@link #handleExternalEntity} and we don't want to release the
+ * parsing context--our parent is using it.
+ */
+ }
+ }
+}
+
diff --git a/xml/src/main/java/org/apache/harmony/xml/ExpatPullParser.java b/xml/src/main/java/org/apache/harmony/xml/ExpatPullParser.java
new file mode 100644
index 0000000..4759718
--- /dev/null
+++ b/xml/src/main/java/org/apache/harmony/xml/ExpatPullParser.java
@@ -0,0 +1,964 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xml;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.Locator;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+
+/**
+ * Fast, partial XmlPullParser implementation based upon Expat. Does not
+ * support validation or {@code DOCTYPE} processing.
+ */
+public class ExpatPullParser implements XmlPullParser {
+ /**
+ * This feature is identified by http://xmlpull.org/v1/doc/features.html#relaxed
+ * If this feature is supported that means that XmlPull parser will be
+ * lenient when checking XML well formedness.
+ * NOTE: use it only if XML input is not well-formed and in general usage
+ * if this feature is discouraged
+ * NOTE: as there is no definition of what is relaxed XML parsing
+ * therefore what parser will do completely depends on implementation used
+ */
+ public static final String FEATURE_RELAXED =
+ "http://xmlpull.org/v1/doc/features.html#relaxed";
+
+ private static final int BUFFER_SIZE = 8096;
+
+ private static final String NOT_A_START_TAG = "This is not a start tag.";
+
+ private Document document;
+ private boolean processNamespaces = false;
+ private boolean relaxed = false;
+
+ public void setFeature(String name, boolean state)
+ throws XmlPullParserException {
+ if (name == null) {
+ // Required by API.
+ throw new IllegalArgumentException("Null feature name");
+ }
+
+ if (name.equals(FEATURE_PROCESS_NAMESPACES)) {
+ processNamespaces = state;
+ return;
+ }
+
+ if (name.equals(FEATURE_RELAXED)) {
+ relaxed = true;
+ return;
+ }
+
+ // You're free to turn these features off because we don't support them.
+ if (!state && (name.equals(FEATURE_REPORT_NAMESPACE_ATTRIBUTES)
+ || name.equals(FEATURE_PROCESS_DOCDECL)
+ || name.equals(FEATURE_VALIDATION))) {
+ return;
+ }
+
+ throw new XmlPullParserException("Unsupported feature: " + name);
+ }
+
+ public boolean getFeature(String name) {
+ if (name == null) {
+ // Required by API.
+ throw new IllegalArgumentException("Null feature name");
+ }
+
+ // We always support namespaces, but no other features.
+ return name.equals(FEATURE_PROCESS_NAMESPACES) && processNamespaces;
+ }
+
+ /**
+ * Returns true if this parser processes namespaces.
+ *
+ * @see #setNamespaceProcessingEnabled(boolean)
+ */
+ public boolean isNamespaceProcessingEnabled() {
+ return processNamespaces;
+ }
+
+ /**
+ * Enables or disables namespace processing. Set to false by default.
+ *
+ * @see #isNamespaceProcessingEnabled()
+ */
+ public void setNamespaceProcessingEnabled(boolean processNamespaces) {
+ this.processNamespaces = processNamespaces;
+ }
+
+ public void setProperty(String name, Object value)
+ throws XmlPullParserException {
+ if (name == null) {
+ // Required by API.
+ throw new IllegalArgumentException("Null feature name");
+ }
+
+ // We don't support any properties.
+ throw new XmlPullParserException("Properties aren't supported.");
+ }
+
+ public Object getProperty(String name) {
+ return null;
+ }
+
+ public void setInput(Reader in) throws XmlPullParserException {
+ this.document = new CharDocument(in, processNamespaces);
+ }
+
+ public void setInput(InputStream in, String encodingName)
+ throws XmlPullParserException {
+ this.document = new ByteDocument(in, encodingName, processNamespaces);
+ }
+
+ public String getInputEncoding() {
+ return this.document.getEncoding();
+ }
+
+ /**
+ * Not supported.
+ *
+ * @throws UnsupportedOperationException always
+ */
+ public void defineEntityReplacementText(String entityName,
+ String replacementText) throws XmlPullParserException {
+ throw new UnsupportedOperationException();
+ }
+
+ public int getNamespaceCount(int depth) throws XmlPullParserException {
+ return document.currentEvent.namespaceStack.countAt(depth);
+ }
+
+ public String getNamespacePrefix(int pos) throws XmlPullParserException {
+ String prefix = document.currentEvent.namespaceStack.prefixAt(pos);
+ @SuppressWarnings("StringEquality")
+ boolean hasPrefix = prefix != "";
+ return hasPrefix ? prefix : null;
+ }
+
+ public String getNamespaceUri(int pos) throws XmlPullParserException {
+ return document.currentEvent.namespaceStack.uriAt(pos);
+ }
+
+ public String getNamespace(String prefix) {
+ // In XmlPullParser API, null == default namespace.
+ if (prefix == null) {
+ // Internally, we use empty string instead of null.
+ prefix = "";
+ }
+
+ return document.currentEvent.namespaceStack.uriFor(prefix);
+ }
+
+ public int getDepth() {
+ return this.document.getDepth();
+ }
+
+ public String getPositionDescription() {
+ return "line " + getLineNumber() + ", column " + getColumnNumber();
+ }
+
+ /**
+ * Not supported.
+ *
+ * @return {@literal -1} always
+ */
+ public int getLineNumber() {
+ // We would have to record the line number in each event.
+ return -1;
+ }
+
+ /**
+ * Not supported.
+ *
+ * @return {@literal -1} always
+ */
+ public int getColumnNumber() {
+ // We would have to record the column number in each event.
+ return -1;
+ }
+
+ public boolean isWhitespace() throws XmlPullParserException {
+ if (getEventType() != TEXT) {
+ throw new XmlPullParserException("Not on text.");
+ }
+
+ String text = getText();
+
+ if (text.length() == 0) {
+ return true;
+ }
+
+ int length = text.length();
+ for (int i = 0; i < length; i++) {
+ if (!Character.isWhitespace(text.charAt(i))) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public String getText() {
+ final StringBuilder builder = this.document.currentEvent.getText();
+ return builder == null ? null : builder.toString();
+ }
+
+ public char[] getTextCharacters(int[] holderForStartAndLength) {
+ final StringBuilder builder = this.document.currentEvent.getText();
+
+ final int length = builder.length();
+ char[] characters = new char[length];
+ builder.getChars(0, length, characters, 0);
+
+ holderForStartAndLength[0] = 0;
+ holderForStartAndLength[1] = length;
+
+ return characters;
+ }
+
+ public String getNamespace() {
+ return this.document.currentEvent.getNamespace();
+ }
+
+ public String getName() {
+ return this.document.currentEvent.getName();
+ }
+
+ /**
+ * Not supported.
+ *
+ * @throws UnsupportedOperationException always
+ */
+ public String getPrefix() {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean isEmptyElementTag() throws XmlPullParserException {
+ return this.document.isCurrentElementEmpty();
+ }
+
+ public int getAttributeCount() {
+ return this.document.currentEvent.getAttributeCount();
+ }
+
+ public String getAttributeNamespace(int index) {
+ return this.document.currentEvent.getAttributeNamespace(index);
+ }
+
+ public String getAttributeName(int index) {
+ return this.document.currentEvent.getAttributeName(index);
+ }
+
+ /**
+ * Not supported.
+ *
+ * @throws UnsupportedOperationException always
+ */
+ public String getAttributePrefix(int index) {
+ throw new UnsupportedOperationException();
+ }
+
+ public String getAttributeType(int index) {
+ return "CDATA";
+ }
+
+ public boolean isAttributeDefault(int index) {
+ return false;
+ }
+
+ public String getAttributeValue(int index) {
+ return this.document.currentEvent.getAttributeValue(index);
+ }
+
+ public String getAttributeValue(String namespace, String name) {
+ return this.document.currentEvent.getAttributeValue(namespace, name);
+ }
+
+ public int getEventType() throws XmlPullParserException {
+ return this.document.currentEvent.getType();
+ }
+
+ public int next() throws XmlPullParserException, IOException {
+ return this.document.dequeue();
+ }
+
+ /**
+ * Not supported.
+ *
+ * @throws UnsupportedOperationException always
+ */
+ public int nextToken() throws XmlPullParserException, IOException {
+ throw new UnsupportedOperationException();
+ }
+
+ public void require(int type, String namespace, String name)
+ throws XmlPullParserException, IOException {
+ if (type != getEventType()
+ || (namespace != null && !namespace.equals(getNamespace()))
+ || (name != null && !name.equals(getName()))) {
+ throw new XmlPullParserException("expected "
+ + TYPES[type] + getPositionDescription());
+ }
+ }
+
+ public String nextText() throws XmlPullParserException, IOException {
+ if (this.document.currentEvent.getType() != START_TAG)
+ throw new XmlPullParserException("Not on start tag.");
+
+ int next = this.document.dequeue();
+ switch (next) {
+ case TEXT: return getText();
+ case END_TAG: return "";
+ default: throw new XmlPullParserException(
+ "Unexpected event type: " + TYPES[next]);
+ }
+ }
+
+ public int nextTag() throws XmlPullParserException, IOException {
+ int eventType = next();
+ if (eventType == TEXT && isWhitespace()) {
+ eventType = next();
+ }
+ if (eventType != START_TAG && eventType != END_TAG) {
+ throw new XmlPullParserException(
+ "Expected start or end tag", this, null);
+ }
+ return eventType;
+ }
+
+ /**
+ * Immutable namespace stack. Pushing a new namespace on to the stack
+ * only results in one object allocation. Most operations are O(N) where
+ * N is the stack size. Accessing recently pushed namespaces, like those
+ * for the current element, is significantly faster.
+ */
+ static class NamespaceStack {
+
+ /** An empty stack. */
+ static final NamespaceStack EMPTY = new NamespaceStack();
+
+ private final NamespaceStack parent;
+ private final String prefix;
+ private final String uri;
+ private final int index;
+ private final int depth;
+
+ /**
+ * Constructs an actual namespace stack node. Internally, the nodes
+ * and the stack are one in the same making for a very efficient
+ * implementation. The user just sees an immutable stack and the
+ * builder.
+ */
+ private NamespaceStack(NamespaceStack parent, String prefix,
+ String uri, int depth) {
+ this.parent = parent;
+ this.prefix = prefix;
+ this.uri = uri;
+ this.index = parent.index + 1;
+ this.depth = depth;
+ }
+
+ /**
+ * Constructs a dummy node which only serves to point to the bottom
+ * of the stack. Using an actual node instead of null simplifies the
+ * code.
+ */
+ private NamespaceStack() {
+ this.parent = null;
+ this.prefix = null;
+ this.uri = null;
+
+ // This node has an index of -1 since the actual first node in the
+ // stack has index 0.
+ this.index = -1;
+
+ // The actual first node will have a depth of 1.
+ this.depth = 0;
+ }
+
+ String uriFor(String prefix) {
+ for (NamespaceStack node = this; node.index >= 0;
+ node = node.parent) {
+ if (node.prefix.equals(prefix)) {
+ return node.uri;
+ }
+ }
+
+ // Not found.
+ return null;
+ }
+
+ /**
+ * Gets the prefix at the given index in the stack.
+ */
+ String prefixAt(int index) {
+ return nodeAt(index).prefix;
+ }
+
+ /**
+ * Gets the URI at the given index in the stack.
+ */
+ String uriAt(int index) {
+ return nodeAt(index).uri;
+ }
+
+ private NamespaceStack nodeAt(int index) {
+ if (index > this.index) {
+ throw new IndexOutOfBoundsException("Index > size.");
+ }
+ if (index < 0) {
+ throw new IndexOutOfBoundsException("Index < 0.");
+ }
+
+ NamespaceStack node = this;
+ while (index != node.index) {
+ node = node.parent;
+ }
+ return node;
+ }
+
+ /**
+ * Gets the size of the stack at the given element depth.
+ */
+ int countAt(int depth) {
+ if (depth > this.depth) {
+ throw new IndexOutOfBoundsException("Depth > maximum.");
+ }
+ if (depth < 0) {
+ throw new IndexOutOfBoundsException("Depth < 0.");
+ }
+
+ NamespaceStack node = this;
+ while (depth < node.depth) {
+ node = node.parent;
+ }
+ return node.index + 1;
+ }
+
+ /** Builds a NamespaceStack. */
+ static class Builder {
+
+ NamespaceStack top = EMPTY;
+
+ /**
+ * Pushes a namespace onto the stack.
+ *
+ * @param depth of the element upon which the namespace was
+ * declared
+ */
+ void push(String prefix, String uri, int depth) {
+ top = new NamespaceStack(top, prefix, uri, depth);
+ }
+
+ /**
+ * Pops all namespaces from the given element depth.
+ */
+ void pop(int depth) {
+ // Remove all nodes at the specified depth.
+ while (top != null && top.depth == depth) {
+ top = top.parent;
+ }
+ }
+
+ /** Returns the current stack. */
+ NamespaceStack build() {
+ return top;
+ }
+ }
+ }
+
+ /**
+ * Base class for events. Implements event chaining and defines event API
+ * along with common implementations which can be overridden.
+ */
+ static abstract class Event {
+
+ /** Element depth at the time of this event. */
+ final int depth;
+
+ /** The namespace stack at the time of this event. */
+ final NamespaceStack namespaceStack;
+
+ /** Next event in the queue. */
+ Event next = null;
+
+ Event(int depth, NamespaceStack namespaceStack) {
+ this.depth = depth;
+ this.namespaceStack = namespaceStack;
+ }
+
+ void setNext(Event next) {
+ this.next = next;
+ }
+
+ Event getNext() {
+ return next;
+ }
+
+ StringBuilder getText() {
+ return null;
+ }
+
+ String getNamespace() {
+ return null;
+ }
+
+ String getName() {
+ return null;
+ }
+
+ int getAttributeCount() {
+ return -1;
+ }
+
+ String getAttributeNamespace(int index) {
+ throw new IndexOutOfBoundsException(NOT_A_START_TAG);
+ }
+
+ String getAttributeName(int index) {
+ throw new IndexOutOfBoundsException(NOT_A_START_TAG);
+ }
+
+ String getAttributeValue(int index) {
+ throw new IndexOutOfBoundsException(NOT_A_START_TAG);
+ }
+
+ abstract int getType();
+
+ String getAttributeValue(String namespace, String name) {
+ throw new IndexOutOfBoundsException(NOT_A_START_TAG);
+ }
+
+ public int getDepth() {
+ return this.depth;
+ }
+ }
+
+ static class StartDocumentEvent extends Event {
+
+ public StartDocumentEvent() {
+ super(0, NamespaceStack.EMPTY);
+ }
+
+ @Override
+ int getType() {
+ return START_DOCUMENT;
+ }
+ }
+
+ static class StartTagEvent extends Event {
+
+ final String name;
+ final String namespace;
+ final Attributes attributes;
+ final boolean processNamespaces;
+
+ StartTagEvent(String namespace,
+ String name,
+ ExpatParser expatParser,
+ int depth,
+ NamespaceStack namespaceStack,
+ boolean processNamespaces) {
+ super(depth, namespaceStack);
+ this.namespace = namespace;
+ this.name = name;
+ this.attributes = expatParser.cloneAttributes();
+ this.processNamespaces = processNamespaces;
+ }
+
+ @Override
+ String getNamespace() {
+ return namespace;
+ }
+
+ @Override
+ String getName() {
+ return name;
+ }
+
+ @Override
+ int getAttributeCount() {
+ return attributes.getLength();
+ }
+
+ @Override
+ String getAttributeNamespace(int index) {
+ return attributes.getURI(index);
+ }
+
+ @Override
+ String getAttributeName(int index) {
+ return processNamespaces ? attributes.getLocalName(index)
+ : attributes.getQName(index);
+ }
+
+ @Override
+ String getAttributeValue(int index) {
+ return attributes.getValue(index);
+ }
+
+ @Override
+ String getAttributeValue(String namespace, String name) {
+ if (namespace == null) {
+ namespace = "";
+ }
+
+ return attributes.getValue(namespace, name);
+ }
+
+ @Override
+ int getType() {
+ return START_TAG;
+ }
+ }
+
+ static class EndTagEvent extends Event {
+
+ final String namespace;
+ final String localName;
+
+ EndTagEvent(String namespace, String localName, int depth,
+ NamespaceStack namespaceStack) {
+ super(depth, namespaceStack);
+ this.namespace = namespace;
+ this.localName = localName;
+ }
+
+ @Override
+ String getName() {
+ return this.localName;
+ }
+
+ @Override
+ String getNamespace() {
+ return this.namespace;
+ }
+
+ @Override
+ int getType() {
+ return END_TAG;
+ }
+ }
+
+ static class TextEvent extends Event {
+
+ final StringBuilder builder;
+
+ public TextEvent(int initialCapacity, int depth,
+ NamespaceStack namespaceStack) {
+ super(depth, namespaceStack);
+ this.builder = new StringBuilder(initialCapacity);
+ }
+
+ @Override
+ int getType() {
+ return TEXT;
+ }
+
+ @Override
+ StringBuilder getText() {
+ return this.builder;
+ }
+
+ void append(char[] text, int start, int length) {
+ builder.append(text, start, length);
+ }
+ }
+
+ static class EndDocumentEvent extends Event {
+
+ EndDocumentEvent() {
+ super(0, NamespaceStack.EMPTY);
+ }
+
+ @Override
+ Event getNext() {
+ throw new IllegalStateException("End of document.");
+ }
+
+ @Override
+ void setNext(Event next) {
+ throw new IllegalStateException("End of document.");
+ }
+
+ @Override
+ int getType() {
+ return END_DOCUMENT;
+ }
+ }
+
+ /**
+ * Encapsulates the parsing context of the current document.
+ */
+ abstract class Document {
+
+ final String encoding;
+ final ExpatParser parser;
+ final boolean processNamespaces;
+
+ TextEvent textEvent = null;
+ boolean finished = false;
+
+ Document(String encoding, boolean processNamespaces) {
+ this.encoding = encoding;
+ this.processNamespaces = processNamespaces;
+
+ ExpatReader xmlReader = new ExpatReader();
+ xmlReader.setContentHandler(new SaxHandler());
+
+ this.parser = new ExpatParser(
+ encoding, xmlReader, processNamespaces, null, null);
+ }
+
+ /** Namespace stack builder. */
+ NamespaceStack.Builder namespaceStackBuilder
+ = new NamespaceStack.Builder();
+
+ Event currentEvent = new StartDocumentEvent();
+ Event last = currentEvent;
+
+ /**
+ * Sends some more XML to the parser.
+ */
+ void pump() throws IOException, XmlPullParserException {
+ if (this.finished) {
+ return;
+ }
+
+ int length = buffer();
+
+ // End of document.
+ if (length == -1) {
+ this.finished = true;
+ if (!relaxed) {
+ try {
+ parser.finish();
+ } catch (SAXException e) {
+ throw new XmlPullParserException(
+ "Premature end of document.", ExpatPullParser.this, e);
+ }
+ }
+ add(new EndDocumentEvent());
+ return;
+ }
+
+ if (length == 0) {
+ return;
+ }
+
+ flush(parser, length);
+ }
+
+ /**
+ * Reads data into the buffer.
+ *
+ * @return the length of data buffered or {@code -1} if we've reached
+ * the end of the data.
+ */
+ abstract int buffer() throws IOException;
+
+ /**
+ * Sends buffered data to the parser.
+ *
+ * @param parser the parser to flush to
+ * @param length of data buffered
+ */
+ abstract void flush(ExpatParser parser, int length)
+ throws XmlPullParserException;
+
+ /**
+ * Adds an event.
+ */
+ void add(Event event) {
+ // Flush pre-exising text event if necessary.
+ if (textEvent != null) {
+ last.setNext(textEvent);
+ last = textEvent;
+ textEvent = null;
+ }
+
+ last.setNext(event);
+ last = event;
+ }
+
+ /**
+ * Moves to the next event in the queue.
+ *
+ * @return type of next event
+ */
+ int dequeue() throws XmlPullParserException, IOException {
+ Event next;
+
+ while ((next = currentEvent.getNext()) == null) {
+ pump();
+ }
+
+ currentEvent.next = null;
+ currentEvent = next;
+
+ return currentEvent.getType();
+ }
+
+ String getEncoding() {
+ return this.encoding;
+ }
+
+ int getDepth() {
+ return currentEvent.getDepth();
+ }
+
+ /**
+ * Returns true if we're on a start element and the next event is
+ * its corresponding end element.
+ *
+ * @throws XmlPullParserException if we aren't on a start element
+ */
+ boolean isCurrentElementEmpty() throws XmlPullParserException {
+ if (currentEvent.getType() != START_TAG) {
+ throw new XmlPullParserException(NOT_A_START_TAG);
+ }
+
+ Event next;
+
+ try {
+ while ((next = currentEvent.getNext()) == null) {
+ pump();
+ }
+ } catch (IOException ex) {
+ throw new XmlPullParserException(ex.toString());
+ }
+
+ return next.getType() == END_TAG;
+ }
+
+ private class SaxHandler implements ContentHandler {
+
+ int depth = 0;
+
+ public void startPrefixMapping(String prefix, String uri)
+ throws SAXException {
+ // Depth + 1--we aren't actually in the element yet.
+ namespaceStackBuilder.push(prefix, uri, depth + 1);
+ }
+
+ public void startElement(String uri, String localName, String qName,
+ Attributes attributes) {
+ String name = processNamespaces ? localName : qName;
+
+ add(new StartTagEvent(uri, name, parser, ++this.depth,
+ namespaceStackBuilder.build(), processNamespaces));
+ }
+
+ public void endElement(String uri, String localName, String qName) {
+ String name = processNamespaces ? localName : qName;
+
+ int depth = this.depth--;
+ add(new EndTagEvent(uri, name, depth,
+ namespaceStackBuilder.build()));
+ namespaceStackBuilder.pop(depth);
+ }
+
+ public void characters(char ch[], int start, int length) {
+ // Ignore empty strings.
+ if (length == 0) {
+ return;
+ }
+
+ // Start a new text event if necessary.
+ if (textEvent == null) {
+ textEvent = new TextEvent(length, this.depth,
+ namespaceStackBuilder.build());
+ }
+
+ // Append to an existing text event.
+ textEvent.append(ch, start, length);
+ }
+
+ public void setDocumentLocator(Locator locator) {}
+ public void startDocument() throws SAXException {}
+ public void endDocument() throws SAXException {}
+ public void endPrefixMapping(String prefix) throws SAXException {}
+ public void ignorableWhitespace(char ch[], int start, int length)
+ throws SAXException {}
+ public void processingInstruction(String target, String data)
+ throws SAXException {}
+ public void skippedEntity(String name) throws SAXException {}
+ }
+ }
+
+ class CharDocument extends Document {
+
+ final char[] buffer = new char[BUFFER_SIZE / 2];
+ final Reader in;
+
+ CharDocument(Reader in, boolean processNamespaces) {
+ super("UTF-16", processNamespaces);
+ this.in = in;
+ }
+
+ @Override
+ int buffer() throws IOException {
+ return in.read(buffer);
+ }
+
+ @Override
+ void flush(ExpatParser parser, int length)
+ throws XmlPullParserException {
+ try {
+ parser.append(buffer, 0, length);
+ } catch (SAXException e) {
+ throw new XmlPullParserException(
+ "Error parsing document.", ExpatPullParser.this, e);
+ }
+ }
+ }
+
+ class ByteDocument extends Document {
+
+ final byte[] buffer = new byte[BUFFER_SIZE];
+ final InputStream in;
+
+ ByteDocument(InputStream in, String encoding,
+ boolean processNamespaces) {
+ super(encoding, processNamespaces);
+ this.in = in;
+ }
+
+ @Override
+ int buffer() throws IOException {
+ return in.read(buffer);
+ }
+
+ @Override
+ void flush(ExpatParser parser, int length)
+ throws XmlPullParserException {
+ try {
+ parser.append(buffer, 0, length);
+ } catch (SAXException e) {
+ throw new XmlPullParserException(
+ "Error parsing document.", ExpatPullParser.this, e);
+ }
+ }
+ }
+}
diff --git a/xml/src/main/java/org/apache/harmony/xml/ExpatReader.java b/xml/src/main/java/org/apache/harmony/xml/ExpatReader.java
new file mode 100644
index 0000000..a6a83a0
--- /dev/null
+++ b/xml/src/main/java/org/apache/harmony/xml/ExpatReader.java
@@ -0,0 +1,335 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xml;
+
+import org.xml.sax.ContentHandler;
+import org.xml.sax.DTDHandler;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXNotRecognizedException;
+import org.xml.sax.SAXNotSupportedException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.ext.LexicalHandler;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.io.InputStream;
+import java.util.logging.Logger;
+
+/**
+ * SAX wrapper around Expat. Interns strings. Does not support validation.
+ * Does not support {@link DTDHandler}.
+ */
+public class ExpatReader implements XMLReader {
+
+ private static final Logger logger
+ = Logger.getLogger(ExpatReader.class.getName());
+
+ /*
+ * ExpatParser accesses these fields directly during parsing. The user
+ * should be able to safely change them during parsing.
+ */
+ /*package*/ ContentHandler contentHandler;
+ /*package*/ EntityResolver entityResolver;
+ /*package*/ ErrorHandler errorHandler;
+ /*package*/ LexicalHandler lexicalHandler;
+
+ private boolean processNamespaces = true;
+ private boolean processNamespacePrefixes = false;
+
+ private static final String LEXICAL_HANDLER_PROPERTY
+ = "http://xml.org/sax/properties/lexical-handler";
+
+ private static class Feature {
+
+ private static final String BASE_URI = "http://xml.org/sax/features/";
+
+ private static final String VALIDATION = BASE_URI + "validation";
+ private static final String NAMESPACES = BASE_URI + "namespaces";
+ private static final String NAMESPACE_PREFIXES
+ = BASE_URI + "namespace-prefixes";
+ private static final String STRING_INTERNING
+ = BASE_URI + "string-interning";
+ }
+
+ public boolean getFeature(String name)
+ throws SAXNotRecognizedException, SAXNotSupportedException {
+ if (name == null) {
+ throw new NullPointerException("name");
+ }
+
+ if (name.equals(Feature.VALIDATION)) {
+ return false;
+ }
+
+ if (name.equals(Feature.NAMESPACES)) {
+ return processNamespaces;
+ }
+
+ if (name.equals(Feature.NAMESPACE_PREFIXES)) {
+ return processNamespacePrefixes;
+ }
+
+ if (name.equals(Feature.STRING_INTERNING)) {
+ return true;
+ }
+
+ throw new SAXNotRecognizedException(name);
+ }
+
+ public void setFeature(String name, boolean value)
+ throws SAXNotRecognizedException, SAXNotSupportedException {
+ if (name == null) {
+ throw new NullPointerException("name");
+ }
+
+ if (name.equals(Feature.VALIDATION)) {
+ if (value) {
+ throw new SAXNotSupportedException("Cannot enable " + name);
+ } else {
+ // Default.
+ return;
+ }
+ }
+
+ if (name.equals(Feature.NAMESPACES)) {
+ processNamespaces = value;
+ return;
+ }
+
+ if (name.equals(Feature.NAMESPACE_PREFIXES)) {
+ processNamespacePrefixes = value;
+ return;
+ }
+
+ if (name.equals(Feature.STRING_INTERNING)) {
+ if (value) {
+ // Default.
+ return;
+ } else {
+ throw new SAXNotSupportedException("Cannot disable " + name);
+ }
+ }
+
+ throw new SAXNotRecognizedException(name);
+ }
+
+ public Object getProperty(String name)
+ throws SAXNotRecognizedException, SAXNotSupportedException {
+ if (name == null) {
+ throw new NullPointerException("name");
+ }
+
+ if (name.equals(LEXICAL_HANDLER_PROPERTY)) {
+ return lexicalHandler;
+ }
+
+ throw new SAXNotRecognizedException(name);
+ }
+
+ public void setProperty(String name, Object value)
+ throws SAXNotRecognizedException, SAXNotSupportedException {
+ if (name == null) {
+ throw new NullPointerException("name");
+ }
+
+ if (name.equals(LEXICAL_HANDLER_PROPERTY)) {
+ // The object must implement LexicalHandler
+ if (value instanceof LexicalHandler) {
+ this.lexicalHandler = (LexicalHandler) value;
+ return;
+ }
+ throw new SAXNotSupportedException("value doesn't implement " +
+ "org.xml.sax.ext.LexicalHandler");
+ }
+
+ throw new SAXNotRecognizedException(name);
+ }
+
+ public void setEntityResolver(EntityResolver resolver) {
+ this.entityResolver = resolver;
+ }
+
+ public EntityResolver getEntityResolver() {
+ return entityResolver;
+ }
+
+ /**
+ * Not implemented.
+ */
+ public void setDTDHandler(DTDHandler ignored) {
+ logger.warning("DTD handlers aren't supported.");
+ }
+
+ /**
+ * Always returns null.
+ */
+ public DTDHandler getDTDHandler() {
+ return null;
+ }
+
+ public void setContentHandler(ContentHandler handler) {
+ this.contentHandler = handler;
+ }
+
+ public ContentHandler getContentHandler() {
+ return this.contentHandler;
+ }
+
+ public void setErrorHandler(ErrorHandler handler) {
+ this.errorHandler = handler;
+ }
+
+ public ErrorHandler getErrorHandler() {
+ return errorHandler;
+ }
+
+ /**
+ * Returns the current lexical handler.
+ *
+ * @return the current lexical handler, or null if none has been registered
+ * @see #setLexicalHandler
+ */
+ public LexicalHandler getLexicalHandler() {
+ return lexicalHandler;
+ }
+
+ /**
+ * Registers a lexical event handler. Supports neither
+ * {@link LexicalHandler#startEntity(String)} nor
+ * {@link LexicalHandler#endEntity(String)}.
+ *
+ * <p>If the application does not register a lexical handler, all
+ * lexical events reported by the SAX parser will be silently
+ * ignored.</p>
+ *
+ * <p>Applications may register a new or different handler in the
+ * middle of a parse, and the SAX parser must begin using the new
+ * handler immediately.</p>
+ *
+ * @param lexicalHandler listens for lexical events
+ * @see #getLexicalHandler()
+ */
+ public void setLexicalHandler(LexicalHandler lexicalHandler) {
+ this.lexicalHandler = lexicalHandler;
+ }
+
+ /**
+ * Returns true if this SAX parser processes namespaces.
+ *
+ * @see #setNamespaceProcessingEnabled(boolean)
+ */
+ public boolean isNamespaceProcessingEnabled() {
+ return processNamespaces;
+ }
+
+ /**
+ * Enables or disables namespace processing. Set to true by default. If you
+ * enable namespace processing, the parser will invoke
+ * {@link ContentHandler#startPrefixMapping(String, String)} and
+ * {@link ContentHandler#endPrefixMapping(String)}, and it will filter
+ * out namespace declarations from element attributes.
+ *
+ * @see #isNamespaceProcessingEnabled()
+ */
+ public void setNamespaceProcessingEnabled(boolean processNamespaces) {
+ this.processNamespaces = processNamespaces;
+ }
+
+ public void parse(InputSource input) throws IOException, SAXException {
+ if (processNamespacePrefixes == processNamespaces) {
+ /*
+ * Expat has XML_SetReturnNSTriplet, but that still doesn't
+ * include xmlns attributes like this feature requires. We may
+ * have to implement namespace processing ourselves if we want
+ * this (not too difficult). We obviously "support" namespace
+ * prefixes if namespaces are disabled.
+ */
+ throw new SAXNotSupportedException("The 'namespace-prefix' " +
+ "feature is not supported while the 'namespaces' " +
+ "feature is enabled.");
+ }
+
+ // Try the character stream.
+ Reader reader = input.getCharacterStream();
+ if (reader != null) {
+ try {
+ parse(reader, input.getPublicId(), input.getSystemId());
+ } finally {
+ // TODO: Don't eat original exception when close() throws.
+ reader.close();
+ }
+ return;
+ }
+
+ // Try the byte stream.
+ InputStream in = input.getByteStream();
+ String encoding = input.getEncoding();
+ if (in != null) {
+ try {
+ parse(in, encoding, input.getPublicId(), input.getSystemId());
+ } finally {
+ // TODO: Don't eat original exception when close() throws.
+ in.close();
+ }
+ return;
+ }
+
+ String systemId = input.getSystemId();
+ if (systemId == null) {
+ throw new SAXException("No input specified.");
+ }
+
+ // Try the system id.
+ in = ExpatParser.openUrl(systemId);
+ try {
+ parse(in, encoding, input.getPublicId(), systemId);
+ } finally {
+ in.close();
+ }
+ }
+
+ private void parse(Reader in, String publicId, String systemId)
+ throws IOException, SAXException {
+ ExpatParser parser = new ExpatParser(
+ ExpatParser.CHARACTER_ENCODING,
+ this,
+ processNamespaces,
+ publicId,
+ systemId
+ );
+ parser.parseDocument(in);
+ }
+
+ private void parse(InputStream in, String encoding, String publicId,
+ String systemId) throws IOException, SAXException {
+ ExpatParser parser = new ExpatParser(
+ encoding,
+ this,
+ processNamespaces,
+ publicId,
+ systemId
+ );
+ parser.parseDocument(in);
+ }
+
+ public void parse(String systemId) throws IOException, SAXException {
+ parse(new InputSource(systemId));
+ }
+}
diff --git a/xml/src/main/java/org/apache/harmony/xml/dom/AttrImpl.java b/xml/src/main/java/org/apache/harmony/xml/dom/AttrImpl.java
new file mode 100644
index 0000000..a39e0c4
--- /dev/null
+++ b/xml/src/main/java/org/apache/harmony/xml/dom/AttrImpl.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xml.dom;
+
+import org.w3c.dom.Attr;
+import org.w3c.dom.DOMException;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+/**
+ * Provides a straightforward implementation of the corresponding W3C DOM
+ * interface. The class is used internally only, thus only notable members that
+ * are not in the original interface are documented (the W3C docs are quite
+ * extensive). Hope that's ok.
+ * <p>
+ * Some of the fields may have package visibility, so other classes belonging to
+ * the DOM implementation can easily access them while maintaining the DOM tree
+ * structure.
+ */
+public class AttrImpl extends NodeImpl implements Attr {
+
+ // Maintained by ElementImpl.
+ ElementImpl ownerElement;
+
+ private boolean namespaceAware;
+
+ private String namespaceURI;
+
+ private String localName;
+
+ private String prefix;
+
+ private String value;
+
+ AttrImpl(DocumentImpl document, String namespaceURI, String qualifiedName) {
+ super(document);
+
+ namespaceAware = true;
+ this.namespaceURI = namespaceURI;
+
+ if (qualifiedName == null || "".equals(qualifiedName)) {
+ throw new DOMException(DOMException.NAMESPACE_ERR, qualifiedName);
+ }
+
+ int prefixSeparator = qualifiedName.lastIndexOf(":");
+ if (prefixSeparator != -1) {
+ setPrefix(qualifiedName.substring(0, prefixSeparator));
+ qualifiedName = qualifiedName.substring(prefixSeparator + 1);
+ }
+
+ localName = qualifiedName;
+
+ if ("".equals(localName)) {
+ throw new DOMException(DOMException.NAMESPACE_ERR, localName);
+ }
+
+ if ("xmlns".equals(localName) && !"http://www.w3.org/2000/xmlns/".equals(namespaceURI)) {
+ throw new DOMException(DOMException.NAMESPACE_ERR, localName);
+ }
+
+ if (!document.isXMLIdentifier(localName)) {
+ throw new DOMException(DOMException.INVALID_CHARACTER_ERR, localName);
+ }
+
+ value = "";
+ }
+
+ AttrImpl(DocumentImpl document, String name) {
+ super(document);
+
+ this.namespaceAware = false;
+
+ int prefixSeparator = name.lastIndexOf(":");
+ if (prefixSeparator != -1) {
+ String prefix = name.substring(0, prefixSeparator);
+ String localName = name.substring(prefixSeparator + 1);
+
+ if (!document.isXMLIdentifier(prefix) || !document.isXMLIdentifier(localName)) {
+ throw new DOMException(DOMException.INVALID_CHARACTER_ERR, name);
+ }
+ } else {
+ if (!document.isXMLIdentifier(name)) {
+ throw new DOMException(DOMException.INVALID_CHARACTER_ERR, name);
+ }
+ }
+
+ this.localName = name;
+ }
+
+ @Override
+ public String getLocalName() {
+ return namespaceAware ? localName : null;
+ }
+
+ public String getName() {
+ return (prefix != null ? prefix + ":" : "") + localName;
+ }
+
+ @Override
+ public String getNamespaceURI() {
+ return namespaceURI;
+ }
+
+ @Override
+ public String getNodeName() {
+ return getName();
+ }
+
+ public short getNodeType() {
+ return Node.ATTRIBUTE_NODE;
+ }
+
+ @Override
+ public String getNodeValue() {
+ return getValue();
+ }
+
+ public Element getOwnerElement() {
+ return ownerElement;
+ }
+
+ @Override
+ public String getPrefix() {
+ return prefix;
+ }
+
+ public boolean getSpecified() {
+ return value != null;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ @Override
+ public void setNodeValue(String value) throws DOMException {
+ setValue(value);
+ }
+
+ @Override
+ public void setPrefix(String prefix) {
+ if (!namespaceAware) {
+ throw new DOMException(DOMException.NAMESPACE_ERR, prefix);
+ }
+
+ if (prefix != null) {
+ if (namespaceURI == null || !document.isXMLIdentifier(prefix) || "xmlns".equals(prefix)) {
+ throw new DOMException(DOMException.NAMESPACE_ERR, prefix);
+ }
+
+ if ("xml".equals(prefix) && !"http://www.w3.org/XML/1998/namespace".equals(namespaceURI)) {
+ throw new DOMException(DOMException.NAMESPACE_ERR, prefix);
+ }
+ }
+
+ this.prefix = prefix;
+ }
+
+ public void setValue(String value) throws DOMException {
+ this.value = value;
+ }
+
+}
diff --git a/xml/src/main/java/org/apache/harmony/xml/dom/CDATASectionImpl.java b/xml/src/main/java/org/apache/harmony/xml/dom/CDATASectionImpl.java
new file mode 100644
index 0000000..f54e5f4
--- /dev/null
+++ b/xml/src/main/java/org/apache/harmony/xml/dom/CDATASectionImpl.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xml.dom;
+
+import org.w3c.dom.CDATASection;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+
+/**
+ * Provides a straightforward implementation of the corresponding W3C DOM
+ * interface. The class is used internally only, thus only notable members that
+ * are not in the original interface are documented (the W3C docs are quite
+ * extensive). Hope that's ok.
+ * <p>
+ * Some of the fields may have package visibility, so other classes belonging to
+ * the DOM implementation can easily access them while maintaining the DOM tree
+ * structure.
+ */
+public class CDATASectionImpl extends TextImpl implements CDATASection {
+
+ CDATASectionImpl(DocumentImpl document, String data) {
+ super(document, data);
+ }
+
+ @Override
+ public String getNodeName() {
+ return "#cdata-section";
+ }
+
+ @Override
+ public short getNodeType() {
+ return Node.CDATA_SECTION_NODE;
+ }
+
+}
diff --git a/xml/src/main/java/org/apache/harmony/xml/dom/CharacterDataImpl.java b/xml/src/main/java/org/apache/harmony/xml/dom/CharacterDataImpl.java
new file mode 100644
index 0000000..010cb22
--- /dev/null
+++ b/xml/src/main/java/org/apache/harmony/xml/dom/CharacterDataImpl.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xml.dom;
+
+import org.w3c.dom.CharacterData;
+import org.w3c.dom.DOMException;
+import org.w3c.dom.Document;
+
+/**
+ * Provides a straightforward implementation of the corresponding W3C DOM
+ * interface. The class is used internally only, thus only notable members that
+ * are not in the original interface are documented (the W3C docs are quite
+ * extensive). Hope that's ok.
+ * <p>
+ * Some of the fields may have package visibility, so other classes belonging to
+ * the DOM implementation can easily access them while maintaining the DOM tree
+ * structure.
+ */
+public abstract class CharacterDataImpl extends LeafNodeImpl implements
+ CharacterData {
+
+ private StringBuffer buffer;
+
+ CharacterDataImpl(DocumentImpl document, String data) {
+ super(document);
+ setData(data);
+ }
+
+ public void appendData(String arg) throws DOMException {
+ buffer.append(arg);
+ }
+
+ public void deleteData(int offset, int count) throws DOMException {
+ buffer.delete(offset, offset + count);
+ }
+
+ public String getData() throws DOMException {
+ return buffer.toString();
+ }
+
+ public int getLength() {
+ return buffer.length();
+ }
+
+ @Override
+ public String getNodeValue() {
+ return getData();
+ }
+
+ public void insertData(int offset, String arg) throws DOMException {
+ try {
+ buffer.insert(offset, arg);
+ } catch (ArrayIndexOutOfBoundsException ex) {
+ throw new DOMException(DOMException.INDEX_SIZE_ERR, null);
+ }
+ }
+
+ public void replaceData(int offset, int count, String arg)
+ throws DOMException {
+ try {
+ buffer.replace(offset, offset + count, arg);
+ } catch (ArrayIndexOutOfBoundsException ex) {
+ throw new DOMException(DOMException.INDEX_SIZE_ERR, null);
+ }
+ }
+
+ public void setData(String data) throws DOMException {
+ buffer = new StringBuffer(data);
+ }
+
+ public String substringData(int offset, int count) throws DOMException {
+ try {
+ return buffer.substring(offset, offset + count);
+ } catch (ArrayIndexOutOfBoundsException ex) {
+ throw new DOMException(DOMException.INDEX_SIZE_ERR, null);
+ }
+ }
+
+}
diff --git a/xml/src/main/java/org/apache/harmony/xml/dom/CommentImpl.java b/xml/src/main/java/org/apache/harmony/xml/dom/CommentImpl.java
new file mode 100644
index 0000000..6c1f446
--- /dev/null
+++ b/xml/src/main/java/org/apache/harmony/xml/dom/CommentImpl.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xml.dom;
+
+import org.w3c.dom.Comment;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+
+/**
+ * Provides a straightforward implementation of the corresponding W3C DOM
+ * interface. The class is used internally only, thus only notable members that
+ * are not in the original interface are documented (the W3C docs are quite
+ * extensive). Hope that's ok.
+ * <p>
+ * Some of the fields may have package visibility, so other classes belonging to
+ * the DOM implementation can easily access them while maintaining the DOM tree
+ * structure.
+ */
+public class CommentImpl extends CharacterDataImpl implements Comment {
+
+ CommentImpl(DocumentImpl document, String data) {
+ super(document, data);
+ }
+
+ @Override
+ public String getNodeName() {
+ return "#comment";
+ }
+
+ @Override
+ public short getNodeType() {
+ return Node.COMMENT_NODE;
+ }
+
+}
diff --git a/xml/src/main/java/org/apache/harmony/xml/dom/DOMImplementationImpl.java b/xml/src/main/java/org/apache/harmony/xml/dom/DOMImplementationImpl.java
new file mode 100644
index 0000000..4e13d19
--- /dev/null
+++ b/xml/src/main/java/org/apache/harmony/xml/dom/DOMImplementationImpl.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xml.dom;
+
+import org.w3c.dom.DOMException;
+import org.w3c.dom.DOMImplementation;
+import org.w3c.dom.Document;
+import org.w3c.dom.DocumentType;
+
+/**
+ * Provides a straightforward implementation of the corresponding W3C DOM
+ * interface. The class is used internally only, thus only notable members that
+ * are not in the original interface are documented (the W3C docs are quite
+ * extensive). Hope that's ok.
+ * <p>
+ * Some of the fields may have package visibility, so other classes belonging to
+ * the DOM implementation can easily access them while maintaining the DOM tree
+ * structure.
+ */
+public class DOMImplementationImpl implements DOMImplementation {
+
+ // Singleton instance.
+ private static DOMImplementationImpl instance;
+
+ DOMImplementationImpl() {
+ }
+
+ public Document createDocument(String namespaceURI, String qualifiedName,
+ DocumentType doctype) throws DOMException {
+ return new DocumentImpl(this, namespaceURI, qualifiedName, doctype);
+ }
+
+ public DocumentType createDocumentType(String qualifiedName,
+ String publicId, String systemId) throws DOMException {
+ return new DocumentTypeImpl(this, qualifiedName, publicId, systemId);
+ }
+
+ public boolean hasFeature(String feature, String version) {
+ // We claim to support DOM Core Level 1 & 2, nothing else.
+
+ if ("Core".equalsIgnoreCase(feature) || "XML".equalsIgnoreCase(feature)) {
+ if (version == null || "".equals(version) || "1.0".equals(version) || "2.0".equals(version)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Requests the singleton instance of the class. Creates it first, if
+ * necessary.
+ *
+ * @return The singleton Android DOMImplementationImpl instance.
+ */
+ public static DOMImplementationImpl getInstance() {
+ if (instance == null) {
+ instance = new DOMImplementationImpl();
+ }
+
+ return instance;
+ }
+
+}
diff --git a/xml/src/main/java/org/apache/harmony/xml/dom/DocumentFragmentImpl.java b/xml/src/main/java/org/apache/harmony/xml/dom/DocumentFragmentImpl.java
new file mode 100644
index 0000000..88e6175
--- /dev/null
+++ b/xml/src/main/java/org/apache/harmony/xml/dom/DocumentFragmentImpl.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xml.dom;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.DocumentFragment;
+import org.w3c.dom.Node;
+
+/**
+ * Provides a straightforward implementation of the corresponding W3C DOM
+ * interface. The class is used internally only, thus only notable members that
+ * are not in the original interface are documented (the W3C docs are quite
+ * extensive). Hope that's ok.
+ * <p>
+ * Some of the fields may have package visibility, so other classes belonging to
+ * the DOM implementation can easily access them while maintaining the DOM tree
+ * structure.
+ */
+public class DocumentFragmentImpl extends InnerNodeImpl implements
+ DocumentFragment {
+
+ DocumentFragmentImpl(DocumentImpl document) {
+ super(document);
+ }
+
+ @Override
+ public String getNodeName() {
+ return "#document-fragment";
+ }
+
+ @Override
+ public short getNodeType() {
+ return Node.DOCUMENT_FRAGMENT_NODE;
+ }
+
+}
diff --git a/xml/src/main/java/org/apache/harmony/xml/dom/DocumentImpl.java b/xml/src/main/java/org/apache/harmony/xml/dom/DocumentImpl.java
new file mode 100644
index 0000000..fbb1cac
--- /dev/null
+++ b/xml/src/main/java/org/apache/harmony/xml/dom/DocumentImpl.java
@@ -0,0 +1,298 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xml.dom;
+
+import org.w3c.dom.Attr;
+import org.w3c.dom.CDATASection;
+import org.w3c.dom.CharacterData;
+import org.w3c.dom.Comment;
+import org.w3c.dom.DOMException;
+import org.w3c.dom.DOMImplementation;
+import org.w3c.dom.Document;
+import org.w3c.dom.DocumentFragment;
+import org.w3c.dom.DocumentType;
+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;
+
+/**
+ * Provides a straightforward implementation of the corresponding W3C DOM
+ * interface. The class is used internally only, thus only notable members that
+ * are not in the original interface are documented (the W3C docs are quite
+ * extensive). Hope that's ok.
+ * <p>
+ * Some of the fields may have package visibility, so other classes belonging to
+ * the DOM implementation can easily access them while maintaining the DOM tree
+ * structure.
+ */
+public class DocumentImpl extends InnerNodeImpl implements Document {
+
+ private DOMImplementation domImplementation;
+
+ DocumentImpl(DOMImplementationImpl impl, String namespaceURI,
+ String qualifiedName, DocumentType doctype) {
+ super(null);
+
+ this.domImplementation = impl;
+ // this.document = this;
+
+ if (doctype != null) {
+ appendChild(doctype);
+ }
+
+ if (qualifiedName != null) {
+ appendChild(createElementNS(namespaceURI, qualifiedName));
+ }
+ }
+
+ private static boolean isXMLIdentifierStart(char c) {
+ return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c == '_');
+ }
+
+ private static boolean isXMLIdentifierPart(char c) {
+ return isXMLIdentifierStart(c) || (c >= '0' && c <= '9') || (c == '-') || (c == '.');
+ }
+
+ static boolean isXMLIdentifier(String s) {
+ if (s.length() == 0) {
+ return false;
+ }
+
+ if (!isXMLIdentifierStart(s.charAt(0))) {
+ return false;
+ }
+
+ for (int i = 1; i < s.length(); i++) {
+ if (!isXMLIdentifierPart(s.charAt(i))) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Clones a node and (if requested) its children. The source node(s) may
+ * have been created by a different DocumentImpl or even DOM implementation.
+ *
+ * @param node The node to clone.
+ * @param deep If true, a deep copy is created (including all child nodes).
+ *
+ * @return The new node.
+ */
+ Node cloneNode(Node node, boolean deep) throws DOMException {
+ Node target;
+
+ switch (node.getNodeType()) {
+ case Node.ATTRIBUTE_NODE: {
+ Attr source = (Attr)node;
+ target = createAttributeNS(source.getNamespaceURI(), source.getLocalName());
+ target.setPrefix(source.getPrefix());
+ target.setNodeValue(source.getNodeValue());
+ break;
+ }
+ case Node.CDATA_SECTION_NODE: {
+ CharacterData source = (CharacterData)node;
+ target = createCDATASection(source.getData());
+ break;
+ }
+ case Node.COMMENT_NODE: {
+ Comment source = (Comment)node;
+ target = createComment(source.getData());
+ break;
+ }
+ case Node.DOCUMENT_FRAGMENT_NODE: {
+ // Source is irrelevant in this case.
+ target = createDocumentFragment();
+ break;
+ }
+ case Node.DOCUMENT_NODE: {
+ throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Cannot clone a Document node");
+ }
+ case Node.DOCUMENT_TYPE_NODE: {
+ throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Cannot clone a DocumentType node");
+ }
+ case Node.ELEMENT_NODE: {
+ Element source = (Element)node;
+ target = createElementNS(source.getNamespaceURI(), source.getLocalName());
+ target.setPrefix(source.getPrefix());
+
+ NamedNodeMap map = source.getAttributes();
+ for (int i = 0; i < map.getLength(); i++) {
+ Attr attr = (Attr)map.item(i);
+ ((Element)target).setAttributeNodeNS((Attr)cloneNode(attr, deep));
+ }
+ break;
+ }
+ case Node.ENTITY_NODE: {
+ throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Cannot clone an Entity node");
+ }
+ case Node.ENTITY_REFERENCE_NODE: {
+ EntityReference source = (EntityReference)node;
+ target = createEntityReference(source.getNodeName());
+ break;
+ }
+ case Node.NOTATION_NODE: {
+ throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Cannot clone a Notation node");
+ }
+ case Node.PROCESSING_INSTRUCTION_NODE: {
+ ProcessingInstruction source = (ProcessingInstruction)node;
+ target = createProcessingInstruction(source.getTarget(), source.getData());
+ break;
+ }
+ case Node.TEXT_NODE: {
+ Text source = (Text)node;
+ target = createTextNode(source.getData());
+ break;
+ }
+ default: {
+ throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Cannot clone unknown node type " + node.getNodeType() + " (" + node.getClass().getSimpleName() + ")");
+ }
+ }
+
+ if (deep) {
+ NodeList list = node.getChildNodes();
+ for (int i = 0; i < list.getLength(); i++) {
+ Node child = cloneNode(list.item(i), deep);
+ target.appendChild(child);
+ }
+ }
+
+ return target;
+ }
+
+ public AttrImpl createAttribute(String name) throws DOMException {
+ return new AttrImpl(this, name);
+ }
+
+ public Attr createAttributeNS(String namespaceURI, String qualifiedName)
+ throws DOMException {
+ return new AttrImpl(this, namespaceURI, qualifiedName);
+ }
+
+ public CDATASection createCDATASection(String data) throws DOMException {
+ return new CDATASectionImpl(this, data);
+ }
+
+ public Comment createComment(String data) {
+ return new CommentImpl(this, data);
+ }
+
+ public DocumentFragment createDocumentFragment() {
+ return new DocumentFragmentImpl(this);
+ }
+
+ public Element createElement(String tagName) throws DOMException {
+ return new ElementImpl(this, tagName);
+ }
+
+ public Element createElementNS(String namespaceURI, String qualifiedName)
+ throws DOMException {
+ return new ElementImpl(this, namespaceURI, qualifiedName);
+ }
+
+ public EntityReference createEntityReference(String name)
+ throws DOMException {
+ return new EntityReferenceImpl(this, name);
+ }
+
+ public ProcessingInstruction createProcessingInstruction(String target,
+ String data) throws DOMException {
+ return new ProcessingInstructionImpl(this, target, data);
+ }
+
+ public Text createTextNode(String data) {
+ return new TextImpl(this, data);
+ }
+
+ public DocumentType getDoctype() {
+ for (int i = 0; i < children.size(); i++) {
+ if (children.get(i) instanceof DocumentType) {
+ return (DocumentType) children.get(i);
+ }
+ }
+
+ return null;
+ }
+
+ public Element getDocumentElement() {
+ for (int i = 0; i < children.size(); i++) {
+ if (children.get(i) instanceof Element) {
+ return (Element) children.get(i);
+ }
+ }
+
+ return null;
+ }
+
+ public Element getElementById(String elementId) {
+ ElementImpl root = (ElementImpl) getDocumentElement();
+
+ return (root == null ? null : root.getElementById(elementId));
+ }
+
+ public NodeList getElementsByTagName(String tagname) {
+ ElementImpl root = (ElementImpl) getDocumentElement();
+
+ return (root == null ? new NodeListImpl()
+ : root.getElementsByTagName(tagname));
+ }
+
+ public NodeList getElementsByTagNameNS(String namespaceURI, String localName) {
+ ElementImpl root = (ElementImpl) getDocumentElement();
+
+ return (root == null ? new NodeListImpl() : root.getElementsByTagNameNS(
+ namespaceURI, localName));
+ }
+
+ public DOMImplementation getImplementation() {
+ return domImplementation;
+ }
+
+ @Override
+ public String getNodeName() {
+ return "#document";
+ }
+
+ @Override
+ public short getNodeType() {
+ return Node.DOCUMENT_NODE;
+ }
+
+ public Node importNode(Node importedNode, boolean deep) throws DOMException {
+ return cloneNode(importedNode, deep);
+ }
+
+ @Override
+ public Node insertChildAt(Node newChild, int index) throws DOMException {
+ // Make sure we have at most one root element and one DTD element.
+ if (newChild instanceof Element && getDocumentElement() != null) {
+ throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR,
+ "Only one root element allowed");
+ } else if (newChild instanceof DocumentType && getDoctype() != null) {
+ throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR,
+ "Only one DOCTYPE element allowed");
+ }
+
+ return super.insertChildAt(newChild, index);
+ }
+
+}
diff --git a/xml/src/main/java/org/apache/harmony/xml/dom/DocumentTypeImpl.java b/xml/src/main/java/org/apache/harmony/xml/dom/DocumentTypeImpl.java
new file mode 100644
index 0000000..df40d4b
--- /dev/null
+++ b/xml/src/main/java/org/apache/harmony/xml/dom/DocumentTypeImpl.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xml.dom;
+
+import org.w3c.dom.DOMException;
+import org.w3c.dom.DocumentType;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+
+/**
+ * Provides a straightforward implementation of the corresponding W3C DOM
+ * interface. The class is used internally only, thus only notable members that
+ * are not in the original interface are documented (the W3C docs are quite
+ * extensive). Hope that's ok.
+ * <p>
+ * Some of the fields may have package visibility, so other classes belonging to
+ * the DOM implementation can easily access them while maintaining the DOM tree
+ * structure.
+ */
+public class DocumentTypeImpl extends LeafNodeImpl implements DocumentType {
+
+ private String qualifiedName;
+
+ private String publicId;
+
+ private String systemId;
+
+ DocumentTypeImpl(DOMImplementationImpl impl, String qualifiedName,
+ String publicId, String systemId) {
+ super(null);
+
+ if (qualifiedName == null || "".equals(qualifiedName)) {
+ throw new DOMException(DOMException.NAMESPACE_ERR, qualifiedName);
+ }
+
+ int prefixSeparator = qualifiedName.lastIndexOf(":");
+ if (prefixSeparator != -1) {
+ String prefix = qualifiedName.substring(0, prefixSeparator);
+ String localName = qualifiedName.substring(prefixSeparator + 1);
+
+ if (!DocumentImpl.isXMLIdentifier(prefix)) {
+ throw new DOMException(DOMException.NAMESPACE_ERR, qualifiedName);
+ }
+
+ if (!DocumentImpl.isXMLIdentifier(localName)) {
+ throw new DOMException(DOMException.INVALID_CHARACTER_ERR, qualifiedName);
+ }
+ } else {
+ if (!DocumentImpl.isXMLIdentifier(qualifiedName)) {
+ throw new DOMException(DOMException.INVALID_CHARACTER_ERR, qualifiedName);
+ }
+ }
+
+ this.qualifiedName = qualifiedName;
+ this.publicId = publicId;
+ this.systemId = systemId;
+ }
+
+ @Override
+ public String getNodeName() {
+ return qualifiedName;
+ }
+
+ @Override
+ public short getNodeType() {
+ return Node.DOCUMENT_TYPE_NODE;
+ }
+
+ public NamedNodeMap getEntities() {
+ // TODO Dummy. Implement this later, if at all (we're DOM level 2 only).
+ return null;
+ }
+
+ public String getInternalSubset() {
+ // TODO Dummy. Implement this later, if at all (we're DOM level 2 only).
+ return null;
+ }
+
+ public String getName() {
+ return qualifiedName;
+ }
+
+ public NamedNodeMap getNotations() {
+ // TODO Dummy. Implement this later, if at all (we're DOM level 2 only).
+ return null;
+ }
+
+ public String getPublicId() {
+ return publicId;
+ }
+
+ public String getSystemId() {
+ return systemId;
+ }
+
+}
diff --git a/xml/src/main/java/org/apache/harmony/xml/dom/ElementImpl.java b/xml/src/main/java/org/apache/harmony/xml/dom/ElementImpl.java
new file mode 100644
index 0000000..3b44ff3
--- /dev/null
+++ b/xml/src/main/java/org/apache/harmony/xml/dom/ElementImpl.java
@@ -0,0 +1,446 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xml.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.w3c.dom.Attr;
+import org.w3c.dom.DOMException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * Provides a straightforward implementation of the corresponding W3C DOM
+ * interface. The class is used internally only, thus only notable members that
+ * are not in the original interface are documented (the W3C docs are quite
+ * extensive). Hope that's ok.
+ * <p>
+ * Some of the fields may have package visibility, so other classes belonging to
+ * the DOM implementation can easily access them while maintaining the DOM tree
+ * structure.
+ */
+public class ElementImpl extends InnerNodeImpl implements Element {
+
+ private boolean namespaceAware;
+
+ private String namespaceURI;
+
+ private String prefix;
+
+ private String localName;
+
+ private List<AttrImpl> attributes = new ArrayList<AttrImpl>();
+
+ ElementImpl(DocumentImpl document, String namespaceURI, String qualifiedName) {
+ super(document);
+
+ this.namespaceAware = true;
+ this.namespaceURI = namespaceURI;
+
+ if (qualifiedName == null || "".equals(qualifiedName)) {
+ throw new DOMException(DOMException.NAMESPACE_ERR, qualifiedName);
+ }
+
+ int p = qualifiedName.lastIndexOf(":");
+ if (p != -1) {
+ setPrefix(qualifiedName.substring(0, p));
+ qualifiedName = qualifiedName.substring(p + 1);
+ }
+
+ if (!document.isXMLIdentifier(qualifiedName)) {
+ throw new DOMException(DOMException.INVALID_CHARACTER_ERR, qualifiedName);
+ }
+
+ this.localName = qualifiedName;
+ }
+
+ ElementImpl(DocumentImpl document, String name) {
+ super(document);
+
+ this.namespaceAware = false;
+
+ int p = name.lastIndexOf(":");
+ if (p != -1) {
+ String prefix = name.substring(0, p);
+ String localName = name.substring(p + 1);
+
+ if (!document.isXMLIdentifier(prefix) || !document.isXMLIdentifier(localName)) {
+ throw new DOMException(DOMException.INVALID_CHARACTER_ERR, name);
+ }
+ } else {
+ if (!document.isXMLIdentifier(name)) {
+ throw new DOMException(DOMException.INVALID_CHARACTER_ERR, name);
+ }
+ }
+
+ this.localName = name;
+ }
+
+ private int indexOfAttribute(String name) {
+ for (int i = 0; i < attributes.size(); i++) {
+ AttrImpl attr = attributes.get(i);
+ if (attr.matchesName(name, false)) {
+ return i;
+ }
+ }
+
+ return -1;
+ }
+
+ private int indexOfAttributeNS(String namespaceURI, String localName) {
+ for (int i = 0; i < attributes.size(); i++) {
+ AttrImpl attr = attributes.get(i);
+ if (attr.matchesNameNS(namespaceURI, localName, false)) {
+ return i;
+ }
+ }
+
+ return -1;
+ }
+
+ public String getAttribute(String name) {
+ Attr attr = getAttributeNode(name);
+
+ if (attr == null) {
+ return "";
+ }
+
+ return attr.getValue();
+ }
+
+ public String getAttributeNS(String namespaceURI, String localName) {
+ Attr attr = getAttributeNodeNS(namespaceURI, localName);
+
+ if (attr == null) {
+ return "";
+ }
+
+ return attr.getValue();
+ }
+
+ public Attr getAttributeNode(String name) {
+ int i = indexOfAttribute(name);
+
+ if (i == -1) {
+ return null;
+ }
+
+ return attributes.get(i);
+ }
+
+ public Attr getAttributeNodeNS(String namespaceURI, String localName) {
+ int i = indexOfAttributeNS(namespaceURI, localName);
+
+ if (i == -1) {
+ return null;
+ }
+
+ return attributes.get(i);
+ }
+
+ @Override
+ public NamedNodeMap getAttributes() {
+ return new ElementAttrNamedNodeMapImpl();
+ }
+
+ Element getElementById(String name) {
+ if (name.equals(getAttribute("id"))) {
+ return this;
+ }
+
+ for (NodeImpl node : children) {
+ if (node.getNodeType() == Node.ELEMENT_NODE) {
+ Element element = ((ElementImpl) node).getElementById(name);
+ if (element != null) {
+ return element;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ public NodeList getElementsByTagName(String name) {
+ NodeListImpl list = new NodeListImpl();
+ getElementsByTagName(list, name);
+ return list;
+ }
+
+ void getElementsByTagName(NodeListImpl list, String name) {
+ if (matchesName(name, true)) {
+ list.add(this);
+ }
+
+ for (NodeImpl node : children) {
+ if (node.getNodeType() == Node.ELEMENT_NODE) {
+ ((ElementImpl) node).getElementsByTagName(list, name);
+ }
+ }
+ }
+
+ public NodeList getElementsByTagNameNS(String namespaceURI, String localName) {
+ NodeListImpl list = new NodeListImpl();
+ getElementsByTagNameNS(list, namespaceURI, localName);
+ return list;
+ }
+
+ void getElementsByTagNameNS(NodeListImpl list, String namespaceURI,
+ String localName) {
+ if (matchesNameNS(namespaceURI, localName, true)) {
+ list.add(this);
+ }
+
+ for (NodeImpl node : children) {
+ if (node.getNodeType() == Node.ELEMENT_NODE) {
+ ((ElementImpl) node).getElementsByTagNameNS(list, namespaceURI,
+ localName);
+ }
+ }
+ }
+
+ @Override
+ public String getLocalName() {
+ return namespaceAware ? localName : null;
+ }
+
+ @Override
+ public String getNamespaceURI() {
+ return namespaceURI;
+ }
+
+ @Override
+ public String getNodeName() {
+ return getTagName();
+ }
+
+ public short getNodeType() {
+ return Node.ELEMENT_NODE;
+ }
+
+ @Override
+ public String getPrefix() {
+ return prefix;
+ }
+
+ public String getTagName() {
+ return (prefix != null ? prefix + ":" : "") + localName;
+ }
+
+ public boolean hasAttribute(String name) {
+ return indexOfAttribute(name) != -1;
+ }
+
+ public boolean hasAttributeNS(String namespaceURI, String localName) {
+ return indexOfAttributeNS(namespaceURI, localName) != -1;
+ }
+
+ @Override
+ public boolean hasAttributes() {
+ return !attributes.isEmpty();
+ }
+
+ public void removeAttribute(String name) throws DOMException {
+ int i = indexOfAttribute(name);
+
+ if (i != -1) {
+ attributes.remove(i);
+ }
+ }
+
+ public void removeAttributeNS(String namespaceURI, String localName)
+ throws DOMException {
+ int i = indexOfAttributeNS(namespaceURI, localName);
+
+ if (i != -1) {
+ attributes.remove(i);
+ }
+ }
+
+ public Attr removeAttributeNode(Attr oldAttr) throws DOMException {
+ AttrImpl oldAttrImpl = (AttrImpl) oldAttr;
+
+ if (oldAttrImpl.getOwnerElement() != this) {
+ throw new DOMException(DOMException.NOT_FOUND_ERR, null);
+ }
+
+ attributes.remove(oldAttr);
+ oldAttrImpl.ownerElement = null;
+
+ return oldAttrImpl;
+ }
+
+ public void setAttribute(String name, String value) throws DOMException {
+ Attr attr = getAttributeNode(name);
+
+ if (attr == null) {
+ attr = document.createAttribute(name);
+ setAttributeNode(attr);
+ }
+
+ attr.setValue(value);
+ }
+
+ public void setAttributeNS(String namespaceURI, String qualifiedName,
+ String value) throws DOMException {
+ Attr attr = getAttributeNodeNS(namespaceURI, qualifiedName);
+
+ if (attr == null) {
+ attr = document.createAttributeNS(namespaceURI, qualifiedName);
+ setAttributeNodeNS(attr);
+ }
+
+ attr.setValue(value);
+ }
+
+ public Attr setAttributeNode(Attr newAttr) throws DOMException {
+ AttrImpl newAttrImpl = (AttrImpl) newAttr;
+
+ if (newAttrImpl.document != this.getOwnerDocument()) {
+ throw new DOMException(DOMException.WRONG_DOCUMENT_ERR, null);
+ }
+
+ if (newAttrImpl.getOwnerElement() != null) {
+ throw new DOMException(DOMException.INUSE_ATTRIBUTE_ERR, null);
+ }
+
+ AttrImpl oldAttrImpl = null;
+
+ int i = indexOfAttribute(newAttr.getName());
+ if (i != -1) {
+ oldAttrImpl = attributes.get(i);
+ attributes.remove(i);
+ }
+
+ attributes.add(newAttrImpl);
+ newAttrImpl.ownerElement = this;
+
+ return oldAttrImpl;
+ }
+
+ public Attr setAttributeNodeNS(Attr newAttr) throws DOMException {
+ AttrImpl newAttrImpl = (AttrImpl) newAttr;
+
+ if (newAttrImpl.document != this.getOwnerDocument()) {
+ throw new DOMException(DOMException.WRONG_DOCUMENT_ERR, null);
+ }
+
+ if (newAttrImpl.getOwnerElement() != null) {
+ throw new DOMException(DOMException.INUSE_ATTRIBUTE_ERR, null);
+ }
+
+ AttrImpl oldAttrImpl = null;
+
+ int i = indexOfAttributeNS(newAttr.getNamespaceURI(), newAttr.getLocalName());
+ if (i != -1) {
+ oldAttrImpl = attributes.get(i);
+ attributes.remove(i);
+ }
+
+ attributes.add(newAttrImpl);
+ newAttrImpl.ownerElement = this;
+
+ return oldAttrImpl;
+ }
+
+ @Override
+ public void setPrefix(String prefix) {
+ if (!namespaceAware) {
+ throw new DOMException(DOMException.NAMESPACE_ERR, prefix);
+ }
+
+ if (prefix != null) {
+ if (namespaceURI == null || !document.isXMLIdentifier(prefix)) {
+ throw new DOMException(DOMException.NAMESPACE_ERR, prefix);
+ }
+
+ if ("xml".equals(prefix) && !"http://www.w3.org/XML/1998/namespace".equals(namespaceURI)) {
+ throw new DOMException(DOMException.NAMESPACE_ERR, prefix);
+ }
+ }
+
+ this.prefix = prefix;
+ }
+
+ public class ElementAttrNamedNodeMapImpl implements NamedNodeMap {
+
+ public int getLength() {
+ return ElementImpl.this.attributes.size();
+ }
+
+ private int indexOfItem(String name) {
+ return ElementImpl.this.indexOfAttribute(name);
+ }
+
+ private int indexOfItemNS(String namespaceURI, String localName) {
+ return ElementImpl.this.indexOfAttributeNS(namespaceURI, localName);
+ }
+
+ public Node getNamedItem(String name) {
+ return ElementImpl.this.getAttributeNode(name);
+ }
+
+ public Node getNamedItemNS(String namespaceURI, String localName) {
+ return ElementImpl.this.getAttributeNodeNS(namespaceURI, localName);
+ }
+
+ public Node item(int index) {
+ return ElementImpl.this.attributes.get(index);
+ }
+
+ public Node removeNamedItem(String name) throws DOMException {
+ int i = indexOfItem(name);
+
+ if (i == -1) {
+ throw new DOMException(DOMException.NOT_FOUND_ERR, null);
+ }
+
+ return ElementImpl.this.attributes.remove(i);
+ }
+
+ public Node removeNamedItemNS(String namespaceURI, String localName)
+ throws DOMException {
+ int i = indexOfItemNS(namespaceURI, localName);
+
+ if (i == -1) {
+ throw new DOMException(DOMException.NOT_FOUND_ERR, null);
+ }
+
+ return ElementImpl.this.attributes.remove(i);
+ }
+
+ public Node setNamedItem(Node arg) throws DOMException {
+ if (!(arg instanceof Attr)) {
+ throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, null);
+ }
+
+ return ElementImpl.this.setAttributeNode((Attr)arg);
+ }
+
+ public Node setNamedItemNS(Node arg) throws DOMException {
+ if (!(arg instanceof Attr)) {
+ throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, null);
+ }
+
+ return ElementImpl.this.setAttributeNodeNS((Attr)arg);
+ }
+ }
+
+}
diff --git a/xml/src/main/java/org/apache/harmony/xml/dom/EntityImpl.java b/xml/src/main/java/org/apache/harmony/xml/dom/EntityImpl.java
new file mode 100644
index 0000000..463e863
--- /dev/null
+++ b/xml/src/main/java/org/apache/harmony/xml/dom/EntityImpl.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xml.dom;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Entity;
+import org.w3c.dom.Node;
+
+/**
+ * Provides a straightforward implementation of the corresponding W3C DOM
+ * interface. The class is used internally only, thus only notable members that
+ * are not in the original interface are documented (the W3C docs are quite
+ * extensive). Hope that's ok.
+ * <p>
+ * Some of the fields may have package visibility, so other classes belonging to
+ * the DOM implementation can easily access them while maintaining the DOM tree
+ * structure.
+ */
+public class EntityImpl extends NodeImpl implements Entity {
+
+ private String notationName;
+
+ private String publicID;
+
+ private String systemID;
+
+ EntityImpl(DocumentImpl document, String notationName, String publicID,
+ String systemID) {
+ super(document);
+ this.notationName = notationName;
+ this.publicID = publicID;
+ this.systemID = systemID;
+ }
+
+ @Override
+ public String getNodeName() {
+ return getNotationName();
+ }
+
+ @Override
+ public short getNodeType() {
+ return Node.ENTITY_NODE;
+ }
+
+ public String getNotationName() {
+ return notationName;
+ }
+
+ public String getPublicId() {
+ return publicID;
+ }
+
+ public String getSystemId() {
+ return systemID;
+ }
+
+}
diff --git a/xml/src/main/java/org/apache/harmony/xml/dom/EntityReferenceImpl.java b/xml/src/main/java/org/apache/harmony/xml/dom/EntityReferenceImpl.java
new file mode 100644
index 0000000..f612a15
--- /dev/null
+++ b/xml/src/main/java/org/apache/harmony/xml/dom/EntityReferenceImpl.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xml.dom;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.EntityReference;
+import org.w3c.dom.Node;
+
+/**
+ * Provides a straightforward implementation of the corresponding W3C DOM
+ * interface. The class is used internally only, thus only notable members that
+ * are not in the original interface are documented (the W3C docs are quite
+ * extensive). Hope that's ok.
+ * <p>
+ * Some of the fields may have package visibility, so other classes belonging to
+ * the DOM implementation can easily access them while maintaining the DOM tree
+ * structure.
+ */
+public class EntityReferenceImpl extends LeafNodeImpl implements EntityReference {
+
+ private String name;
+
+ EntityReferenceImpl(DocumentImpl document, String name) {
+ super(document);
+ this.name = name;
+ }
+
+ @Override
+ public String getNodeName() {
+ return name;
+ }
+
+ @Override
+ public short getNodeType() {
+ return Node.ENTITY_REFERENCE_NODE;
+ }
+
+}
diff --git a/xml/src/main/java/org/apache/harmony/xml/dom/InnerNodeImpl.java b/xml/src/main/java/org/apache/harmony/xml/dom/InnerNodeImpl.java
new file mode 100644
index 0000000..f71d289
--- /dev/null
+++ b/xml/src/main/java/org/apache/harmony/xml/dom/InnerNodeImpl.java
@@ -0,0 +1,221 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xml.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.w3c.dom.DOMException;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Text;
+
+/**
+ * Provides a straightforward implementation of the corresponding W3C DOM
+ * interface. The class is used internally only, thus only notable members that
+ * are not in the original interface are documented (the W3C docs are quite
+ * extensive). Hope that's ok.
+ * <p>
+ * Some of the fields may have package visibility, so other classes belonging to
+ * the DOM implementation can easily access them while maintaining the DOM tree
+ * structure.
+ * <p>
+ * This class represents a Node that has a parent Node as well as (potentially)
+ * a number of children.
+ */
+public abstract class InnerNodeImpl extends LeafNodeImpl {
+
+ // Maintained by LeafNodeImpl and ElementImpl.
+ List<LeafNodeImpl> children = new ArrayList<LeafNodeImpl>();
+
+ public InnerNodeImpl(DocumentImpl document) {
+ super(document);
+ }
+
+ public Node appendChild(Node newChild) throws DOMException {
+ return insertChildAt(newChild, children.size());
+ }
+
+ public NodeList getChildNodes() {
+ NodeListImpl list = new NodeListImpl();
+
+ for (NodeImpl node : children) {
+ list.add(node);
+ }
+
+ return list;
+ }
+
+ public Node getFirstChild() {
+ return (!children.isEmpty() ? children.get(0) : null);
+ }
+
+ public Node getLastChild() {
+ return (!children.isEmpty() ? children.get(children.size() - 1) : null);
+ }
+
+ public Node getNextSibling() {
+ if (parent == null || index >= parent.children.size()) {
+ return null;
+ }
+
+ return parent.children.get(index + 1);
+ }
+
+ public boolean hasChildNodes() {
+ return children.size() != 0;
+ }
+
+ public Node insertBefore(Node newChild, Node refChild) throws DOMException {
+ LeafNodeImpl refChildImpl = (LeafNodeImpl) refChild;
+
+ if (refChildImpl.document != document) {
+ throw new DOMException(DOMException.WRONG_DOCUMENT_ERR, null);
+ }
+
+ if (refChildImpl.parent != this) {
+ throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, null);
+ }
+
+ return insertChildAt(newChild, refChildImpl.index);
+ }
+
+ /**
+ * Inserts a new child node into this node at a given position. If the new
+ * node is already child of another node, it is first removed from there.
+ * This method is the generalization of the appendChild() and insertBefore()
+ * methods.
+ *
+ * @param newChild The new child node to add.
+ * @param index The index at which to insert the new child node.
+ *
+ * @return The node added.
+ *
+ * @throws DOMException If the attempted operation violates the XML/DOM
+ * well-formedness rules.
+ */
+ public Node insertChildAt(Node newChild, int index) throws DOMException {
+ LeafNodeImpl newChildImpl = (LeafNodeImpl) newChild;
+
+ if (document != null && newChildImpl.document != null && newChildImpl.document != document) {
+ throw new DOMException(DOMException.WRONG_DOCUMENT_ERR, null);
+ }
+
+ if (newChildImpl.isParentOf(this)) {
+ throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, null);
+ }
+
+ if (newChildImpl.parent != null) {
+ int oldIndex = newChildImpl.index;
+ newChildImpl.parent.children.remove(oldIndex);
+ newChildImpl.parent.refreshIndices(oldIndex);
+ }
+
+ children.add(index, newChildImpl);
+ newChildImpl.parent = this;
+ refreshIndices(index);
+
+ return newChild;
+ }
+
+ public boolean isParentOf(Node node) {
+ LeafNodeImpl nodeImpl = (LeafNodeImpl) node;
+
+ while (nodeImpl != null) {
+ if (nodeImpl == this) {
+ return true;
+ }
+
+ nodeImpl = nodeImpl.parent;
+ }
+
+ return false;
+ }
+
+ @Override
+ public void normalize() {
+ Node nextNode = null;
+
+ for (int i = children.size() - 1; i >= 0; i--) {
+ Node thisNode = children.get(i);
+
+ thisNode.normalize();
+
+ if (thisNode.getNodeType() == Node.TEXT_NODE) {
+ if (nextNode != null && nextNode.getNodeType() == Node.TEXT_NODE) {
+ ((Text)thisNode).setData(thisNode.getNodeValue() + nextNode.getNodeValue());
+ removeChild(nextNode);
+ }
+
+ if ("".equals(thisNode.getNodeValue())) {
+ removeChild(thisNode);
+ nextNode = null;
+ } else {
+ nextNode = thisNode;
+ }
+ }
+ }
+ }
+
+ private void refreshIndices(int fromIndex) {
+ for (int i = fromIndex; i < children.size(); i++) {
+ children.get(i).index = i;
+ }
+ }
+
+ public Node removeChild(Node oldChild) throws DOMException {
+ LeafNodeImpl oldChildImpl = (LeafNodeImpl) oldChild;
+
+ if (oldChildImpl.document != document) {
+ throw new DOMException(DOMException.WRONG_DOCUMENT_ERR, null);
+ }
+
+ if (oldChildImpl.parent != this) {
+ throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, null);
+ }
+
+ int index = oldChildImpl.index;
+ children.remove(index);
+ oldChildImpl.parent = null;
+ refreshIndices(index);
+
+ return oldChild;
+ }
+
+ public Node replaceChild(Node newChild, Node oldChild) throws DOMException {
+ LeafNodeImpl oldChildImpl = (LeafNodeImpl) oldChild;
+ LeafNodeImpl newChildImpl = (LeafNodeImpl) newChild;
+
+ if (oldChildImpl.document != document
+ || newChildImpl.document != document) {
+ throw new DOMException(DOMException.WRONG_DOCUMENT_ERR, null);
+ }
+
+ if (oldChildImpl.parent != this || newChildImpl.isParentOf(this)) {
+ throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, null);
+ }
+
+ int index = oldChildImpl.index;
+ children.set(index, newChildImpl);
+ oldChildImpl.parent = null;
+ newChildImpl.parent = this;
+ refreshIndices(index);
+
+ return oldChildImpl;
+ }
+
+}
diff --git a/xml/src/main/java/org/apache/harmony/xml/dom/LeafNodeImpl.java b/xml/src/main/java/org/apache/harmony/xml/dom/LeafNodeImpl.java
new file mode 100644
index 0000000..5f9698e
--- /dev/null
+++ b/xml/src/main/java/org/apache/harmony/xml/dom/LeafNodeImpl.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xml.dom;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+
+/**
+ * Provides a straightforward implementation of the corresponding W3C DOM
+ * interface. The class is used internally only, thus only notable members that
+ * are not in the original interface are documented (the W3C docs are quite
+ * extensive). Hope that's ok.
+ * <p>
+ * Some of the fields may have package visibility, so other classes belonging to
+ * the DOM implementation can easily access them while maintaining the DOM tree
+ * structure.
+ * <p>
+ * This class represents a Node that has a parent Node, but no children.
+ */
+public abstract class LeafNodeImpl extends NodeImpl {
+
+ // Maintained by InnerNodeImpl.
+ InnerNodeImpl parent;
+
+ // Maintained by InnerNodeImpl.
+ int index;
+
+ LeafNodeImpl(DocumentImpl document) {
+ super(document);
+ }
+
+ public Node getNextSibling() {
+ if (parent == null || index + 1 >= parent.children.size()) {
+ return null;
+ }
+
+ return parent.children.get(index + 1);
+ }
+
+ public Node getParentNode() {
+ return parent;
+ }
+
+ public Node getPreviousSibling() {
+ if (parent == null || index == 0) {
+ return null;
+ }
+
+ return parent.children.get(index - 1);
+ }
+
+ boolean isParentOf(Node node) {
+ return false;
+ }
+
+}
diff --git a/xml/src/main/java/org/apache/harmony/xml/dom/NamedNodeMapImpl.java b/xml/src/main/java/org/apache/harmony/xml/dom/NamedNodeMapImpl.java
new file mode 100644
index 0000000..0952d83
--- /dev/null
+++ b/xml/src/main/java/org/apache/harmony/xml/dom/NamedNodeMapImpl.java
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xml.dom;
+
+import org.w3c.dom.DOMException;
+import org.w3c.dom.Document;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Provides a straightforward implementation of the corresponding W3C DOM
+ * interface. The class is used internally only, thus only notable members that
+ * are not in the original interface are documented (the W3C docs are quite
+ * extensive). Hope that's ok.
+ * <p>
+ * Some of the fields may have package visibility, so other classes belonging to
+ * the DOM implementation can easily access them while maintaining the DOM tree
+ * structure.
+ */
+public class NamedNodeMapImpl implements NamedNodeMap {
+
+ private Class<?> type;
+
+ private List<NodeImpl> list;
+
+ NamedNodeMapImpl(Class<?> type) {
+ list = new ArrayList<NodeImpl>();
+ this.type = type;
+ }
+
+ NamedNodeMapImpl(List<NodeImpl> list, Class<?> type) {
+ this.list = list;
+ this.type = type;
+ }
+
+ public int getLength() {
+ return list.size();
+ }
+
+ private int indexOfItem(String name) {
+ for (int i = 0; i < list.size(); i++) {
+ NodeImpl node = list.get(i);
+ if (node.matchesName(name, false)) {
+ return i;
+ }
+ }
+
+ return -1;
+ }
+
+ private int indexOfItemNS(String namespaceURI, String localName) {
+ for (int i = 0; i < list.size(); i++) {
+ NodeImpl node = list.get(i);
+ if (node.matchesNameNS(namespaceURI, localName, false)) {
+ return i;
+ }
+ }
+
+ return -1;
+ }
+
+ public Node getNamedItem(String name) {
+ int i = indexOfItem(name);
+
+ return (i == -1 ? null : item(i));
+ }
+
+ public Node getNamedItemNS(String namespaceURI, String localName) {
+ int i = indexOfItemNS(namespaceURI, localName);
+
+ return (i == -1 ? null : item(i));
+ }
+
+ public Node item(int index) {
+ return list.get(index);
+ }
+
+ public Node removeNamedItem(String name) throws DOMException {
+ int i = indexOfItem(name);
+
+ if (i == -1) {
+ throw new DOMException(DOMException.NOT_FOUND_ERR, null);
+ }
+
+ return list.remove(i);
+ }
+
+ public Node removeNamedItemNS(String namespaceURI, String localName)
+ throws DOMException {
+ int i = indexOfItemNS(namespaceURI, localName);
+
+ if (i == -1) {
+ throw new DOMException(DOMException.NOT_FOUND_ERR, null);
+ }
+
+ return list.remove(i);
+ }
+
+ public Node setNamedItem(Node arg) throws DOMException {
+ // Ensure we only accept nodes of the correct type.
+ if (!type.isAssignableFrom(arg.getClass())) {
+ throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, null);
+ }
+
+ // All nodes in the map must belong to the same document.
+ if (list.size() != 0) {
+ Document document = list.get(0).getOwnerDocument();
+
+ if (document != null && arg.getOwnerDocument() != document) {
+ throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, null);
+ }
+ }
+
+// TODO Theoretically we should ensure that the nodes don't have a parent.
+// if (newAttrImpl.getOwnerElement() != null) {
+// throw new DOMException(DOMException.INUSE_ATTRIBUTE_ERR, null);
+// }
+
+ int i = indexOfItem(arg.getNodeName());
+
+ if (i != -1) {
+ list.remove(i);
+ }
+
+ list.add((NodeImpl)arg);
+ return arg;
+ }
+
+ public Node setNamedItemNS(Node arg) throws DOMException {
+ // Ensure we only accept nodes of the correct type.
+ if (!type.isAssignableFrom(arg.getClass())) {
+ throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, null);
+ }
+
+ // All nodes in the map must belong to the same document.
+ if (list.size() != 0) {
+ Document document = list.get(0).getOwnerDocument();
+
+ if (document != null && arg.getOwnerDocument() != document) {
+ throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, null);
+ }
+ }
+
+// TODO Theoretically we should ensure that the nodes don't have a parent.
+// if (newAttrImpl.getOwnerElement() != null) {
+// throw new DOMException(DOMException.INUSE_ATTRIBUTE_ERR, null);
+// }
+
+ int i = indexOfItemNS(arg.getNamespaceURI(), arg.getLocalName());
+
+ if (i != -1) {
+ list.remove(i);
+ }
+
+ list.add((NodeImpl)arg);
+ return arg;
+ }
+
+}
diff --git a/xml/src/main/java/org/apache/harmony/xml/dom/NodeImpl.java b/xml/src/main/java/org/apache/harmony/xml/dom/NodeImpl.java
new file mode 100644
index 0000000..ca6fb8f
--- /dev/null
+++ b/xml/src/main/java/org/apache/harmony/xml/dom/NodeImpl.java
@@ -0,0 +1,191 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xml.dom;
+
+import org.w3c.dom.DOMException;
+import org.w3c.dom.Document;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * Provides a straightforward implementation of the corresponding W3C DOM
+ * interface. The class is used internally only, thus only notable members that
+ * are not in the original interface are documented (the W3C docs are quite
+ * extensive). Hope that's ok.
+ * <p>
+ * Some of the fields may have package visibility, so other classes belonging to
+ * the DOM implementation can easily access them while maintaining the DOM tree
+ * structure.
+ * <p>
+ * This class represents a Node that has neither a parent nor children.
+ */
+public abstract class NodeImpl implements Node {
+
+ private static final NodeList EMPTY_LIST = new NodeListImpl();
+
+ // Maintained by InnerNodeImpl and ElementImpl.
+ DocumentImpl document;
+
+ NodeImpl(DocumentImpl document) {
+ this.document = document;
+ }
+
+ public Node appendChild(Node newChild) throws DOMException {
+ throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, null);
+ }
+
+ public Node cloneNode(boolean deep) {
+ return document.cloneNode(this, deep);
+ }
+
+ public NamedNodeMap getAttributes() {
+ return null;
+ }
+
+ public NodeList getChildNodes() {
+ return EMPTY_LIST;
+ }
+
+ public Node getFirstChild() {
+ return null;
+ }
+
+ public Node getLastChild() {
+ return null;
+ }
+
+ public String getLocalName() {
+ return null;
+ }
+
+ public String getNamespaceURI() {
+ return null;
+ }
+
+ public Node getNextSibling() {
+ return null;
+ }
+
+ public String getNodeName() {
+ return null;
+ }
+
+ public abstract short getNodeType();
+
+ public String getNodeValue() throws DOMException {
+ return null;
+ }
+
+ public Document getOwnerDocument() {
+ return document;
+ }
+
+ public Node getParentNode() {
+ return null;
+ }
+
+ public String getPrefix() {
+ return null;
+ }
+
+ public Node getPreviousSibling() {
+ return null;
+ }
+
+ public boolean hasAttributes() {
+ return false;
+ }
+
+ public boolean hasChildNodes() {
+ return false;
+ }
+
+ public Node insertBefore(Node newChild, Node refChild) throws DOMException {
+ throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, null);
+ }
+
+ public boolean isSupported(String feature, String version) {
+ return DOMImplementationImpl.getInstance().hasFeature(feature, version);
+ }
+
+ public void normalize() {
+ }
+
+ public Node removeChild(Node oldChild) throws DOMException {
+ throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, null);
+ }
+
+ public Node replaceChild(Node newChild, Node oldChild) throws DOMException {
+ throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, null);
+ }
+
+ public void setNodeValue(String nodeValue) throws DOMException {
+ }
+
+ public void setPrefix(String prefix) throws DOMException {
+ }
+
+ /**
+ * Checks whether a required string matches an actual string. This utility
+ * method is used for comparing namespaces and such. It takes into account
+ * null arguments and the "*" special case.
+ *
+ * @param required The required string.
+ * @param actual The actual string.
+ * @return True if and only if the actual string matches the required one.
+ */
+ private static boolean matchesName(String required, String actual, boolean wildcard) {
+ if (wildcard && "*".equals(required)) {
+ return true;
+ }
+
+ if (required == null) {
+ return (actual == null);
+ }
+
+ return required.equals(actual);
+ }
+
+ /**
+ * Checks whether this node's name matches a required name. It takes into
+ * account null arguments and the "*" special case.
+ *
+ * @param name The required name.
+ * @param wildcard TODO
+ * @return True if and only if the actual name matches the required one.
+ */
+ public boolean matchesName(String name, boolean wildcard) {
+ return matchesName(name, getNodeName(), wildcard);
+ }
+
+ /**
+ * Checks whether this node's namespace and local name match a required
+ * pair of namespace and local name. It takes into account null arguments
+ * and the "*" special case.
+ *
+ * @param namespaceURI The required namespace.
+ * @param localName The required local name.
+ * @param wildcard TODO
+ * @return True if and only if the actual namespace and local name match
+ * the required pair of namespace and local name.
+ */
+ public boolean matchesNameNS(String namespaceURI, String localName, boolean wildcard) {
+ return matchesName(namespaceURI, getNamespaceURI(), wildcard) && matchesName(localName, getLocalName(), wildcard);
+ }
+
+}
diff --git a/xml/src/main/java/org/apache/harmony/xml/dom/NodeListImpl.java b/xml/src/main/java/org/apache/harmony/xml/dom/NodeListImpl.java
new file mode 100644
index 0000000..caa56af
--- /dev/null
+++ b/xml/src/main/java/org/apache/harmony/xml/dom/NodeListImpl.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xml.dom;
+
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Provides a straightforward implementation of the corresponding W3C DOM
+ * interface. The class is used internally only, thus only notable members that
+ * are not in the original interface are documented (the W3C docs are quite
+ * extensive). Hope that's ok.
+ * <p>
+ * Some of the fields may have package visibility, so other classes belonging to
+ * the DOM implementation can easily access them while maintaining the DOM tree
+ * structure.
+ */
+public class NodeListImpl implements NodeList {
+
+ private List<NodeImpl> children;
+
+ NodeListImpl() {
+ children = new ArrayList<NodeImpl>();
+ }
+
+ NodeListImpl(List<NodeImpl> list) {
+ children = list;
+ }
+
+ void add(NodeImpl node) {
+ children.add(node);
+ }
+
+ public int getLength() {
+ return children.size();
+ }
+
+ public Node item(int index) {
+ if (index >= children.size()) {
+ return null;
+ } else {
+ return children.get(index);
+ }
+ }
+
+}
diff --git a/xml/src/main/java/org/apache/harmony/xml/dom/NotationImpl.java b/xml/src/main/java/org/apache/harmony/xml/dom/NotationImpl.java
new file mode 100644
index 0000000..4d91d75
--- /dev/null
+++ b/xml/src/main/java/org/apache/harmony/xml/dom/NotationImpl.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xml.dom;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.Notation;
+
+/**
+ * Provides a straightforward implementation of the corresponding W3C DOM
+ * interface. The class is used internally only, thus only notable members that
+ * are not in the original interface are documented (the W3C docs are quite
+ * extensive). Hope that's ok.
+ * <p>
+ * Some of the fields may have package visibility, so other classes belonging to
+ * the DOM implementation can easily access them while maintaining the DOM tree
+ * structure.
+ */
+public class NotationImpl extends LeafNodeImpl implements Notation {
+
+ private String notationName;
+
+ private String publicID;
+
+ private String systemID;
+
+ NotationImpl(DocumentImpl document, String notationName, String publicID,
+ String systemID) {
+ super(document);
+ }
+
+ @Override
+ public String getNodeName() {
+ return notationName;
+ }
+
+ @Override
+ public short getNodeType() {
+ return Node.NOTATION_NODE;
+ }
+
+ public String getPublicId() {
+ return publicID;
+ }
+
+ public String getSystemId() {
+ return systemID;
+ }
+
+}
diff --git a/xml/src/main/java/org/apache/harmony/xml/dom/ProcessingInstructionImpl.java b/xml/src/main/java/org/apache/harmony/xml/dom/ProcessingInstructionImpl.java
new file mode 100644
index 0000000..c3610d5
--- /dev/null
+++ b/xml/src/main/java/org/apache/harmony/xml/dom/ProcessingInstructionImpl.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xml.dom;
+
+import org.w3c.dom.DOMException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.ProcessingInstruction;
+
+/**
+ * Provides a straightforward implementation of the corresponding W3C DOM
+ * interface. The class is used internally only, thus only notable members that
+ * are not in the original interface are documented (the W3C docs are quite
+ * extensive). Hope that's ok.
+ * <p>
+ * Some of the fields may have package visibility, so other classes belonging to
+ * the DOM implementation can easily access them while maintaining the DOM tree
+ * structure.
+ */
+public class ProcessingInstructionImpl extends LeafNodeImpl implements
+ ProcessingInstruction {
+
+ private String target;
+
+ private String data;
+
+ ProcessingInstructionImpl(DocumentImpl document, String target, String data) {
+ super(document);
+ this.target = target;
+ this.data = data;
+ }
+
+ public String getData() {
+ return data;
+ }
+
+ @Override
+ public String getNodeName() {
+ return target;
+ }
+
+ @Override
+ public short getNodeType() {
+ return Node.PROCESSING_INSTRUCTION_NODE;
+ }
+
+ @Override
+ public String getNodeValue() {
+ return data;
+ }
+
+ public String getTarget() {
+ return target;
+ }
+
+ public void setData(String data) throws DOMException {
+ this.data = data;
+ }
+
+}
diff --git a/xml/src/main/java/org/apache/harmony/xml/dom/TextImpl.java b/xml/src/main/java/org/apache/harmony/xml/dom/TextImpl.java
new file mode 100644
index 0000000..3553546
--- /dev/null
+++ b/xml/src/main/java/org/apache/harmony/xml/dom/TextImpl.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xml.dom;
+
+import org.w3c.dom.DOMException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.Text;
+
+/**
+ * Provides a straightforward implementation of the corresponding W3C DOM
+ * interface. The class is used internally only, thus only notable members that
+ * are not in the original interface are documented (the W3C docs are quite
+ * extensive). Hope that's ok.
+ * <p>
+ * Some of the fields may have package visibility, so other classes belonging to
+ * the DOM implementation can easily access them while maintaining the DOM tree
+ * structure.
+ */
+public class TextImpl extends CharacterDataImpl implements Text {
+
+ TextImpl(DocumentImpl document, String data) {
+ super(document, data);
+ }
+
+ @Override
+ public String getNodeName() {
+ return "#text";
+ }
+
+ @Override
+ public short getNodeType() {
+ return Node.TEXT_NODE;
+ }
+
+ @Override
+ public String getNodeValue() {
+ return getData();
+ }
+
+ public Text splitText(int offset) throws DOMException {
+ Text newText = getOwnerDocument().createTextNode(
+ substringData(offset, getLength() - offset));
+ deleteData(0, offset);
+
+ Node refNode = getNextSibling();
+ if (refNode == null) {
+ getParentNode().appendChild(newText);
+ } else {
+ getParentNode().insertBefore(newText, refNode);
+ }
+
+ return this;
+ }
+
+}
diff --git a/xml/src/main/java/org/apache/harmony/xml/parsers/DocumentBuilderFactoryImpl.java b/xml/src/main/java/org/apache/harmony/xml/parsers/DocumentBuilderFactoryImpl.java
new file mode 100644
index 0000000..4b8eef3
--- /dev/null
+++ b/xml/src/main/java/org/apache/harmony/xml/parsers/DocumentBuilderFactoryImpl.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xml.parsers;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+/**
+ * Provides a straightforward DocumentBuilderFactory implementation based on
+ * XMLPull/KXML. The class is used internally only, thus only notable members
+ * that are not already in the abstract superclass are documented. Hope that's
+ * ok.
+ */
+public class DocumentBuilderFactoryImpl extends DocumentBuilderFactory {
+
+ private static final String NAMESPACES =
+ "http://xml.org/sax/features/namespaces";
+
+ private static final String VALIDATION =
+ "http://xml.org/sax/features/validation";
+
+ @Override
+ public Object getAttribute(String name) throws IllegalArgumentException {
+ throw new IllegalArgumentException(name);
+ }
+
+ @Override
+ public boolean getFeature(String name) throws ParserConfigurationException {
+ if (name == null) {
+ throw new NullPointerException();
+ }
+
+ if (NAMESPACES.equals(name)) {
+ return isNamespaceAware();
+ } else if (VALIDATION.equals(name)) {
+ return isValidating();
+ } else {
+ throw new ParserConfigurationException(name);
+ }
+ }
+
+ @Override
+ public DocumentBuilder newDocumentBuilder()
+ throws ParserConfigurationException {
+ if (isValidating()) {
+ throw new ParserConfigurationException(
+ "No validating DocumentBuilder implementation available");
+ }
+
+ /**
+ * TODO If Android is going to support a different DocumentBuilder
+ * implementations, this should be wired here. If we wanted to
+ * allow different implementations, these could be distinguished by
+ * a special feature (like http://www.org.apache.harmony.com/xml/expat)
+ * or by throwing the full SPI monty at it.
+ */
+ DocumentBuilderImpl builder = new DocumentBuilderImpl();
+
+ builder.setIgnoreComments(isIgnoringComments());
+ builder.setIgnoreElementContentWhitespace(
+ isIgnoringElementContentWhitespace());
+ builder.setNamespaceAware(isNamespaceAware());
+
+ // TODO What about expandEntityReferences?
+
+ return builder;
+ }
+
+ @Override
+ public void setAttribute(String name, Object value)
+ throws IllegalArgumentException {
+ throw new IllegalArgumentException(name);
+ }
+
+ @Override
+ public void setFeature(String name, boolean value)
+ throws ParserConfigurationException {
+ if (name == null) {
+ throw new NullPointerException();
+ }
+
+ if (NAMESPACES.equals(name)) {
+ setNamespaceAware(value);
+ } else if (VALIDATION.equals(name)) {
+ setValidating(value);
+ } else {
+ throw new ParserConfigurationException(name);
+ }
+ }
+
+}
diff --git a/xml/src/main/java/org/apache/harmony/xml/parsers/DocumentBuilderImpl.java b/xml/src/main/java/org/apache/harmony/xml/parsers/DocumentBuilderImpl.java
new file mode 100644
index 0000000..f831c8b
--- /dev/null
+++ b/xml/src/main/java/org/apache/harmony/xml/parsers/DocumentBuilderImpl.java
@@ -0,0 +1,436 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xml.parsers;
+
+import java.io.IOException;
+import java.util.StringTokenizer;
+
+import javax.xml.parsers.DocumentBuilder;
+
+import org.kxml2.io.KXmlParser;
+import org.w3c.dom.Attr;
+import org.w3c.dom.DOMImplementation;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.helpers.LocatorImpl;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import org.apache.harmony.xml.dom.DOMImplementationImpl;
+
+/**
+ * Provides a straightforward DocumentBuilder implementation based on
+ * XMLPull/KXML. The class is used internally only, thus only notable members
+ * that are not already in the abstract superclass are documented. Hope that's
+ * ok.
+ */
+class DocumentBuilderImpl extends DocumentBuilder {
+
+ private static DOMImplementation dom = DOMImplementationImpl.getInstance();
+
+ private EntityResolver entityResolver;
+
+ private ErrorHandler errorHandler;
+
+ private boolean ignoreComments;
+
+ private boolean ignoreElementContentWhitespace;
+
+ private boolean namespaceAware;
+
+ DocumentBuilderImpl() {
+ // Do nothing.
+ }
+
+ @Override
+ public DOMImplementation getDOMImplementation() {
+ return dom;
+ }
+
+ /**
+ * Reflects whether this DocumentBuilder is configured to ignore comments.
+ *
+ * @return True if and only if comments are ignored.
+ */
+ public boolean isIgnoringComments() {
+ return ignoreComments;
+ }
+
+ /**
+ * Reflects whether this DocumentBuilder is configured to ignore element
+ * content whitespace.
+ *
+ * @return True if and only if whitespace element content is ignored.
+ */
+ public boolean isIgnoringElementContentWhitespace() {
+ return ignoreElementContentWhitespace;
+ }
+
+ @Override
+ public boolean isNamespaceAware() {
+ return namespaceAware;
+ }
+
+ @Override
+ public boolean isValidating() {
+ return false;
+ }
+
+ @Override
+ public Document newDocument() {
+ return dom.createDocument(null, null, null);
+ }
+
+ @Override
+ public Document parse(InputSource source) throws SAXException, IOException {
+ if (source == null) {
+ throw new IllegalArgumentException();
+ }
+
+ Document document = newDocument();
+
+ try {
+ XmlPullParser parser = new KXmlParser();
+
+ parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES,
+ namespaceAware);
+
+ if (source.getByteStream() != null) {
+ parser.setInput(source.getByteStream(), source.getEncoding());
+ } else if (source.getCharacterStream() != null) {
+ parser.setInput(source.getCharacterStream());
+ } else {
+ // TODO Accept other sources as well?
+ throw new SAXParseException(
+ "InputSource needs either stream or reader", null);
+ }
+
+ if(parser.nextToken() == XmlPullParser.END_DOCUMENT) {
+ throw new SAXParseException(
+ "Unexpected end of document", null);
+ }
+
+ parse(parser, document, document, XmlPullParser.END_DOCUMENT);
+
+ parser.require(XmlPullParser.END_DOCUMENT, null, null);
+ } catch (XmlPullParserException ex) {
+ if(ex.getDetail() instanceof IOException) {
+ throw (IOException)ex.getDetail();
+ }
+ if(ex.getDetail() instanceof RuntimeException) {
+ throw (RuntimeException)ex.getDetail();
+ }
+
+ LocatorImpl locator = new LocatorImpl();
+
+ locator.setPublicId(source.getPublicId());
+ locator.setSystemId(source.getSystemId());
+ locator.setLineNumber(ex.getLineNumber());
+ locator.setColumnNumber(ex.getColumnNumber());
+
+ SAXParseException newEx = new SAXParseException(ex.getMessage(),
+ locator);
+
+ if (errorHandler != null) {
+ errorHandler.error(newEx);
+ }
+
+ throw newEx;
+ }
+
+ return document;
+ }
+
+ /**
+ * Implements the whole parsing of the XML document. The XML pull parser is
+ * actually more of a tokenizer, and we are doing a classical recursive
+ * descent parsing (the method invokes itself for XML elements). Our
+ * approach to parsing does accept some illegal documents (more than one
+ * root element, for example). The assumption is that the DOM implementation
+ * throws the proper exceptions in these cases.
+ *
+ * @param parser The XML pull parser we're reading from.
+ * @param document The document we're building.
+ * @param node The node we're currently on (initially the document itself).
+ * @param endToken The token that will end this recursive call. Either
+ * XmlPullParser.END_DOCUMENT or XmlPullParser.END_TAG.
+ *
+ * @throws XmlPullParserException If a parsing error occurs.
+ * @throws IOException If a general IO error occurs.
+ */
+ private void parse(XmlPullParser parser, Document document, Node node,
+ int endToken) throws XmlPullParserException, IOException {
+
+ int token = parser.getEventType();
+
+ /*
+ * The main parsing loop. The precondition is that we are already on the
+ * token to be processed. This holds for each iteration of the loop, so
+ * the inner statements have to ensure that (in particular the recursive
+ * call).
+ */
+ while (token != endToken && token != XmlPullParser.END_DOCUMENT) {
+ if (token == XmlPullParser.PROCESSING_INSTRUCTION) {
+ /*
+ * Found a processing instructions. We need to split the token
+ * text at the first whitespace character.
+ */
+ String text = parser.getText();
+
+ int dot = text.indexOf(' ');
+
+ String target = (dot != -1 ? text.substring(0, dot) : text);
+ String data = (dot != -1 ? text.substring(dot + 1) : "");
+
+ node.appendChild(document.createProcessingInstruction(target,
+ data));
+ } else if (token == XmlPullParser.DOCDECL) {
+ /*
+ * Found a document type declaration. Unfortunately KXML doesn't
+ * have the necessary details. Do we parse it ourselves, or do
+ * we silently ignore it, since it isn't mandatory in DOM 2
+ * anyway?
+ */
+ StringTokenizer tokenizer = new StringTokenizer(parser.getText());
+ if (tokenizer.hasMoreTokens()) {
+ String name = tokenizer.nextToken();
+ String pubid = null;
+ String sysid = null;
+
+ if (tokenizer.hasMoreTokens()) {
+ String text = tokenizer.nextToken();
+
+ if ("SYSTEM".equals(text)) {
+ if (tokenizer.hasMoreTokens()) {
+ sysid = tokenizer.nextToken();
+ }
+ } else if ("PUBLIC".equals(text)) {
+ if (tokenizer.hasMoreTokens()) {
+ pubid = tokenizer.nextToken();
+ }
+ if (tokenizer.hasMoreTokens()) {
+ sysid = tokenizer.nextToken();
+ }
+ }
+ }
+
+ if (pubid != null && pubid.length() >= 2 && pubid.startsWith("\"") && pubid.endsWith("\"")) {
+ pubid = pubid.substring(1, pubid.length() - 1);
+ }
+
+ if (sysid != null && sysid.length() >= 2 && sysid.startsWith("\"") && sysid.endsWith("\"")) {
+ sysid = sysid.substring(1, sysid.length() - 1);
+ }
+
+ document.appendChild(dom.createDocumentType(name, pubid, sysid));
+ }
+
+ } else if (token == XmlPullParser.COMMENT) {
+ /*
+ * Found a comment. We simply take the token text, but we only
+ * create a node if the client wants to see comments at all.
+ */
+ if (!ignoreComments) {
+ node.appendChild(document.createComment(parser.getText()));
+ }
+ } else if (token == XmlPullParser.IGNORABLE_WHITESPACE) {
+ /*
+ * Found some ignorable whitespace. We simply take the token
+ * text, but we only create a node if the client wants to see
+ * whitespace at all.
+ */
+ if (!ignoreElementContentWhitespace) {
+ node.appendChild(document.createTextNode(parser.getText()));
+ }
+ } else if (token == XmlPullParser.TEXT) {
+ /*
+ * Found a piece of text. That's the easiest case. We simply
+ * take it and create a corresponding node.
+ */
+ node.appendChild(document.createTextNode(parser.getText()));
+ } else if (token == XmlPullParser.CDSECT) {
+ /*
+ * Found a CDATA section. That's also trivial. We simply
+ * take it and create a corresponding node.
+ */
+ node.appendChild(document.createCDATASection(parser.getText()));
+ } else if (token == XmlPullParser.ENTITY_REF) {
+ /*
+ * Found an entity reference. If an entity resolver is
+ * installed, we replace it by text (if possible). Otherwise we
+ * add an entity reference node.
+ */
+ String entity = parser.getName();
+
+ if (entityResolver != null) {
+ // TODO Implement this...
+ }
+
+ String replacement = resolveStandardEntity(entity);
+ if (replacement != null) {
+ node.appendChild(document.createTextNode(replacement));
+ } else {
+ node.appendChild(document.createEntityReference(entity));
+ }
+ } else if (token == XmlPullParser.START_TAG) {
+ /*
+ * Found an element start tag. We create an element node with
+ * the proper info and attributes. We then invoke parse()
+ * recursively to handle the next level of nesting. When we
+ * return from this call, we check that we are on the proper
+ * element end tag. The whole handling differs somewhat
+ * depending on whether the parser is namespace-aware or not.
+ */
+ if (namespaceAware) {
+ // Collect info for element node
+ String namespace = parser.getNamespace();
+ String name = parser.getName();
+ String prefix = parser.getPrefix();
+
+ if ("".equals(namespace)) {
+ namespace = null;
+ }
+
+ // Create element node and wire it correctly
+ Element element = document.createElementNS(namespace, name);
+ element.setPrefix(prefix);
+ node.appendChild(element);
+
+ for (int i = 0; i < parser.getAttributeCount(); i++) {
+ // Collect info for a single attribute node
+ String attrNamespace = parser.getAttributeNamespace(i);
+ String attrPrefix = parser.getAttributePrefix(i);
+ String attrName = parser.getAttributeName(i);
+ String attrValue = parser.getAttributeValue(i);
+
+ if ("".equals(attrNamespace)) {
+ attrNamespace = null;
+ }
+
+ // Create attribute node and wire it correctly
+ Attr attr = document.createAttributeNS(attrNamespace, attrName);
+ attr.setPrefix(attrPrefix);
+ attr.setValue(attrValue);
+ element.setAttributeNodeNS(attr);
+ }
+
+ // Recursive descent
+ token = parser.nextToken();
+ parse(parser, document, element, XmlPullParser.END_TAG);
+
+ // Expect the element's end tag here
+ parser.require(XmlPullParser.END_TAG, namespace, name);
+
+ } else {
+ // Collect info for element node
+ String name = parser.getName();
+
+ // Create element node and wire it correctly
+ Element element = document.createElement(name);
+ node.appendChild(element);
+
+ for (int i = 0; i < parser.getAttributeCount(); i++) {
+ // Collect info for a single attribute node
+ String attrName = parser.getAttributeName(i);
+ String attrValue = parser.getAttributeValue(i);
+
+ // Create attribute node and wire it correctly
+ Attr attr = document.createAttribute(attrName);
+ attr.setValue(attrValue);
+ element.setAttributeNode(attr);
+ }
+
+ // Recursive descent
+ token = parser.nextToken();
+ parse(parser, document, element, XmlPullParser.END_TAG);
+
+ // Expect the element's end tag here
+ parser.require(XmlPullParser.END_TAG, "", name);
+ }
+ }
+
+ token = parser.nextToken();
+ }
+ }
+
+ @Override
+ public void setEntityResolver(EntityResolver resolver) {
+ entityResolver = resolver;
+ }
+
+ @Override
+ public void setErrorHandler(ErrorHandler handler) {
+ errorHandler = handler;
+ }
+
+ /**
+ * Controls whether this DocumentBuilder ignores comments.
+ *
+ * @param value Turns comment ignorance on or off.
+ */
+ public void setIgnoreComments(boolean value) {
+ ignoreComments = value;
+ }
+
+ /**
+ * Controls whether this DocumentBuilder ignores element content whitespace.
+ *
+ * @param value Turns element whitespace content ignorance on or off.
+ */
+ public void setIgnoreElementContentWhitespace(boolean value) {
+ ignoreElementContentWhitespace = value;
+ }
+
+ /**
+ * Controls whether this DocumentBuilder is namespace-aware.
+ *
+ * @param value Turns namespace awareness on or off.
+ */
+ public void setNamespaceAware(boolean value) {
+ namespaceAware = value;
+ }
+
+ /**
+ * Resolves one of the five standard XML entities.
+ *
+ * @param entity The name of the entity to resolve, not including
+ * the ampersand or the semicolon.
+ *
+ * @return The proper replacement, or null, if the entity is unknown.
+ */
+ private String resolveStandardEntity(String entity) {
+ if ("lt".equals(entity)) {
+ return "<";
+ } else if ("gt".equals(entity)) {
+ return ">";
+ } else if ("amp".equals(entity)) {
+ return "&";
+ } else if ("apos".equals(entity)) {
+ return "'";
+ } else if ("quot".equals(entity)) {
+ return "\"";
+ } else {
+ return null;
+ }
+ }
+}
diff --git a/xml/src/main/java/org/apache/harmony/xml/parsers/SAXParserFactoryImpl.java b/xml/src/main/java/org/apache/harmony/xml/parsers/SAXParserFactoryImpl.java
new file mode 100644
index 0000000..6846216
--- /dev/null
+++ b/xml/src/main/java/org/apache/harmony/xml/parsers/SAXParserFactoryImpl.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xml.parsers;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.xml.sax.SAXNotRecognizedException;
+
+/**
+ * Provides a straightforward SAXParserFactory implementation based on
+ * Expat. The class is used internally only, thus only notable members
+ * that are not already in the abstract superclass are documented.
+ */
+public class SAXParserFactoryImpl extends SAXParserFactory {
+
+ private static final String NAMESPACES
+ = "http://xml.org/sax/features/namespaces";
+
+ private static final String VALIDATION
+ = "http://xml.org/sax/features/validation";
+
+ private Map<String, Boolean> features = new HashMap<String, Boolean>();
+
+ @Override
+ public boolean getFeature(String name) throws SAXNotRecognizedException {
+ if (name == null) {
+ throw new NullPointerException();
+ }
+
+ if (!name.startsWith("http://xml.org/sax/features/")) {
+ throw new SAXNotRecognizedException(name);
+ }
+
+ return Boolean.TRUE.equals(features.get(name));
+ }
+
+ @Override
+ public boolean isNamespaceAware() {
+ try {
+ return getFeature(NAMESPACES);
+ } catch (SAXNotRecognizedException ex) {
+ throw new AssertionError(ex);
+ }
+ }
+
+ @Override
+ public boolean isValidating() {
+ try {
+ return getFeature(VALIDATION);
+ } catch (SAXNotRecognizedException ex) {
+ throw new AssertionError(ex);
+ }
+ }
+
+ @Override
+ public SAXParser newSAXParser() throws ParserConfigurationException {
+ if (isValidating()) {
+ throw new ParserConfigurationException(
+ "No validating SAXParser implementation available");
+ }
+
+ try {
+ return new SAXParserImpl(features);
+ } catch (Exception ex) {
+ throw new ParserConfigurationException(ex.toString());
+ }
+ }
+
+ @Override
+ public void setFeature(String name, boolean value) throws SAXNotRecognizedException {
+ if (name == null) {
+ throw new NullPointerException();
+ }
+
+ if (!name.startsWith("http://xml.org/sax/features/")) {
+ throw new SAXNotRecognizedException(name);
+ }
+
+ if (value) {
+ features.put(name, Boolean.TRUE);
+ } else {
+ // This is needed to disable features that are enabled by default.
+ features.put(name, Boolean.FALSE);
+ }
+ }
+
+ @Override
+ public void setNamespaceAware(boolean value) {
+ try {
+ setFeature(NAMESPACES, value);
+ } catch (SAXNotRecognizedException ex) {
+ throw new AssertionError(ex);
+ }
+ }
+
+ @Override
+ public void setValidating(boolean value) {
+ try {
+ setFeature(VALIDATION, value);
+ } catch (SAXNotRecognizedException ex) {
+ throw new AssertionError(ex);
+ }
+ }
+}
diff --git a/xml/src/main/java/org/apache/harmony/xml/parsers/SAXParserImpl.java b/xml/src/main/java/org/apache/harmony/xml/parsers/SAXParserImpl.java
new file mode 100644
index 0000000..b3af61f
--- /dev/null
+++ b/xml/src/main/java/org/apache/harmony/xml/parsers/SAXParserImpl.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xml.parsers;
+
+import org.apache.harmony.xml.ExpatReader;
+
+import java.util.Map;
+
+import javax.xml.parsers.SAXParser;
+
+import org.xml.sax.Parser;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXNotRecognizedException;
+import org.xml.sax.SAXNotSupportedException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.XMLReaderAdapter;
+
+/**
+ * Provides a straightforward SAXParser implementation based on ExpatReader.
+ * The class is used internally only, thus only notable members that are not
+ * already in the abstract superclass are documented. Hope that's ok.
+ */
+class SAXParserImpl extends SAXParser {
+
+ private XMLReader reader;
+
+ private Parser parser;
+
+ SAXParserImpl(Map<String, Boolean> features)
+ throws SAXNotRecognizedException, SAXNotSupportedException {
+ reader = new ExpatReader();
+
+ for (Map.Entry<String,Boolean> entry : features.entrySet()) {
+ reader.setFeature(entry.getKey(), entry.getValue());
+ }
+ }
+
+ @Override
+ public Parser getParser() {
+ if (parser == null) {
+ parser = new XMLReaderAdapter(reader);
+ }
+
+ return parser;
+ }
+
+ @Override
+ public Object getProperty(String name) throws SAXNotRecognizedException,
+ SAXNotSupportedException {
+ return reader.getProperty(name);
+ }
+
+ @Override
+ public XMLReader getXMLReader() {
+ return reader;
+ }
+
+ @Override
+ public boolean isNamespaceAware() {
+ try {
+ return reader.getFeature("http://xml.org/sax/features/namespaces");
+ } catch (SAXException ex) {
+ return false;
+ }
+ }
+
+ @Override
+ public boolean isValidating() {
+ return false;
+ }
+
+ @Override
+ public void setProperty(String name, Object value)
+ throws SAXNotRecognizedException, SAXNotSupportedException {
+ reader.setProperty(name, value);
+ }
+}
diff --git a/xml/src/main/java/org/kxml2/io/KXmlParser.java b/xml/src/main/java/org/kxml2/io/KXmlParser.java
new file mode 100644
index 0000000..0727bc7
--- /dev/null
+++ b/xml/src/main/java/org/kxml2/io/KXmlParser.java
@@ -0,0 +1,1440 @@
+/* Copyright (c) 2002,2003, Stefan Haustein, Oberhausen, Rhld., Germany
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE. */
+
+// Contributors: Paul Hackenberger (unterminated entity handling in relaxed mode)
+
+package org.kxml2.io;
+
+import java.io.*;
+import java.util.*;
+
+import org.xmlpull.v1.*;
+
+/** A simple, pull based XML parser. This classe replaces the kXML 1
+ XmlParser class and the corresponding event classes. */
+
+public class KXmlParser implements XmlPullParser {
+
+ private Object location;
+ static final private String UNEXPECTED_EOF = "Unexpected EOF";
+ static final private String ILLEGAL_TYPE = "Wrong event type";
+ static final private int LEGACY = 999;
+ static final private int XML_DECL = 998;
+
+ // general
+
+ private String version;
+ private Boolean standalone;
+
+ private boolean processNsp;
+ private boolean relaxed;
+ private Hashtable entityMap;
+ private int depth;
+ private String[] elementStack = new String[16];
+ private String[] nspStack = new String[8];
+ private int[] nspCounts = new int[4];
+
+ // source
+
+ private Reader reader;
+ private String encoding;
+ private char[] srcBuf;
+
+ private int srcPos;
+ private int srcCount;
+
+ private int line;
+ private int column;
+
+ // txtbuffer
+
+ private char[] txtBuf = new char[128];
+ private int txtPos;
+
+ // Event-related
+
+ private int type;
+ //private String text;
+ private boolean isWhitespace;
+ private String namespace;
+ private String prefix;
+ private String name;
+
+ private boolean degenerated;
+ private int attributeCount;
+ private String[] attributes = new String[16];
+ private int stackMismatch = 0;
+ private String error;
+
+ /**
+ * A separate peek buffer seems simpler than managing
+ * wrap around in the first level read buffer */
+
+ private int[] peek = new int[2];
+ private int peekCount;
+ private boolean wasCR;
+
+ private boolean unresolved;
+ private boolean token;
+
+ public KXmlParser() {
+ // BEGIN android-changed
+ // We don't have a Runtime class at this time.
+ // srcBuf =
+ // new char[Runtime.getRuntime().freeMemory() >= 1048576 ? 8192 : 128];
+ srcBuf = new char[8192];
+ // END android-changed
+ }
+
+ private final boolean isProp(String n1, boolean prop, String n2) {
+ if (!n1.startsWith("http://xmlpull.org/v1/doc/"))
+ return false;
+ if (prop)
+ return n1.substring(42).equals(n2);
+ else
+ return n1.substring(40).equals(n2);
+ }
+
+ private final boolean adjustNsp() throws XmlPullParserException {
+
+ boolean any = false;
+
+ for (int i = 0; i < attributeCount << 2; i += 4) {
+ // * 4 - 4; i >= 0; i -= 4) {
+
+ String attrName = attributes[i + 2];
+ int cut = attrName.indexOf(':');
+ String prefix;
+
+ if (cut != -1) {
+ prefix = attrName.substring(0, cut);
+ attrName = attrName.substring(cut + 1);
+ }
+ else if (attrName.equals("xmlns")) {
+ prefix = attrName;
+ attrName = null;
+ }
+ else
+ continue;
+
+ if (!prefix.equals("xmlns")) {
+ any = true;
+ }
+ else {
+ int j = (nspCounts[depth]++) << 1;
+
+ nspStack = ensureCapacity(nspStack, j + 2);
+ nspStack[j] = attrName;
+ nspStack[j + 1] = attributes[i + 3];
+
+ if (attrName != null && attributes[i + 3].equals(""))
+ error("illegal empty namespace");
+
+ // prefixMap = new PrefixMap (prefixMap, attrName, attr.getValue ());
+
+ //System.out.println (prefixMap);
+
+ System.arraycopy(
+ attributes,
+ i + 4,
+ attributes,
+ i,
+ ((--attributeCount) << 2) - i);
+
+ i -= 4;
+ }
+ }
+
+ if (any) {
+ for (int i = (attributeCount << 2) - 4; i >= 0; i -= 4) {
+
+ String attrName = attributes[i + 2];
+ int cut = attrName.indexOf(':');
+
+ if (cut == 0 && !relaxed)
+ throw new RuntimeException(
+ "illegal attribute name: " + attrName + " at " + this);
+
+ else if (cut != -1) {
+ String attrPrefix = attrName.substring(0, cut);
+
+ attrName = attrName.substring(cut + 1);
+
+ String attrNs = getNamespace(attrPrefix);
+
+ if (attrNs == null && !relaxed)
+ throw new RuntimeException(
+ "Undefined Prefix: " + attrPrefix + " in " + this);
+
+ attributes[i] = attrNs;
+ attributes[i + 1] = attrPrefix;
+ attributes[i + 2] = attrName;
+
+ /*
+ if (!relaxed) {
+ for (int j = (attributeCount << 2) - 4; j > i; j -= 4)
+ if (attrName.equals(attributes[j + 2])
+ && attrNs.equals(attributes[j]))
+ exception(
+ "Duplicate Attribute: {"
+ + attrNs
+ + "}"
+ + attrName);
+ }
+ */
+ }
+ }
+ }
+
+ int cut = name.indexOf(':');
+
+ if (cut == 0)
+ error("illegal tag name: " + name);
+
+ if (cut != -1) {
+ prefix = name.substring(0, cut);
+ name = name.substring(cut + 1);
+ }
+
+ this.namespace = getNamespace(prefix);
+
+ if (this.namespace == null) {
+ if (prefix != null)
+ error("undefined prefix: " + prefix);
+ this.namespace = NO_NAMESPACE;
+ }
+
+ return any;
+ }
+
+ private final String[] ensureCapacity(String[] arr, int required) {
+ if (arr.length >= required)
+ return arr;
+ String[] bigger = new String[required + 16];
+ System.arraycopy(arr, 0, bigger, 0, arr.length);
+ return bigger;
+ }
+
+ private final void error(String desc) throws XmlPullParserException {
+ if (relaxed) {
+ if (error == null)
+ error = "ERR: " + desc;
+ }
+ else
+ exception(desc);
+ }
+
+ private final void exception(String desc) throws XmlPullParserException {
+ throw new XmlPullParserException(
+ desc.length() < 100 ? desc : desc.substring(0, 100) + "\n",
+ this,
+ null);
+ }
+
+ /**
+ * common base for next and nextToken. Clears the state, except from
+ * txtPos and whitespace. Does not set the type variable */
+
+ private final void nextImpl() throws IOException, XmlPullParserException {
+
+ if (reader == null)
+ exception("No Input specified");
+
+ if (type == END_TAG)
+ depth--;
+
+ while (true) {
+ attributeCount = -1;
+
+ // degenerated needs to be handled before error because of possible
+ // processor expectations(!)
+
+ if (degenerated) {
+ degenerated = false;
+ type = END_TAG;
+ return;
+ }
+
+
+ if (error != null) {
+ for (int i = 0; i < error.length(); i++)
+ push(error.charAt(i));
+ // text = error;
+ error = null;
+ type = COMMENT;
+ return;
+ }
+
+
+ if (relaxed
+ && (stackMismatch > 0 || (peek(0) == -1 && depth > 0))) {
+ int sp = (depth - 1) << 2;
+ type = END_TAG;
+ namespace = elementStack[sp];
+ prefix = elementStack[sp + 1];
+ name = elementStack[sp + 2];
+ if (stackMismatch != 1)
+ error = "missing end tag /" + name + " inserted";
+ if (stackMismatch > 0)
+ stackMismatch--;
+ return;
+ }
+
+ prefix = null;
+ name = null;
+ namespace = null;
+ // text = null;
+
+ type = peekType();
+
+ switch (type) {
+
+ case ENTITY_REF :
+ pushEntity();
+ return;
+
+ case START_TAG :
+ parseStartTag(false);
+ return;
+
+ case END_TAG :
+ parseEndTag();
+ return;
+
+ case END_DOCUMENT :
+ return;
+
+ case TEXT :
+ pushText('<', !token);
+ if (depth == 0) {
+ if (isWhitespace)
+ type = IGNORABLE_WHITESPACE;
+ // make exception switchable for instances.chg... !!!!
+ // else
+ // exception ("text '"+getText ()+"' not allowed outside root element");
+ }
+ return;
+
+ default :
+ type = parseLegacy(token);
+ if (type != XML_DECL)
+ return;
+ }
+ }
+ }
+
+ private final int parseLegacy(boolean push)
+ throws IOException, XmlPullParserException {
+
+ String req = "";
+ int term;
+ int result;
+ int prev = 0;
+
+ read(); // <
+ int c = read();
+
+ if (c == '?') {
+ if ((peek(0) == 'x' || peek(0) == 'X')
+ && (peek(1) == 'm' || peek(1) == 'M')) {
+
+ if (push) {
+ push(peek(0));
+ push(peek(1));
+ }
+ read();
+ read();
+
+ if ((peek(0) == 'l' || peek(0) == 'L') && peek(1) <= ' ') {
+
+ if (line != 1 || column > 4)
+ error("PI must not start with xml");
+
+ parseStartTag(true);
+
+ if (attributeCount < 1 || !"version".equals(attributes[2]))
+ error("version expected");
+
+ version = attributes[3];
+
+ int pos = 1;
+
+ if (pos < attributeCount
+ && "encoding".equals(attributes[2 + 4])) {
+ encoding = attributes[3 + 4];
+ pos++;
+ }
+
+ if (pos < attributeCount
+ && "standalone".equals(attributes[4 * pos + 2])) {
+ String st = attributes[3 + 4 * pos];
+ if ("yes".equals(st))
+ standalone = new Boolean(true);
+ else if ("no".equals(st))
+ standalone = new Boolean(false);
+ else
+ error("illegal standalone value: " + st);
+ pos++;
+ }
+
+ if (pos != attributeCount)
+ error("illegal xmldecl");
+
+ isWhitespace = true;
+ txtPos = 0;
+
+ return XML_DECL;
+ }
+ }
+
+ /* int c0 = read ();
+ int c1 = read ();
+ int */
+
+ term = '?';
+ result = PROCESSING_INSTRUCTION;
+ }
+ else if (c == '!') {
+ if (peek(0) == '-') {
+ result = COMMENT;
+ req = "--";
+ term = '-';
+ }
+ else if (peek(0) == '[') {
+ result = CDSECT;
+ req = "[CDATA[";
+ term = ']';
+ push = true;
+ }
+ else {
+ result = DOCDECL;
+ req = "DOCTYPE";
+ term = -1;
+ }
+ }
+ else {
+ error("illegal: <" + c);
+ return COMMENT;
+ }
+
+ for (int i = 0; i < req.length(); i++)
+ read(req.charAt(i));
+
+ if (result == DOCDECL)
+ parseDoctype(push);
+ else {
+ while (true) {
+ c = read();
+ if (c == -1){
+ error(UNEXPECTED_EOF);
+ return COMMENT;
+ }
+
+ if (push)
+ push(c);
+
+ if ((term == '?' || c == term)
+ && peek(0) == term
+ && peek(1) == '>')
+ break;
+
+ prev = c;
+ }
+
+ if (term == '-' && prev == '-')
+ error("illegal comment delimiter: --->");
+
+ read();
+ read();
+
+ if (push && term != '?')
+ txtPos--;
+
+ }
+ return result;
+ }
+
+ /** precondition: &lt! consumed */
+
+ private final void parseDoctype(boolean push)
+ throws IOException, XmlPullParserException {
+
+ int nesting = 1;
+ boolean quoted = false;
+
+ // read();
+
+ while (true) {
+ int i = read();
+ switch (i) {
+
+ case -1 :
+ error(UNEXPECTED_EOF);
+ return;
+
+ case '\'' :
+ quoted = !quoted;
+ break;
+
+ case '<' :
+ if (!quoted)
+ nesting++;
+ break;
+
+ case '>' :
+ if (!quoted) {
+ if ((--nesting) == 0)
+ return;
+ }
+ break;
+ }
+ if (push)
+ push(i);
+ }
+ }
+
+ /* precondition: &lt;/ consumed */
+
+ private final void parseEndTag()
+ throws IOException, XmlPullParserException {
+
+ read(); // '<'
+ read(); // '/'
+ name = readName();
+ skip();
+ read('>');
+
+ int sp = (depth - 1) << 2;
+
+ if (depth == 0) {
+ error("element stack empty");
+ type = COMMENT;
+ return;
+ }
+
+ if (!name.equals(elementStack[sp + 3])) {
+ error("expected: /" + elementStack[sp + 3] + " read: " + name);
+
+ // become case insensitive in relaxed mode
+
+ int probe = sp;
+ while (probe >= 0 && !name.toLowerCase().equals(elementStack[probe + 3].toLowerCase())) {
+ stackMismatch++;
+ probe -= 4;
+ }
+
+ if (probe < 0) {
+ stackMismatch = 0;
+ // text = "unexpected end tag ignored";
+ type = COMMENT;
+ return;
+ }
+ }
+
+ namespace = elementStack[sp];
+ prefix = elementStack[sp + 1];
+ name = elementStack[sp + 2];
+ }
+
+ private final int peekType() throws IOException {
+ switch (peek(0)) {
+ case -1 :
+ return END_DOCUMENT;
+ case '&' :
+ return ENTITY_REF;
+ case '<' :
+ switch (peek(1)) {
+ case '/' :
+ return END_TAG;
+ case '?' :
+ case '!' :
+ return LEGACY;
+ default :
+ return START_TAG;
+ }
+ default :
+ return TEXT;
+ }
+ }
+
+ private final String get(int pos) {
+ return new String(txtBuf, pos, txtPos - pos);
+ }
+
+ /*
+ private final String pop (int pos) {
+ String result = new String (txtBuf, pos, txtPos - pos);
+ txtPos = pos;
+ return result;
+ }
+ */
+
+ private final void push(int c) {
+
+ isWhitespace &= c <= ' ';
+
+ if (txtPos == txtBuf.length) {
+ char[] bigger = new char[txtPos * 4 / 3 + 4];
+ System.arraycopy(txtBuf, 0, bigger, 0, txtPos);
+ txtBuf = bigger;
+ }
+
+ txtBuf[txtPos++] = (char) c;
+ }
+
+ /** Sets name and attributes */
+
+ private final void parseStartTag(boolean xmldecl)
+ throws IOException, XmlPullParserException {
+
+ if (!xmldecl)
+ read();
+ name = readName();
+ attributeCount = 0;
+
+ while (true) {
+ skip();
+
+ int c = peek(0);
+
+ if (xmldecl) {
+ if (c == '?') {
+ read();
+ read('>');
+ return;
+ }
+ }
+ else {
+ if (c == '/') {
+ degenerated = true;
+ read();
+ skip();
+ read('>');
+ break;
+ }
+
+ if (c == '>' && !xmldecl) {
+ read();
+ break;
+ }
+ }
+
+ if (c == -1) {
+ error(UNEXPECTED_EOF);
+ //type = COMMENT;
+ return;
+ }
+
+ String attrName = readName();
+
+ if (attrName.length() == 0) {
+ error("attr name expected");
+ //type = COMMENT;
+ break;
+ }
+
+ int i = (attributeCount++) << 2;
+
+ attributes = ensureCapacity(attributes, i + 4);
+
+ attributes[i++] = "";
+ attributes[i++] = null;
+ attributes[i++] = attrName;
+
+ skip();
+
+ if (peek(0) != '=') {
+ error("Attr.value missing f. "+attrName);
+ attributes[i] = "1";
+ }
+ else {
+ read('=');
+ skip();
+ int delimiter = peek(0);
+
+ if (delimiter != '\'' && delimiter != '"') {
+ error("attr value delimiter missing!");
+ delimiter = ' ';
+ }
+ else
+ read();
+
+ int p = txtPos;
+ pushText(delimiter, true);
+
+ attributes[i] = get(p);
+ txtPos = p;
+
+ if (delimiter != ' ')
+ read(); // skip endquote
+ }
+ }
+
+ int sp = depth++ << 2;
+
+ elementStack = ensureCapacity(elementStack, sp + 4);
+ elementStack[sp + 3] = name;
+
+ if (depth >= nspCounts.length) {
+ int[] bigger = new int[depth + 4];
+ System.arraycopy(nspCounts, 0, bigger, 0, nspCounts.length);
+ nspCounts = bigger;
+ }
+
+ nspCounts[depth] = nspCounts[depth - 1];
+
+ /*
+ if(!relaxed){
+ for (int i = attributeCount - 1; i > 0; i--) {
+ for (int j = 0; j < i; j++) {
+ if (getAttributeName(i).equals(getAttributeName(j)))
+ exception("Duplicate Attribute: " + getAttributeName(i));
+ }
+ }
+ }
+ */
+ if (processNsp)
+ adjustNsp();
+ else
+ namespace = "";
+
+ elementStack[sp] = namespace;
+ elementStack[sp + 1] = prefix;
+ elementStack[sp + 2] = name;
+ }
+
+ /**
+ * result: isWhitespace; if the setName parameter is set,
+ * the name of the entity is stored in "name" */
+
+ private final void pushEntity()
+ throws IOException, XmlPullParserException {
+
+ push(read()); // &
+
+
+ int pos = txtPos;
+
+ while (true) {
+ int c = read();
+ if (c == ';')
+ break;
+ if (c < 128
+ && (c < '0' || c > '9')
+ && (c < 'a' || c > 'z')
+ && (c < 'A' || c > 'Z')
+ && c != '_'
+ && c != '-'
+ && c != '#') {
+ if(!relaxed){
+ error("unterminated entity ref");
+ }
+ //; ends with:"+(char)c);
+ if (c != -1)
+ push(c);
+ return;
+ }
+
+ push(c);
+ }
+
+ String code = get(pos);
+ txtPos = pos - 1;
+ if (token && type == ENTITY_REF){
+ name = code;
+ }
+
+ if (code.charAt(0) == '#') {
+ int c =
+ (code.charAt(1) == 'x'
+ ? Integer.parseInt(code.substring(2), 16)
+ : Integer.parseInt(code.substring(1)));
+ push(c);
+ return;
+ }
+
+ String result = (String) entityMap.get(code);
+
+ unresolved = result == null;
+
+ if (unresolved) {
+ if (!token)
+ error("unresolved: &" + code + ";");
+ }
+ else {
+ for (int i = 0; i < result.length(); i++)
+ push(result.charAt(i));
+ }
+ }
+
+ /** types:
+ '<': parse to any token (for nextToken ())
+ '"': parse to quote
+ ' ': parse to whitespace or '>'
+ */
+
+ private final void pushText(int delimiter, boolean resolveEntities)
+ throws IOException, XmlPullParserException {
+
+ int next = peek(0);
+ int cbrCount = 0;
+
+ while (next != -1 && next != delimiter) { // covers eof, '<', '"'
+
+ if (delimiter == ' ')
+ if (next <= ' ' || next == '>')
+ break;
+
+ if (next == '&') {
+ if (!resolveEntities)
+ break;
+
+ pushEntity();
+ }
+ else if (next == '\n' && type == START_TAG) {
+ read();
+ push(' ');
+ }
+ else
+ push(read());
+
+ if (next == '>' && cbrCount >= 2 && delimiter != ']')
+ error("Illegal: ]]>");
+
+ if (next == ']')
+ cbrCount++;
+ else
+ cbrCount = 0;
+
+ next = peek(0);
+ }
+ }
+
+ private final void read(char c)
+ throws IOException, XmlPullParserException {
+ int a = read();
+ if (a != c)
+ error("expected: '" + c + "' actual: '" + ((char) a) + "'");
+ }
+
+ private final int read() throws IOException {
+ int result;
+
+ if (peekCount == 0)
+ result = peek(0);
+ else {
+ result = peek[0];
+ peek[0] = peek[1];
+ }
+ // else {
+ // result = peek[0];
+ // System.arraycopy (peek, 1, peek, 0, peekCount-1);
+ // }
+ peekCount--;
+
+ column++;
+
+ if (result == '\n') {
+
+ line++;
+ column = 1;
+ }
+
+ return result;
+ }
+
+ /** Does never read more than needed */
+
+ private final int peek(int pos) throws IOException {
+
+ while (pos >= peekCount) {
+
+ int nw;
+
+ if (srcBuf.length <= 1)
+ nw = reader.read();
+ else if (srcPos < srcCount)
+ nw = srcBuf[srcPos++];
+ else {
+ srcCount = reader.read(srcBuf, 0, srcBuf.length);
+ if (srcCount <= 0)
+ nw = -1;
+ else
+ nw = srcBuf[0];
+
+ srcPos = 1;
+ }
+
+ if (nw == '\r') {
+ wasCR = true;
+ peek[peekCount++] = '\n';
+ }
+ else {
+ if (nw == '\n') {
+ if (!wasCR)
+ peek[peekCount++] = '\n';
+ }
+ else
+ peek[peekCount++] = nw;
+
+ wasCR = false;
+ }
+ }
+
+ return peek[pos];
+ }
+
+ private final String readName()
+ throws IOException, XmlPullParserException {
+
+ int pos = txtPos;
+ int c = peek(0);
+ if ((c < 'a' || c > 'z')
+ && (c < 'A' || c > 'Z')
+ && c != '_'
+ && c != ':'
+ && c < 0x0c0
+ && !relaxed)
+ error("name expected");
+
+ do {
+ push(read());
+ c = peek(0);
+ }
+ while ((c >= 'a' && c <= 'z')
+ || (c >= 'A' && c <= 'Z')
+ || (c >= '0' && c <= '9')
+ || c == '_'
+ || c == '-'
+ || c == ':'
+ || c == '.'
+ || c >= 0x0b7);
+
+ String result = get(pos);
+ txtPos = pos;
+ return result;
+ }
+
+ private final void skip() throws IOException {
+
+ while (true) {
+ int c = peek(0);
+ if (c > ' ' || c == -1)
+ break;
+ read();
+ }
+ }
+
+ // public part starts here...
+
+ public void setInput(Reader reader) throws XmlPullParserException {
+ this.reader = reader;
+
+ line = 1;
+ column = 0;
+ type = START_DOCUMENT;
+ name = null;
+ namespace = null;
+ degenerated = false;
+ attributeCount = -1;
+ encoding = null;
+ version = null;
+ standalone = null;
+
+ if (reader == null)
+ return;
+
+ srcPos = 0;
+ srcCount = 0;
+ peekCount = 0;
+ depth = 0;
+
+ entityMap = new Hashtable();
+ entityMap.put("amp", "&");
+ entityMap.put("apos", "'");
+ entityMap.put("gt", ">");
+ entityMap.put("lt", "<");
+ entityMap.put("quot", "\"");
+ }
+
+ public void setInput(InputStream is, String _enc)
+ throws XmlPullParserException {
+
+ srcPos = 0;
+ srcCount = 0;
+ String enc = _enc;
+
+ if (is == null)
+ throw new IllegalArgumentException();
+
+ try {
+
+ if (enc == null) {
+ // read four bytes
+
+ int chk = 0;
+
+ while (srcCount < 4) {
+ int i = is.read();
+ if (i == -1)
+ break;
+ chk = (chk << 8) | i;
+ srcBuf[srcCount++] = (char) i;
+ }
+
+ if (srcCount == 4) {
+ switch (chk) {
+ case 0x00000FEFF :
+ enc = "UTF-32BE";
+ srcCount = 0;
+ break;
+
+ case 0x0FFFE0000 :
+ enc = "UTF-32LE";
+ srcCount = 0;
+ break;
+
+ case 0x03c :
+ enc = "UTF-32BE";
+ srcBuf[0] = '<';
+ srcCount = 1;
+ break;
+
+ case 0x03c000000 :
+ enc = "UTF-32LE";
+ srcBuf[0] = '<';
+ srcCount = 1;
+ break;
+
+ case 0x0003c003f :
+ enc = "UTF-16BE";
+ srcBuf[0] = '<';
+ srcBuf[1] = '?';
+ srcCount = 2;
+ break;
+
+ case 0x03c003f00 :
+ enc = "UTF-16LE";
+ srcBuf[0] = '<';
+ srcBuf[1] = '?';
+ srcCount = 2;
+ break;
+
+ case 0x03c3f786d :
+ while (true) {
+ int i = is.read();
+ if (i == -1)
+ break;
+ srcBuf[srcCount++] = (char) i;
+ if (i == '>') {
+ String s = new String(srcBuf, 0, srcCount);
+ int i0 = s.indexOf("encoding");
+ if (i0 != -1) {
+ while (s.charAt(i0) != '"'
+ && s.charAt(i0) != '\'')
+ i0++;
+ char deli = s.charAt(i0++);
+ int i1 = s.indexOf(deli, i0);
+ enc = s.substring(i0, i1);
+ }
+ break;
+ }
+ }
+
+ default :
+ if ((chk & 0x0ffff0000) == 0x0FEFF0000) {
+ enc = "UTF-16BE";
+ srcBuf[0] =
+ (char) ((srcBuf[2] << 8) | srcBuf[3]);
+ srcCount = 1;
+ }
+ else if ((chk & 0x0ffff0000) == 0x0fffe0000) {
+ enc = "UTF-16LE";
+ srcBuf[0] =
+ (char) ((srcBuf[3] << 8) | srcBuf[2]);
+ srcCount = 1;
+ }
+ else if ((chk & 0x0ffffff00) == 0x0EFBBBF00) {
+ enc = "UTF-8";
+ srcBuf[0] = srcBuf[3];
+ srcCount = 1;
+ }
+ }
+ }
+ }
+
+ if (enc == null)
+ enc = "UTF-8";
+
+ int sc = srcCount;
+ setInput(new InputStreamReader(is, enc));
+ encoding = _enc;
+ srcCount = sc;
+ }
+ catch (Exception e) {
+ throw new XmlPullParserException(
+ "Invalid stream or encoding: " + e.toString(),
+ this,
+ e);
+ }
+ }
+
+ public boolean getFeature(String feature) {
+ if (XmlPullParser.FEATURE_PROCESS_NAMESPACES.equals(feature))
+ return processNsp;
+ else if (isProp(feature, false, "relaxed"))
+ return relaxed;
+ else
+ return false;
+ }
+
+ public String getInputEncoding() {
+ return encoding;
+ }
+
+ public void defineEntityReplacementText(String entity, String value)
+ throws XmlPullParserException {
+ if (entityMap == null)
+ throw new RuntimeException("entity replacement text must be defined after setInput!");
+ entityMap.put(entity, value);
+ }
+
+ public Object getProperty(String property) {
+ if (isProp(property, true, "xmldecl-version"))
+ return version;
+ if (isProp(property, true, "xmldecl-standalone"))
+ return standalone;
+ if (isProp(property, true, "location"))
+ return location != null ? location : reader.toString();
+ return null;
+ }
+
+ public int getNamespaceCount(int depth) {
+ if (depth > this.depth)
+ throw new IndexOutOfBoundsException();
+ return nspCounts[depth];
+ }
+
+ public String getNamespacePrefix(int pos) {
+ return nspStack[pos << 1];
+ }
+
+ public String getNamespaceUri(int pos) {
+ return nspStack[(pos << 1) + 1];
+ }
+
+ public String getNamespace(String prefix) {
+
+ if ("xml".equals(prefix))
+ return "http://www.w3.org/XML/1998/namespace";
+ if ("xmlns".equals(prefix))
+ return "http://www.w3.org/2000/xmlns/";
+
+ for (int i = (getNamespaceCount(depth) << 1) - 2; i >= 0; i -= 2) {
+ if (prefix == null) {
+ if (nspStack[i] == null)
+ return nspStack[i + 1];
+ }
+ else if (prefix.equals(nspStack[i]))
+ return nspStack[i + 1];
+ }
+ return null;
+ }
+
+ public int getDepth() {
+ return depth;
+ }
+
+ public String getPositionDescription() {
+
+ StringBuffer buf =
+ new StringBuffer(type < TYPES.length ? TYPES[type] : "unknown");
+ buf.append(' ');
+
+ if (type == START_TAG || type == END_TAG) {
+ if (degenerated)
+ buf.append("(empty) ");
+ buf.append('<');
+ if (type == END_TAG)
+ buf.append('/');
+
+ if (prefix != null)
+ buf.append("{" + namespace + "}" + prefix + ":");
+ buf.append(name);
+
+ int cnt = attributeCount << 2;
+ for (int i = 0; i < cnt; i += 4) {
+ buf.append(' ');
+ if (attributes[i + 1] != null)
+ buf.append(
+ "{" + attributes[i] + "}" + attributes[i + 1] + ":");
+ buf.append(attributes[i + 2] + "='" + attributes[i + 3] + "'");
+ }
+
+ buf.append('>');
+ }
+ else if (type == IGNORABLE_WHITESPACE);
+ else if (type != TEXT)
+ buf.append(getText());
+ else if (isWhitespace)
+ buf.append("(whitespace)");
+ else {
+ String text = getText();
+ if (text.length() > 16)
+ text = text.substring(0, 16) + "...";
+ buf.append(text);
+ }
+
+ buf.append("@"+line + ":" + column);
+ if(location != null){
+ buf.append(" in ");
+ buf.append(location);
+ }
+ else if(reader != null){
+ buf.append(" in ");
+ buf.append(reader.toString());
+ }
+ return buf.toString();
+ }
+
+ public int getLineNumber() {
+ return line;
+ }
+
+ public int getColumnNumber() {
+ return column;
+ }
+
+ public boolean isWhitespace() throws XmlPullParserException {
+ if (type != TEXT && type != IGNORABLE_WHITESPACE && type != CDSECT)
+ exception(ILLEGAL_TYPE);
+ return isWhitespace;
+ }
+
+ public String getText() {
+ return type < TEXT
+ || (type == ENTITY_REF && unresolved) ? null : get(0);
+ }
+
+ public char[] getTextCharacters(int[] poslen) {
+ if (type >= TEXT) {
+ if (type == ENTITY_REF) {
+ poslen[0] = 0;
+ poslen[1] = name.length();
+ return name.toCharArray();
+ }
+ poslen[0] = 0;
+ poslen[1] = txtPos;
+ return txtBuf;
+ }
+
+ poslen[0] = -1;
+ poslen[1] = -1;
+ return null;
+ }
+
+ public String getNamespace() {
+ return namespace;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getPrefix() {
+ return prefix;
+ }
+
+ public boolean isEmptyElementTag() throws XmlPullParserException {
+ if (type != START_TAG)
+ exception(ILLEGAL_TYPE);
+ return degenerated;
+ }
+
+ public int getAttributeCount() {
+ return attributeCount;
+ }
+
+ public String getAttributeType(int index) {
+ return "CDATA";
+ }
+
+ public boolean isAttributeDefault(int index) {
+ return false;
+ }
+
+ public String getAttributeNamespace(int index) {
+ if (index >= attributeCount)
+ throw new IndexOutOfBoundsException();
+ return attributes[index << 2];
+ }
+
+ public String getAttributeName(int index) {
+ if (index >= attributeCount)
+ throw new IndexOutOfBoundsException();
+ return attributes[(index << 2) + 2];
+ }
+
+ public String getAttributePrefix(int index) {
+ if (index >= attributeCount)
+ throw new IndexOutOfBoundsException();
+ return attributes[(index << 2) + 1];
+ }
+
+ public String getAttributeValue(int index) {
+ if (index >= attributeCount)
+ throw new IndexOutOfBoundsException();
+ return attributes[(index << 2) + 3];
+ }
+
+ public String getAttributeValue(String namespace, String name) {
+
+ for (int i = (attributeCount << 2) - 4; i >= 0; i -= 4) {
+ if (attributes[i + 2].equals(name)
+ && (namespace == null || attributes[i].equals(namespace)))
+ return attributes[i + 3];
+ }
+
+ return null;
+ }
+
+ public int getEventType() throws XmlPullParserException {
+ return type;
+ }
+
+ public int next() throws XmlPullParserException, IOException {
+
+ txtPos = 0;
+ isWhitespace = true;
+ int minType = 9999;
+ token = false;
+
+ do {
+ nextImpl();
+ if (type < minType)
+ minType = type;
+ // if (curr <= TEXT) type = curr;
+ }
+ while (minType > ENTITY_REF // ignorable
+ || (minType >= TEXT && peekType() >= TEXT));
+
+ type = minType;
+ if (type > TEXT)
+ type = TEXT;
+
+ return type;
+ }
+
+ public int nextToken() throws XmlPullParserException, IOException {
+
+ isWhitespace = true;
+ txtPos = 0;
+
+ token = true;
+ nextImpl();
+ return type;
+ }
+
+ //
+ // utility methods to make XML parsing easier ...
+
+ public int nextTag() throws XmlPullParserException, IOException {
+
+ next();
+ if (type == TEXT && isWhitespace)
+ next();
+
+ if (type != END_TAG && type != START_TAG)
+ exception("unexpected type");
+
+ return type;
+ }
+
+ public void require(int type, String namespace, String name)
+ throws XmlPullParserException, IOException {
+
+ if (type != this.type
+ || (namespace != null && !namespace.equals(getNamespace()))
+ || (name != null && !name.equals(getName())))
+ exception(
+ "expected: " + TYPES[type] + " {" + namespace + "}" + name);
+ }
+
+ public String nextText() throws XmlPullParserException, IOException {
+ if (type != START_TAG)
+ exception("precondition: START_TAG");
+
+ next();
+
+ String result;
+
+ if (type == TEXT) {
+ result = getText();
+ next();
+ }
+ else
+ result = "";
+
+ if (type != END_TAG)
+ exception("END_TAG expected");
+
+ return result;
+ }
+
+ public void setFeature(String feature, boolean value)
+ throws XmlPullParserException {
+ if (XmlPullParser.FEATURE_PROCESS_NAMESPACES.equals(feature))
+ processNsp = value;
+ else if (isProp(feature, false, "relaxed"))
+ relaxed = value;
+ else
+ exception("unsupported feature: " + feature);
+ }
+
+ public void setProperty(String property, Object value)
+ throws XmlPullParserException {
+ if(isProp(property, true, "location"))
+ location = value;
+ else
+ throw new XmlPullParserException("unsupported property: " + property);
+ }
+
+ /**
+ * Skip sub tree that is currently porser positioned on.
+ * <br>NOTE: parser must be on START_TAG and when funtion returns
+ * parser will be positioned on corresponding END_TAG.
+ */
+
+ // Implementation copied from Alek's mail...
+
+ public void skipSubTree() throws XmlPullParserException, IOException {
+ require(START_TAG, null, null);
+ int level = 1;
+ while (level > 0) {
+ int eventType = next();
+ if (eventType == END_TAG) {
+ --level;
+ }
+ else if (eventType == START_TAG) {
+ ++level;
+ }
+ }
+ }
+}
diff --git a/xml/src/main/java/org/kxml2/io/KXmlSerializer.java b/xml/src/main/java/org/kxml2/io/KXmlSerializer.java
new file mode 100644
index 0000000..d63ed04
--- /dev/null
+++ b/xml/src/main/java/org/kxml2/io/KXmlSerializer.java
@@ -0,0 +1,562 @@
+/* Copyright (c) 2002,2003, Stefan Haustein, Oberhausen, Rhld., Germany
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE. */
+
+
+package org.kxml2.io;
+
+import java.io.*;
+import org.xmlpull.v1.*;
+
+public class KXmlSerializer implements XmlSerializer {
+
+ // static final String UNDEFINED = ":";
+
+ // BEGIN android-added
+ /** size (in characters) for the write buffer */
+ private static final int WRITE_BUFFER_SIZE = 500;
+ // END android-added
+
+ // BEGIN android-changed
+ // (Guarantee that the writer is always buffered.)
+ private BufferedWriter writer;
+ // END android-changed
+
+ private boolean pending;
+ private int auto;
+ private int depth;
+
+ private String[] elementStack = new String[12];
+ //nsp/prefix/name
+ private int[] nspCounts = new int[4];
+ private String[] nspStack = new String[8];
+ //prefix/nsp; both empty are ""
+ private boolean[] indent = new boolean[4];
+ private boolean unicode;
+ private String encoding;
+
+ private final void check(boolean close) throws IOException {
+ if (!pending)
+ return;
+
+ depth++;
+ pending = false;
+
+ if (indent.length <= depth) {
+ boolean[] hlp = new boolean[depth + 4];
+ System.arraycopy(indent, 0, hlp, 0, depth);
+ indent = hlp;
+ }
+ indent[depth] = indent[depth - 1];
+
+ for (int i = nspCounts[depth - 1];
+ i < nspCounts[depth];
+ i++) {
+ writer.write(' ');
+ writer.write("xmlns");
+ if (!"".equals(nspStack[i * 2])) {
+ writer.write(':');
+ writer.write(nspStack[i * 2]);
+ }
+ else if ("".equals(getNamespace()) && !"".equals(nspStack[i * 2 + 1]))
+ throw new IllegalStateException("Cannot set default namespace for elements in no namespace");
+ writer.write("=\"");
+ writeEscaped(nspStack[i * 2 + 1], '"');
+ writer.write('"');
+ }
+
+ if (nspCounts.length <= depth + 1) {
+ int[] hlp = new int[depth + 8];
+ System.arraycopy(nspCounts, 0, hlp, 0, depth + 1);
+ nspCounts = hlp;
+ }
+
+ nspCounts[depth + 1] = nspCounts[depth];
+ // nspCounts[depth + 2] = nspCounts[depth];
+
+ writer.write(close ? " />" : ">");
+ }
+
+ private final void writeEscaped(String s, int quot)
+ throws IOException {
+
+ for (int i = 0; i < s.length(); i++) {
+ char c = s.charAt(i);
+ switch (c) {
+ case '\n':
+ case '\r':
+ case '\t':
+ if(quot == -1)
+ writer.write(c);
+ else
+ writer.write("&#"+((int) c)+';');
+ break;
+ case '&' :
+ writer.write("&amp;");
+ break;
+ case '>' :
+ writer.write("&gt;");
+ break;
+ case '<' :
+ writer.write("&lt;");
+ break;
+ case '"' :
+ case '\'' :
+ if (c == quot) {
+ writer.write(
+ c == '"' ? "&quot;" : "&apos;");
+ break;
+ }
+ default :
+ //if(c < ' ')
+ // throw new IllegalArgumentException("Illegal control code:"+((int) c));
+
+ if (c >= ' ' && c !='@' && (c < 127 || unicode))
+ writer.write(c);
+ else
+ writer.write("&#" + ((int) c) + ";");
+
+ }
+ }
+ }
+
+ /*
+ private final void writeIndent() throws IOException {
+ writer.write("\r\n");
+ for (int i = 0; i < depth; i++)
+ writer.write(' ');
+ }*/
+
+ public void docdecl(String dd) throws IOException {
+ writer.write("<!DOCTYPE");
+ writer.write(dd);
+ writer.write(">");
+ }
+
+ public void endDocument() throws IOException {
+ while (depth > 0) {
+ endTag(
+ elementStack[depth * 3 - 3],
+ elementStack[depth * 3 - 1]);
+ }
+ flush();
+ }
+
+ public void entityRef(String name) throws IOException {
+ check(false);
+ writer.write('&');
+ writer.write(name);
+ writer.write(';');
+ }
+
+ public boolean getFeature(String name) {
+ //return false;
+ return (
+ "http://xmlpull.org/v1/doc/features.html#indent-output"
+ .equals(
+ name))
+ ? indent[depth]
+ : false;
+ }
+
+ public String getPrefix(String namespace, boolean create) {
+ try {
+ return getPrefix(namespace, false, create);
+ }
+ catch (IOException e) {
+ throw new RuntimeException(e.toString());
+ }
+ }
+
+ private final String getPrefix(
+ String namespace,
+ boolean includeDefault,
+ boolean create)
+ throws IOException {
+
+ for (int i = nspCounts[depth + 1] * 2 - 2;
+ i >= 0;
+ i -= 2) {
+ if (nspStack[i + 1].equals(namespace)
+ && (includeDefault || !nspStack[i].equals(""))) {
+ String cand = nspStack[i];
+ for (int j = i + 2;
+ j < nspCounts[depth + 1] * 2;
+ j++) {
+ if (nspStack[j].equals(cand)) {
+ cand = null;
+ break;
+ }
+ }
+ if (cand != null)
+ return cand;
+ }
+ }
+
+ if (!create)
+ return null;
+
+ String prefix;
+
+ if ("".equals(namespace))
+ prefix = "";
+ else {
+ do {
+ prefix = "n" + (auto++);
+ for (int i = nspCounts[depth + 1] * 2 - 2;
+ i >= 0;
+ i -= 2) {
+ if (prefix.equals(nspStack[i])) {
+ prefix = null;
+ break;
+ }
+ }
+ }
+ while (prefix == null);
+ }
+
+ boolean p = pending;
+ pending = false;
+ setPrefix(prefix, namespace);
+ pending = p;
+ return prefix;
+ }
+
+ public Object getProperty(String name) {
+ throw new RuntimeException("Unsupported property");
+ }
+
+ public void ignorableWhitespace(String s)
+ throws IOException {
+ text(s);
+ }
+
+ public void setFeature(String name, boolean value) {
+ if ("http://xmlpull.org/v1/doc/features.html#indent-output"
+ .equals(name)) {
+ indent[depth] = value;
+ }
+ else
+ throw new RuntimeException("Unsupported Feature");
+ }
+
+ public void setProperty(String name, Object value) {
+ throw new RuntimeException(
+ "Unsupported Property:" + value);
+ }
+
+ public void setPrefix(String prefix, String namespace)
+ throws IOException {
+
+ check(false);
+ if (prefix == null)
+ prefix = "";
+ if (namespace == null)
+ namespace = "";
+
+ String defined = getPrefix(namespace, true, false);
+
+ // boil out if already defined
+
+ if (prefix.equals(defined))
+ return;
+
+ int pos = (nspCounts[depth + 1]++) << 1;
+
+ if (nspStack.length < pos + 1) {
+ String[] hlp = new String[nspStack.length + 16];
+ System.arraycopy(nspStack, 0, hlp, 0, pos);
+ nspStack = hlp;
+ }
+
+ nspStack[pos++] = prefix;
+ nspStack[pos] = namespace;
+ }
+
+ public void setOutput(Writer writer) {
+ // BEGIN android-changed
+ // Guarantee that the writer is always buffered.
+ if (writer instanceof BufferedWriter) {
+ this.writer = (BufferedWriter) writer;
+ } else {
+ this.writer = new BufferedWriter(writer, WRITE_BUFFER_SIZE);
+ }
+ // END android-changed
+
+ // elementStack = new String[12]; //nsp/prefix/name
+ //nspCounts = new int[4];
+ //nspStack = new String[8]; //prefix/nsp
+ //indent = new boolean[4];
+
+ nspCounts[0] = 2;
+ nspCounts[1] = 2;
+ nspStack[0] = "";
+ nspStack[1] = "";
+ nspStack[2] = "xml";
+ nspStack[3] = "http://www.w3.org/XML/1998/namespace";
+ pending = false;
+ auto = 0;
+ depth = 0;
+
+ unicode = false;
+ }
+
+ public void setOutput(OutputStream os, String encoding)
+ throws IOException {
+ if (os == null)
+ throw new IllegalArgumentException();
+ setOutput(
+ encoding == null
+ ? new OutputStreamWriter(os)
+ : new OutputStreamWriter(os, encoding));
+ this.encoding = encoding;
+ if (encoding != null
+ && encoding.toLowerCase().startsWith("utf"))
+ unicode = true;
+ }
+
+ public void startDocument(
+ String encoding,
+ Boolean standalone)
+ throws IOException {
+ writer.write("<?xml version='1.0' ");
+
+ if (encoding != null) {
+ this.encoding = encoding;
+ if (encoding.toLowerCase().startsWith("utf"))
+ unicode = true;
+ }
+
+ if (this.encoding != null) {
+ writer.write("encoding='");
+ writer.write(this.encoding);
+ writer.write("' ");
+ }
+
+ if (standalone != null) {
+ writer.write("standalone='");
+ writer.write(
+ standalone.booleanValue() ? "yes" : "no");
+ writer.write("' ");
+ }
+ writer.write("?>");
+ }
+
+ public XmlSerializer startTag(String namespace, String name)
+ throws IOException {
+ check(false);
+
+ // if (namespace == null)
+ // namespace = "";
+
+ if (indent[depth]) {
+ writer.write("\r\n");
+ for (int i = 0; i < depth; i++)
+ writer.write(" ");
+ }
+
+ int esp = depth * 3;
+
+ if (elementStack.length < esp + 3) {
+ String[] hlp = new String[elementStack.length + 12];
+ System.arraycopy(elementStack, 0, hlp, 0, esp);
+ elementStack = hlp;
+ }
+
+ String prefix =
+ namespace == null
+ ? ""
+ : getPrefix(namespace, true, true);
+
+ if ("".equals(namespace)) {
+ for (int i = nspCounts[depth];
+ i < nspCounts[depth + 1];
+ i++) {
+ if ("".equals(nspStack[i * 2]) && !"".equals(nspStack[i * 2 + 1])) {
+ throw new IllegalStateException("Cannot set default namespace for elements in no namespace");
+ }
+ }
+ }
+
+ elementStack[esp++] = namespace;
+ elementStack[esp++] = prefix;
+ elementStack[esp] = name;
+
+ writer.write('<');
+ if (!"".equals(prefix)) {
+ writer.write(prefix);
+ writer.write(':');
+ }
+
+ writer.write(name);
+
+ pending = true;
+
+ return this;
+ }
+
+ public XmlSerializer attribute(
+ String namespace,
+ String name,
+ String value)
+ throws IOException {
+ if (!pending)
+ throw new IllegalStateException("illegal position for attribute");
+
+ // int cnt = nspCounts[depth];
+
+ if (namespace == null)
+ namespace = "";
+
+ // depth--;
+ // pending = false;
+
+ String prefix =
+ "".equals(namespace)
+ ? ""
+ : getPrefix(namespace, false, true);
+
+ // pending = true;
+ // depth++;
+
+ /* if (cnt != nspCounts[depth]) {
+ writer.write(' ');
+ writer.write("xmlns");
+ if (nspStack[cnt * 2] != null) {
+ writer.write(':');
+ writer.write(nspStack[cnt * 2]);
+ }
+ writer.write("=\"");
+ writeEscaped(nspStack[cnt * 2 + 1], '"');
+ writer.write('"');
+ }
+ */
+
+ writer.write(' ');
+ if (!"".equals(prefix)) {
+ writer.write(prefix);
+ writer.write(':');
+ }
+ writer.write(name);
+ writer.write('=');
+ char q = value.indexOf('"') == -1 ? '"' : '\'';
+ writer.write(q);
+ writeEscaped(value, q);
+ writer.write(q);
+
+ return this;
+ }
+
+ public void flush() throws IOException {
+ check(false);
+ writer.flush();
+ }
+ /*
+ public void close() throws IOException {
+ check();
+ writer.close();
+ }
+ */
+ public XmlSerializer endTag(String namespace, String name)
+ throws IOException {
+
+ if (!pending)
+ depth--;
+ // if (namespace == null)
+ // namespace = "";
+
+ if ((namespace == null
+ && elementStack[depth * 3] != null)
+ || (namespace != null
+ && !namespace.equals(elementStack[depth * 3]))
+ || !elementStack[depth * 3 + 2].equals(name))
+ throw new IllegalArgumentException("</{"+namespace+"}"+name+"> does not match start");
+
+ if (pending) {
+ check(true);
+ depth--;
+ }
+ else {
+ if (indent[depth + 1]) {
+ writer.write("\r\n");
+ for (int i = 0; i < depth; i++)
+ writer.write(" ");
+ }
+
+ writer.write("</");
+ String prefix = elementStack[depth * 3 + 1];
+ if (!"".equals(prefix)) {
+ writer.write(prefix);
+ writer.write(':');
+ }
+ writer.write(name);
+ writer.write('>');
+ }
+
+ nspCounts[depth + 1] = nspCounts[depth];
+ return this;
+ }
+
+ public String getNamespace() {
+ return getDepth() == 0 ? null : elementStack[getDepth() * 3 - 3];
+ }
+
+ public String getName() {
+ return getDepth() == 0 ? null : elementStack[getDepth() * 3 - 1];
+ }
+
+ public int getDepth() {
+ return pending ? depth + 1 : depth;
+ }
+
+ public XmlSerializer text(String text) throws IOException {
+ check(false);
+ indent[depth] = false;
+ writeEscaped(text, -1);
+ return this;
+ }
+
+ public XmlSerializer text(char[] text, int start, int len)
+ throws IOException {
+ text(new String(text, start, len));
+ return this;
+ }
+
+ public void cdsect(String data) throws IOException {
+ check(false);
+ writer.write("<![CDATA[");
+ writer.write(data);
+ writer.write("]]>");
+ }
+
+ public void comment(String comment) throws IOException {
+ check(false);
+ writer.write("<!--");
+ writer.write(comment);
+ writer.write("-->");
+ }
+
+ public void processingInstruction(String pi)
+ throws IOException {
+ check(false);
+ writer.write("<?");
+ writer.write(pi);
+ writer.write("?>");
+ }
+}
diff --git a/xml/src/main/java/org/kxml2/kdom/Document.java b/xml/src/main/java/org/kxml2/kdom/Document.java
new file mode 100644
index 0000000..859334c
--- /dev/null
+++ b/xml/src/main/java/org/kxml2/kdom/Document.java
@@ -0,0 +1,129 @@
+/* Copyright (c) 2002,2003, Stefan Haustein, Oberhausen, Rhld., Germany
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE. */
+
+
+package org.kxml2.kdom;
+
+import java.io.*;
+
+import org.xmlpull.v1.*;
+/** The document consists of some legacy events and a single root
+ element. This class basically adds some consistency checks to
+ Node. */
+
+public class Document extends Node {
+
+ protected int rootIndex = -1;
+ String encoding;
+ Boolean standalone;
+
+ /** returns "#document" */
+
+ public String getEncoding () {
+ return encoding;
+ }
+
+ public void setEncoding(String enc) {
+ this.encoding = enc;
+ }
+
+ public void setStandalone (Boolean standalone) {
+ this.standalone = standalone;
+ }
+
+ public Boolean getStandalone() {
+ return standalone;
+ }
+
+
+ public String getName() {
+ return "#document";
+ }
+
+ /** Adds a child at the given index position. Throws
+ an exception when a second root element is added */
+
+ public void addChild(int index, int type, Object child) {
+ if (type == ELEMENT) {
+ // if (rootIndex != -1)
+ // throw new RuntimeException("Only one document root element allowed");
+
+ rootIndex = index;
+ }
+ else if (rootIndex >= index)
+ rootIndex++;
+
+ super.addChild(index, type, child);
+ }
+
+ /** reads the document and checks if the last event
+ is END_DOCUMENT. If not, an exception is thrown.
+ The end event is consumed. For parsing partial
+ XML structures, consider using Node.parse (). */
+
+ public void parse(XmlPullParser parser)
+ throws IOException, XmlPullParserException {
+
+ parser.require(XmlPullParser.START_DOCUMENT, null, null);
+ parser.nextToken ();
+
+ encoding = parser.getInputEncoding();
+ standalone = (Boolean)parser.getProperty ("http://xmlpull.org/v1/doc/properties.html#xmldecl-standalone");
+
+ super.parse(parser);
+
+ if (parser.getEventType() != XmlPullParser.END_DOCUMENT)
+ throw new RuntimeException("Document end expected!");
+
+ }
+
+ public void removeChild(int index) {
+ if (index == rootIndex)
+ rootIndex = -1;
+ else if (index < rootIndex)
+ rootIndex--;
+
+ super.removeChild(index);
+ }
+
+ /** returns the root element of this document. */
+
+ public Element getRootElement() {
+ if (rootIndex == -1)
+ throw new RuntimeException("Document has no root element!");
+
+ return (Element) getChild(rootIndex);
+ }
+
+
+ /** Writes this node to the given XmlWriter. For node and document,
+ this method is identical to writeChildren, except that the
+ stream is flushed automatically. */
+
+ public void write(XmlSerializer writer)
+ throws IOException {
+
+ writer.startDocument(encoding, standalone);
+ writeChildren(writer);
+ writer.endDocument();
+ }
+
+
+} \ No newline at end of file
diff --git a/xml/src/main/java/org/kxml2/kdom/Element.java b/xml/src/main/java/org/kxml2/kdom/Element.java
new file mode 100644
index 0000000..6a5777b
--- /dev/null
+++ b/xml/src/main/java/org/kxml2/kdom/Element.java
@@ -0,0 +1,335 @@
+/* Copyright (c) 2002,2003, Stefan Haustein, Oberhausen, Rhld., Germany
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE. */
+
+package org.kxml2.kdom;
+
+import java.io.*;
+import java.util.*;
+
+import org.xmlpull.v1.*;
+
+/**
+ * In order to create an element, please use the createElement method
+ * instead of invoking the constructor directly. The right place to
+ * add user defined initialization code is the init method. */
+
+public class Element extends Node {
+
+ protected String namespace;
+ protected String name;
+ protected Vector attributes;
+ protected Node parent;
+ protected Vector prefixes;
+
+ public Element() {
+ }
+
+ /**
+ * called when all properties are set, but before children
+ * are parsed. Please do not use setParent for initialization
+ * code any longer. */
+
+ public void init() {
+ }
+
+
+
+
+ /**
+ * removes all children and attributes */
+
+ public void clear() {
+ attributes = null;
+ children = null;
+ }
+
+ /**
+ * Forwards creation request to parent if any, otherwise
+ * calls super.createElement. */
+
+ public Element createElement(
+ String namespace,
+ String name) {
+
+ return (this.parent == null)
+ ? super.createElement(namespace, name)
+ : this.parent.createElement(namespace, name);
+ }
+
+ /**
+ * Returns the number of attributes of this element. */
+
+ public int getAttributeCount() {
+ return attributes == null ? 0 : attributes.size();
+ }
+
+ public String getAttributeNamespace (int index) {
+ return ((String []) attributes.elementAt (index)) [0];
+ }
+
+/* public String getAttributePrefix (int index) {
+ return ((String []) attributes.elementAt (index)) [1];
+ }*/
+
+ public String getAttributeName (int index) {
+ return ((String []) attributes.elementAt (index)) [1];
+ }
+
+
+ public String getAttributeValue (int index) {
+ return ((String []) attributes.elementAt (index)) [2];
+ }
+
+
+ public String getAttributeValue (String namespace, String name) {
+ for (int i = 0; i < getAttributeCount (); i++) {
+ if (name.equals (getAttributeName (i))
+ && (namespace == null || namespace.equals (getAttributeNamespace(i)))) {
+ return getAttributeValue (i);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns the root node, determined by ascending to the
+ * all parents un of the root element. */
+
+ public Node getRoot() {
+
+ Element current = this;
+
+ while (current.parent != null) {
+ if (!(current.parent instanceof Element)) return current.parent;
+ current = (Element) current.parent;
+ }
+
+ return current;
+ }
+
+ /**
+ * returns the (local) name of the element */
+
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * returns the namespace of the element */
+
+ public String getNamespace() {
+ return namespace;
+ }
+
+
+ /**
+ * returns the namespace for the given prefix */
+
+ public String getNamespaceUri (String prefix) {
+ int cnt = getNamespaceCount ();
+ for (int i = 0; i < cnt; i++) {
+ if (prefix == getNamespacePrefix (i) ||
+ (prefix != null && prefix.equals (getNamespacePrefix (i))))
+ return getNamespaceUri (i);
+ }
+ return parent instanceof Element ? ((Element) parent).getNamespaceUri (prefix) : null;
+ }
+
+
+ /**
+ * returns the number of declared namespaces, NOT including
+ * parent elements */
+
+ public int getNamespaceCount () {
+ return (prefixes == null ? 0 : prefixes.size ());
+ }
+
+
+ public String getNamespacePrefix (int i) {
+ return ((String []) prefixes.elementAt (i)) [0];
+ }
+
+ public String getNamespaceUri (int i) {
+ return ((String []) prefixes.elementAt (i)) [1];
+ }
+
+
+ /**
+ * Returns the parent node of this element */
+
+ public Node getParent() {
+ return parent;
+ }
+
+ /*
+ * Returns the parent element if available, null otherwise
+
+ public Element getParentElement() {
+ return (parent instanceof Element)
+ ? ((Element) parent)
+ : null;
+ }
+*/
+
+ /**
+ * Builds the child elements from the given Parser. By overwriting
+ * parse, an element can take complete control over parsing its
+ * subtree. */
+
+ public void parse(XmlPullParser parser)
+ throws IOException, XmlPullParserException {
+
+ for (int i = parser.getNamespaceCount (parser.getDepth () - 1);
+ i < parser.getNamespaceCount (parser.getDepth ()); i++) {
+ setPrefix (parser.getNamespacePrefix (i), parser.getNamespaceUri(i));
+ }
+
+
+ for (int i = 0; i < parser.getAttributeCount (); i++)
+ setAttribute (parser.getAttributeNamespace (i),
+// parser.getAttributePrefix (i),
+ parser.getAttributeName (i),
+ parser.getAttributeValue (i));
+
+
+ // if (prefixMap == null) throw new RuntimeException ("!!");
+
+ init();
+
+
+ if (parser.isEmptyElementTag())
+ parser.nextToken ();
+ else {
+ parser.nextToken ();
+ super.parse(parser);
+
+ if (getChildCount() == 0)
+ addChild(IGNORABLE_WHITESPACE, "");
+ }
+
+ parser.require(
+ XmlPullParser.END_TAG,
+ getNamespace(),
+ getName());
+
+ parser.nextToken ();
+ }
+
+
+ /**
+ * Sets the given attribute; a value of null removes the attribute */
+
+ public void setAttribute (String namespace, String name, String value) {
+ if (attributes == null)
+ attributes = new Vector ();
+
+ if (namespace == null)
+ namespace = "";
+
+ for (int i = attributes.size()-1; i >=0; i--){
+ String[] attribut = (String[]) attributes.elementAt(i);
+ if (attribut[0].equals(namespace) &&
+ attribut[1].equals(name)){
+
+ if (value == null) {
+ attributes.removeElementAt(i);
+ }
+ else {
+ attribut[2] = value;
+ }
+ return;
+ }
+ }
+
+ attributes.addElement
+ (new String [] {namespace, name, value});
+ }
+
+
+ /**
+ * Sets the given prefix; a namespace value of null removess the
+ * prefix */
+
+ public void setPrefix (String prefix, String namespace) {
+ if (prefixes == null) prefixes = new Vector ();
+ prefixes.addElement (new String [] {prefix, namespace});
+ }
+
+
+ /**
+ * sets the name of the element */
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * sets the namespace of the element. Please note: For no
+ * namespace, please use Xml.NO_NAMESPACE, null is not a legal
+ * value. Currently, null is converted to Xml.NO_NAMESPACE, but
+ * future versions may throw an exception. */
+
+ public void setNamespace(String namespace) {
+ if (namespace == null)
+ throw new NullPointerException ("Use \"\" for empty namespace");
+ this.namespace = namespace;
+ }
+
+ /**
+ * Sets the Parent of this element. Automatically called from the
+ * add method. Please use with care, you can simply
+ * create inconsitencies in the document tree structure using
+ * this method! */
+
+ protected void setParent(Node parent) {
+ this.parent = parent;
+ }
+
+
+ /**
+ * Writes this element and all children to the given XmlWriter. */
+
+ public void write(XmlSerializer writer)
+ throws IOException {
+
+ if (prefixes != null) {
+ for (int i = 0; i < prefixes.size(); i++) {
+ writer.setPrefix (getNamespacePrefix (i), getNamespaceUri (i));
+ }
+ }
+
+ writer.startTag(
+ getNamespace(),
+ getName());
+
+ int len = getAttributeCount();
+
+ for (int i = 0; i < len; i++) {
+ writer.attribute(
+ getAttributeNamespace(i),
+ getAttributeName(i),
+ getAttributeValue(i));
+ }
+
+ writeChildren(writer);
+
+ writer.endTag(getNamespace (), getName ());
+ }
+}
diff --git a/xml/src/main/java/org/kxml2/kdom/Node.java b/xml/src/main/java/org/kxml2/kdom/Node.java
new file mode 100644
index 0000000..a3cc78d
--- /dev/null
+++ b/xml/src/main/java/org/kxml2/kdom/Node.java
@@ -0,0 +1,366 @@
+/* Copyright (c) 2002,2003, Stefan Haustein, Oberhausen, Rhld., Germany
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE. */
+
+package org.kxml2.kdom;
+
+import java.util.*;
+import java.io.*;
+import org.xmlpull.v1.*;
+/** A common base class for Document and Element, also used for
+ storing XML fragments. */
+
+public class Node { //implements XmlIO{
+
+ public static final int DOCUMENT = 0;
+ public static final int ELEMENT = 2;
+ public static final int TEXT = 4;
+ public static final int CDSECT = 5;
+ public static final int ENTITY_REF = 6;
+ public static final int IGNORABLE_WHITESPACE = 7;
+ public static final int PROCESSING_INSTRUCTION = 8;
+ public static final int COMMENT = 9;
+ public static final int DOCDECL = 10;
+
+ protected Vector children;
+ protected StringBuffer types;
+
+ /** inserts the given child object of the given type at the
+ given index. */
+
+ public void addChild(int index, int type, Object child) {
+
+ if (child == null)
+ throw new NullPointerException();
+
+ if (children == null) {
+ children = new Vector();
+ types = new StringBuffer();
+ }
+
+ if (type == ELEMENT) {
+ if (!(child instanceof Element))
+ throw new RuntimeException("Element obj expected)");
+
+ ((Element) child).setParent(this);
+ }
+ else if (!(child instanceof String))
+ throw new RuntimeException("String expected");
+
+ children.insertElementAt(child, index);
+ types.insert(index, (char) type);
+ }
+
+ /** convenience method for addChild (getChildCount (), child) */
+
+ public void addChild(int type, Object child) {
+ addChild(getChildCount(), type, child);
+ }
+
+ /** Builds a default element with the given properties. Elements
+ should always be created using this method instead of the
+ constructor in order to enable construction of specialized
+ subclasses by deriving custom Document classes. Please note:
+ For no namespace, please use Xml.NO_NAMESPACE, null is not a
+ legal value. Currently, null is converted to Xml.NO_NAMESPACE,
+ but future versions may throw an exception. */
+
+ public Element createElement(String namespace, String name) {
+
+ Element e = new Element();
+ e.namespace = namespace == null ? "" : namespace;
+ e.name = name;
+ return e;
+ }
+
+ /** Returns the child object at the given index. For child
+ elements, an Element object is returned. For all other child
+ types, a String is returned. */
+
+ public Object getChild(int index) {
+ return children.elementAt(index);
+ }
+
+ /** Returns the number of child objects */
+
+ public int getChildCount() {
+ return children == null ? 0 : children.size();
+ }
+
+ /** returns the element at the given index. If the node at the
+ given index is a text node, null is returned */
+
+ public Element getElement(int index) {
+ Object child = getChild(index);
+ return (child instanceof Element) ? (Element) child : null;
+ }
+
+ /** Returns the element with the given namespace and name. If the
+ element is not found, or more than one matching elements are
+ found, an exception is thrown. */
+
+ public Element getElement(String namespace, String name) {
+
+ int i = indexOf(namespace, name, 0);
+ int j = indexOf(namespace, name, i + 1);
+
+ if (i == -1 || j != -1)
+ throw new RuntimeException(
+ "Element {"
+ + namespace
+ + "}"
+ + name
+ + (i == -1 ? " not found in " : " more than once in ")
+ + this);
+
+ return getElement(i);
+ }
+
+ /* returns "#document-fragment". For elements, the element name is returned
+
+ public String getName() {
+ return "#document-fragment";
+ }
+
+ /** Returns the namespace of the current element. For Node
+ and Document, Xml.NO_NAMESPACE is returned.
+
+ public String getNamespace() {
+ return "";
+ }
+
+ public int getNamespaceCount () {
+ return 0;
+ }
+
+ /** returns the text content if the element has text-only
+ content. Throws an exception for mixed content
+
+ public String getText() {
+
+ StringBuffer buf = new StringBuffer();
+ int len = getChildCount();
+
+ for (int i = 0; i < len; i++) {
+ if (isText(i))
+ buf.append(getText(i));
+ else if (getType(i) == ELEMENT)
+ throw new RuntimeException("not text-only content!");
+ }
+
+ return buf.toString();
+ }
+ */
+
+ /** Returns the text node with the given index or null if the node
+ with the given index is not a text node. */
+
+ public String getText(int index) {
+ return (isText(index)) ? (String) getChild(index) : null;
+ }
+
+ /** Returns the type of the child at the given index. Possible
+ types are ELEMENT, TEXT, COMMENT, and PROCESSING_INSTRUCTION */
+
+ public int getType(int index) {
+ return types.charAt(index);
+ }
+
+ /** Convenience method for indexOf (getNamespace (), name,
+ startIndex).
+
+ public int indexOf(String name, int startIndex) {
+ return indexOf(getNamespace(), name, startIndex);
+ }
+ */
+
+ /** Performs search for an element with the given namespace and
+ name, starting at the given start index. A null namespace
+ matches any namespace, please use Xml.NO_NAMESPACE for no
+ namespace). returns -1 if no matching element was found. */
+
+ public int indexOf(String namespace, String name, int startIndex) {
+
+ int len = getChildCount();
+
+ for (int i = startIndex; i < len; i++) {
+
+ Element child = getElement(i);
+
+ if (child != null
+ && name.equals(child.getName())
+ && (namespace == null || namespace.equals(child.getNamespace())))
+ return i;
+ }
+ return -1;
+ }
+
+ public boolean isText(int i) {
+ int t = getType(i);
+ return t == TEXT || t == IGNORABLE_WHITESPACE || t == CDSECT;
+ }
+
+ /** Recursively builds the child elements from the given parser
+ until an end tag or end document is found.
+ The end tag is not consumed. */
+
+ public void parse(XmlPullParser parser)
+ throws IOException, XmlPullParserException {
+
+ boolean leave = false;
+
+ do {
+ int type = parser.getEventType();
+
+ // System.out.println(parser.getPositionDescription());
+
+ switch (type) {
+
+ case XmlPullParser.START_TAG :
+ {
+ Element child =
+ createElement(
+ parser.getNamespace(),
+ parser.getName());
+ // child.setAttributes (event.getAttributes ());
+ addChild(ELEMENT, child);
+
+ // order is important here since
+ // setparent may perform some init code!
+
+ child.parse(parser);
+ break;
+ }
+
+ case XmlPullParser.END_DOCUMENT :
+ case XmlPullParser.END_TAG :
+ leave = true;
+ break;
+
+ default :
+ if (parser.getText() != null)
+ addChild(
+ type == XmlPullParser.ENTITY_REF ? TEXT : type,
+ parser.getText());
+ else if (
+ type == XmlPullParser.ENTITY_REF
+ && parser.getName() != null) {
+ addChild(ENTITY_REF, parser.getName());
+ }
+ parser.nextToken();
+ }
+ }
+ while (!leave);
+ }
+
+ /** Removes the child object at the given index */
+
+ public void removeChild(int idx) {
+ children.removeElementAt(idx);
+
+ /*** Modification by HHS - start ***/
+ // types.deleteCharAt (index);
+ /***/
+ int n = types.length() - 1;
+
+ for (int i = idx; i < n; i++)
+ types.setCharAt(i, types.charAt(i + 1));
+
+ types.setLength(n);
+
+ /*** Modification by HHS - end ***/
+ }
+
+ /* returns a valid XML representation of this Element including
+ attributes and children.
+ public String toString() {
+ try {
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream();
+ XmlWriter xw =
+ new XmlWriter(new OutputStreamWriter(bos));
+ write(xw);
+ xw.close();
+ return new String(bos.toByteArray());
+ }
+ catch (IOException e) {
+ throw new RuntimeException(e.toString());
+ }
+ }
+ */
+
+ /** Writes this node to the given XmlWriter. For node and document,
+ this method is identical to writeChildren, except that the
+ stream is flushed automatically. */
+
+ public void write(XmlSerializer writer) throws IOException {
+ writeChildren(writer);
+ writer.flush();
+ }
+
+ /** Writes the children of this node to the given XmlWriter. */
+
+ public void writeChildren(XmlSerializer writer) throws IOException {
+ if (children == null)
+ return;
+
+ int len = children.size();
+
+ for (int i = 0; i < len; i++) {
+ int type = getType(i);
+ Object child = children.elementAt(i);
+ switch (type) {
+ case ELEMENT :
+ ((Element) child).write(writer);
+ break;
+
+ case TEXT :
+ writer.text((String) child);
+ break;
+
+ case IGNORABLE_WHITESPACE :
+ writer.ignorableWhitespace((String) child);
+ break;
+
+ case CDSECT :
+ writer.cdsect((String) child);
+ break;
+
+ case COMMENT :
+ writer.comment((String) child);
+ break;
+
+ case ENTITY_REF :
+ writer.entityRef((String) child);
+ break;
+
+ case PROCESSING_INSTRUCTION :
+ writer.processingInstruction((String) child);
+ break;
+
+ case DOCDECL :
+ writer.docdecl((String) child);
+ break;
+
+ default :
+ throw new RuntimeException("Illegal type: " + type);
+ }
+ }
+ }
+}
diff --git a/xml/src/main/java/org/kxml2/wap/Wbxml.java b/xml/src/main/java/org/kxml2/wap/Wbxml.java
new file mode 100644
index 0000000..5b0c2d3
--- /dev/null
+++ b/xml/src/main/java/org/kxml2/wap/Wbxml.java
@@ -0,0 +1,49 @@
+/* Copyright (c) 2002,2003, Stefan Haustein, Oberhausen, Rhld., Germany
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE. */
+
+package org.kxml2.wap;
+
+
+/** contains the WBXML constants */
+
+
+public interface Wbxml {
+
+ static public final int SWITCH_PAGE = 0;
+ static public final int END = 1;
+ static public final int ENTITY = 2;
+ static public final int STR_I = 3;
+ static public final int LITERAL = 4;
+ static public final int EXT_I_0 = 0x40;
+ static public final int EXT_I_1 = 0x41;
+ static public final int EXT_I_2 = 0x42;
+ static public final int PI = 0x43;
+ static public final int LITERAL_C = 0x44;
+ static public final int EXT_T_0 = 0x80;
+ static public final int EXT_T_1 = 0x81;
+ static public final int EXT_T_2 = 0x82;
+ static public final int STR_T = 0x83;
+ static public final int LITERAL_A = 0x084;
+ static public final int EXT_0 = 0x0c0;
+ static public final int EXT_1 = 0x0c1;
+ static public final int EXT_2 = 0x0c2;
+ static public final int OPAQUE = 0x0c3;
+ static public final int LITERAL_AC = 0x0c4;
+}
diff --git a/xml/src/main/java/org/kxml2/wap/WbxmlParser.java b/xml/src/main/java/org/kxml2/wap/WbxmlParser.java
new file mode 100644
index 0000000..617e1d4
--- /dev/null
+++ b/xml/src/main/java/org/kxml2/wap/WbxmlParser.java
@@ -0,0 +1,1075 @@
+/* Copyright (c) 2002,2003,2004 Stefan Haustein, Oberhausen, Rhld., Germany
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE. */
+
+// Contributors: Bjorn Aadland, Chris Bartley, Nicola Fankhauser,
+// Victor Havin, Christian Kurzke, Bogdan Onoiu,
+// Elias Ross, Jain Sanjay, David Santoro.
+
+package org.kxml2.wap;
+
+import java.io.*;
+import java.util.Vector;
+import java.util.Hashtable;
+
+import org.xmlpull.v1.*;
+
+
+public class WbxmlParser implements XmlPullParser {
+
+ static final String HEX_DIGITS = "0123456789abcdef";
+
+ /** Parser event type for Wbxml-specific events. The Wbxml event code can be
+ * accessed with getWapCode() */
+
+ public static final int WAP_EXTENSION = 64;
+
+ static final private String UNEXPECTED_EOF =
+ "Unexpected EOF";
+ static final private String ILLEGAL_TYPE =
+ "Wrong event type";
+
+ private InputStream in;
+
+ private int TAG_TABLE = 0;
+ private int ATTR_START_TABLE = 1;
+ private int ATTR_VALUE_TABLE = 2;
+
+ private String[] attrStartTable;
+ private String[] attrValueTable;
+ private String[] tagTable;
+ private byte[] stringTable;
+ private Hashtable cacheStringTable = null;
+ private boolean processNsp;
+
+ private int depth;
+ private String[] elementStack = new String[16];
+ private String[] nspStack = new String[8];
+ private int[] nspCounts = new int[4];
+
+ private int attributeCount;
+ private String[] attributes = new String[16];
+ private int nextId = -2;
+
+ private Vector tables = new Vector();
+
+ private int version;
+ private int publicIdentifierId;
+
+ // StartTag current;
+ // ParseEvent next;
+
+ private String prefix;
+ private String namespace;
+ private String name;
+ private String text;
+
+ private Object wapExtensionData;
+ private int wapCode;
+
+ private int type;
+
+ private boolean degenerated;
+ private boolean isWhitespace;
+ private String encoding;
+
+ public boolean getFeature(String feature) {
+ if (XmlPullParser
+ .FEATURE_PROCESS_NAMESPACES
+ .equals(feature))
+ return processNsp;
+ else
+ return false;
+ }
+
+ public String getInputEncoding() {
+ return encoding;
+ }
+
+ public void defineEntityReplacementText(
+ String entity,
+ String value)
+ throws XmlPullParserException {
+
+ // just ignore, has no effect
+ }
+
+ public Object getProperty(String property) {
+ return null;
+ }
+
+ public int getNamespaceCount(int depth) {
+ if (depth > this.depth)
+ throw new IndexOutOfBoundsException();
+ return nspCounts[depth];
+ }
+
+ public String getNamespacePrefix(int pos) {
+ return nspStack[pos << 1];
+ }
+
+ public String getNamespaceUri(int pos) {
+ return nspStack[(pos << 1) + 1];
+ }
+
+ public String getNamespace(String prefix) {
+
+ if ("xml".equals(prefix))
+ return "http://www.w3.org/XML/1998/namespace";
+ if ("xmlns".equals(prefix))
+ return "http://www.w3.org/2000/xmlns/";
+
+ for (int i = (getNamespaceCount(depth) << 1) - 2;
+ i >= 0;
+ i -= 2) {
+ if (prefix == null) {
+ if (nspStack[i] == null)
+ return nspStack[i + 1];
+ }
+ else if (prefix.equals(nspStack[i]))
+ return nspStack[i + 1];
+ }
+ return null;
+ }
+
+ public int getDepth() {
+ return depth;
+ }
+
+ public String getPositionDescription() {
+
+ StringBuffer buf =
+ new StringBuffer(
+ type < TYPES.length ? TYPES[type] : "unknown");
+ buf.append(' ');
+
+ if (type == START_TAG || type == END_TAG) {
+ if (degenerated)
+ buf.append("(empty) ");
+ buf.append('<');
+ if (type == END_TAG)
+ buf.append('/');
+
+ if (prefix != null)
+ buf.append("{" + namespace + "}" + prefix + ":");
+ buf.append(name);
+
+ int cnt = attributeCount << 2;
+ for (int i = 0; i < cnt; i += 4) {
+ buf.append(' ');
+ if (attributes[i + 1] != null)
+ buf.append(
+ "{"
+ + attributes[i]
+ + "}"
+ + attributes[i
+ + 1]
+ + ":");
+ buf.append(
+ attributes[i
+ + 2]
+ + "='"
+ + attributes[i
+ + 3]
+ + "'");
+ }
+
+ buf.append('>');
+ }
+ else if (type == IGNORABLE_WHITESPACE);
+ else if (type != TEXT)
+ buf.append(getText());
+ else if (isWhitespace)
+ buf.append("(whitespace)");
+ else {
+ String text = getText();
+ if (text.length() > 16)
+ text = text.substring(0, 16) + "...";
+ buf.append(text);
+ }
+
+ return buf.toString();
+ }
+
+ public int getLineNumber() {
+ return -1;
+ }
+
+ public int getColumnNumber() {
+ return -1;
+ }
+
+ public boolean isWhitespace()
+ throws XmlPullParserException {
+ if (type != TEXT
+ && type != IGNORABLE_WHITESPACE
+ && type != CDSECT)
+ exception(ILLEGAL_TYPE);
+ return isWhitespace;
+ }
+
+ public String getText() {
+ return text;
+ }
+
+ public char[] getTextCharacters(int[] poslen) {
+ if (type >= TEXT) {
+ poslen[0] = 0;
+ poslen[1] = text.length();
+ char[] buf = new char[text.length()];
+ text.getChars(0, text.length(), buf, 0);
+ return buf;
+ }
+
+ poslen[0] = -1;
+ poslen[1] = -1;
+ return null;
+ }
+
+ public String getNamespace() {
+ return namespace;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getPrefix() {
+ return prefix;
+ }
+
+ public boolean isEmptyElementTag()
+ throws XmlPullParserException {
+ if (type != START_TAG)
+ exception(ILLEGAL_TYPE);
+ return degenerated;
+ }
+
+ public int getAttributeCount() {
+ return attributeCount;
+ }
+
+ public String getAttributeType(int index) {
+ return "CDATA";
+ }
+
+ public boolean isAttributeDefault(int index) {
+ return false;
+ }
+
+ public String getAttributeNamespace(int index) {
+ if (index >= attributeCount)
+ throw new IndexOutOfBoundsException();
+ return attributes[index << 2];
+ }
+
+ public String getAttributeName(int index) {
+ if (index >= attributeCount)
+ throw new IndexOutOfBoundsException();
+ return attributes[(index << 2) + 2];
+ }
+
+ public String getAttributePrefix(int index) {
+ if (index >= attributeCount)
+ throw new IndexOutOfBoundsException();
+ return attributes[(index << 2) + 1];
+ }
+
+ public String getAttributeValue(int index) {
+ if (index >= attributeCount)
+ throw new IndexOutOfBoundsException();
+ return attributes[(index << 2) + 3];
+ }
+
+ public String getAttributeValue(
+ String namespace,
+ String name) {
+
+ for (int i = (attributeCount << 2) - 4;
+ i >= 0;
+ i -= 4) {
+ if (attributes[i + 2].equals(name)
+ && (namespace == null
+ || attributes[i].equals(namespace)))
+ return attributes[i + 3];
+ }
+
+ return null;
+ }
+
+ public int getEventType() throws XmlPullParserException {
+ return type;
+ }
+
+
+ // TODO: Reuse resolveWapExtension here? Raw Wap extensions would still be accessible
+ // via nextToken(); ....?
+
+ public int next() throws XmlPullParserException, IOException {
+
+ isWhitespace = true;
+ int minType = 9999;
+
+ while (true) {
+
+ String save = text;
+
+ nextImpl();
+
+ if (type < minType)
+ minType = type;
+
+ if (minType > CDSECT) continue; // no "real" event so far
+
+ if (minType >= TEXT) { // text, see if accumulate
+
+ if (save != null) text = text == null ? save : save + text;
+
+ switch(peekId()) {
+ case Wbxml.ENTITY:
+ case Wbxml.STR_I:
+ case Wbxml.STR_T:
+ case Wbxml.LITERAL:
+ case Wbxml.LITERAL_C:
+ case Wbxml.LITERAL_A:
+ case Wbxml.LITERAL_AC: continue;
+ }
+ }
+
+ break;
+ }
+
+ type = minType;
+
+ if (type > TEXT)
+ type = TEXT;
+
+ return type;
+ }
+
+
+ public int nextToken() throws XmlPullParserException, IOException {
+
+ isWhitespace = true;
+ nextImpl();
+ return type;
+ }
+
+
+
+ public int nextTag() throws XmlPullParserException, IOException {
+
+ next();
+ if (type == TEXT && isWhitespace)
+ next();
+
+ if (type != END_TAG && type != START_TAG)
+ exception("unexpected type");
+
+ return type;
+ }
+
+
+ public String nextText() throws XmlPullParserException, IOException {
+ if (type != START_TAG)
+ exception("precondition: START_TAG");
+
+ next();
+
+ String result;
+
+ if (type == TEXT) {
+ result = getText();
+ next();
+ }
+ else
+ result = "";
+
+ if (type != END_TAG)
+ exception("END_TAG expected");
+
+ return result;
+ }
+
+
+ public void require(int type, String namespace, String name)
+ throws XmlPullParserException, IOException {
+
+ if (type != this.type
+ || (namespace != null && !namespace.equals(getNamespace()))
+ || (name != null && !name.equals(getName())))
+ exception(
+ "expected: " + (type == WAP_EXTENSION ? "WAP Ext." : (TYPES[type] + " {" + namespace + "}" + name)));
+ }
+
+
+ public void setInput(Reader reader) throws XmlPullParserException {
+ exception("InputStream required");
+ }
+
+ public void setInput(InputStream in, String enc)
+ throws XmlPullParserException {
+
+ this.in = in;
+
+ try {
+ version = readByte();
+ publicIdentifierId = readInt();
+
+ if (publicIdentifierId == 0)
+ readInt();
+
+ int charset = readInt(); // skip charset
+
+ if (null == enc){
+ switch (charset){
+ case 4: encoding = "ISO-8859-1"; break;
+ case 106: encoding = "UTF-8"; break;
+ // add more if you need them
+ // http://www.iana.org/assignments/character-sets
+ // case MIBenum: encoding = Name break;
+ default: throw new UnsupportedEncodingException(""+charset);
+ }
+ }else{
+ encoding = enc;
+ }
+
+ int strTabSize = readInt();
+ stringTable = new byte[strTabSize];
+
+ int ok = 0;
+ while(ok < strTabSize){
+ int cnt = in.read(stringTable, ok, strTabSize - ok);
+ if(cnt <= 0) break;
+ ok += cnt;
+ }
+
+ selectPage(0, true);
+ selectPage(0, false);
+ }
+ catch (IOException e) {
+ exception("Illegal input format");
+ }
+ }
+
+ public void setFeature(String feature, boolean value)
+ throws XmlPullParserException {
+ if (XmlPullParser.FEATURE_PROCESS_NAMESPACES.equals(feature))
+ processNsp = value;
+ else
+ exception("unsupported feature: " + feature);
+ }
+
+ public void setProperty(String property, Object value)
+ throws XmlPullParserException {
+ throw new XmlPullParserException("unsupported property: " + property);
+ }
+
+ // ---------------------- private / internal methods
+
+ private final boolean adjustNsp()
+ throws XmlPullParserException {
+
+ boolean any = false;
+
+ for (int i = 0; i < attributeCount << 2; i += 4) {
+ // * 4 - 4; i >= 0; i -= 4) {
+
+ String attrName = attributes[i + 2];
+ int cut = attrName.indexOf(':');
+ String prefix;
+
+ if (cut != -1) {
+ prefix = attrName.substring(0, cut);
+ attrName = attrName.substring(cut + 1);
+ }
+ else if (attrName.equals("xmlns")) {
+ prefix = attrName;
+ attrName = null;
+ }
+ else
+ continue;
+
+ if (!prefix.equals("xmlns")) {
+ any = true;
+ }
+ else {
+ int j = (nspCounts[depth]++) << 1;
+
+ nspStack = ensureCapacity(nspStack, j + 2);
+ nspStack[j] = attrName;
+ nspStack[j + 1] = attributes[i + 3];
+
+ if (attrName != null
+ && attributes[i + 3].equals(""))
+ exception("illegal empty namespace");
+
+ // prefixMap = new PrefixMap (prefixMap, attrName, attr.getValue ());
+
+ //System.out.println (prefixMap);
+
+ System.arraycopy(
+ attributes,
+ i + 4,
+ attributes,
+ i,
+ ((--attributeCount) << 2) - i);
+
+ i -= 4;
+ }
+ }
+
+ if (any) {
+ for (int i = (attributeCount << 2) - 4;
+ i >= 0;
+ i -= 4) {
+
+ String attrName = attributes[i + 2];
+ int cut = attrName.indexOf(':');
+
+ if (cut == 0)
+ throw new RuntimeException(
+ "illegal attribute name: "
+ + attrName
+ + " at "
+ + this);
+
+ else if (cut != -1) {
+ String attrPrefix =
+ attrName.substring(0, cut);
+
+ attrName = attrName.substring(cut + 1);
+
+ String attrNs = getNamespace(attrPrefix);
+
+ if (attrNs == null)
+ throw new RuntimeException(
+ "Undefined Prefix: "
+ + attrPrefix
+ + " in "
+ + this);
+
+ attributes[i] = attrNs;
+ attributes[i + 1] = attrPrefix;
+ attributes[i + 2] = attrName;
+
+ for (int j = (attributeCount << 2) - 4;
+ j > i;
+ j -= 4)
+ if (attrName.equals(attributes[j + 2])
+ && attrNs.equals(attributes[j]))
+ exception(
+ "Duplicate Attribute: {"
+ + attrNs
+ + "}"
+ + attrName);
+ }
+ }
+ }
+
+ int cut = name.indexOf(':');
+
+ if (cut == 0)
+ exception("illegal tag name: " + name);
+ else if (cut != -1) {
+ prefix = name.substring(0, cut);
+ name = name.substring(cut + 1);
+ }
+
+ this.namespace = getNamespace(prefix);
+
+ if (this.namespace == null) {
+ if (prefix != null)
+ exception("undefined prefix: " + prefix);
+ this.namespace = NO_NAMESPACE;
+ }
+
+ return any;
+ }
+
+ private final void setTable(int page, int type, String[] table) {
+ if(stringTable != null){
+ throw new RuntimeException("setXxxTable must be called before setInput!");
+ }
+ while(tables.size() < 3*page +3){
+ tables.addElement(null);
+ }
+ tables.setElementAt(table, page*3+type);
+ }
+
+
+
+
+
+ private final void exception(String desc)
+ throws XmlPullParserException {
+ throw new XmlPullParserException(desc, this, null);
+ }
+
+
+ private void selectPage(int nr, boolean tags) throws XmlPullParserException{
+ if(tables.size() == 0 && nr == 0) return;
+
+ if(nr*3 > tables.size())
+ exception("Code Page "+nr+" undefined!");
+
+ if(tags)
+ tagTable = (String[]) tables.elementAt(nr * 3 + TAG_TABLE);
+ else {
+ attrStartTable = (String[]) tables.elementAt(nr * 3 + ATTR_START_TABLE);
+ attrValueTable = (String[]) tables.elementAt(nr * 3 + ATTR_VALUE_TABLE);
+ }
+ }
+
+ private final void nextImpl()
+ throws IOException, XmlPullParserException {
+
+ String s;
+
+ if (type == END_TAG) {
+ depth--;
+ }
+
+ if (degenerated) {
+ type = XmlPullParser.END_TAG;
+ degenerated = false;
+ return;
+ }
+
+ text = null;
+ prefix = null;
+ name = null;
+
+ int id = peekId ();
+ while(id == Wbxml.SWITCH_PAGE){
+ nextId = -2;
+ selectPage(readByte(), true);
+ id = peekId();
+ }
+ nextId = -2;
+
+ switch (id) {
+ case -1 :
+ type = XmlPullParser.END_DOCUMENT;
+ break;
+
+ case Wbxml.END :
+ {
+ int sp = (depth - 1) << 2;
+
+ type = END_TAG;
+ namespace = elementStack[sp];
+ prefix = elementStack[sp + 1];
+ name = elementStack[sp + 2];
+ }
+ break;
+
+ case Wbxml.ENTITY :
+ {
+ type = ENTITY_REF;
+ char c = (char) readInt();
+ text = "" + c;
+ name = "#" + ((int) c);
+ }
+
+ break;
+
+ case Wbxml.STR_I :
+ type = TEXT;
+ text = readStrI();
+ break;
+
+ case Wbxml.EXT_I_0 :
+ case Wbxml.EXT_I_1 :
+ case Wbxml.EXT_I_2 :
+ case Wbxml.EXT_T_0 :
+ case Wbxml.EXT_T_1 :
+ case Wbxml.EXT_T_2 :
+ case Wbxml.EXT_0 :
+ case Wbxml.EXT_1 :
+ case Wbxml.EXT_2 :
+ case Wbxml.OPAQUE :
+
+ type = WAP_EXTENSION;
+ wapCode = id;
+ wapExtensionData = parseWapExtension(id);
+ break;
+
+ case Wbxml.PI :
+ throw new RuntimeException("PI curr. not supp.");
+ // readPI;
+ // break;
+
+ case Wbxml.STR_T :
+ {
+ type = TEXT;
+ text = readStrT();
+ }
+ break;
+
+ default :
+ parseElement(id);
+ }
+ // }
+ // while (next == null);
+
+ // return next;
+ }
+
+ /** Overwrite this method to intercept all wap events */
+
+ public Object parseWapExtension(int id) throws IOException, XmlPullParserException {
+
+ switch (id) {
+ case Wbxml.EXT_I_0 :
+ case Wbxml.EXT_I_1 :
+ case Wbxml.EXT_I_2 :
+ return readStrI();
+
+ case Wbxml.EXT_T_0 :
+ case Wbxml.EXT_T_1 :
+ case Wbxml.EXT_T_2 :
+ return new Integer(readInt());
+
+ case Wbxml.EXT_0 :
+ case Wbxml.EXT_1 :
+ case Wbxml.EXT_2 :
+ return null;
+
+ case Wbxml.OPAQUE :
+ {
+ int count = readInt();
+ byte[] buf = new byte[count];
+
+ while(count > 0){
+ count -= in.read(buf, buf.length-count, count);
+ }
+
+ return buf;
+ } // case OPAQUE
+
+
+ default:
+ exception("illegal id: "+id);
+ return null; // dead code
+ } // SWITCH
+ }
+
+ public void readAttr() throws IOException, XmlPullParserException {
+
+ int id = readByte();
+ int i = 0;
+
+ while (id != 1) {
+
+ while(id == Wbxml.SWITCH_PAGE){
+ selectPage(readByte(), false);
+ id = readByte();
+ }
+
+ String name = resolveId(attrStartTable, id);
+ StringBuffer value;
+
+ int cut = name.indexOf('=');
+
+ if (cut == -1)
+ value = new StringBuffer();
+ else {
+ value =
+ new StringBuffer(name.substring(cut + 1));
+ name = name.substring(0, cut);
+ }
+
+ id = readByte();
+ while (id > 128
+ || id == Wbxml.SWITCH_PAGE
+ || id == Wbxml.ENTITY
+ || id == Wbxml.STR_I
+ || id == Wbxml.STR_T
+ || (id >= Wbxml.EXT_I_0 && id <= Wbxml.EXT_I_2)
+ || (id >= Wbxml.EXT_T_0 && id <= Wbxml.EXT_T_2)) {
+
+ switch (id) {
+ case Wbxml.SWITCH_PAGE :
+ selectPage(readByte(), false);
+ break;
+
+ case Wbxml.ENTITY :
+ value.append((char) readInt());
+ break;
+
+ case Wbxml.STR_I :
+ value.append(readStrI());
+ break;
+
+ case Wbxml.EXT_I_0 :
+ case Wbxml.EXT_I_1 :
+ case Wbxml.EXT_I_2 :
+ case Wbxml.EXT_T_0 :
+ case Wbxml.EXT_T_1 :
+ case Wbxml.EXT_T_2 :
+ case Wbxml.EXT_0 :
+ case Wbxml.EXT_1 :
+ case Wbxml.EXT_2 :
+ case Wbxml.OPAQUE :
+ value.append(resolveWapExtension(id, parseWapExtension(id)));
+ break;
+
+ case Wbxml.STR_T :
+ value.append(readStrT());
+ break;
+
+ default :
+ value.append(
+ resolveId(attrValueTable, id));
+ }
+
+ id = readByte();
+ }
+
+ attributes = ensureCapacity(attributes, i + 4);
+
+ attributes[i++] = "";
+ attributes[i++] = null;
+ attributes[i++] = name;
+ attributes[i++] = value.toString();
+
+ attributeCount++;
+ }
+ }
+
+ private int peekId () throws IOException {
+ if (nextId == -2) {
+ nextId = in.read ();
+ }
+ return nextId;
+ }
+
+ /** overwrite for own WAP extension handling in attributes and high level parsing
+ * (above nextToken() level) */
+
+ protected String resolveWapExtension(int id, Object data){
+
+ if(data instanceof byte[]){
+ StringBuffer sb = new StringBuffer();
+ byte[] b = (byte[]) data;
+
+ for (int i = 0; i < b.length; i++) {
+ sb.append(HEX_DIGITS.charAt((b[i] >> 4) & 0x0f));
+ sb.append(HEX_DIGITS.charAt(b[i] & 0x0f));
+ }
+ return sb.toString();
+ }
+
+ return "$("+data+")";
+ }
+
+ String resolveId(String[] tab, int id) throws IOException {
+ int idx = (id & 0x07f) - 5;
+ if (idx == -1){
+ wapCode = -1;
+ return readStrT();
+ }
+ if (idx < 0
+ || tab == null
+ || idx >= tab.length
+ || tab[idx] == null)
+ throw new IOException("id " + id + " undef.");
+
+ wapCode = idx+5;
+
+ return tab[idx];
+ }
+
+ void parseElement(int id)
+ throws IOException, XmlPullParserException {
+
+ type = START_TAG;
+ name = resolveId(tagTable, id & 0x03f);
+
+ attributeCount = 0;
+ if ((id & 128) != 0) {
+ readAttr();
+ }
+
+ degenerated = (id & 64) == 0;
+
+ int sp = depth++ << 2;
+
+ // transfer to element stack
+
+ elementStack = ensureCapacity(elementStack, sp + 4);
+ elementStack[sp + 3] = name;
+
+ if (depth >= nspCounts.length) {
+ int[] bigger = new int[depth + 4];
+ System.arraycopy(nspCounts, 0, bigger, 0, nspCounts.length);
+ nspCounts = bigger;
+ }
+
+ nspCounts[depth] = nspCounts[depth - 1];
+
+ for (int i = attributeCount - 1; i > 0; i--) {
+ for (int j = 0; j < i; j++) {
+ if (getAttributeName(i)
+ .equals(getAttributeName(j)))
+ exception(
+ "Duplicate Attribute: "
+ + getAttributeName(i));
+ }
+ }
+
+ if (processNsp)
+ adjustNsp();
+ else
+ namespace = "";
+
+ elementStack[sp] = namespace;
+ elementStack[sp + 1] = prefix;
+ elementStack[sp + 2] = name;
+
+ }
+
+ private final String[] ensureCapacity(
+ String[] arr,
+ int required) {
+ if (arr.length >= required)
+ return arr;
+ String[] bigger = new String[required + 16];
+ System.arraycopy(arr, 0, bigger, 0, arr.length);
+ return bigger;
+ }
+
+ int readByte() throws IOException {
+ int i = in.read();
+ if (i == -1)
+ throw new IOException("Unexpected EOF");
+ return i;
+ }
+
+ int readInt() throws IOException {
+ int result = 0;
+ int i;
+
+ do {
+ i = readByte();
+ result = (result << 7) | (i & 0x7f);
+ }
+ while ((i & 0x80) != 0);
+
+ return result;
+ }
+
+ String readStrI() throws IOException {
+ ByteArrayOutputStream buf = new ByteArrayOutputStream();
+ boolean wsp = true;
+ while (true){
+ int i = in.read();
+ if (i == 0){
+ break;
+ }
+ if (i == -1){
+ throw new IOException(UNEXPECTED_EOF);
+ }
+ if (i > 32){
+ wsp = false;
+ }
+ buf.write(i);
+ }
+ isWhitespace = wsp;
+ String result = new String(buf.toByteArray(), encoding);
+ buf.close();
+ return result;
+ }
+
+ String readStrT() throws IOException {
+ int pos = readInt();
+ // As the main reason of stringTable is compression we build a cache of Strings
+ // stringTable is supposed to help create Strings from parts which means some cache hit rate
+ // This will help to minimize the Strings created when invoking readStrT() repeatedly
+ if (cacheStringTable == null){
+ //Lazy init if device is not using StringTable but inline 0x03 strings
+ cacheStringTable = new Hashtable();
+ }
+ String forReturn = (String) cacheStringTable.get(new Integer(pos));
+ if (forReturn == null){
+
+ int end = pos;
+ while(end < stringTable.length && stringTable[end] != '\0'){
+ end++;
+ }
+ forReturn = new String(stringTable, pos, end-pos, encoding);
+ cacheStringTable.put(new Integer(pos), forReturn);
+ }
+ return forReturn;
+ }
+
+ /**
+ * Sets the tag table for a given page.
+ * The first string in the array defines tag 5, the second tag 6 etc.
+ */
+
+ public void setTagTable(int page, String[] table) {
+ setTable(page, TAG_TABLE, table);
+
+ // this.tagTable = tagTable;
+ // if (page != 0)
+ // throw new RuntimeException("code pages curr. not supp.");
+ }
+
+ /** Sets the attribute start Table for a given page.
+ * The first string in the array defines attribute
+ * 5, the second attribute 6 etc. Please use the
+ * character '=' (without quote!) as delimiter
+ * between the attribute name and the (start of the) value
+ */
+
+ public void setAttrStartTable(
+ int page,
+ String[] table) {
+
+ setTable(page, ATTR_START_TABLE, table);
+ }
+
+ /** Sets the attribute value Table for a given page.
+ * The first string in the array defines attribute value 0x85,
+ * the second attribute value 0x86 etc.
+ */
+
+ public void setAttrValueTable(
+ int page,
+ String[] table) {
+
+ setTable(page, ATTR_VALUE_TABLE, table);
+ }
+
+ /** Returns the token ID for start tags or the event type for wap proprietary events
+ * such as OPAQUE.
+ */
+
+ public int getWapCode(){
+ return wapCode;
+ }
+
+ public Object getWapExtensionData(){
+ return wapExtensionData;
+ }
+
+
+}
diff --git a/xml/src/main/java/org/kxml2/wap/WbxmlSerializer.java b/xml/src/main/java/org/kxml2/wap/WbxmlSerializer.java
new file mode 100644
index 0000000..8c1b598
--- /dev/null
+++ b/xml/src/main/java/org/kxml2/wap/WbxmlSerializer.java
@@ -0,0 +1,512 @@
+/* Copyright (c) 2002,2003, Stefan Haustein, Oberhausen, Rhld., Germany
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE. */
+
+//Contributors: Jonathan Cox, Bogdan Onoiu, Jerry Tian
+
+package org.kxml2.wap;
+
+import java.io.*;
+import java.util.*;
+
+import org.xmlpull.v1.*;
+
+// TODO: make some of the "direct" WBXML token writing methods public??
+
+/**
+ * A class for writing WBXML.
+ *
+ */
+
+
+
+public class WbxmlSerializer implements XmlSerializer {
+
+
+ Hashtable stringTable = new Hashtable();
+
+ OutputStream out;
+
+ ByteArrayOutputStream buf = new ByteArrayOutputStream();
+ ByteArrayOutputStream stringTableBuf = new ByteArrayOutputStream();
+
+ String pending;
+ int depth;
+ String name;
+ String namespace;
+ Vector attributes = new Vector();
+
+ Hashtable attrStartTable = new Hashtable();
+ Hashtable attrValueTable = new Hashtable();
+ Hashtable tagTable = new Hashtable();
+
+ private int attrPage;
+ private int tagPage;
+
+ private String encoding;
+
+
+ public XmlSerializer attribute(String namespace, String name, String value) {
+ attributes.addElement(name);
+ attributes.addElement(value);
+ return this;
+ }
+
+
+ public void cdsect (String cdsect) throws IOException{
+ text (cdsect);
+ }
+
+
+
+ /* silently ignore comment */
+
+ public void comment (String comment) {
+ }
+
+
+ public void docdecl (String docdecl) {
+ throw new RuntimeException ("Cannot write docdecl for WBXML");
+ }
+
+
+ public void entityRef (String er) {
+ throw new RuntimeException ("EntityReference not supported for WBXML");
+ }
+
+ public int getDepth() {
+ return depth;
+ }
+
+
+ public boolean getFeature (String name) {
+ return false;
+ }
+
+ public String getNamespace() {
+ throw new RuntimeException("NYI");
+ }
+
+ public String getName() {
+ throw new RuntimeException("NYI");
+ }
+
+ public String getPrefix(String nsp, boolean create) {
+ throw new RuntimeException ("NYI");
+ }
+
+
+ public Object getProperty (String name) {
+ return null;
+ }
+
+ public void ignorableWhitespace (String sp) {
+ }
+
+
+ public void endDocument() throws IOException {
+ writeInt(out, stringTableBuf.size());
+
+ // write StringTable
+
+ out.write(stringTableBuf.toByteArray());
+
+ // write buf
+
+ out.write(buf.toByteArray());
+
+ // ready!
+
+ out.flush();
+ }
+
+
+ /** ATTENTION: flush cannot work since Wbxml documents require
+ buffering. Thus, this call does nothing. */
+
+ public void flush() {
+ }
+
+
+ public void checkPending(boolean degenerated) throws IOException {
+ if (pending == null)
+ return;
+
+ int len = attributes.size();
+
+ int[] idx = (int[]) tagTable.get(pending);
+
+ // if no entry in known table, then add as literal
+ if (idx == null) {
+ buf.write(
+ len == 0
+ ? (degenerated ? Wbxml.LITERAL : Wbxml.LITERAL_C)
+ : (degenerated ? Wbxml.LITERAL_A : Wbxml.LITERAL_AC));
+
+ writeStrT(pending, false);
+ }
+ else {
+ if(idx[0] != tagPage){
+ tagPage=idx[0];
+ buf.write(Wbxml.SWITCH_PAGE);
+ buf.write(tagPage);
+ }
+
+ buf.write(
+ len == 0
+ ? (degenerated ? idx[1] : idx[1] | 64)
+ : (degenerated
+ ? idx[1] | 128
+ : idx[1] | 192));
+
+ }
+
+ for (int i = 0; i < len;) {
+ idx = (int[]) attrStartTable.get(attributes.elementAt(i));
+
+ if (idx == null) {
+ buf.write(Wbxml.LITERAL);
+ writeStrT((String) attributes.elementAt(i), false);
+ }
+ else {
+ if(idx[0] != attrPage){
+ attrPage = idx[0];
+ buf.write(0);
+ buf.write(attrPage);
+ }
+ buf.write(idx[1]);
+ }
+ idx = (int[]) attrValueTable.get(attributes.elementAt(++i));
+ if (idx == null) {
+ writeStr((String) attributes.elementAt(i));
+ }
+ else {
+ if(idx[0] != attrPage){
+ attrPage = idx[0];
+ buf.write(0);
+ buf.write(attrPage);
+ }
+ buf.write(idx[1]);
+ }
+ ++i;
+ }
+
+ if (len > 0)
+ buf.write(Wbxml.END);
+
+ pending = null;
+ attributes.removeAllElements();
+ }
+
+
+ public void processingInstruction(String pi) {
+ throw new RuntimeException ("PI NYI");
+ }
+
+
+ public void setFeature(String name, boolean value) {
+ throw new IllegalArgumentException ("unknown feature "+name);
+ }
+
+
+
+ public void setOutput (Writer writer) {
+ throw new RuntimeException ("Wbxml requires an OutputStream!");
+ }
+
+ public void setOutput (OutputStream out, String encoding) throws IOException {
+
+ this.encoding = encoding == null ? "UTF-8" : encoding;
+ this.out = out;
+
+ buf = new ByteArrayOutputStream();
+ stringTableBuf = new ByteArrayOutputStream();
+
+ // ok, write header
+ }
+
+
+ public void setPrefix(String prefix, String nsp) {
+ throw new RuntimeException("NYI");
+ }
+
+ public void setProperty(String property, Object value) {
+ throw new IllegalArgumentException ("unknown property "+property);
+ }
+
+
+ public void startDocument(String s, Boolean b) throws IOException{
+ out.write(0x03); // version 1.3
+ // http://www.openmobilealliance.org/tech/omna/omna-wbxml-public-docid.htm
+ out.write(0x01); // unknown or missing public identifier
+
+ // default encoding is UTF-8
+
+ if(s != null){
+ encoding = s;
+ }
+
+ if (encoding.toUpperCase().equals("UTF-8")){
+ out.write(106);
+ }else if (encoding.toUpperCase().equals("ISO-8859-1")){
+ out.write(0x04);
+ }else{
+ throw new UnsupportedEncodingException(s);
+ }
+ }
+
+
+ public XmlSerializer startTag(String namespace, String name) throws IOException {
+
+ if (namespace != null && !"".equals(namespace))
+ throw new RuntimeException ("NSP NYI");
+
+ //current = new State(current, prefixMap, name);
+
+ checkPending(false);
+ pending = name;
+ depth++;
+
+ return this;
+ }
+
+ public XmlSerializer text(char[] chars, int start, int len) throws IOException {
+
+ checkPending(false);
+
+ writeStr(new String(chars, start, len));
+
+ return this;
+ }
+
+ public XmlSerializer text(String text) throws IOException {
+
+ checkPending(false);
+
+ writeStr(text);
+
+ return this;
+ }
+
+
+ /** Used in text() and attribute() to write text */
+
+ private void writeStr(String text) throws IOException{
+ int p0 = 0;
+ int lastCut = 0;
+ int len = text.length();
+
+ while(p0 < len){
+ while(p0 < len && text.charAt(p0) < 'A' ){ // skip interpunctation
+ p0++;
+ }
+ int p1 = p0;
+ while(p1 < len && text.charAt(p1) >= 'A'){
+ p1++;
+ }
+
+ if(p1 - p0 > 10) {
+
+ if(p0 > lastCut && text.charAt(p0-1) == ' '
+ && stringTable.get(text.substring(p0, p1)) == null){
+
+ buf.write(Wbxml.STR_T);
+ writeStrT(text.substring(lastCut, p1), false);
+ }
+ else {
+
+ if(p0 > lastCut && text.charAt(p0-1) == ' '){
+ p0--;
+ }
+
+ if(p0 > lastCut){
+ buf.write(Wbxml.STR_T);
+ writeStrT(text.substring(lastCut, p0), false);
+ }
+ buf.write(Wbxml.STR_T);
+ writeStrT(text.substring(p0, p1), true);
+ }
+ lastCut = p1;
+ }
+ p0 = p1;
+ }
+
+ if(lastCut < len){
+ buf.write(Wbxml.STR_T);
+ writeStrT(text.substring(lastCut, len), false);
+ }
+ }
+
+
+
+ public XmlSerializer endTag(String namespace, String name) throws IOException {
+
+ // current = current.prev;
+
+ if (pending != null)
+ checkPending(true);
+ else
+ buf.write(Wbxml.END);
+
+ depth--;
+
+ return this;
+ }
+
+ /**
+ * @throws IOException */
+
+ public void writeWapExtension(int type, Object data) throws IOException {
+ checkPending(false);
+ buf.write(type);
+ switch(type){
+ case Wbxml.EXT_0:
+ case Wbxml.EXT_1:
+ case Wbxml.EXT_2:
+ break;
+
+ case Wbxml.OPAQUE:
+ byte[] bytes = (byte[]) data;
+ writeInt(buf, bytes.length);
+ buf.write(bytes);
+ break;
+
+ case Wbxml.EXT_I_0:
+ case Wbxml.EXT_I_1:
+ case Wbxml.EXT_I_2:
+ writeStrI(buf, (String) data);
+ break;
+
+ case Wbxml.EXT_T_0:
+ case Wbxml.EXT_T_1:
+ case Wbxml.EXT_T_2:
+ writeStrT((String) data, false);
+ break;
+
+ default:
+ throw new IllegalArgumentException();
+ }
+ }
+
+ // ------------- internal methods --------------------------
+
+ static void writeInt(OutputStream out, int i) throws IOException {
+ byte[] buf = new byte[5];
+ int idx = 0;
+
+ do {
+ buf[idx++] = (byte) (i & 0x7f);
+ i = i >> 7;
+ }
+ while (i != 0);
+
+ while (idx > 1) {
+ out.write(buf[--idx] | 0x80);
+ }
+ out.write(buf[0]);
+ }
+
+ void writeStrI(OutputStream out, String s) throws IOException {
+ byte[] data = s.getBytes(encoding);
+ out.write(data);
+ out.write(0);
+ }
+
+ private final void writeStrT(String s, boolean mayPrependSpace) throws IOException {
+
+ Integer idx = (Integer) stringTable.get(s);
+
+ if (idx != null) {
+ writeInt(buf, idx.intValue());
+ }
+ else{
+ int i = stringTableBuf.size();
+ if(s.charAt(0) >= '0' && mayPrependSpace){
+ s = ' ' + s;
+ writeInt(buf, i+1);
+ }
+ else{
+ writeInt(buf, i);
+ }
+
+ stringTable.put(s, new Integer(i));
+ if(s.charAt(0) == ' '){
+ stringTable.put(s.substring(1), new Integer(i+1));
+ }
+ int j = s.lastIndexOf(' ');
+ if(j > 1){
+ stringTable.put(s.substring(j), new Integer(i+j));
+ stringTable.put(s.substring(j+1), new Integer(i+j+1));
+ }
+
+ writeStrI(stringTableBuf, s);
+ stringTableBuf.flush();
+ }
+
+ }
+
+ /**
+ * Sets the tag table for a given page.
+ * The first string in the array defines tag 5, the second tag 6 etc.
+ */
+
+ public void setTagTable(int page, String[] tagTable) {
+ // TODO: clear entries in tagTable?
+
+ for (int i = 0; i < tagTable.length; i++) {
+ if (tagTable[i] != null) {
+ Object idx = new int[]{page, i+5};
+ this.tagTable.put(tagTable[i], idx);
+ }
+ }
+ }
+
+ /**
+ * Sets the attribute start Table for a given page.
+ * The first string in the array defines attribute
+ * 5, the second attribute 6 etc.
+ * Please use the
+ * character '=' (without quote!) as delimiter
+ * between the attribute name and the (start of the) value
+ */
+ public void setAttrStartTable(int page, String[] attrStartTable) {
+
+ for (int i = 0; i < attrStartTable.length; i++) {
+ if (attrStartTable[i] != null) {
+ Object idx = new int[] {page, i + 5};
+ this.attrStartTable.put(attrStartTable[i], idx);
+ }
+ }
+ }
+
+ /**
+ * Sets the attribute value Table for a given page.
+ * The first string in the array defines attribute value 0x85,
+ * the second attribute value 0x86 etc.
+ */
+ public void setAttrValueTable(int page, String[] attrValueTable) {
+ // clear entries in this.table!
+ for (int i = 0; i < attrValueTable.length; i++) {
+ if (attrValueTable[i] != null) {
+ Object idx = new int[]{page, i + 0x085};
+ this.attrValueTable.put(attrValueTable[i], idx);
+ }
+ }
+ }
+}
diff --git a/xml/src/main/java/org/kxml2/wap/syncml/SyncML.java b/xml/src/main/java/org/kxml2/wap/syncml/SyncML.java
new file mode 100644
index 0000000..5ea8496
--- /dev/null
+++ b/xml/src/main/java/org/kxml2/wap/syncml/SyncML.java
@@ -0,0 +1,192 @@
+package org.kxml2.wap.syncml;
+
+import org.kxml2.wap.*;
+
+public abstract class SyncML {
+
+
+ // SyncML-Common (-//SYNCML//DTD SyncML 1.2//EN and -//SYNCML//DTD MetInf 1.2//EN) support
+
+ public static WbxmlParser createParser() {
+ WbxmlParser p = new WbxmlParser();
+ p.setTagTable(0, TAG_TABLE_0);
+ p.setTagTable(1, TAG_TABLE_1);
+ return p;
+ }
+
+ public static WbxmlSerializer createSerializer() {
+ WbxmlSerializer s = new WbxmlSerializer();
+ s.setTagTable(0, TAG_TABLE_0);
+ s.setTagTable(1, TAG_TABLE_1);
+ return s;
+ }
+
+
+ // SyncML-Common + DMDDF (-//OMA//DTD-DM-DDF 1.2//EN) support
+
+ public static WbxmlParser createDMParser() {
+ WbxmlParser p = createParser();
+ p.setTagTable(2, TAG_TABLE_2_DM);
+ return p;
+ }
+
+ public static WbxmlSerializer createDMSerializer() {
+ WbxmlSerializer s = createSerializer();
+ s.setTagTable(2, TAG_TABLE_2_DM);
+ return s;
+ }
+
+ // Tables
+
+ public static final String [] TAG_TABLE_0 = {
+
+ // -//SYNCML//DTD SyncML 1.2//EN
+
+ "Add", // 0x05
+ "Alert", // 0x06
+ "Archive", // 0x07
+ "Atomic", // 0x08
+ "Chal", // 0x09
+ "Cmd", // 0x0a
+ "CmdID", // 0x0b
+ "CmdRef", // 0x0c
+ "Copy", // 0x0d
+ "Cred", // 0x0e
+ "Data", // 0x0f
+ "Delete", // 0x10
+ "Exec", // 0x11
+ "Final", // 0x12
+ "Get", // 0x13
+ "Item", // 0x14
+ "Lang", // 0x15
+ "LocName", // 0x16
+ "LocURI", // 0x17
+ "Map", // 0x18
+ "MapItem", // 0x19
+ "Meta", // 0x1a
+ "MsgID", // 0x1b
+ "MsgRef", // 0x1c
+ "NoResp", // 0x1d
+ "NoResults", // 0x1e
+ "Put", // 0x1f
+ "Replace", // 0x20
+ "RespURI", // 0x21
+ "Results", // 0x22
+ "Search", // 0x23
+ "Sequence", // 0x24
+ "SessionID", // 0x25
+ "SftDel", // 0x26
+ "Source", // 0x27
+ "SourceRef", // 0x28
+ "Status", // 0x29
+ "Sync", // 0x2a
+ "SyncBody", // 0x2b
+ "SyncHdr", // 0x2c
+ "SyncML", // 0x2d
+ "Target", // 0x2e
+ "TargetRef", // 0x2f
+ "Reserved for future use", // 0x30
+ "VerDTD", // 0x31
+ "VerProto", // 0x32
+ "NumberOfChanged",// 0x33
+ "MoreData", // 0x34
+ "Field", // 0x35
+ "Filter", // 0x36
+ "Record", // 0x37
+ "FilterType", // 0x38
+ "SourceParent", // 0x39
+ "TargetParent", // 0x3a
+ "Move", // 0x3b
+ "Correlator" // 0x3c
+ };
+
+ public static final String [] TAG_TABLE_1 = {
+
+ // -//SYNCML//DTD MetInf 1.2//EN
+
+ "Anchor", // 0x05
+ "EMI", // 0x06
+ "Format", // 0x07
+ "FreeID", // 0x08
+ "FreeMem", // 0x09
+ "Last", // 0x0a
+ "Mark", // 0x0b
+ "MaxMsgSize", // 0x0c
+ "Mem", // 0x0d
+ "MetInf", // 0x0e
+ "Next", // 0x0f
+ "NextNonce", // 0x10
+ "SharedMem", // 0x11
+ "Size", // 0x12
+ "Type", // 0x13
+ "Version", // 0x14
+ "MaxObjSize", // 0x15
+ "FieldLevel" // 0x16
+
+ };
+
+ public static final String [] TAG_TABLE_2_DM = {
+
+ // -//OMA//DTD-DM-DDF 1.2//EN
+
+ "AccessType", // 0x05
+ "ACL", // 0x06
+ "Add", // 0x07
+ "b64", // 0x08
+ "bin", // 0x09
+ "bool", // 0x0a
+ "chr", // 0x0b
+ "CaseSense", // 0x0c
+ "CIS", // 0x0d
+ "Copy", // 0x0e
+ "CS", // 0x0f
+ "date", // 0x10
+ "DDFName", // 0x11
+ "DefaultValue", // 0x12
+ "Delete", // 0x13
+ "Description", // 0x14
+ "DDFFormat", // 0x15
+ "DFProperties", // 0x16
+ "DFTitle", // 0x17
+ "DFType", // 0x18
+ "Dynamic", // 0x19
+ "Exec", // 0x1a
+ "float", // 0x1b
+ "Format", // 0x1c
+ "Get", // 0x1d
+ "int", // 0x1e
+ "Man", // 0x1f
+ "MgmtTree", // 0x20
+ "MIME", // 0x21
+ "Mod", // 0x22
+ "Name", // 0x23
+ "Node", // 0x24
+ "node", // 0x25
+ "NodeName", // 0x26
+ "null", // 0x27
+ "Occurence", // 0x28
+ "One", // 0x29
+ "OneOrMore", // 0x2a
+ "OneOrN", // 0x2b
+ "Path", // 0x2c
+ "Permanent", // 0x2d
+ "Replace", // 0x2e
+ "RTProperties", // 0x2f
+ "Scope", // 0x30
+ "Size", // 0x31
+ "time", // 0x32
+ "Title", // 0x33
+ "TStamp", // 0x34
+ "Type", // 0x35
+ "Value", // 0x36
+ "VerDTD", // 0x37
+ "VerNo", // 0x38
+ "xml", // 0x39
+ "ZeroOrMore", // 0x3a
+ "ZeroOrN", // 0x3b
+ "ZeroOrOne" // 0x3c
+
+ };
+
+}
+
diff --git a/xml/src/main/java/org/kxml2/wap/wml/Wml.java b/xml/src/main/java/org/kxml2/wap/wml/Wml.java
new file mode 100644
index 0000000..7e925d8
--- /dev/null
+++ b/xml/src/main/java/org/kxml2/wap/wml/Wml.java
@@ -0,0 +1,233 @@
+package org.kxml2.wap.wml;
+
+import org.kxml2.wap.*;
+
+
+/** This class contains the wml coding tables for elements
+ * and attributes needed by the WmlParser.
+ */
+
+
+public abstract class Wml {
+
+ /** Creates a WbxmlParser with the WML code pages set */
+
+ public static WbxmlParser createParser() {
+ WbxmlParser p = new WbxmlParser();
+ p.setTagTable(0, TAG_TABLE);
+ p.setAttrStartTable(0, ATTR_START_TABLE);
+ p.setAttrValueTable(0, ATTR_VALUE_TABLE);
+ return p;
+ }
+
+ public static WbxmlSerializer createSerializer() {
+ WbxmlSerializer s = new WbxmlSerializer();
+ s.setTagTable(0, TAG_TABLE);
+ s.setAttrStartTable(0, ATTR_START_TABLE);
+ s.setAttrValueTable(0, ATTR_VALUE_TABLE);
+ return s;
+ }
+
+
+ public static final String [] TAG_TABLE = {
+
+ null, // 05
+ null, // 06
+ null, // 07
+ null, // 08
+ null, // 09
+ null, // 0A
+ null, // 0B
+ null, // 0C
+ null, // 0D
+ null, // 0E
+ null, // 0F
+
+ null, // 10
+ null, // 11
+ null, // 12
+ null, // 13
+ null, // 14
+ null, // 15
+ null, // 16
+ null, // 17
+ null, // 18
+ null, // 19
+ null, // 1A
+ null, // 1B
+ "a", // 1C
+ "td", // 1D
+ "tr", // 1E
+ "table", // 1F
+
+ "p", // 20
+ "postfield", // 21
+ "anchor", // 22
+ "access", // 23
+ "b", // 24
+ "big", // 25
+ "br", // 26
+ "card", // 27
+ "do", // 28
+ "em", // 29
+ "fieldset", // 2A
+ "go", // 2B
+ "head", // 2C
+ "i", // 2D
+ "img", // 2E
+ "input", // 2F
+
+ "meta", // 30
+ "noop", // 31
+ "prev", // 32
+ "onevent", // 33
+ "optgroup", // 34
+ "option", // 35
+ "refresh", // 36
+ "select", // 37
+ "small", // 38
+ "strong", // 39
+ null, // 3A
+ "template", // 3B
+ "timer", // 3C
+ "u", // 3D
+ "setvar", // 3E
+ "wml", // 3F
+ };
+
+
+ public static final String [] ATTR_START_TABLE = {
+ "accept-charset", // 05
+ "align=bottom", // 06
+ "align=center", // 07
+ "align=left", // 08
+ "align=middle", // 09
+ "align=right", // 0A
+ "align=top", // 0B
+ "alt", // 0C
+ "content", // 0D
+ null, // 0E
+ "domain", // 0F
+
+ "emptyok=false", // 10
+ "emptyok=true", // 11
+ "format", // 12
+ "height", // 13
+ "hspace", // 14
+ "ivalue", // 15
+ "iname", // 16
+ null, // 17
+ "label", // 18
+ "localsrc", // 19
+ "maxlength", // 1A
+ "method=get", // 1B
+ "method=post", // 1C
+ "mode=nowrap", // 1D
+ "mode=wrap", // 1E
+ "multiple=false", // 1F
+
+ "multiple=true", // 20
+ "name", // 21
+ "newcontext=false", // 22
+ "newcontext=true", // 23
+ "onpick", // 24
+ "onenterbackward", // 25
+ "onenterforward", // 26
+ "ontimer", // 27
+ "optimal=false", // 28
+ "optimal=true", // 29
+ "path", // 2A
+ null, // 2B
+ null, // 2C
+ null, // 2D
+ "scheme", // 2E
+ "sendreferer=false", // 2F
+
+ "sendreferer=true", // 30
+ "size", // 31
+ "src", // 32
+ "ordered=true", // 33
+ "ordered=false", // 34
+ "tabindex", // 35
+ "title", // 36
+ "type", // 37
+ "type=accept", // 38
+ "type=delete", // 39
+ "type=help", // 3A
+ "type=password", // 3B
+ "type=onpick", // 3C
+ "type=onenterbackward", // 3D
+ "type=onenterforward", // 3E
+ "type=ontimer", // 3F
+
+ null, // 40
+ null, // 41
+ null, // 42
+ null, // 43
+ null, // 44
+ "type=options", // 45
+ "type=prev", // 46
+ "type=reset", // 47
+ "type=text", // 48
+ "type=vnd.", // 49
+ "href", // 4A
+ "href=http://", // 4B
+ "href=https://", // 4C
+ "value", // 4D
+ "vspace", // 4E
+ "width", // 4F
+
+ "xml:lang", // 50
+ null, // 51
+ "align", // 52
+ "columns", // 53
+ "class", // 54
+ "id", // 55
+ "forua=false", // 56
+ "forua=true", // 57
+ "src=http://", // 58
+ "src=https://", // 59
+ "http-equiv", // 5A
+ "http-equiv=Content-Type", // 5B
+ "content=application/vnd.wap.wmlc;charset=", // 5C
+ "http-equiv=Expires", // 5D
+ null, // 5E
+ null, // 5F
+ };
+
+
+ public static final String [] ATTR_VALUE_TABLE = {
+ ".com/", // 85
+ ".edu/", // 86
+ ".net/", // 87
+ ".org/", // 88
+ "accept", // 89
+ "bottom", // 8A
+ "clear", // 8B
+ "delete", // 8C
+ "help", // 8D
+ "http://", // 8E
+ "http://www.", // 8F
+
+ "https://", // 90
+ "https://www.", // 91
+ null, // 92
+ "middle", // 93
+ "nowrap", // 94
+ "onpick", // 95
+ "onenterbackward", // 96
+ "onenterforward", // 97
+ "ontimer", // 98
+ "options", // 99
+ "password", // 9A
+ "reset", // 9B
+ null, // 9C
+ "text", // 9D
+ "top", // 9E
+ "unknown", // 9F
+
+ "wrap", // A0
+ "www.", // A1
+ };
+}
+
diff --git a/xml/src/main/java/org/kxml2/wap/wv/WV.java b/xml/src/main/java/org/kxml2/wap/wv/WV.java
new file mode 100644
index 0000000..e2afbfb
--- /dev/null
+++ b/xml/src/main/java/org/kxml2/wap/wv/WV.java
@@ -0,0 +1,593 @@
+package org.kxml2.wap.wv;
+
+import java.io.IOException;
+
+import org.kxml2.wap.*;
+
+/*
+
+ * WV.java
+
+ *
+
+ * Created on 25 September 2003, 10:40
+
+ */
+
+
+
+
+
+ /**
+ * Wireless Village CSP 1.1 ("OMA-WV-CSP-V1_1-20021001-A.pdf")
+ * Wireless Village CSP 1.2 ("OMA-IMPS-WV-CSP_WBXML-v1_2-20030221-C.PDF")
+ * There are some bugs in the 1.2 spec but this is Ok. 1.2 is candidate
+ *
+
+ * @author Bogdan Onoiu
+
+ */
+
+public abstract class WV {
+
+
+
+
+
+ public static WbxmlParser createParser () throws IOException {
+
+ WbxmlParser parser = new WbxmlParser();
+
+ parser.setTagTable (0, WV.tagTablePage0);
+ parser.setTagTable (1, WV.tagTablePage1);
+ parser.setTagTable (2, WV.tagTablePage2);
+ parser.setTagTable (3, WV.tagTablePage3);
+ parser.setTagTable (4, WV.tagTablePage4);
+ parser.setTagTable (5, WV.tagTablePage5);
+ parser.setTagTable (6, WV.tagTablePage6);
+ parser.setTagTable (7, WV.tagTablePage7);
+ parser.setTagTable (8, WV.tagTablePage8);
+ parser.setTagTable (9, WV.tagTablePage9);
+ parser.setTagTable (10, WV.tagTablePageA);
+
+ parser.setAttrStartTable (0, WV.attrStartTable);
+
+ parser.setAttrValueTable (0, WV.attrValueTable);
+
+ return parser;
+ }
+
+
+
+ public static final String [] tagTablePage0 = {
+ /* Common ... continue on Page 0x09 */
+ "Acceptance", //0x00, 0x05
+ "AddList", //0x00, 0x06
+ "AddNickList", //0x00, 0x07
+ "SName", //0x00, 0x08
+ "WV-CSP-Message", //0x00, 0x09
+ "ClientID", //0x00, 0x0A
+ "Code", //0x00, 0x0B
+ "ContactList", //0x00, 0x0C
+ "ContentData", //0x00, 0x0D
+ "ContentEncoding",//0x00, 0x0E
+ "ContentSize", //0x00, 0x0F
+ "ContentType", //0x00, 0x10
+ "DateTime", //0x00, 0x11
+ "Description", //0x00, 0x12
+ "DetailedResult", //0x00, 0x13
+ "EntityList", //0x00, 0x14
+ "Group", //0x00, 0x15
+ "GroupID", //0x00, 0x16
+ "GroupList", //0x00, 0x17
+ "InUse", //0x00, 0x18
+ "Logo", //0x00, 0x19
+ "MessageCount", //0x00, 0x1A
+ "MessageID", //0x00, 0x1B
+ "MessageURI", //0x00, 0x1C
+ "MSISDN", //0x00, 0x1D
+ "Name", //0x00, 0x1E
+ "NickList", //0x00, 0x1F
+ "NickName", //0x00, 0x20
+ "Poll", //0x00, 0x21
+ "Presence", //0x00, 0x22
+ "PresenceSubList",//0x00, 0x23
+ "PresenceValue", //0x00, 0x24
+ "Property", //0x00, 0x25
+ "Qualifier", //0x00, 0x26
+ "Recipient", //0x00, 0x27
+ "RemoveList", //0x00, 0x28
+ "RemoveNickList", //0x00, 0x29
+ "Result", //0x00, 0x2A
+ "ScreenName", //0x00, 0x2B
+ "Sender", //0x00, 0x2C
+ "Session", //0x00, 0x2D
+ "SessionDescriptor",//0x00, 0x2E
+ "SessionID", //0x00, 0x2F
+ "SessionType", //0x00, 0x30
+ "Status", //0x00, 0x31
+ "Transaction", //0x00, 0x32
+ "TransactionContent",//0x00, 0x33
+ "TransactionDescriptor",//0x00, 0x34
+ "TransactionID", //0x00, 0x35
+ "TransactionMode",//0x00, 0x36
+ "URL", //0x00, 0x37
+ "URLList", //0x00, 0x38
+ "User", //0x00, 0x39
+ "UserID", //0x00, 0x3A
+ "UserList", //0x00, 0x3B
+ "Validity", //0x00, 0x3C
+ "Value", //0x00, 0x3D
+ };
+
+ public static final String [] tagTablePage1 = {
+ /* Access ... continue on Page 0x0A */
+ "AllFunctions", // 0x01, 0x05
+ "AllFunctionsRequest", // 0x01, 0x06
+ "CancelInvite-Request", // 0x01, 0x07
+ "CancelInviteUser-Request", // 0x01, 0x08
+ "Capability", // 0x01, 0x09
+ "CapabilityList", // 0x01, 0x0A
+ "CapabilityRequest", // 0x01, 0x0B
+ "ClientCapability-Request", // 0x01, 0x0C
+ "ClientCapability-Response",// 0x01, 0x0D
+ "DigestBytes", // 0x01, 0x0E
+ "DigestSchema", // 0x01, 0x0F
+ "Disconnect", // 0x01, 0x10
+ "Functions", // 0x01, 0x11
+ "GetSPInfo-Request", // 0x01, 0x12
+ "GetSPInfo-Response", // 0x01, 0x13
+ "InviteID", // 0x01, 0x14
+ "InviteNote", // 0x01, 0x15
+ "Invite-Request", // 0x01, 0x16
+ "Invite-Response", // 0x01, 0x17
+ "InviteType", // 0x01, 0x18
+ "InviteUser-Request", // 0x01, 0x19
+ "InviteUser-Response", // 0x01, 0x1A
+ "KeepAlive-Request", // 0x01, 0x1B
+ "KeepAliveTime", // 0x01, 0x1C
+ "Login-Request", // 0x01, 0x1D
+ "Login-Response", // 0x01, 0x1E
+ "Logout-Request", // 0x01, 0x1F
+ "Nonce", // 0x01, 0x20
+ "Password", // 0x01, 0x21
+ "Polling-Request", // 0x01, 0x22
+ "ResponseNote", // 0x01, 0x23
+ "SearchElement", // 0x01, 0x24
+ "SearchFindings", // 0x01, 0x25
+ "SearchID", // 0x01, 0x26
+ "SearchIndex", // 0x01, 0x27
+ "SearchLimit", // 0x01, 0x28
+ "KeepAlive-Response", // 0x01, 0x29
+ "SearchPairList", // 0x01, 0x2A
+ "Search-Request", // 0x01, 0x2B
+ "Search-Response", // 0x01, 0x2C
+ "SearchResult", // 0x01, 0x2D
+ "Service-Request", // 0x01, 0x2E
+ "Service-Response", // 0x01, 0x2F
+ "SessionCookie", // 0x01, 0x30
+ "StopSearch-Request", // 0x01, 0x31
+ "TimeToLive", // 0x01, 0x32
+ "SearchString", // 0x01, 0x33
+ "CompletionFlag", // 0x01, 0x34
+ null, // 0x01, 0x35
+ "ReceiveList", // 0x01, 0x36 /* WV 1.2 */
+ "VerifyID-Request", // 0x01, 0x37 /* WV 1.2 */
+ "Extended-Request", // 0x01, 0x38 /* WV 1.2 */
+ "Extended-Response", // 0x01, 0x39 /* WV 1.2 */
+ "AgreedCapabilityList", // 0x01, 0x3A /* WV 1.2 */
+ "Extended-Data", // 0x01, 0x3B /* WV 1.2 */
+ "OtherServer", // 0x01, 0x3C /* WV 1.2 */
+ "PresenceAttributeNSName",//0x01, 0x3D /* WV 1.2 */
+ "SessionNSName", // 0x01, 0x3E /* WV 1.2 */
+ "TransactionNSName", // 0x01, 0x3F /* WV 1.2 */
+ };
+
+ public static final String [] tagTablePage2 = {
+ /* Service ... continue on Page 0x08 */
+ "ADDGM", // 0x02, 0x05
+ "AttListFunc", // 0x02, 0x06
+ "BLENT", // 0x02, 0x07
+ "CAAUT", // 0x02, 0x08
+ "CAINV", // 0x02, 0x09
+ "CALI", // 0x02, 0x0A
+ "CCLI", // 0x02, 0x0B
+ "ContListFunc", // 0x02, 0x0C
+ "CREAG", // 0x02, 0x0D
+ "DALI", // 0x02, 0x0E
+ "DCLI", // 0x02, 0x0F
+ "DELGR", // 0x02, 0x10
+ "FundamentalFeat",//0x02, 0x11
+ "FWMSG", // 0x02, 0x12
+ "GALS", // 0x02, 0x13
+ "GCLI", // 0x02, 0x14
+ "GETGM", // 0x02, 0x15
+ "GETGP", // 0x02, 0x16
+ "GETLM", // 0x02, 0x17
+ "GETM", // 0x02, 0x18
+ "GETPR", // 0x02, 0x19
+ "GETSPI", // 0x02, 0x1A
+ "GETWL", // 0x02, 0x1B
+ "GLBLU", // 0x02, 0x1C
+ "GRCHN", // 0x02, 0x1D
+ "GroupAuthFunc",// 0x02, 0x1E
+ "GroupFeat", // 0x02, 0x1F
+ "GroupMgmtFunc",// 0x02, 0x20
+ "GroupUseFunc", // 0x02, 0x21
+ "IMAuthFunc", // 0x02, 0x22
+ "IMFeat", // 0x02, 0x23
+ "IMReceiveFunc",// 0x02, 0x24
+ "IMSendFunc", // 0x02, 0x25
+ "INVIT", // 0x02, 0x26
+ "InviteFunc", // 0x02, 0x27
+ "MBRAC", // 0x02, 0x28
+ "MCLS", // 0x02, 0x29
+ "MDELIV", // 0x02, 0x2A
+ "NEWM", // 0x02, 0x2B
+ "NOTIF", // 0x02, 0x2C
+ "PresenceAuthFunc",//0x02, 0x2D
+ "PresenceDeliverFunc",//0x02, 0x2E
+ "PresenceFeat", // 0x02, 0x2F
+ "REACT", // 0x02, 0x30
+ "REJCM", // 0x02, 0x31
+ "REJEC", // 0x02, 0x32
+ "RMVGM", // 0x02, 0x33
+ "SearchFunc", // 0x02, 0x34
+ "ServiceFunc", // 0x02, 0x35
+ "SETD", // 0x02, 0x36
+ "SETGP", // 0x02, 0x37
+ "SRCH", // 0x02, 0x38
+ "STSRC", // 0x02, 0x39
+ "SUBGCN", // 0x02, 0x3A
+ "UPDPR", // 0x02, 0x3B
+ "WVCSPFeat", // 0x02, 0x3C
+ "MF", // 0x02, 0x3D /* WV 1.2 */
+ "MG", // 0x02, 0x3E /* WV 1.2 */
+ "MM" // 0x02, 0x3F /* WV 1.2 */
+ };
+
+ public static final String [] tagTablePage3 = {
+ /* Client Capability */
+ "AcceptedCharset", // 0x03, 0x05
+ "AcceptedContentLength", // 0x03, 0x06
+ "AcceptedContentType", // 0x03, 0x07
+ "AcceptedTransferEncoding", // 0x03, 0x08
+ "AnyContent", // 0x03, 0x09
+ "DefaultLanguage", // 0x03, 0x0A
+ "InitialDeliveryMethod", // 0x03, 0x0B
+ "MultiTrans", // 0x03, 0x0C
+ "ParserSize", // 0x03, 0x0D
+ "ServerPollMin", // 0x03, 0x0E
+ "SupportedBearer", // 0x03, 0x0F
+ "SupportedCIRMethod", // 0x03, 0x10
+ "TCPAddress", // 0x03, 0x11
+ "TCPPort", // 0x03, 0x12
+ "UDPPort" // 0x03, 0x13
+ };
+
+ public static final String [] tagTablePage4 = {
+ /* Presence Primitive */
+ "CancelAuth-Request", // 0x04, 0x05
+ "ContactListProperties", // 0x04, 0x06
+ "CreateAttributeList-Request", // 0x04, 0x07
+ "CreateList-Request", // 0x04, 0x08
+ "DefaultAttributeList", // 0x04, 0x09
+ "DefaultContactList", // 0x04, 0x0A
+ "DefaultList", // 0x04, 0x0B
+ "DeleteAttributeList-Request", // 0x04, 0x0C
+ "DeleteList-Request", // 0x04, 0x0D
+ "GetAttributeList-Request", // 0x04, 0x0E
+ "GetAttributeList-Response", // 0x04, 0x0F
+ "GetList-Request", // 0x04, 0x10
+ "GetList-Response", // 0x04, 0x11
+ "GetPresence-Request", // 0x04, 0x12
+ "GetPresence-Response", // 0x04, 0x13
+ "GetWatcherList-Request", // 0x04, 0x14
+ "GetWatcherList-Response", // 0x04, 0x15
+ "ListManage-Request", // 0x04, 0x16
+ "ListManage-Response", // 0x04, 0x17
+ "UnsubscribePresence-Request", // 0x04, 0x18
+ "PresenceAuth-Request", // 0x04, 0x19
+ "PresenceAuth-User", // 0x04, 0x1A
+ "PresenceNotification-Request", // 0x04, 0x1B
+ "UpdatePresence-Request", // 0x04, 0x1C
+ "SubscribePresence-Request", // 0x04, 0x1D
+ "Auto-Subscribe", // 0x04, 0x1E /* WV 1.2 */
+ "GetReactiveAuthStatus-Request",// 0x04, 0x1F /* WV 1.2 */
+ "GetReactiveAuthStatus-Response",// 0x04, 0x20 /* WV 1.2 */
+ };
+
+ public static final String [] tagTablePage5 = {
+ /* Presence Attribute */
+ "Accuracy", // 0x05, 0x05
+ "Address", // 0x05, 0x06
+ "AddrPref", // 0x05, 0x07
+ "Alias", // 0x05, 0x08
+ "Altitude", // 0x05, 0x09
+ "Building", // 0x05, 0x0A
+ "Caddr", // 0x05, 0x0B
+ "City", // 0x05, 0x0C
+ "ClientInfo", // 0x05, 0x0D
+ "ClientProducer", // 0x05, 0x0E
+ "ClientType", // 0x05, 0x0F
+ "ClientVersion", // 0x05, 0x10
+ "CommC", // 0x05, 0x11
+ "CommCap", // 0x05, 0x12
+ "ContactInfo", // 0x05, 0x13
+ "ContainedvCard", // 0x05, 0x14
+ "Country", // 0x05, 0x15
+ "Crossing1", // 0x05, 0x16
+ "Crossing2", // 0x05, 0x17
+ "DevManufacturer", // 0x05, 0x18
+ "DirectContent", // 0x05, 0x19
+ "FreeTextLocation", // 0x05, 0x1A
+ "GeoLocation", // 0x05, 0x1B
+ "Language", // 0x05, 0x1C
+ "Latitude", // 0x05, 0x1D
+ "Longitude", // 0x05, 0x1E
+ "Model", // 0x05, 0x1F
+ "NamedArea", // 0x05, 0x20
+ "OnlineStatus", // 0x05, 0x21
+ "PLMN", // 0x05, 0x22
+ "PrefC", // 0x05, 0x23
+ "PreferredContacts",// 0x05, 0x24
+ "PreferredLanguage",// 0x05, 0x25
+ "PreferredContent", // 0x05, 0x26
+ "PreferredvCard", // 0x05, 0x27
+ "Registration", // 0x05, 0x28
+ "StatusContent", // 0x05, 0x29
+ "StatusMood", // 0x05, 0x2A
+ "StatusText", // 0x05, 0x2B
+ "Street", // 0x05, 0x2C
+ "TimeZone", // 0x05, 0x2D
+ "UserAvailability", // 0x05, 0x2E
+ "Cap", // 0x05, 0x2F
+ "Cname", // 0x05, 0x30
+ "Contact", // 0x05, 0x31
+ "Cpriority", // 0x05, 0x32
+ "Cstatus", // 0x05, 0x33
+ "Note", // 0x05, 0x34 /* WV 1.2 */
+ "Zone", // 0x05, 0x35
+ null,
+ "Inf_link", // 0x05, 0x37 /* WV 1.2 */
+ "InfoLink", // 0x05, 0x38 /* WV 1.2 */
+ "Link", // 0x05, 0x39 /* WV 1.2 */
+ "Text", // 0x05, 0x3A /* WV 1.2 */
+ };
+
+ public static final String [] tagTablePage6 = {
+ /* Messaging */
+ "BlockList", // 0x06, 0x05
+// "BlockUser-Request", // 0x06, 0x06 //This is a bug in the spec
+ "BlockEntity-Request", // 0x06, 0x06
+ "DeliveryMethod", // 0x06, 0x07
+ "DeliveryReport", // 0x06, 0x08
+ "DeliveryReport-Request", // 0x06, 0x09
+ "ForwardMessage-Request", // 0x06, 0x0A
+ "GetBlockedList-Request", // 0x06, 0x0B
+ "GetBlockedList-Response", // 0x06, 0x0C
+ "GetMessageList-Request", // 0x06, 0x0D
+ "GetMessageList-Response", // 0x06, 0x0E
+ "GetMessage-Request", // 0x06, 0x0F
+ "GetMessage-Response", // 0x06, 0x10
+ "GrantList", // 0x06, 0x11
+ "MessageDelivered", // 0x06, 0x12
+ "MessageInfo", // 0x06, 0x13
+ "MessageNotification", // 0x06, 0x14
+ "NewMessage", // 0x06, 0x15
+ "RejectMessage-Request", // 0x06, 0x16
+ "SendMessage-Request", // 0x06, 0x17
+ "SendMessage-Response", // 0x06, 0x18
+ "SetDeliveryMethod-Request",// 0x06, 0x19
+ "DeliveryTime", // 0x06, 0x1A
+ };
+
+ public static final String [] tagTablePage7 = {
+ /* Group */
+ "AddGroupMembers-Request", // 0x07, 0x05
+ "Admin", // 0x07, 0x06
+ "CreateGroup-Request", // 0x07, 0x07
+ "DeleteGroup-Request", // 0x07, 0x08
+ "GetGroupMembers-Request", // 0x07, 0x09
+ "GetGroupMembers-Response", // 0x07, 0x0A
+ "GetGroupProps-Request", // 0x07, 0x0B
+ "GetGroupProps-Response", // 0x07, 0x0C
+ "GroupChangeNotice", // 0x07, 0x0D
+ "GroupProperties", // 0x07, 0x0E
+ "Joined", // 0x07, 0x0F
+ "JoinedRequest", // 0x07, 0x10
+ "JoinGroup-Request", // 0x07, 0x11
+ "JoinGroup-Response", // 0x07, 0x12
+ "LeaveGroup-Request", // 0x07, 0x13
+ "LeaveGroup-Response", // 0x07, 0x14
+ "Left", // 0x07, 0x15
+ "MemberAccess-Request", // 0x07, 0x16
+ "Mod", // 0x07, 0x17
+ "OwnProperties", // 0x07, 0x18
+ "RejectList-Request", // 0x07, 0x19
+ "RejectList-Response", // 0x07, 0x1A
+ "RemoveGroupMembers-Request",// 0x07, 0x1B
+ "SetGroupProps-Request", // 0x07, 0x1C
+ "SubscribeGroupNotice-Request", // 0x07, 0x1D
+ "SubscribeGroupNotice-Response",// 0x07, 0x1E
+ "Users", // 0x07, 0x1F
+ "WelcomeNote", // 0x07, 0x20
+ "JoinGroup", // 0x07, 0x21
+ "SubscribeNotification", // 0x07, 0x22
+ "SubscribeType", // 0x07, 0x23
+ "GetJoinedUsers-Request", // 0x07, 0x24 /* WV 1.2 */
+ "GetJoinedUsers-Response", // 0x07, 0x25 /* WV 1.2 */
+ "AdminMapList", // 0x07, 0x26 /* WV 1.2 */
+ "AdminMapping", // 0x07, 0x27 /* WV 1.2 */
+ "Mapping", // 0x07, 0x28 /* WV 1.2 */
+ "ModMapping", // 0x07, 0x29 /* WV 1.2 */
+ "UserMapList", // 0x07, 0x2A /* WV 1.2 */
+ "UserMapping", // 0x07, 0x2B /* WV 1.2 */
+ };
+
+ public static final String [] tagTablePage8 = {
+ /* Service ... continued */
+ "MP", // 0x08, 0x05 /* WV 1.2 */
+ "GETAUT", // 0x08, 0x06 /* WV 1.2 */
+ "GETJU", // 0x08, 0x07 /* WV 1.2 */
+ "VRID", // 0x08, 0x08 /* WV 1.2 */
+ "VerifyIDFunc", // 0x08, 0x09 /* WV 1.2 */
+ };
+
+ public static final String [] tagTablePage9 = {
+ /* Common ... continued */
+ "CIR", // 0x09, 0x05 /* WV 1.2 */
+ "Domain", // 0x09, 0x06 /* WV 1.2 */
+ "ExtBlock", // 0x09, 0x07 /* WV 1.2 */
+ "HistoryPeriod", // 0x09, 0x08 /* WV 1.2 */
+ "IDList", // 0x09, 0x09 /* WV 1.2 */
+ "MaxWatcherList", // 0x09, 0x0A /* WV 1.2 */
+ "ReactiveAuthState", // 0x09, 0x0B /* WV 1.2 */
+ "ReactiveAuthStatus", // 0x09, 0x0C /* WV 1.2 */
+ "ReactiveAuthStatusList", // 0x09, 0x0D /* WV 1.2 */
+ "Watcher", // 0x09, 0x0E /* WV 1.2 */
+ "WatcherStatus" // 0x09, 0x0F /* WV 1.2 */
+ };
+
+ public static final String [] tagTablePageA = {
+ /* Access ... continued */
+ "WV-CSP-NSDiscovery-Request", //0x0A, 0x05 /* WV 1.2 */
+ "WV-CSP-NSDiscovery-Response", //0x0A, 0x06 /* WV 1.2 */
+ "VersionList" //0x0A, 0x07 /* WV 1.2 */
+ };
+
+ public static final String [] attrStartTable = {
+ "xmlns=http://www.wireless-village.org/CSP",// 0x00, 0x05
+ "xmlns=http://www.wireless-village.org/PA", // 0x00, 0x06
+ "xmlns=http://www.wireless-village.org/TRC",// 0x00, 0x07
+ "xmlns=http://www.openmobilealliance.org/DTD/WV-CSP", // 0x00, 0x08
+ "xmlns=http://www.openmobilealliance.org/DTD/WV-PA", // 0x00, 0x09
+ "xmlns=http://www.openmobilealliance.org/DTD/WV-TRC", // 0x00, 0x0A
+ };
+
+ public static final String [] attrValueTable = {
+
+ "AccessType", // 0x00 /* Common value token */
+ "ActiveUsers", // 0x01 /* Common value token */
+ "Admin", // 0x02 /* Common value token */
+ "application/", // 0x03 /* Common value token */
+ "application/vnd.wap.mms-message", // 0x04 /* Common value token */
+ "application/x-sms", // 0x05 /* Common value token */
+ "AutoJoin", // 0x06 /* Common value token */
+ "BASE64", // 0x07 /* Common value token */
+ "Closed", // 0x08 /* Common value token */
+ "Default", // 0x09 /* Common value token */
+ "DisplayName", // 0x0a /* Common value token */
+ "F", // 0x0b /* Common value token */
+ "G", // 0x0c /* Common value token */
+ "GR", // 0x0d /* Common value token */
+ "http://", // 0x0e /* Common value token */
+ "https://", // 0x0f /* Common value token */
+ "image/", // 0x10 /* Common value token */
+ "Inband", // 0x11 /* Common value token */
+ "IM", // 0x12 /* Common value token */
+ "MaxActiveUsers", // 0x13 /* Common value token */
+ "Mod", // 0x14 /* Common value token */
+ "Name", // 0x15 /* Common value token */
+ "None", // 0x16 /* Common value token */
+ "N", // 0x17 /* Common value token */
+ "Open", // 0x18 /* Common value token */
+ "Outband", // 0x19 /* Common value token */
+ "PR", // 0x1a /* Common value token */
+ "Private", // 0x1b /* Common value token */
+ "PrivateMessaging", // 0x1c /* Common value token */
+ "PrivilegeLevel", // 0x1d /* Common value token */
+ "Public", // 0x1e /* Common value token */
+ "P", // 0x1f /* Common value token */
+ "Request", // 0x20 /* Common value token */
+ "Response", // 0x21 /* Common value token */
+ "Restricted", // 0x22 /* Common value token */
+ "ScreenName", // 0x23 /* Common value token */
+ "Searchable", // 0x24 /* Common value token */
+ "S", // 0x25 /* Common value token */
+ "SC", // 0x26 /* Common value token */
+ "text/", // 0x27 /* Common value token */
+ "text/plain", // 0x28 /* Common value token */
+ "text/x-vCalendar", // 0x29 /* Common value token */
+ "text/x-vCard", // 0x2a /* Common value token */
+ "Topic", // 0x2b /* Common value token */
+ "T", // 0x2c /* Common value token */
+ "Type", // 0x2d /* Common value token */
+ "U", // 0x2e /* Common value token */
+ "US", // 0x2f /* Common value token */
+ "www.wireless-village.org", // 0x30 /* Common value token */
+ "AutoDelete", // 0x31 /* Common value token */ /* WV 1.2 */
+ "GM", // 0x32 /* Common value token */ /* WV 1.2 */
+ "Validity", // 0x33 /* Common value token */ /* WV 1.2 */
+ "ShowID", // 0x34 /* Common value token */ /* WV 1.2 */
+ "GRANTED", // 0x35 /* Common value token */ /* WV 1.2 */
+ "PENDING", // 0x36 /* Common value token */ /* WV 1.2 */
+ null, // 0x37
+ null, // 0x38
+ null, // 0x39
+ null, // 0x3a
+ null, // 0x3b
+ null, // 0x3c
+ "GROUP_ID", // 0x3d /* Access value token */
+ "GROUP_NAME", // 0x3e /* Access value token */
+ "GROUP_TOPIC", // 0x3f /* Access value token */
+ "GROUP_USER_ID_JOINED", // 0x40 /* Access value token */
+ "GROUP_USER_ID_OWNER", // 0x41 /* Access value token */
+ "HTTP", // 0x42 /* Access value token */
+ "SMS", // 0x43 /* Access value token */
+ "STCP", // 0x44 /* Access value token */
+ "SUDP", // 0x45 /* Access value token */
+ "USER_ALIAS", // 0x46 /* Access value token */
+ "USER_EMAIL_ADDRESS", // 0x47 /* Access value token */
+ "USER_FIRST_NAME", // 0x48 /* Access value token */
+ "USER_ID", // 0x49 /* Access value token */
+ "USER_LAST_NAME", // 0x4a /* Access value token */
+ "USER_MOBILE_NUMBER", // 0x4b /* Access value token */
+ "USER_ONLINE_STATUS", // 0x4c /* Access value token */
+ "WAPSMS", // 0x4d /* Access value token */
+ "WAPUDP", // 0x4e /* Access value token */
+ "WSP", // 0x4f /* Access value token */
+ "GROUP_USER_ID_AUTOJOIN", // 0x50 /* Access value token */ /* WV 1.2 */
+ null, // 0x51
+ null, // 0x52
+ null, // 0x53
+ null, // 0x54
+ null, // 0x55
+ null, // 0x56
+ null, // 0x57
+ null, // 0x58
+ null, // 0x59
+ null, // 0x5a
+ "ANGRY", // 0x5b /* Presence value token */
+ "ANXIOUS", // 0x5c /* Presence value token */
+ "ASHAMED", // 0x5d /* Presence value token */
+ "AUDIO_CALL", // 0x5e /* Presence value token */
+ "AVAILABLE", // 0x5f /* Presence value token */
+ "BORED", // 0x60 /* Presence value token */
+ "CALL", // 0x61 /* Presence value token */
+ "CLI", // 0x62 /* Presence value token */
+ "COMPUTER", // 0x63 /* Presence value token */
+ "DISCREET", // 0x64 /* Presence value token */
+ "EMAIL", // 0x65 /* Presence value token */
+ "EXCITED", // 0x66 /* Presence value token */
+ "HAPPY", // 0x67 /* Presence value token */
+ "IM", // 0x68 /* Presence value token */
+ "IM_OFFLINE", // 0x69 /* Presence value token */
+ "IM_ONLINE", // 0x6a /* Presence value token */
+ "IN_LOVE", // 0x6b /* Presence value token */
+ "INVINCIBLE", // 0x6c /* Presence value token */
+ "JEALOUS", // 0x6d /* Presence value token */
+ "MMS", // 0x6e /* Presence value token */
+ "MOBILE_PHONE", // 0x6f /* Presence value token */
+ "NOT_AVAILABLE", // 0x70 /* Presence value token */
+ "OTHER", // 0x71 /* Presence value token */
+ "PDA", // 0x72 /* Presence value token */
+ "SAD", // 0x73 /* Presence value token */
+ "SLEEPY", // 0x74 /* Presence value token */
+ "SMS", // 0x75 /* Presence value token */
+ "VIDEO_CALL", // 0x76 /* Presence value token */
+ "VIDEO_STREAM", // 0x77 /* Presence value token */
+ };
+
+
+}
diff --git a/xml/src/main/java/org/w3c/dom/Attr.java b/xml/src/main/java/org/w3c/dom/Attr.java
new file mode 100644
index 0000000..3bfde52
--- /dev/null
+++ b/xml/src/main/java/org/w3c/dom/Attr.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2000 World Wide Web Consortium,
+ * (Massachusetts Institute of Technology, Institut National de
+ * Recherche en Informatique et en Automatique, Keio University). All
+ * Rights Reserved. This program is distributed under the W3C's Software
+ * Intellectual Property License. This program is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.
+ * See W3C License http://www.w3.org/Consortium/Legal/ for more details.
+ */
+
+package org.w3c.dom;
+
+//BEGIN android-note
+//Filled some gaps in the documentation and refactored parts of the existing
+//documentation to make the Doclet happy.
+//END android-note
+
+/**
+ * The <code>Attr</code> interface represents an attribute in an
+ * <code>Element</code> object. Typically the allowable values for the
+ * attribute are defined in a document type definition.
+ * <p><code>Attr</code> objects inherit the <code>Node</code> interface, but
+ * since they are not actually child nodes of the element they describe, the
+ * DOM does not consider them part of the document tree. Thus, the
+ * <code>Node</code> attributes <code>parentNode</code>,
+ * <code>previousSibling</code>, and <code>nextSibling</code> have a
+ * <code>null</code> value for <code>Attr</code> objects. The DOM takes the
+ * view that attributes are properties of elements rather than having a
+ * separate identity from the elements they are associated with; this should
+ * make it more efficient to implement such features as default attributes
+ * associated with all elements of a given type. Furthermore,
+ * <code>Attr</code> nodes may not be immediate children of a
+ * <code>DocumentFragment</code>. However, they can be associated with
+ * <code>Element</code> nodes contained within a
+ * <code>DocumentFragment</code>. In short, users and implementors of the
+ * DOM need to be aware that <code>Attr</code> nodes have some things in
+ * common with other objects inheriting the <code>Node</code> interface, but
+ * they also are quite distinct.
+ * <p> The attribute's effective value is determined as follows: if this
+ * attribute has been explicitly assigned any value, that value is the
+ * attribute's effective value; otherwise, if there is a declaration for
+ * this attribute, and that declaration includes a default value, then that
+ * default value is the attribute's effective value; otherwise, the
+ * attribute does not exist on this element in the structure model until it
+ * has been explicitly added. Note that the <code>nodeValue</code> attribute
+ * on the <code>Attr</code> instance can also be used to retrieve the string
+ * version of the attribute's value(s).
+ * <p>In XML, where the value of an attribute can contain entity references,
+ * the child nodes of the <code>Attr</code> node may be either
+ * <code>Text</code> or <code>EntityReference</code> nodes (when these are
+ * in use; see the description of <code>EntityReference</code> for
+ * discussion). Because the DOM Core is not aware of attribute types, it
+ * treats all attribute values as simple strings, even if the DTD or schema
+ * declares them as having tokenized types.
+ * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113'>Document Object Model (DOM) Level 2 Core Specification</a>.
+ */
+public interface Attr extends Node {
+ /**
+ * Returns the name of this attribute.
+ *
+ * @return the name of the attribute.
+ */
+ public String getName();
+
+ /**
+ * If this attribute was explicitly given a value in the original
+ * document, this is <code>true</code>; otherwise, it is
+ * <code>false</code>. Note that the implementation is in charge of this
+ * attribute, not the user. If the user changes the value of the
+ * attribute (even if it ends up having the same value as the default
+ * value) then the <code>specified</code> flag is automatically flipped
+ * to <code>true</code>. To re-specify the attribute as the default
+ * value from the DTD, the user must delete the attribute. The
+ * implementation will then make a new attribute available with
+ * <code>specified</code> set to <code>false</code> and the default
+ * value (if one exists).
+ * <br>In summary: If the attribute has an assigned value in the document
+ * then <code>specified</code> is <code>true</code>, and the value is
+ * the assigned value. If the attribute has no assigned value in the
+ * document and has a default value in the DTD, then
+ * <code>specified</code> is <code>false</code>, and the value is the
+ * default value in the DTD. If the attribute has no assigned value in
+ * the document and has a value of #IMPLIED in the DTD, then the
+ * attribute does not appear in the structure model of the document. If
+ * the <code>ownerElement</code> attribute is <code>null</code> (i.e.
+ * because it was just created or was set to <code>null</code> by the
+ * various removal and cloning operations) <code>specified</code> is
+ * <code>true</code>.
+ *
+ * @return <code>true</code> if the attribute was specified,
+ * <code>false</false> otherwise.
+ */
+ public boolean getSpecified();
+
+ /**
+ * Returns the value of the attribute is returned as a string.
+ * Character and general entity references are replaced with their
+ * values. See also the method <code>getAttribute</code> on the
+ * <code>Element</code> interface.
+ *
+ * @return the attribute value as a string.
+ */
+ public String getValue();
+
+ /**
+ * Sets the value of the attribute. This creates a <code>Text</code> node
+ * with the unparsed contents of the string. I.e. any characters that an
+ * XML processor would recognize as markup are instead treated as literal
+ * text. See also the method <code>setAttribute</code> on the
+ * <code>Element</code>
+ * interface.
+ *
+ * @param value the new attribute value.
+ *
+ * @exception DOMException
+ * NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly.
+ */
+ public void setValue(String value)
+ throws DOMException;
+
+ /**
+ * The <code>Element</code> node this attribute is attached to or
+ * <code>null</code> if this attribute is not in use.
+ *
+ * @return the owner <code>Element</element>, or <code>null</code> is the
+ * attribute is unused.
+ *
+ * @since DOM Level 2
+ */
+ public Element getOwnerElement();
+
+}
diff --git a/xml/src/main/java/org/w3c/dom/CDATASection.java b/xml/src/main/java/org/w3c/dom/CDATASection.java
new file mode 100644
index 0000000..9e74734
--- /dev/null
+++ b/xml/src/main/java/org/w3c/dom/CDATASection.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2000 World Wide Web Consortium,
+ * (Massachusetts Institute of Technology, Institut National de
+ * Recherche en Informatique et en Automatique, Keio University). All
+ * Rights Reserved. This program is distributed under the W3C's Software
+ * Intellectual Property License. This program is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.
+ * See W3C License http://www.w3.org/Consortium/Legal/ for more details.
+ */
+
+package org.w3c.dom;
+
+/**
+ * CDATA sections are used to escape blocks of text containing characters that
+ * would otherwise be regarded as markup. The only delimiter that is
+ * recognized in a CDATA section is the "]]&gt;" string that ends the CDATA
+ * section. CDATA sections cannot be nested. Their primary purpose is for
+ * including material such as XML fragments, without needing to escape all
+ * the delimiters.
+ * <p>The <code>DOMString</code> attribute of the <code>Text</code> node holds
+ * the text that is contained by the CDATA section. Note that this may
+ * contain characters that need to be escaped outside of CDATA sections and
+ * that, depending on the character encoding ("charset") chosen for
+ * serialization, it may be impossible to write out some characters as part
+ * of a CDATA section.
+ * <p> The <code>CDATASection</code> interface inherits from the
+ * <code>CharacterData</code> interface through the <code>Text</code>
+ * interface. Adjacent <code>CDATASection</code> nodes are not merged by use
+ * of the <code>normalize</code> method of the <code>Node</code> interface.
+ * Because no markup is recognized within a <code>CDATASection</code>,
+ * character numeric references cannot be used as an escape mechanism when
+ * serializing. Therefore, action needs to be taken when serializing a
+ * <code>CDATASection</code> with a character encoding where some of the
+ * contained characters cannot be represented. Failure to do so would not
+ * produce well-formed XML.One potential solution in the serialization
+ * process is to end the CDATA section before the character, output the
+ * character using a character reference or entity reference, and open a new
+ * CDATA section for any further characters in the text node. Note, however,
+ * that some code conversion libraries at the time of writing do not return
+ * an error or exception when a character is missing from the encoding,
+ * making the task of ensuring that data is not corrupted on serialization
+ * more difficult.
+ * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113'>Document Object Model (DOM) Level 2 Core Specification</a>.
+ */
+public interface CDATASection extends Text {
+}
diff --git a/xml/src/main/java/org/w3c/dom/CharacterData.java b/xml/src/main/java/org/w3c/dom/CharacterData.java
new file mode 100644
index 0000000..47386e9
--- /dev/null
+++ b/xml/src/main/java/org/w3c/dom/CharacterData.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2000 World Wide Web Consortium,
+ * (Massachusetts Institute of Technology, Institut National de
+ * Recherche en Informatique et en Automatique, Keio University). All
+ * Rights Reserved. This program is distributed under the W3C's Software
+ * Intellectual Property License. This program is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.
+ * See W3C License http://www.w3.org/Consortium/Legal/ for more details.
+ */
+
+package org.w3c.dom;
+
+// BEGIN android-note
+// Cleaned up @param tags that seemed to be missing spaces between
+// the parameter name and the start of the description.
+// END android-note
+
+//BEGIN android-note
+//Filled some gaps in the documentation and refactored parts of the existing
+//documentation to make the Doclet happy.
+//END android-note
+
+/**
+ * The <code>CharacterData</code> interface extends Node with a set of
+ * attributes and methods for accessing character data in the DOM. For
+ * clarity this set is defined here rather than on each object that uses
+ * these attributes and methods. No DOM objects correspond directly to
+ * <code>CharacterData</code>, though <code>Text</code> and others do
+ * inherit the interface from it. All <code>offsets</code> in this interface
+ * start from <code>0</code>.
+ * <p>As explained in the <code>DOMString</code> interface, text strings in
+ * the DOM are represented in UTF-16, i.e. as a sequence of 16-bit units. In
+ * the following, the term 16-bit units is used whenever necessary to
+ * indicate that indexing on CharacterData is done in 16-bit units.
+ * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113'>Document Object Model (DOM) Level 2 Core Specification</a>.
+ */
+public interface CharacterData extends Node {
+ /**
+ * Returns the character data of the node that implements this interface.
+ * The DOM implementation may not put arbitrary limits on the amount of data
+ * that may be stored in a <code>CharacterData</code> node. However,
+ * implementation limits may mean that the entirety of a node's data may
+ * not fit into a single <code>DOMString</code>. In such cases, the user
+ * may call <code>substringData</code> to retrieve the data in
+ * appropriately sized pieces.
+ *
+ * @return the character data as a string.
+ *
+ * @exception DOMException
+ * DOMSTRING_SIZE_ERR: Raised when it would return more characters than
+ * fit in a <code>DOMString</code> variable on the implementation
+ * platform.
+ */
+ public String getData()
+ throws DOMException;
+ /**
+ * Sets the character data of the node that implements this interface. The
+ * DOM implementation may not put arbitrary limits on the amount of data
+ * that may be stored in a <code>CharacterData</code> node. However,
+ * implementation limits may mean that the entirety of a node's data may
+ * not fit into a single <code>DOMString</code>. In such cases, the user
+ * may call <code>substringData</code> to retrieve the data in
+ * appropriately sized pieces.
+ *
+ * @param data the new character data.
+ *
+ * @exception DOMException
+ * NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly.
+ */
+ public void setData(String data)
+ throws DOMException;
+
+ /**
+ * The number of 16-bit units that are available through <code>data</code>
+ * and the <code>substringData</code> method below. This may have the
+ * value zero, i.e., <code>CharacterData</code> nodes may be empty.
+ *
+ * @return the length in characters.
+ */
+ public int getLength();
+
+ /**
+ * Extracts a range of data from the node.
+ * @param offset Start offset of substring to extract.
+ * @param count The number of 16-bit units to extract.
+ * @return The specified substring. If the sum of <code>offset</code> and
+ * <code>count</code> exceeds the <code>length</code>, then all 16-bit
+ * units to the end of the data are returned.
+ * @exception DOMException
+ * INDEX_SIZE_ERR: Raised if the specified <code>offset</code> is
+ * negative or greater than the number of 16-bit units in
+ * <code>data</code>, or if the specified <code>count</code> is
+ * negative.
+ * <br>DOMSTRING_SIZE_ERR: Raised if the specified range of text does
+ * not fit into a <code>DOMString</code>.
+ */
+ public String substringData(int offset,
+ int count)
+ throws DOMException;
+
+ /**
+ * Append the string to the end of the character data of the node. Upon
+ * success, <code>data</code> provides access to the concatenation of
+ * <code>data</code> and the <code>DOMString</code> specified.
+ * @param arg The <code>DOMString</code> to append.
+ * @exception DOMException
+ * NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
+ */
+ public void appendData(String arg)
+ throws DOMException;
+
+ /**
+ * Insert a string at the specified 16-bit unit offset.
+ * @param offset The character offset at which to insert.
+ * @param arg The <code>DOMString</code> to insert.
+ * @exception DOMException
+ * INDEX_SIZE_ERR: Raised if the specified <code>offset</code> is
+ * negative or greater than the number of 16-bit units in
+ * <code>data</code>.
+ * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
+ */
+ public void insertData(int offset,
+ String arg)
+ throws DOMException;
+
+ /**
+ * Remove a range of 16-bit units from the node. Upon success,
+ * <code>data</code> and <code>length</code> reflect the change.
+ * @param offset The offset from which to start removing.
+ * @param count The number of 16-bit units to delete. If the sum of
+ * <code>offset</code> and <code>count</code> exceeds
+ * <code>length</code> then all 16-bit units from <code>offset</code>
+ * to the end of the data are deleted.
+ * @exception DOMException
+ * INDEX_SIZE_ERR: Raised if the specified <code>offset</code> is
+ * negative or greater than the number of 16-bit units in
+ * <code>data</code>, or if the specified <code>count</code> is
+ * negative.
+ * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
+ */
+ public void deleteData(int offset,
+ int count)
+ throws DOMException;
+
+ /**
+ * Replace the characters starting at the specified 16-bit unit offset
+ * with the specified string.
+ * @param offset The offset from which to start replacing.
+ * @param count The number of 16-bit units to replace. If the sum of
+ * <code>offset</code> and <code>count</code> exceeds
+ * <code>length</code>, then all 16-bit units to the end of the data
+ * are replaced; (i.e., the effect is the same as a <code>remove</code>
+ * method call with the same range, followed by an <code>append</code>
+ * method invocation).
+ * @param arg The <code>DOMString</code> with which the range must be
+ * replaced.
+ * @exception DOMException
+ * INDEX_SIZE_ERR: Raised if the specified <code>offset</code> is
+ * negative or greater than the number of 16-bit units in
+ * <code>data</code>, or if the specified <code>count</code> is
+ * negative.
+ * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
+ */
+ public void replaceData(int offset,
+ int count,
+ String arg)
+ throws DOMException;
+
+}
diff --git a/xml/src/main/java/org/w3c/dom/Comment.java b/xml/src/main/java/org/w3c/dom/Comment.java
new file mode 100644
index 0000000..1097921
--- /dev/null
+++ b/xml/src/main/java/org/w3c/dom/Comment.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2000 World Wide Web Consortium,
+ * (Massachusetts Institute of Technology, Institut National de
+ * Recherche en Informatique et en Automatique, Keio University). All
+ * Rights Reserved. This program is distributed under the W3C's Software
+ * Intellectual Property License. This program is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.
+ * See W3C License http://www.w3.org/Consortium/Legal/ for more details.
+ */
+
+package org.w3c.dom;
+
+/**
+ * This interface inherits from <code>CharacterData</code> and represents the
+ * content of a comment, i.e., all the characters between the starting '
+ * <code>&lt;!--</code>' and ending '<code>--&gt;</code>'. Note that this is
+ * the definition of a comment in XML, and, in practice, HTML, although some
+ * HTML tools may implement the full SGML comment structure.
+ * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113'>Document Object Model (DOM) Level 2 Core Specification</a>.
+ */
+public interface Comment extends CharacterData {
+}
diff --git a/xml/src/main/java/org/w3c/dom/DOMException.java b/xml/src/main/java/org/w3c/dom/DOMException.java
new file mode 100644
index 0000000..76bac3c
--- /dev/null
+++ b/xml/src/main/java/org/w3c/dom/DOMException.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2000 World Wide Web Consortium,
+ * (Massachusetts Institute of Technology, Institut National de
+ * Recherche en Informatique et en Automatique, Keio University). All
+ * Rights Reserved. This program is distributed under the W3C's Software
+ * Intellectual Property License. This program is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.
+ * See W3C License http://www.w3.org/Consortium/Legal/ for more details.
+ */
+
+package org.w3c.dom;
+
+//BEGIN android-note
+//Filled some gaps in the documentation and refactored parts of the existing
+//documentation to make the Doclet happy.
+//END android-note
+
+/**
+ * DOM operations only raise exceptions in "exceptional" circumstances, i.e.,
+ * when an operation is impossible to perform (either for logical reasons,
+ * because data is lost, or because the implementation has become unstable).
+ * In general, DOM methods return specific error values in ordinary
+ * processing situations, such as out-of-bound errors when using
+ * <code>NodeList</code>.
+ * <p>Implementations should raise other exceptions under other circumstances.
+ * For example, implementations should raise an implementation-dependent
+ * exception if a <code>null</code> argument is passed.
+ * <p>Some languages and object systems do not support the concept of
+ * exceptions. For such systems, error conditions may be indicated using
+ * native error reporting mechanisms. For some bindings, for example,
+ * methods may return error codes similar to those listed in the
+ * corresponding method descriptions.
+ * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113'>Document Object Model (DOM) Level 2 Core Specification</a>.
+ */
+public class DOMException extends RuntimeException {
+ /**
+ * Creates a new <code>DOMException</code> with the given error code and
+ * human-readable message.
+ * @param code the error code.
+ * @param message the human-readable message.
+ */
+ public DOMException(short code, String message) {
+ super(message);
+ this.code = code;
+ }
+ /**
+ * Holds the error code of the <code>DOMException</code>.
+ */
+ public short code;
+ // ExceptionCode
+ /**
+ * If index or size is negative, or greater than the allowed value
+ */
+ public static final short INDEX_SIZE_ERR = 1;
+ /**
+ * If the specified range of text does not fit into a DOMString
+ */
+ public static final short DOMSTRING_SIZE_ERR = 2;
+ /**
+ * If any node is inserted somewhere it doesn't belong
+ */
+ public static final short HIERARCHY_REQUEST_ERR = 3;
+ /**
+ * If a node is used in a different document than the one that created it
+ * (that doesn't support it)
+ */
+ public static final short WRONG_DOCUMENT_ERR = 4;
+ /**
+ * If an invalid or illegal character is specified, such as in a name. See
+ * production 2 in the XML specification for the definition of a legal
+ * character, and production 5 for the definition of a legal name
+ * character.
+ */
+ public static final short INVALID_CHARACTER_ERR = 5;
+ /**
+ * If data is specified for a node which does not support data
+ */
+ public static final short NO_DATA_ALLOWED_ERR = 6;
+ /**
+ * If an attempt is made to modify an object where modifications are not
+ * allowed
+ */
+ public static final short NO_MODIFICATION_ALLOWED_ERR = 7;
+ /**
+ * If an attempt is made to reference a node in a context where it does
+ * not exist
+ */
+ public static final short NOT_FOUND_ERR = 8;
+ /**
+ * If the implementation does not support the requested type of object or
+ * operation.
+ */
+ public static final short NOT_SUPPORTED_ERR = 9;
+ /**
+ * If an attempt is made to add an attribute that is already in use
+ * elsewhere
+ */
+ public static final short INUSE_ATTRIBUTE_ERR = 10;
+ /**
+ * If an attempt is made to use an object that is not, or is no longer,
+ * usable.
+ * @since DOM Level 2
+ */
+ public static final short INVALID_STATE_ERR = 11;
+ /**
+ * If an invalid or illegal string is specified.
+ * @since DOM Level 2
+ */
+ public static final short SYNTAX_ERR = 12;
+ /**
+ * If an attempt is made to modify the type of the underlying object.
+ * @since DOM Level 2
+ */
+ public static final short INVALID_MODIFICATION_ERR = 13;
+ /**
+ * If an attempt is made to create or change an object in a way which is
+ * incorrect with regard to namespaces.
+ * @since DOM Level 2
+ */
+ public static final short NAMESPACE_ERR = 14;
+ /**
+ * If a parameter or an operation is not supported by the underlying
+ * object.
+ * @since DOM Level 2
+ */
+ public static final short INVALID_ACCESS_ERR = 15;
+
+}
diff --git a/xml/src/main/java/org/w3c/dom/DOMImplementation.java b/xml/src/main/java/org/w3c/dom/DOMImplementation.java
new file mode 100644
index 0000000..dcb19c9
--- /dev/null
+++ b/xml/src/main/java/org/w3c/dom/DOMImplementation.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2000 World Wide Web Consortium,
+ * (Massachusetts Institute of Technology, Institut National de
+ * Recherche en Informatique et en Automatique, Keio University). All
+ * Rights Reserved. This program is distributed under the W3C's Software
+ * Intellectual Property License. This program is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.
+ * See W3C License http://www.w3.org/Consortium/Legal/ for more details.
+ */
+
+package org.w3c.dom;
+
+// BEGIN android-note
+// Cleaned up @param tags that seemed to be missing spaces between
+// the parameter name and the start of the description.
+// END android-note
+
+/**
+ * The <code>DOMImplementation</code> interface provides a number of methods
+ * for performing operations that are independent of any particular instance
+ * of the document object model.
+ * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113'>Document Object Model (DOM) Level 2 Core Specification</a>.
+ */
+public interface DOMImplementation {
+ /**
+ * Test if the DOM implementation implements a specific feature.
+ * @param feature The name of the feature to test (case-insensitive). The
+ * values used by DOM features are defined throughout the DOM Level 2
+ * specifications and listed in the section. The name must be an XML
+ * name. To avoid possible conflicts, as a convention, names referring
+ * to features defined outside the DOM specification should be made
+ * unique by reversing the name of the Internet domain name of the
+ * person (or the organization that the person belongs to) who defines
+ * the feature, component by component, and using this as a prefix.
+ * For instance, the W3C SVG Working Group defines the feature
+ * "org.w3c.dom.svg".
+ * @param version This is the version number of the feature to test. In
+ * Level 2, the string can be either "2.0" or "1.0". If the version is
+ * not specified, supporting any version of the feature causes the
+ * method to return <code>true</code>.
+ * @return <code>true</code> if the feature is implemented in the
+ * specified version, <code>false</code> otherwise.
+ */
+ public boolean hasFeature(String feature,
+ String version);
+
+ /**
+ * Creates an empty <code>DocumentType</code> node. Entity declarations
+ * and notations are not made available. Entity reference expansions and
+ * default attribute additions do not occur. It is expected that a
+ * future version of the DOM will provide a way for populating a
+ * <code>DocumentType</code>.
+ * <br>HTML-only DOM implementations do not need to implement this method.
+ * @param qualifiedName The qualified name of the document type to be
+ * created.
+ * @param publicId The external subset public identifier.
+ * @param systemId The external subset system identifier.
+ * @return A new <code>DocumentType</code> node with
+ * <code>Node.ownerDocument</code> set to <code>null</code>.
+ * @exception DOMException
+ * INVALID_CHARACTER_ERR: Raised if the specified qualified name
+ * contains an illegal character.
+ * <br>NAMESPACE_ERR: Raised if the <code>qualifiedName</code> is
+ * malformed.
+ * @since DOM Level 2
+ */
+ public DocumentType createDocumentType(String qualifiedName,
+ String publicId,
+ String systemId)
+ throws DOMException;
+
+ /**
+ * Creates an XML <code>Document</code> object of the specified type with
+ * its document element. HTML-only DOM implementations do not need to
+ * implement this method.
+ * @param namespaceURI The namespace URI of the document element to create.
+ * @param qualifiedName The qualified name of the document element to be
+ * created.
+ * @param doctype The type of document to be created or <code>null</code>.
+ * When <code>doctype</code> is not <code>null</code>, its
+ * <code>Node.ownerDocument</code> attribute is set to the document
+ * being created.
+ * @return A new <code>Document</code> object.
+ * @exception DOMException
+ * INVALID_CHARACTER_ERR: Raised if the specified qualified name
+ * contains an illegal character.
+ * <br>NAMESPACE_ERR: Raised if the <code>qualifiedName</code> is
+ * malformed, if the <code>qualifiedName</code> has a prefix and the
+ * <code>namespaceURI</code> is <code>null</code>, or if the
+ * <code>qualifiedName</code> has a prefix that is "xml" and the
+ * <code>namespaceURI</code> is different from "
+ * http://www.w3.org/XML/1998/namespace" .
+ * <br>WRONG_DOCUMENT_ERR: Raised if <code>doctype</code> has already
+ * been used with a different document or was created from a different
+ * implementation.
+ * @since DOM Level 2
+ */
+ public Document createDocument(String namespaceURI,
+ String qualifiedName,
+ DocumentType doctype)
+ throws DOMException;
+
+}
diff --git a/xml/src/main/java/org/w3c/dom/Document.java b/xml/src/main/java/org/w3c/dom/Document.java
new file mode 100644
index 0000000..3beddaa
--- /dev/null
+++ b/xml/src/main/java/org/w3c/dom/Document.java
@@ -0,0 +1,382 @@
+/*
+ * Copyright (c) 2000 World Wide Web Consortium,
+ * (Massachusetts Institute of Technology, Institut National de
+ * Recherche en Informatique et en Automatique, Keio University). All
+ * Rights Reserved. This program is distributed under the W3C's Software
+ * Intellectual Property License. This program is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.
+ * See W3C License http://www.w3.org/Consortium/Legal/ for more details.
+ */
+
+package org.w3c.dom;
+
+// BEGIN android-note
+// Cleaned up @param tags that seemed to be missing spaces between
+// the parameter name and the start of the description.
+// END android-note
+
+//BEGIN android-note
+//Filled some gaps in the documentation and refactored parts of the existing
+//documentation to make the Doclet happy.
+//END android-note
+
+/**
+ * The <code>Document</code> interface represents the entire HTML or XML
+ * document. Conceptually, it is the root of the document tree, and provides
+ * the primary access to the document's data.
+ * <p>Since elements, text nodes, comments, processing instructions, etc.
+ * cannot exist outside the context of a <code>Document</code>, the
+ * <code>Document</code> interface also contains the factory methods needed
+ * to create these objects. The <code>Node</code> objects created have a
+ * <code>ownerDocument</code> attribute which associates them with the
+ * <code>Document</code> within whose context they were created.
+ * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113'>Document Object Model (DOM) Level 2 Core Specification</a>.
+ */
+public interface Document extends Node {
+ /**
+ * The Document Type Declaration (see <code>DocumentType</code>)
+ * associated with this document. For HTML documents as well as XML
+ * documents without a document type declaration this returns
+ * <code>null</code>. The DOM Level 2 does not support editing the
+ * Document Type Declaration. <code>docType</code> cannot be altered in
+ * any way, including through the use of methods inherited from the
+ * <code>Node</code> interface, such as <code>insertNode</code> or
+ * <code>removeNode</code>.
+ *
+ * @return the Document Type Declaration associated with this document, if
+ * any.
+ */
+ public DocumentType getDoctype();
+
+ /**
+ * The <code>DOMImplementation</code> object that handles this document. A
+ * DOM application may use objects from multiple implementations.
+ *
+ * @return <code>DOMImplementation</code> object that handles this document.
+ */
+ public DOMImplementation getImplementation();
+
+ /**
+ * This is a convenience attribute that allows direct access to the child
+ * node that is the root element of the document. For HTML documents,
+ * this is the element with the tagName "HTML".
+ *
+ * @return the root element of this document.
+ */
+ public Element getDocumentElement();
+
+ /**
+ * Creates an element of the type specified. Note that the instance
+ * returned implements the <code>Element</code> interface, so attributes
+ * can be specified directly on the returned object.
+ * <br>In addition, if there are known attributes with default values,
+ * <code>Attr</code> nodes representing them are automatically created
+ * and attached to the element.
+ * <br>To create an element with a qualified name and namespace URI, use
+ * the <code>createElementNS</code> method.
+ * @param tagName The name of the element type to instantiate. For XML,
+ * this is case-sensitive. For HTML, the <code>tagName</code>
+ * parameter may be provided in any case, but it must be mapped to the
+ * canonical uppercase form by the DOM implementation.
+ * @return A new <code>Element</code> object with the
+ * <code>nodeName</code> attribute set to <code>tagName</code>, and
+ * <code>localName</code>, <code>prefix</code>, and
+ * <code>namespaceURI</code> set to <code>null</code>.
+ * @exception DOMException
+ * INVALID_CHARACTER_ERR: Raised if the specified name contains an
+ * illegal character.
+ */
+ public Element createElement(String tagName)
+ throws DOMException;
+
+ /**
+ * Creates an empty <code>DocumentFragment</code> object.
+ * @return A new <code>DocumentFragment</code>.
+ */
+ public DocumentFragment createDocumentFragment();
+
+ /**
+ * Creates a <code>Text</code> node given the specified string.
+ * @param data The data for the node.
+ * @return The new <code>Text</code> object.
+ */
+ public Text createTextNode(String data);
+
+ /**
+ * Creates a <code>Comment</code> node given the specified string.
+ * @param data The data for the node.
+ * @return The new <code>Comment</code> object.
+ */
+ public Comment createComment(String data);
+
+ /**
+ * Creates a <code>CDATASection</code> node whose value is the specified
+ * string.
+ * @param data The data for the <code>CDATASection</code> contents.
+ * @return The new <code>CDATASection</code> object.
+ * @exception DOMException
+ * NOT_SUPPORTED_ERR: Raised if this document is an HTML document.
+ */
+ public CDATASection createCDATASection(String data)
+ throws DOMException;
+
+ /**
+ * Creates a <code>ProcessingInstruction</code> node given the specified
+ * name and data strings.
+ * @param target The target part of the processing instruction.
+ * @param data The data for the node.
+ * @return The new <code>ProcessingInstruction</code> object.
+ * @exception DOMException
+ * INVALID_CHARACTER_ERR: Raised if the specified target contains an
+ * illegal character.
+ * <br>NOT_SUPPORTED_ERR: Raised if this document is an HTML document.
+ */
+ public ProcessingInstruction createProcessingInstruction(String target,
+ String data)
+ throws DOMException;
+
+ /**
+ * Creates an <code>Attr</code> of the given name. Note that the
+ * <code>Attr</code> instance can then be set on an <code>Element</code>
+ * using the <code>setAttributeNode</code> method.
+ * <br>To create an attribute with a qualified name and namespace URI, use
+ * the <code>createAttributeNS</code> method.
+ * @param name The name of the attribute.
+ * @return A new <code>Attr</code> object with the <code>nodeName</code>
+ * attribute set to <code>name</code>, and <code>localName</code>,
+ * <code>prefix</code>, and <code>namespaceURI</code> set to
+ * <code>null</code>. The value of the attribute is the empty string.
+ * @exception DOMException
+ * INVALID_CHARACTER_ERR: Raised if the specified name contains an
+ * illegal character.
+ */
+ public Attr createAttribute(String name)
+ throws DOMException;
+
+ /**
+ * Creates an <code>EntityReference</code> object. In addition, if the
+ * referenced entity is known, the child list of the
+ * <code>EntityReference</code> node is made the same as that of the
+ * corresponding <code>Entity</code> node.If any descendant of the
+ * <code>Entity</code> node has an unbound namespace prefix, the
+ * corresponding descendant of the created <code>EntityReference</code>
+ * node is also unbound; (its <code>namespaceURI</code> is
+ * <code>null</code>). The DOM Level 2 does not support any mechanism to
+ * resolve namespace prefixes.
+ * @param name The name of the entity to reference.
+ * @return The new <code>EntityReference</code> object.
+ * @exception DOMException
+ * INVALID_CHARACTER_ERR: Raised if the specified name contains an
+ * illegal character.
+ * <br>NOT_SUPPORTED_ERR: Raised if this document is an HTML document.
+ */
+ public EntityReference createEntityReference(String name)
+ throws DOMException;
+
+ /**
+ * Returns a <code>NodeList</code> of all the <code>Elements</code> with a
+ * given tag name in the order in which they are encountered in a
+ * preorder traversal of the <code>Document</code> tree.
+ * @param tagname The name of the tag to match on. The special value "*"
+ * matches all tags.
+ * @return A new <code>NodeList</code> object containing all the matched
+ * <code>Elements</code>.
+ */
+ public NodeList getElementsByTagName(String tagname);
+
+ /**
+ * Imports a node from another document to this document. The returned
+ * node has no parent; (<code>parentNode</code> is <code>null</code>).
+ * The source node is not altered or removed from the original document;
+ * this method creates a new copy of the source node.
+ * <br>For all nodes, importing a node creates a node object owned by the
+ * importing document, with attribute values identical to the source
+ * node's <code>nodeName</code> and <code>nodeType</code>, plus the
+ * attributes related to namespaces (<code>prefix</code>,
+ * <code>localName</code>, and <code>namespaceURI</code>). As in the
+ * <code>cloneNode</code> operation on a <code>Node</code>, the source
+ * node is not altered.
+ * <br>Additional information is copied as appropriate to the
+ * <code>nodeType</code>, attempting to mirror the behavior expected if
+ * a fragment of XML or HTML source was copied from one document to
+ * another, recognizing that the two documents may have different DTDs
+ * in the XML case. The following list describes the specifics for each
+ * type of node.
+ * <dl>
+ * <dt>ATTRIBUTE_NODE</dt>
+ * <dd>The <code>ownerElement</code> attribute
+ * is set to <code>null</code> and the <code>specified</code> flag is
+ * set to <code>true</code> on the generated <code>Attr</code>. The
+ * descendants of the source <code>Attr</code> are recursively imported
+ * and the resulting nodes reassembled to form the corresponding subtree.
+ * Note that the <code>deep</code> parameter has no effect on
+ * <code>Attr</code> nodes; they always carry their children with them
+ * when imported.</dd>
+ * <dt>DOCUMENT_FRAGMENT_NODE</dt>
+ * <dd>If the <code>deep</code> option
+ * was set to <code>true</code>, the descendants of the source element
+ * are recursively imported and the resulting nodes reassembled to form
+ * the corresponding subtree. Otherwise, this simply generates an empty
+ * <code>DocumentFragment</code>.</dd>
+ * <dt>DOCUMENT_NODE</dt>
+ * <dd><code>Document</code>
+ * nodes cannot be imported.</dd>
+ * <dt>DOCUMENT_TYPE_NODE</dt>
+ * <dd><code>DocumentType</code>
+ * nodes cannot be imported.</dd>
+ * <dt>ELEMENT_NODE</dt>
+ * <dd>Specified attribute nodes of the
+ * source element are imported, and the generated <code>Attr</code>
+ * nodes are attached to the generated <code>Element</code>. Default
+ * attributes are not copied, though if the document being imported into
+ * defines default attributes for this element name, those are assigned.
+ * If the <code>importNode</code> <code>deep</code> parameter was set to
+ * <code>true</code>, the descendants of the source element are
+ * recursively imported and the resulting nodes reassembled to form the
+ * corresponding subtree.</dd>
+ * <dt>ENTITY_NODE</dt>
+ * <dd><code>Entity</code> nodes can be
+ * imported, however in the current release of the DOM the
+ * <code>DocumentType</code> is readonly. Ability to add these imported
+ * nodes to a <code>DocumentType</code> will be considered for addition
+ * to a future release of the DOM.On import, the <code>publicId</code>,
+ * <code>systemId</code>, and <code>notationName</code> attributes are
+ * copied. If a <code>deep</code> import is requested, the descendants
+ * of the the source <code>Entity</code> are recursively imported and
+ * the resulting nodes reassembled to form the corresponding subtree.</dd>
+ * <dt>
+ * ENTITY_REFERENCE_NODE</dt>
+ * <dd>Only the <code>EntityReference</code> itself is
+ * copied, even if a <code>deep</code> import is requested, since the
+ * source and destination documents might have defined the entity
+ * differently. If the document being imported into provides a
+ * definition for this entity name, its value is assigned.</dd>
+ * <dt>NOTATION_NODE</dt>
+ * <dd>
+ * <code>Notation</code> nodes can be imported, however in the current
+ * release of the DOM the <code>DocumentType</code> is readonly. Ability
+ * to add these imported nodes to a <code>DocumentType</code> will be
+ * considered for addition to a future release of the DOM.On import, the
+ * <code>publicId</code> and <code>systemId</code> attributes are copied.
+ * Note that the <code>deep</code> parameter has no effect on
+ * <code>Notation</code> nodes since they never have any children.</dd>
+ * <dt>
+ * PROCESSING_INSTRUCTION_NODE</dt>
+ * <dd>The imported node copies its
+ * <code>target</code> and <code>data</code> values from those of the
+ * source node.</dd>
+ * <dt>TEXT_NODE, CDATA_SECTION_NODE, COMMENT_NODE</dt>
+ * <dd>These three
+ * types of nodes inheriting from <code>CharacterData</code> copy their
+ * <code>data</code> and <code>length</code> attributes from those of
+ * the source node.</dd>
+ *
+ * @param importedNode The node to import.
+ * @param deep If <code>true</code>, recursively import the subtree under
+ * the specified node; if <code>false</code>, import only the node
+ * itself, as explained above. This has no effect on <code>Attr</code>
+ * , <code>EntityReference</code>, and <code>Notation</code> nodes.
+ * @return The imported node that belongs to this <code>Document</code>.
+ * @exception DOMException
+ * NOT_SUPPORTED_ERR: Raised if the type of node being imported is not
+ * supported.
+ * @since DOM Level 2
+ */
+ public Node importNode(Node importedNode,
+ boolean deep)
+ throws DOMException;
+
+ /**
+ * Creates an element of the given qualified name and namespace URI.
+ * HTML-only DOM implementations do not need to implement this method.
+ * @param namespaceURI The namespace URI of the element to create.
+ * @param qualifiedName The qualified name of the element type to
+ * instantiate.
+ * @return A new <code>Element</code> object with the following
+ * attributes:AttributeValue<code>Node.nodeName</code>
+ * <code>qualifiedName</code><code>Node.namespaceURI</code>
+ * <code>namespaceURI</code><code>Node.prefix</code>prefix, extracted
+ * from <code>qualifiedName</code>, or <code>null</code> if there is
+ * no prefix<code>Node.localName</code>local name, extracted from
+ * <code>qualifiedName</code><code>Element.tagName</code>
+ * <code>qualifiedName</code>
+ * @exception DOMException
+ * INVALID_CHARACTER_ERR: Raised if the specified qualified name
+ * contains an illegal character.
+ * <br>NAMESPACE_ERR: Raised if the <code>qualifiedName</code> is
+ * malformed, if the <code>qualifiedName</code> has a prefix and the
+ * <code>namespaceURI</code> is <code>null</code>, or if the
+ * <code>qualifiedName</code> has a prefix that is "xml" and the
+ * <code>namespaceURI</code> is different from "
+ * http://www.w3.org/XML/1998/namespace" .
+ * @since DOM Level 2
+ */
+ public Element createElementNS(String namespaceURI,
+ String qualifiedName)
+ throws DOMException;
+
+ /**
+ * Creates an attribute of the given qualified name and namespace URI.
+ * HTML-only DOM implementations do not need to implement this method.
+ * @param namespaceURI The namespace URI of the attribute to create.
+ * @param qualifiedName The qualified name of the attribute to instantiate.
+ * @return A new <code>Attr</code> object with the following attributes:
+ * AttributeValue<code>Node.nodeName</code>qualifiedName
+ * <code>Node.namespaceURI</code><code>namespaceURI</code>
+ * <code>Node.prefix</code>prefix, extracted from
+ * <code>qualifiedName</code>, or <code>null</code> if there is no
+ * prefix<code>Node.localName</code>local name, extracted from
+ * <code>qualifiedName</code><code>Attr.name</code>
+ * <code>qualifiedName</code><code>Node.nodeValue</code>the empty
+ * string
+ * @exception DOMException
+ * INVALID_CHARACTER_ERR: Raised if the specified qualified name
+ * contains an illegal character.
+ * <br>NAMESPACE_ERR: Raised if the <code>qualifiedName</code> is
+ * malformed, if the <code>qualifiedName</code> has a prefix and the
+ * <code>namespaceURI</code> is <code>null</code>, if the
+ * <code>qualifiedName</code> has a prefix that is "xml" and the
+ * <code>namespaceURI</code> is different from "
+ * http://www.w3.org/XML/1998/namespace", or if the
+ * <code>qualifiedName</code> is "xmlns" and the
+ * <code>namespaceURI</code> is different from "
+ * http://www.w3.org/2000/xmlns/".
+ * @since DOM Level 2
+ */
+ public Attr createAttributeNS(String namespaceURI,
+ String qualifiedName)
+ throws DOMException;
+
+ /**
+ * Returns a <code>NodeList</code> of all the <code>Elements</code> with a
+ * given local name and namespace URI in the order in which they are
+ * encountered in a preorder traversal of the <code>Document</code> tree.
+ * @param namespaceURI The namespace URI of the elements to match on. The
+ * special value "*" matches all namespaces.
+ * @param localName The local name of the elements to match on. The
+ * special value "*" matches all local names.
+ * @return A new <code>NodeList</code> object containing all the matched
+ * <code>Elements</code>.
+ * @since DOM Level 2
+ */
+ public NodeList getElementsByTagNameNS(String namespaceURI,
+ String localName);
+
+ /**
+ * Returns the <code>Element</code> whose <code>ID</code> is given by
+ * <code>elementId</code>. If no such element exists, returns
+ * <code>null</code>. Behavior is not defined if more than one element
+ * has this <code>ID</code>. The DOM implementation must have
+ * information that says which attributes are of type ID. Attributes
+ * with the name "ID" are not of type ID unless so defined.
+ * Implementations that do not know whether attributes are of type ID or
+ * not are expected to return <code>null</code>.
+ * @param elementId The unique <code>id</code> value for an element.
+ * @return The matching element.
+ * @since DOM Level 2
+ */
+ public Element getElementById(String elementId);
+
+}
diff --git a/xml/src/main/java/org/w3c/dom/DocumentFragment.java b/xml/src/main/java/org/w3c/dom/DocumentFragment.java
new file mode 100644
index 0000000..6ade30c
--- /dev/null
+++ b/xml/src/main/java/org/w3c/dom/DocumentFragment.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2000 World Wide Web Consortium,
+ * (Massachusetts Institute of Technology, Institut National de
+ * Recherche en Informatique et en Automatique, Keio University). All
+ * Rights Reserved. This program is distributed under the W3C's Software
+ * Intellectual Property License. This program is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.
+ * See W3C License http://www.w3.org/Consortium/Legal/ for more details.
+ */
+
+package org.w3c.dom;
+
+/**
+ * <code>DocumentFragment</code> is a "lightweight" or "minimal"
+ * <code>Document</code> object. It is very common to want to be able to
+ * extract a portion of a document's tree or to create a new fragment of a
+ * document. Imagine implementing a user command like cut or rearranging a
+ * document by moving fragments around. It is desirable to have an object
+ * which can hold such fragments and it is quite natural to use a Node for
+ * this purpose. While it is true that a <code>Document</code> object could
+ * fulfill this role, a <code>Document</code> object can potentially be a
+ * heavyweight object, depending on the underlying implementation. What is
+ * really needed for this is a very lightweight object.
+ * <code>DocumentFragment</code> is such an object.
+ * <p>Furthermore, various operations -- such as inserting nodes as children
+ * of another <code>Node</code> -- may take <code>DocumentFragment</code>
+ * objects as arguments; this results in all the child nodes of the
+ * <code>DocumentFragment</code> being moved to the child list of this node.
+ * <p>The children of a <code>DocumentFragment</code> node are zero or more
+ * nodes representing the tops of any sub-trees defining the structure of
+ * the document. <code>DocumentFragment</code> nodes do not need to be
+ * well-formed XML documents (although they do need to follow the rules
+ * imposed upon well-formed XML parsed entities, which can have multiple top
+ * nodes). For example, a <code>DocumentFragment</code> might have only one
+ * child and that child node could be a <code>Text</code> node. Such a
+ * structure model represents neither an HTML document nor a well-formed XML
+ * document.
+ * <p>When a <code>DocumentFragment</code> is inserted into a
+ * <code>Document</code> (or indeed any other <code>Node</code> that may
+ * take children) the children of the <code>DocumentFragment</code> and not
+ * the <code>DocumentFragment</code> itself are inserted into the
+ * <code>Node</code>. This makes the <code>DocumentFragment</code> very
+ * useful when the user wishes to create nodes that are siblings; the
+ * <code>DocumentFragment</code> acts as the parent of these nodes so that
+ * the user can use the standard methods from the <code>Node</code>
+ * interface, such as <code>insertBefore</code> and <code>appendChild</code>.
+ * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113'>Document Object Model (DOM) Level 2 Core Specification</a>.
+ */
+public interface DocumentFragment extends Node {
+}
diff --git a/xml/src/main/java/org/w3c/dom/DocumentType.java b/xml/src/main/java/org/w3c/dom/DocumentType.java
new file mode 100644
index 0000000..685c073
--- /dev/null
+++ b/xml/src/main/java/org/w3c/dom/DocumentType.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2000 World Wide Web Consortium,
+ * (Massachusetts Institute of Technology, Institut National de
+ * Recherche en Informatique et en Automatique, Keio University). All
+ * Rights Reserved. This program is distributed under the W3C's Software
+ * Intellectual Property License. This program is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.
+ * See W3C License http://www.w3.org/Consortium/Legal/ for more details.
+ */
+
+package org.w3c.dom;
+
+//BEGIN android-note
+//Filled some gaps in the documentation and refactored parts of the existing
+//documentation to make the Doclet happy.
+//END android-note
+
+/**
+ * Each <code>Document</code> has a <code>doctype</code> attribute whose value
+ * is either <code>null</code> or a <code>DocumentType</code> object. The
+ * <code>DocumentType</code> interface in the DOM Core provides an interface
+ * to the list of entities that are defined for the document, and little
+ * else because the effect of namespaces and the various XML schema efforts
+ * on DTD representation are not clearly understood as of this writing.
+ * <p>The DOM Level 2 doesn't support editing <code>DocumentType</code> nodes.
+ * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113'>Document Object Model (DOM) Level 2 Core Specification</a>.
+ */
+public interface DocumentType extends Node {
+ /**
+ * The name of DTD; i.e., the name immediately following the
+ * <code>DOCTYPE</code> keyword.
+ *
+ * @return the name of the DTD.
+ */
+ public String getName();
+
+ /**
+ * A <code>NamedNodeMap</code> containing the general entities, both
+ * external and internal, declared in the DTD. Parameter entities are
+ * not contained. Duplicates are discarded. For example in:
+ * <pre>&lt;!DOCTYPE
+ * ex SYSTEM "ex.dtd" [ &lt;!ENTITY foo "foo"&gt; &lt;!ENTITY bar
+ * "bar"&gt; &lt;!ENTITY bar "bar2"&gt; &lt;!ENTITY % baz "baz"&gt;
+ * ]&gt; &lt;ex/&gt;</pre>
+ * the interface provides access to <code>foo</code>
+ * and the first declaration of <code>bar</code> but not the second
+ * declaration of <code>bar</code> or <code>baz</code>. Every node in
+ * this map also implements the <code>Entity</code> interface.
+ * <br>The DOM Level 2 does not support editing entities, therefore
+ * <code>entities</code> cannot be altered in any way.
+ *
+ * @return the entities declared in this DTD.
+ */
+ public NamedNodeMap getEntities();
+
+ /**
+ * A <code>NamedNodeMap</code> containing the notations declared in the
+ * DTD. Duplicates are discarded. Every node in this map also implements
+ * the <code>Notation</code> interface.
+ * <br>The DOM Level 2 does not support editing notations, therefore
+ * <code>notations</code> cannot be altered in any way.
+ *
+ * @return the notations declared in this DTD.
+ */
+ public NamedNodeMap getNotations();
+
+ /**
+ * The public identifier of the external subset.
+ *
+ * @return the public identifier.
+ *
+ * @since DOM Level 2
+ */
+ public String getPublicId();
+
+ /**
+ * The system identifier of the external subset.
+ *
+ * @return the system identifier.
+ *
+ * @since DOM Level 2
+ */
+ public String getSystemId();
+
+ /**
+ * The internal subset as a string. The actual content returned depends on
+ * how much information is available to the implementation. This may
+ * vary depending on various parameters, including the XML processor
+ * used to build the document.
+ *
+ * @return the internal subset.
+ *
+ * @since DOM Level 2
+ */
+ public String getInternalSubset();
+
+}
diff --git a/xml/src/main/java/org/w3c/dom/Element.java b/xml/src/main/java/org/w3c/dom/Element.java
new file mode 100644
index 0000000..72e3478
--- /dev/null
+++ b/xml/src/main/java/org/w3c/dom/Element.java
@@ -0,0 +1,314 @@
+/*
+ * Copyright (c) 2000 World Wide Web Consortium,
+ * (Massachusetts Institute of Technology, Institut National de
+ * Recherche en Informatique et en Automatique, Keio University). All
+ * Rights Reserved. This program is distributed under the W3C's Software
+ * Intellectual Property License. This program is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.
+ * See W3C License http://www.w3.org/Consortium/Legal/ for more details.
+ */
+
+package org.w3c.dom;
+
+// BEGIN android-note
+// Cleaned up @param tags that seemed to be missing spaces between
+// the parameter name and the start of the description.
+// END android-note
+
+//BEGIN android-note
+//Filled some gaps in the documentation and refactored parts of the existing
+//documentation to make the Doclet happy.
+//END android-note
+
+/**
+ * The <code>Element</code> interface represents an element in an HTML or XML
+ * document. Elements may have attributes associated with them; since the
+ * <code>Element</code> interface inherits from <code>Node</code>, the
+ * generic <code>Node</code> interface attribute <code>attributes</code> may
+ * be used to retrieve the set of all attributes for an element. There are
+ * methods on the <code>Element</code> interface to retrieve either an
+ * <code>Attr</code> object by name or an attribute value by name. In XML,
+ * where an attribute value may contain entity references, an
+ * <code>Attr</code> object should be retrieved to examine the possibly
+ * fairly complex sub-tree representing the attribute value. On the other
+ * hand, in HTML, where all attributes have simple string values, methods to
+ * directly access an attribute value can safely be used as a convenience.In
+ * DOM Level 2, the method <code>normalize</code> is inherited from the
+ * <code>Node</code> interface where it was moved.
+ * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113'>Document Object Model (DOM) Level 2 Core Specification</a>.
+ */
+public interface Element extends Node {
+ /**
+ * The name of the element. For example, in:
+ * <pre> &lt;elementExample
+ * id="demo"&gt; ... &lt;/elementExample&gt; , </pre>
+ * <code>tagName</code> has
+ * the value <code>"elementExample"</code>. Note that this is
+ * case-preserving in XML, as are all of the operations of the DOM. The
+ * HTML DOM returns the <code>tagName</code> of an HTML element in the
+ * canonical uppercase form, regardless of the case in the source HTML
+ * document.
+ *
+ * @return the name of the element.
+ */
+ public String getTagName();
+
+ /**
+ * Retrieves an attribute value by name.
+ * @param name The name of the attribute to retrieve.
+ * @return The <code>Attr</code> value as a string, or the empty string
+ * if that attribute does not have a specified or default value.
+ */
+ public String getAttribute(String name);
+
+ /**
+ * Adds a new attribute. If an attribute with that name is already present
+ * in the element, its value is changed to be that of the value
+ * parameter. This value is a simple string; it is not parsed as it is
+ * being set. So any markup (such as syntax to be recognized as an
+ * entity reference) is treated as literal text, and needs to be
+ * appropriately escaped by the implementation when it is written out.
+ * In order to assign an attribute value that contains entity
+ * references, the user must create an <code>Attr</code> node plus any
+ * <code>Text</code> and <code>EntityReference</code> nodes, build the
+ * appropriate subtree, and use <code>setAttributeNode</code> to assign
+ * it as the value of an attribute.
+ * <br>To set an attribute with a qualified name and namespace URI, use
+ * the <code>setAttributeNS</code> method.
+ * @param name The name of the attribute to create or alter.
+ * @param value Value to set in string form.
+ * @exception DOMException
+ * INVALID_CHARACTER_ERR: Raised if the specified name contains an
+ * illegal character.
+ * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
+ */
+ public void setAttribute(String name,
+ String value)
+ throws DOMException;
+
+ /**
+ * Removes an attribute by name. If the removed attribute is known to have
+ * a default value, an attribute immediately appears containing the
+ * default value as well as the corresponding namespace URI, local name,
+ * and prefix when applicable.
+ * <br>To remove an attribute by local name and namespace URI, use the
+ * <code>removeAttributeNS</code> method.
+ * @param name The name of the attribute to remove.
+ * @exception DOMException
+ * NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
+ */
+ public void removeAttribute(String name)
+ throws DOMException;
+
+ /**
+ * Retrieves an attribute node by name.
+ * <br>To retrieve an attribute node by qualified name and namespace URI,
+ * use the <code>getAttributeNodeNS</code> method.
+ * @param name The name (<code>nodeName</code>) of the attribute to
+ * retrieve.
+ * @return The <code>Attr</code> node with the specified name (
+ * <code>nodeName</code>) or <code>null</code> if there is no such
+ * attribute.
+ */
+ public Attr getAttributeNode(String name);
+
+ /**
+ * Adds a new attribute node. If an attribute with that name (
+ * <code>nodeName</code>) is already present in the element, it is
+ * replaced by the new one.
+ * <br>To add a new attribute node with a qualified name and namespace
+ * URI, use the <code>setAttributeNodeNS</code> method.
+ * @param newAttr The <code>Attr</code> node to add to the attribute list.
+ * @return If the <code>newAttr</code> attribute replaces an existing
+ * attribute, the replaced <code>Attr</code> node is returned,
+ * otherwise <code>null</code> is returned.
+ * @exception DOMException
+ * WRONG_DOCUMENT_ERR: Raised if <code>newAttr</code> was created from a
+ * different document than the one that created the element.
+ * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
+ * <br>INUSE_ATTRIBUTE_ERR: Raised if <code>newAttr</code> is already an
+ * attribute of another <code>Element</code> object. The DOM user must
+ * explicitly clone <code>Attr</code> nodes to re-use them in other
+ * elements.
+ */
+ public Attr setAttributeNode(Attr newAttr)
+ throws DOMException;
+
+ /**
+ * Removes the specified attribute node. If the removed <code>Attr</code>
+ * has a default value it is immediately replaced. The replacing
+ * attribute has the same namespace URI and local name, as well as the
+ * original prefix, when applicable.
+ * @param oldAttr The <code>Attr</code> node to remove from the attribute
+ * list.
+ * @return The <code>Attr</code> node that was removed.
+ * @exception DOMException
+ * NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
+ * <br>NOT_FOUND_ERR: Raised if <code>oldAttr</code> is not an attribute
+ * of the element.
+ */
+ public Attr removeAttributeNode(Attr oldAttr)
+ throws DOMException;
+
+ /**
+ * Returns a <code>NodeList</code> of all descendant <code>Elements</code>
+ * with a given tag name, in the order in which they are encountered in
+ * a preorder traversal of this <code>Element</code> tree.
+ * @param name The name of the tag to match on. The special value "*"
+ * matches all tags.
+ * @return A list of matching <code>Element</code> nodes.
+ */
+ public NodeList getElementsByTagName(String name);
+
+ /**
+ * Retrieves an attribute value by local name and namespace URI. HTML-only
+ * DOM implementations do not need to implement this method.
+ * @param namespaceURI The namespace URI of the attribute to retrieve.
+ * @param localName The local name of the attribute to retrieve.
+ * @return The <code>Attr</code> value as a string, or the empty string
+ * if that attribute does not have a specified or default value.
+ * @since DOM Level 2
+ */
+ public String getAttributeNS(String namespaceURI,
+ String localName);
+
+ /**
+ * Adds a new attribute. If an attribute with the same local name and
+ * namespace URI is already present on the element, its prefix is
+ * changed to be the prefix part of the <code>qualifiedName</code>, and
+ * its value is changed to be the <code>value</code> parameter. This
+ * value is a simple string; it is not parsed as it is being set. So any
+ * markup (such as syntax to be recognized as an entity reference) is
+ * treated as literal text, and needs to be appropriately escaped by the
+ * implementation when it is written out. In order to assign an
+ * attribute value that contains entity references, the user must create
+ * an <code>Attr</code> node plus any <code>Text</code> and
+ * <code>EntityReference</code> nodes, build the appropriate subtree,
+ * and use <code>setAttributeNodeNS</code> or
+ * <code>setAttributeNode</code> to assign it as the value of an
+ * attribute.
+ * <br>HTML-only DOM implementations do not need to implement this method.
+ * @param namespaceURI The namespace URI of the attribute to create or
+ * alter.
+ * @param qualifiedName The qualified name of the attribute to create or
+ * alter.
+ * @param value The value to set in string form.
+ * @exception DOMException
+ * INVALID_CHARACTER_ERR: Raised if the specified qualified name
+ * contains an illegal character.
+ * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
+ * <br>NAMESPACE_ERR: Raised if the <code>qualifiedName</code> is
+ * malformed, if the <code>qualifiedName</code> has a prefix and the
+ * <code>namespaceURI</code> is <code>null</code>, if the
+ * <code>qualifiedName</code> has a prefix that is "xml" and the
+ * <code>namespaceURI</code> is different from "
+ * http://www.w3.org/XML/1998/namespace", or if the
+ * <code>qualifiedName</code> is "xmlns" and the
+ * <code>namespaceURI</code> is different from "
+ * http://www.w3.org/2000/xmlns/".
+ * @since DOM Level 2
+ */
+ public void setAttributeNS(String namespaceURI,
+ String qualifiedName,
+ String value)
+ throws DOMException;
+
+ /**
+ * Removes an attribute by local name and namespace URI. If the removed
+ * attribute has a default value it is immediately replaced. The
+ * replacing attribute has the same namespace URI and local name, as
+ * well as the original prefix.
+ * <br>HTML-only DOM implementations do not need to implement this method.
+ * @param namespaceURI The namespace URI of the attribute to remove.
+ * @param localName The local name of the attribute to remove.
+ * @exception DOMException
+ * NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
+ * @since DOM Level 2
+ */
+ public void removeAttributeNS(String namespaceURI,
+ String localName)
+ throws DOMException;
+
+ /**
+ * Retrieves an <code>Attr</code> node by local name and namespace URI.
+ * HTML-only DOM implementations do not need to implement this method.
+ * @param namespaceURI The namespace URI of the attribute to retrieve.
+ * @param localName The local name of the attribute to retrieve.
+ * @return The <code>Attr</code> node with the specified attribute local
+ * name and namespace URI or <code>null</code> if there is no such
+ * attribute.
+ * @since DOM Level 2
+ */
+ public Attr getAttributeNodeNS(String namespaceURI,
+ String localName);
+
+ /**
+ * Adds a new attribute. If an attribute with that local name and that
+ * namespace URI is already present in the element, it is replaced by
+ * the new one.
+ * <br>HTML-only DOM implementations do not need to implement this method.
+ * @param newAttr The <code>Attr</code> node to add to the attribute list.
+ * @return If the <code>newAttr</code> attribute replaces an existing
+ * attribute with the same local name and namespace URI, the replaced
+ * <code>Attr</code> node is returned, otherwise <code>null</code> is
+ * returned.
+ * @exception DOMException
+ * WRONG_DOCUMENT_ERR: Raised if <code>newAttr</code> was created from a
+ * different document than the one that created the element.
+ * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
+ * <br>INUSE_ATTRIBUTE_ERR: Raised if <code>newAttr</code> is already an
+ * attribute of another <code>Element</code> object. The DOM user must
+ * explicitly clone <code>Attr</code> nodes to re-use them in other
+ * elements.
+ * @since DOM Level 2
+ */
+ public Attr setAttributeNodeNS(Attr newAttr)
+ throws DOMException;
+
+ /**
+ * Returns a <code>NodeList</code> of all the descendant
+ * <code>Elements</code> with a given local name and namespace URI in
+ * the order in which they are encountered in a preorder traversal of
+ * this <code>Element</code> tree.
+ * <br>HTML-only DOM implementations do not need to implement this method.
+ * @param namespaceURI The namespace URI of the elements to match on. The
+ * special value "*" matches all namespaces.
+ * @param localName The local name of the elements to match on. The
+ * special value "*" matches all local names.
+ * @return A new <code>NodeList</code> object containing all the matched
+ * <code>Elements</code>.
+ * @since DOM Level 2
+ */
+ public NodeList getElementsByTagNameNS(String namespaceURI,
+ String localName);
+
+ /**
+ * Returns <code>true</code> when an attribute with a given name is
+ * specified on this element or has a default value, <code>false</code>
+ * otherwise.
+ * @param name The name of the attribute to look for.
+ * @return <code>true</code> if an attribute with the given name is
+ * specified on this element or has a default value, <code>false</code>
+ * otherwise.
+ * @since DOM Level 2
+ */
+ public boolean hasAttribute(String name);
+
+ /**
+ * Returns <code>true</code> when an attribute with a given local name and
+ * namespace URI is specified on this element or has a default value,
+ * <code>false</code> otherwise. HTML-only DOM implementations do not
+ * need to implement this method.
+ * @param namespaceURI The namespace URI of the attribute to look for.
+ * @param localName The local name of the attribute to look for.
+ * @return <code>true</code> if an attribute with the given local name
+ * and namespace URI is specified or has a default value on this
+ * element, <code>false</code> otherwise.
+ * @since DOM Level 2
+ */
+ public boolean hasAttributeNS(String namespaceURI,
+ String localName);
+
+}
diff --git a/xml/src/main/java/org/w3c/dom/Entity.java b/xml/src/main/java/org/w3c/dom/Entity.java
new file mode 100644
index 0000000..5b09608
--- /dev/null
+++ b/xml/src/main/java/org/w3c/dom/Entity.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2000 World Wide Web Consortium,
+ * (Massachusetts Institute of Technology, Institut National de
+ * Recherche en Informatique et en Automatique, Keio University). All
+ * Rights Reserved. This program is distributed under the W3C's Software
+ * Intellectual Property License. This program is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.
+ * See W3C License http://www.w3.org/Consortium/Legal/ for more details.
+ */
+
+package org.w3c.dom;
+
+//BEGIN android-note
+//Filled some gaps in the documentation and refactored parts of the existing
+//documentation to make the Doclet happy.
+//END android-note
+
+/**
+ * This interface represents an entity, either parsed or unparsed, in an XML
+ * document. Note that this models the entity itself not the entity
+ * declaration. <code>Entity</code> declaration modeling has been left for a
+ * later Level of the DOM specification.
+ * <p>The <code>nodeName</code> attribute that is inherited from
+ * <code>Node</code> contains the name of the entity.
+ * <p>An XML processor may choose to completely expand entities before the
+ * structure model is passed to the DOM; in this case there will be no
+ * <code>EntityReference</code> nodes in the document tree.
+ * <p>XML does not mandate that a non-validating XML processor read and
+ * process entity declarations made in the external subset or declared in
+ * external parameter entities. This means that parsed entities declared in
+ * the external subset need not be expanded by some classes of applications,
+ * and that the replacement value of the entity may not be available. When
+ * the replacement value is available, the corresponding <code>Entity</code>
+ * node's child list represents the structure of that replacement text.
+ * Otherwise, the child list is empty.
+ * <p>The DOM Level 2 does not support editing <code>Entity</code> nodes; if a
+ * user wants to make changes to the contents of an <code>Entity</code>,
+ * every related <code>EntityReference</code> node has to be replaced in the
+ * structure model by a clone of the <code>Entity</code>'s contents, and
+ * then the desired changes must be made to each of those clones instead.
+ * <code>Entity</code> nodes and all their descendants are readonly.
+ * <p>An <code>Entity</code> node does not have any parent.If the entity
+ * contains an unbound namespace prefix, the <code>namespaceURI</code> of
+ * the corresponding node in the <code>Entity</code> node subtree is
+ * <code>null</code>. The same is true for <code>EntityReference</code>
+ * nodes that refer to this entity, when they are created using the
+ * <code>createEntityReference</code> method of the <code>Document</code>
+ * interface. The DOM Level 2 does not support any mechanism to resolve
+ * namespace prefixes.
+ * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113'>Document Object Model (DOM) Level 2 Core Specification</a>.
+ */
+public interface Entity extends Node {
+ /**
+ * The public identifier associated with the entity, if specified. If the
+ * public identifier was not specified, this is <code>null</code>.
+ *
+ * @return the public identifier of the entity or <code>null</code>, if the
+ * entity does not have a public identifier.
+ */
+ public String getPublicId();
+
+ /**
+ * The system identifier associated with the entity, if specified. If the
+ * system identifier was not specified, this is <code>null</code>.
+ *
+ * @return the system identifier of the entity or <code>null</code>, if the
+ * entity does not have a system identifier.
+ */
+ public String getSystemId();
+
+ /**
+ * For unparsed entities, the name of the notation for the entity. For
+ * parsed entities, this is <code>null</code>.
+ *
+ * @return the notation name of the entity or <code>null</code>, if the
+ * entity is parsed.
+ */
+ public String getNotationName();
+
+}
diff --git a/xml/src/main/java/org/w3c/dom/EntityReference.java b/xml/src/main/java/org/w3c/dom/EntityReference.java
new file mode 100644
index 0000000..ff3cf9d
--- /dev/null
+++ b/xml/src/main/java/org/w3c/dom/EntityReference.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2000 World Wide Web Consortium,
+ * (Massachusetts Institute of Technology, Institut National de
+ * Recherche en Informatique et en Automatique, Keio University). All
+ * Rights Reserved. This program is distributed under the W3C's Software
+ * Intellectual Property License. This program is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.
+ * See W3C License http://www.w3.org/Consortium/Legal/ for more details.
+ */
+
+package org.w3c.dom;
+
+/**
+ * <code>EntityReference</code> objects may be inserted into the structure
+ * model when an entity reference is in the source document, or when the
+ * user wishes to insert an entity reference. Note that character references
+ * and references to predefined entities are considered to be expanded by
+ * the HTML or XML processor so that characters are represented by their
+ * Unicode equivalent rather than by an entity reference. Moreover, the XML
+ * processor may completely expand references to entities while building the
+ * structure model, instead of providing <code>EntityReference</code>
+ * objects. If it does provide such objects, then for a given
+ * <code>EntityReference</code> node, it may be that there is no
+ * <code>Entity</code> node representing the referenced entity. If such an
+ * <code>Entity</code> exists, then the subtree of the
+ * <code>EntityReference</code> node is in general a copy of the
+ * <code>Entity</code> node subtree. However, this may not be true when an
+ * entity contains an unbound namespace prefix. In such a case, because the
+ * namespace prefix resolution depends on where the entity reference is, the
+ * descendants of the <code>EntityReference</code> node may be bound to
+ * different namespace URIs.
+ * <p>As for <code>Entity</code> nodes, <code>EntityReference</code> nodes and
+ * all their descendants are readonly.
+ * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113'>Document Object Model (DOM) Level 2 Core Specification</a>.
+ */
+public interface EntityReference extends Node {
+}
diff --git a/xml/src/main/java/org/w3c/dom/NamedNodeMap.java b/xml/src/main/java/org/w3c/dom/NamedNodeMap.java
new file mode 100644
index 0000000..a6cbf09
--- /dev/null
+++ b/xml/src/main/java/org/w3c/dom/NamedNodeMap.java
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 2000 World Wide Web Consortium,
+ * (Massachusetts Institute of Technology, Institut National de
+ * Recherche en Informatique et en Automatique, Keio University). All
+ * Rights Reserved. This program is distributed under the W3C's Software
+ * Intellectual Property License. This program is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.
+ * See W3C License http://www.w3.org/Consortium/Legal/ for more details.
+ */
+
+package org.w3c.dom;
+
+// BEGIN android-note
+// Cleaned up @param tags that seemed to be missing spaces between
+// the parameter name and the start of the description.
+// END android-note
+
+//BEGIN android-note
+//Filled some gaps in the documentation and refactored parts of the existing
+//documentation to make the Doclet happy.
+//END android-note
+
+/**
+ * Objects implementing the <code>NamedNodeMap</code> interface are used to
+ * represent collections of nodes that can be accessed by name. Note that
+ * <code>NamedNodeMap</code> does not inherit from <code>NodeList</code>;
+ * <code>NamedNodeMaps</code> are not maintained in any particular order.
+ * Objects contained in an object implementing <code>NamedNodeMap</code> may
+ * also be accessed by an ordinal index, but this is simply to allow
+ * convenient enumeration of the contents of a <code>NamedNodeMap</code>,
+ * and does not imply that the DOM specifies an order to these Nodes.
+ * <p><code>NamedNodeMap</code> objects in the DOM are live.
+ * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113'>Document Object Model (DOM) Level 2 Core Specification</a>.
+ */
+public interface NamedNodeMap {
+ /**
+ * Retrieves a node specified by name.
+ * @param name The <code>nodeName</code> of a node to retrieve.
+ * @return A <code>Node</code> (of any type) with the specified
+ * <code>nodeName</code>, or <code>null</code> if it does not identify
+ * any node in this map.
+ */
+ public Node getNamedItem(String name);
+
+ /**
+ * Adds a node using its <code>nodeName</code> attribute. If a node with
+ * that name is already present in this map, it is replaced by the new
+ * one.
+ * <br>As the <code>nodeName</code> attribute is used to derive the name
+ * which the node must be stored under, multiple nodes of certain types
+ * (those that have a "special" string value) cannot be stored as the
+ * names would clash. This is seen as preferable to allowing nodes to be
+ * aliased.
+ * @param arg A node to store in this map. The node will later be
+ * accessible using the value of its <code>nodeName</code> attribute.
+ * @return If the new <code>Node</code> replaces an existing node the
+ * replaced <code>Node</code> is returned, otherwise <code>null</code>
+ * is returned.
+ * @exception DOMException
+ * WRONG_DOCUMENT_ERR: Raised if <code>arg</code> was created from a
+ * different document than the one that created this map.
+ * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this map is readonly.
+ * <br>INUSE_ATTRIBUTE_ERR: Raised if <code>arg</code> is an
+ * <code>Attr</code> that is already an attribute of another
+ * <code>Element</code> object. The DOM user must explicitly clone
+ * <code>Attr</code> nodes to re-use them in other elements.
+ */
+ public Node setNamedItem(Node arg)
+ throws DOMException;
+
+ /**
+ * Removes a node specified by name. When this map contains the attributes
+ * attached to an element, if the removed attribute is known to have a
+ * default value, an attribute immediately appears containing the
+ * default value as well as the corresponding namespace URI, local name,
+ * and prefix when applicable.
+ * @param name The <code>nodeName</code> of the node to remove.
+ * @return The node removed from this map if a node with such a name
+ * exists.
+ * @exception DOMException
+ * NOT_FOUND_ERR: Raised if there is no node named <code>name</code> in
+ * this map.
+ * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this map is readonly.
+ */
+ public Node removeNamedItem(String name)
+ throws DOMException;
+
+ /**
+ * Returns the <code>index</code>th item in the map. If <code>index</code>
+ * is greater than or equal to the number of nodes in this map, this
+ * returns <code>null</code>.
+ * @param index Index into this map.
+ * @return The node at the <code>index</code>th position in the map, or
+ * <code>null</code> if that is not a valid index.
+ */
+ public Node item(int index);
+
+ /**
+ * The number of nodes in this map. The range of valid child node indices
+ * is <code>0</code> to <code>length-1</code> inclusive.
+ *
+ * @return the length of the map.
+ */
+ public int getLength();
+
+ /**
+ * Retrieves a node specified by local name and namespace URI. HTML-only
+ * DOM implementations do not need to implement this method.
+ * @param namespaceURI The namespace URI of the node to retrieve.
+ * @param localName The local name of the node to retrieve.
+ * @return A <code>Node</code> (of any type) with the specified local
+ * name and namespace URI, or <code>null</code> if they do not
+ * identify any node in this map.
+ * @since DOM Level 2
+ */
+ public Node getNamedItemNS(String namespaceURI,
+ String localName);
+
+ /**
+ * Adds a node using its <code>namespaceURI</code> and
+ * <code>localName</code>. If a node with that namespace URI and that
+ * local name is already present in this map, it is replaced by the new
+ * one.
+ * <br>HTML-only DOM implementations do not need to implement this method.
+ * @param arg A node to store in this map. The node will later be
+ * accessible using the value of its <code>namespaceURI</code> and
+ * <code>localName</code> attributes.
+ * @return If the new <code>Node</code> replaces an existing node the
+ * replaced <code>Node</code> is returned, otherwise <code>null</code>
+ * is returned.
+ * @exception DOMException
+ * WRONG_DOCUMENT_ERR: Raised if <code>arg</code> was created from a
+ * different document than the one that created this map.
+ * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this map is readonly.
+ * <br>INUSE_ATTRIBUTE_ERR: Raised if <code>arg</code> is an
+ * <code>Attr</code> that is already an attribute of another
+ * <code>Element</code> object. The DOM user must explicitly clone
+ * <code>Attr</code> nodes to re-use them in other elements.
+ * @since DOM Level 2
+ */
+ public Node setNamedItemNS(Node arg)
+ throws DOMException;
+
+ /**
+ * Removes a node specified by local name and namespace URI. A removed
+ * attribute may be known to have a default value when this map contains
+ * the attributes attached to an element, as returned by the attributes
+ * attribute of the <code>Node</code> interface. If so, an attribute
+ * immediately appears containing the default value as well as the
+ * corresponding namespace URI, local name, and prefix when applicable.
+ * <br>HTML-only DOM implementations do not need to implement this method.
+ * @param namespaceURI The namespace URI of the node to remove.
+ * @param localName The local name of the node to remove.
+ * @return The node removed from this map if a node with such a local
+ * name and namespace URI exists.
+ * @exception DOMException
+ * NOT_FOUND_ERR: Raised if there is no node with the specified
+ * <code>namespaceURI</code> and <code>localName</code> in this map.
+ * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this map is readonly.
+ * @since DOM Level 2
+ */
+ public Node removeNamedItemNS(String namespaceURI,
+ String localName)
+ throws DOMException;
+
+}
diff --git a/xml/src/main/java/org/w3c/dom/Node.java b/xml/src/main/java/org/w3c/dom/Node.java
new file mode 100644
index 0000000..c91c46d
--- /dev/null
+++ b/xml/src/main/java/org/w3c/dom/Node.java
@@ -0,0 +1,454 @@
+/*
+ * Copyright (c) 2000 World Wide Web Consortium,
+ * (Massachusetts Institute of Technology, Institut National de
+ * Recherche en Informatique et en Automatique, Keio University). All
+ * Rights Reserved. This program is distributed under the W3C's Software
+ * Intellectual Property License. This program is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.
+ * See W3C License http://www.w3.org/Consortium/Legal/ for more details.
+ */
+
+package org.w3c.dom;
+
+// BEGIN android-note
+// Cleaned up @param tags that seemed to be missing spaces between
+// the parameter name and the start of the description.
+// END android-note
+
+//BEGIN android-note
+//Filled some gaps in the documentation and refactored parts of the existing
+//documentation to make the Doclet happy.
+//END android-note
+
+/**
+ * The <code>Node</code> interface is the primary datatype for the entire
+ * Document Object Model. It represents a single node in the document tree.
+ * While all objects implementing the <code>Node</code> interface expose
+ * methods for dealing with children, not all objects implementing the
+ * <code>Node</code> interface may have children. For example,
+ * <code>Text</code> nodes may not have children, and adding children to
+ * such nodes results in a <code>DOMException</code> being raised.
+ * <p>The attributes <code>nodeName</code>, <code>nodeValue</code> and
+ * <code>attributes</code> are included as a mechanism to get at node
+ * information without casting down to the specific derived interface. In
+ * cases where there is no obvious mapping of these attributes for a
+ * specific <code>nodeType</code> (e.g., <code>nodeValue</code> for an
+ * <code>Element</code> or <code>attributes</code> for a <code>Comment</code>
+ * ), this returns <code>null</code>. Note that the specialized interfaces
+ * may contain additional and more convenient mechanisms to get and set the
+ * relevant information.
+ * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113'>Document Object Model (DOM) Level 2 Core Specification</a>.
+ */
+public interface Node {
+ // NodeType
+ /**
+ * The node is an <code>Element</code>.
+ */
+ public static final short ELEMENT_NODE = 1;
+ /**
+ * The node is an <code>Attr</code>.
+ */
+ public static final short ATTRIBUTE_NODE = 2;
+ /**
+ * The node is a <code>Text</code> node.
+ */
+ public static final short TEXT_NODE = 3;
+ /**
+ * The node is a <code>CDATASection</code>.
+ */
+ public static final short CDATA_SECTION_NODE = 4;
+ /**
+ * The node is an <code>EntityReference</code>.
+ */
+ public static final short ENTITY_REFERENCE_NODE = 5;
+ /**
+ * The node is an <code>Entity</code>.
+ */
+ public static final short ENTITY_NODE = 6;
+ /**
+ * The node is a <code>ProcessingInstruction</code>.
+ */
+ public static final short PROCESSING_INSTRUCTION_NODE = 7;
+ /**
+ * The node is a <code>Comment</code>.
+ */
+ public static final short COMMENT_NODE = 8;
+ /**
+ * The node is a <code>Document</code>.
+ */
+ public static final short DOCUMENT_NODE = 9;
+ /**
+ * The node is a <code>DocumentType</code>.
+ */
+ public static final short DOCUMENT_TYPE_NODE = 10;
+ /**
+ * The node is a <code>DocumentFragment</code>.
+ */
+ public static final short DOCUMENT_FRAGMENT_NODE = 11;
+ /**
+ * The node is a <code>Notation</code>.
+ */
+ public static final short NOTATION_NODE = 12;
+
+ /**
+ * The name of this node, depending on its type; see the table above.
+ *
+ * @return the name of the node.
+ */
+ public String getNodeName();
+
+ /**
+ * Returns the value of this node, depending on its type; see the table
+ * above.
+ *
+ * @return the value of the node.
+ *
+ * @exception DOMException
+ * DOMSTRING_SIZE_ERR: Raised when it would return more characters than
+ * fit in a <code>DOMString</code> variable on the implementation
+ * platform.
+ */
+ public String getNodeValue()
+ throws DOMException;
+ /**
+ * Sets the value of this node, depending on its type; see the table above.
+ * When it is defined to be <code>null</code>, setting it has no effect.
+ *
+ * @param nodeValue the new value of the node.
+ *
+ * @exception DOMException
+ * NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly.
+ */
+ public void setNodeValue(String nodeValue)
+ throws DOMException;
+
+ /**
+ * A code representing the type of the underlying object, as defined above.
+ *
+ * @return the type of the node.
+ */
+ public short getNodeType();
+
+ /**
+ * The parent of this node. All nodes, except <code>Attr</code>,
+ * <code>Document</code>, <code>DocumentFragment</code>,
+ * <code>Entity</code>, and <code>Notation</code> may have a parent.
+ * However, if a node has just been created and not yet added to the
+ * tree, or if it has been removed from the tree, this is
+ * <code>null</code>.
+ *
+ * @return the parent node, if any.
+ */
+ public Node getParentNode();
+
+ /**
+ * A <code>NodeList</code> that contains all children of this node. If
+ * there are no children, this is a <code>NodeList</code> containing no
+ * nodes.
+ *
+ * @return the list of children, which may be empty.
+ */
+ public NodeList getChildNodes();
+
+ /**
+ * The first child of this node. If there is no such node, this returns
+ * <code>null</code>.
+ *
+ * @return the first child of the node, if any.
+ */
+ public Node getFirstChild();
+
+ /**
+ * The last child of this node. If there is no such node, this returns
+ * <code>null</code>.
+ *
+ * @return the last child of the node, if any.
+ */
+ public Node getLastChild();
+
+ /**
+ * The node immediately preceding this node. If there is no such node,
+ * this returns <code>null</code>.
+ *
+ * @return the preceding node, if any.
+ */
+ public Node getPreviousSibling();
+
+ /**
+ * The node immediately following this node. If there is no such node,
+ * this returns <code>null</code>.
+ *
+ * @return the following node, if any.
+ */
+ public Node getNextSibling();
+
+ /**
+ * A <code>NamedNodeMap</code> containing the attributes of this node (if
+ * it is an <code>Element</code>) or <code>null</code> otherwise.
+ *
+ * @return the attributes of the node, which may be an empty map, or
+ * <code>null</code>, if this the node cannot have any attributes.
+ */
+ public NamedNodeMap getAttributes();
+
+ /**
+ * The <code>Document</code> object associated with this node. This is
+ * also the <code>Document</code> object used to create new nodes. When
+ * this node is a <code>Document</code> or a <code>DocumentType</code>
+ * which is not used with any <code>Document</code> yet, this is
+ * <code>null</code>.
+ *
+ * @return the document this node belongs to, if any.
+ *
+ * @version DOM Level 2
+ */
+ public Document getOwnerDocument();
+
+ /**
+ * Inserts the node <code>newChild</code> before the existing child node
+ * <code>refChild</code>. If <code>refChild</code> is <code>null</code>,
+ * insert <code>newChild</code> at the end of the list of children.
+ * <br>If <code>newChild</code> is a <code>DocumentFragment</code> object,
+ * all of its children are inserted, in the same order, before
+ * <code>refChild</code>. If the <code>newChild</code> is already in the
+ * tree, it is first removed.
+ * @param newChild The node to insert.
+ * @param refChild The reference node, i.e., the node before which the new
+ * node must be inserted.
+ * @return The node being inserted.
+ * @exception DOMException
+ * HIERARCHY_REQUEST_ERR: Raised if this node is of a type that does not
+ * allow children of the type of the <code>newChild</code> node, or if
+ * the node to insert is one of this node's ancestors.
+ * <br>WRONG_DOCUMENT_ERR: Raised if <code>newChild</code> was created
+ * from a different document than the one that created this node.
+ * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly or
+ * if the parent of the node being inserted is readonly.
+ * <br>NOT_FOUND_ERR: Raised if <code>refChild</code> is not a child of
+ * this node.
+ */
+ public Node insertBefore(Node newChild,
+ Node refChild)
+ throws DOMException;
+
+ /**
+ * Replaces the child node <code>oldChild</code> with <code>newChild</code>
+ * in the list of children, and returns the <code>oldChild</code> node.
+ * <br>If <code>newChild</code> is a <code>DocumentFragment</code> object,
+ * <code>oldChild</code> is replaced by all of the
+ * <code>DocumentFragment</code> children, which are inserted in the
+ * same order. If the <code>newChild</code> is already in the tree, it
+ * is first removed.
+ * @param newChild The new node to put in the child list.
+ * @param oldChild The node being replaced in the list.
+ * @return The node replaced.
+ * @exception DOMException
+ * HIERARCHY_REQUEST_ERR: Raised if this node is of a type that does not
+ * allow children of the type of the <code>newChild</code> node, or if
+ * the node to put in is one of this node's ancestors.
+ * <br>WRONG_DOCUMENT_ERR: Raised if <code>newChild</code> was created
+ * from a different document than the one that created this node.
+ * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this node or the parent of
+ * the new node is readonly.
+ * <br>NOT_FOUND_ERR: Raised if <code>oldChild</code> is not a child of
+ * this node.
+ */
+ public Node replaceChild(Node newChild,
+ Node oldChild)
+ throws DOMException;
+
+ /**
+ * Removes the child node indicated by <code>oldChild</code> from the list
+ * of children, and returns it.
+ * @param oldChild The node being removed.
+ * @return The node removed.
+ * @exception DOMException
+ * NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
+ * <br>NOT_FOUND_ERR: Raised if <code>oldChild</code> is not a child of
+ * this node.
+ */
+ public Node removeChild(Node oldChild)
+ throws DOMException;
+
+ /**
+ * Adds the node <code>newChild</code> to the end of the list of children
+ * of this node. If the <code>newChild</code> is already in the tree, it
+ * is first removed.
+ * @param newChild The node to add.If it is a <code>DocumentFragment</code>
+ * object, the entire contents of the document fragment are moved
+ * into the child list of this node
+ * @return The node added.
+ * @exception DOMException
+ * HIERARCHY_REQUEST_ERR: Raised if this node is of a type that does not
+ * allow children of the type of the <code>newChild</code> node, or if
+ * the node to append is one of this node's ancestors.
+ * <br>WRONG_DOCUMENT_ERR: Raised if <code>newChild</code> was created
+ * from a different document than the one that created this node.
+ * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
+ */
+ public Node appendChild(Node newChild)
+ throws DOMException;
+
+ /**
+ * Returns whether this node has any children.
+ * @return <code>true</code> if this node has any children,
+ * <code>false</code> otherwise.
+ */
+ public boolean hasChildNodes();
+
+ /**
+ * Returns a duplicate of this node, i.e., serves as a generic copy
+ * constructor for nodes. The duplicate node has no parent; (
+ * <code>parentNode</code> is <code>null</code>.).
+ * <br>Cloning an <code>Element</code> copies all attributes and their
+ * values, including those generated by the XML processor to represent
+ * defaulted attributes, but this method does not copy any text it
+ * contains unless it is a deep clone, since the text is contained in a
+ * child <code>Text</code> node. Cloning an <code>Attribute</code>
+ * directly, as opposed to be cloned as part of an <code>Element</code>
+ * cloning operation, returns a specified attribute (
+ * <code>specified</code> is <code>true</code>). Cloning any other type
+ * of node simply returns a copy of this node.
+ * <br>Note that cloning an immutable subtree results in a mutable copy,
+ * but the children of an <code>EntityReference</code> clone are readonly
+ * . In addition, clones of unspecified <code>Attr</code> nodes are
+ * specified. And, cloning <code>Document</code>,
+ * <code>DocumentType</code>, <code>Entity</code>, and
+ * <code>Notation</code> nodes is implementation dependent.
+ * @param deep If <code>true</code>, recursively clone the subtree under
+ * the specified node; if <code>false</code>, clone only the node
+ * itself (and its attributes, if it is an <code>Element</code>).
+ * @return The duplicate node.
+ */
+ public Node cloneNode(boolean deep);
+
+ /**
+ * Puts all <code>Text</code> nodes in the full depth of the sub-tree
+ * underneath this <code>Node</code>, including attribute nodes, into a
+ * "normal" form where only structure (e.g., elements, comments,
+ * processing instructions, CDATA sections, and entity references)
+ * separates <code>Text</code> nodes, i.e., there are neither adjacent
+ * <code>Text</code> nodes nor empty <code>Text</code> nodes. This can
+ * be used to ensure that the DOM view of a document is the same as if
+ * it were saved and re-loaded, and is useful when operations (such as
+ * XPointer lookups) that depend on a particular document tree
+ * structure are to be used.In cases where the document contains
+ * <code>CDATASections</code>, the normalize operation alone may not be
+ * sufficient, since XPointers do not differentiate between
+ * <code>Text</code> nodes and <code>CDATASection</code> nodes.
+ * @version DOM Level 2
+ */
+ public void normalize();
+
+ /**
+ * Tests whether the DOM implementation implements a specific feature and
+ * that feature is supported by this node.
+ * @param feature The name of the feature to test. This is the same name
+ * which can be passed to the method <code>hasFeature</code> on
+ * <code>DOMImplementation</code>.
+ * @param version This is the version number of the feature to test. In
+ * Level 2, version 1, this is the string "2.0". If the version is not
+ * specified, supporting any version of the feature will cause the
+ * method to return <code>true</code>.
+ * @return Returns <code>true</code> if the specified feature is
+ * supported on this node, <code>false</code> otherwise.
+ * @since DOM Level 2
+ */
+ public boolean isSupported(String feature,
+ String version);
+
+ /**
+ * The namespace URI of this node, or <code>null</code> if it is
+ * unspecified.
+ * <br>This is not a computed value that is the result of a namespace
+ * lookup based on an examination of the namespace declarations in
+ * scope. It is merely the namespace URI given at creation time.
+ * <br>For nodes of any type other than <code>ELEMENT_NODE</code> and
+ * <code>ATTRIBUTE_NODE</code> and nodes created with a DOM Level 1
+ * method, such as <code>createElement</code> from the
+ * <code>Document</code> interface, this is always <code>null</code>.Per
+ * the Namespaces in XML Specification an attribute does not inherit
+ * its namespace from the element it is attached to. If an attribute is
+ * not explicitly given a namespace, it simply has no namespace.
+ *
+ * @return the namespace URI, if any.
+ *
+ * @since DOM Level 2
+ */
+ public String getNamespaceURI();
+
+ /**
+ * Returns the namespace prefix of this node, or <code>null</code> if it is
+ * unspecified.
+ * <br>For nodes of any type other than <code>ELEMENT_NODE</code> and
+ * <code>ATTRIBUTE_NODE</code> and nodes created with a DOM Level 1
+ * method, such as <code>createElement</code> from the
+ * <code>Document</code> interface, this is always <code>null</code>.
+ *
+ * @return the namespace prefix, if any.
+ *
+ * @exception DOMException
+ * @since DOM Level 2
+ */
+ public String getPrefix();
+
+ /**
+ * Sets the namespace prefix of this node.
+ * <br>Note that setting this attribute, when permitted, changes the
+ * <code>nodeName</code> attribute, which holds the qualified name, as
+ * well as the <code>tagName</code> and <code>name</code> attributes of
+ * the <code>Element</code> and <code>Attr</code> interfaces, when
+ * applicable.
+ * <br>Note also that changing the prefix of an attribute that is known to
+ * have a default value, does not make a new attribute with the default
+ * value and the original prefix appear, since the
+ * <code>namespaceURI</code> and <code>localName</code> do not change.
+ * <br>For nodes of any type other than <code>ELEMENT_NODE</code> and
+ * <code>ATTRIBUTE_NODE</code> and nodes created with a DOM Level 1
+ * method, such as <code>createElement</code> from the
+ * <code>Document</code> interface, this is always <code>null</code>.
+ * @exception DOMException
+ * INVALID_CHARACTER_ERR: Raised if the specified prefix contains an
+ * illegal character.
+ * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
+ * <br>NAMESPACE_ERR: Raised if the specified <code>prefix</code> is
+ * malformed, if the <code>namespaceURI</code> of this node is
+ * <code>null</code>, if the specified prefix is "xml" and the
+ * <code>namespaceURI</code> of this node is different from "
+ * http://www.w3.org/XML/1998/namespace", if this node is an attribute
+ * and the specified prefix is "xmlns" and the
+ * <code>namespaceURI</code> of this node is different from "
+ * http://www.w3.org/2000/xmlns/", or if this node is an attribute and
+ * the <code>qualifiedName</code> of this node is "xmlns" .
+ *
+ * @param prefix the new namespace prefix.
+ *
+ * @since DOM Level 2
+ */
+ public void setPrefix(String prefix)
+ throws DOMException;
+
+ /**
+ * Returns the local part of the qualified name of this node.
+ * <br>For nodes of any type other than <code>ELEMENT_NODE</code> and
+ * <code>ATTRIBUTE_NODE</code> and nodes created with a DOM Level 1
+ * method, such as <code>createElement</code> from the
+ * <code>Document</code> interface, this is always <code>null</code>.
+ *
+ * @return the local name, if any.
+ *
+ * @since DOM Level 2
+ */
+ public String getLocalName();
+
+ /**
+ * Returns whether this node (if it is an element) has any attributes.
+ * @return <code>true</code> if this node has any attributes,
+ * <code>false</code> otherwise.
+ * @since DOM Level 2
+ */
+ public boolean hasAttributes();
+
+}
diff --git a/xml/src/main/java/org/w3c/dom/NodeList.java b/xml/src/main/java/org/w3c/dom/NodeList.java
new file mode 100644
index 0000000..0dbadda
--- /dev/null
+++ b/xml/src/main/java/org/w3c/dom/NodeList.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2000 World Wide Web Consortium,
+ * (Massachusetts Institute of Technology, Institut National de
+ * Recherche en Informatique et en Automatique, Keio University). All
+ * Rights Reserved. This program is distributed under the W3C's Software
+ * Intellectual Property License. This program is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.
+ * See W3C License http://www.w3.org/Consortium/Legal/ for more details.
+ */
+
+package org.w3c.dom;
+
+// BEGIN android-note
+// Cleaned up @param tags that seemed to be missing spaces between
+// the parameter name and the start of the description.
+// END android-note
+
+//BEGIN android-note
+//Filled some gaps in the documentation and refactored parts of the existing
+//documentation to make the Doclet happy.
+//END android-note
+
+/**
+ * The <code>NodeList</code> interface provides the abstraction of an ordered
+ * collection of nodes, without defining or constraining how this collection
+ * is implemented. <code>NodeList</code> objects in the DOM are live.
+ * <p>The items in the <code>NodeList</code> are accessible via an integral
+ * index, starting from 0.
+ * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113'>Document Object Model (DOM) Level 2 Core Specification</a>.
+ */
+public interface NodeList {
+ /**
+ * Returns the <code>index</code>th item in the collection. If
+ * <code>index</code> is greater than or equal to the number of nodes in
+ * the list, this returns <code>null</code>.
+ * @param index Index into the collection.
+ * @return The node at the <code>index</code>th position in the
+ * <code>NodeList</code>, or <code>null</code> if that is not a valid
+ * index.
+ */
+ public Node item(int index);
+
+ /**
+ * The number of nodes in the list. The range of valid child node indices
+ * is 0 to <code>length-1</code> inclusive.
+ *
+ * @return the length of the list.
+ */
+ public int getLength();
+
+}
diff --git a/xml/src/main/java/org/w3c/dom/Notation.java b/xml/src/main/java/org/w3c/dom/Notation.java
new file mode 100644
index 0000000..00c702f
--- /dev/null
+++ b/xml/src/main/java/org/w3c/dom/Notation.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2000 World Wide Web Consortium,
+ * (Massachusetts Institute of Technology, Institut National de
+ * Recherche en Informatique et en Automatique, Keio University). All
+ * Rights Reserved. This program is distributed under the W3C's Software
+ * Intellectual Property License. This program is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.
+ * See W3C License http://www.w3.org/Consortium/Legal/ for more details.
+ */
+
+package org.w3c.dom;
+
+//BEGIN android-note
+//Filled some gaps in the documentation and refactored parts of the existing
+//documentation to make the Doclet happy.
+//END android-note
+
+/**
+ * This interface represents a notation declared in the DTD. A notation either
+ * declares, by name, the format of an unparsed entity (see section 4.7 of
+ * the XML 1.0 specification ), or is used for formal declaration of
+ * processing instruction targets (see section 2.6 of the XML 1.0
+ * specification ). The <code>nodeName</code> attribute inherited from
+ * <code>Node</code> is set to the declared name of the notation.
+ * <p>The DOM Level 1 does not support editing <code>Notation</code> nodes;
+ * they are therefore readonly.
+ * <p>A <code>Notation</code> node does not have any parent.
+ * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113'>Document Object Model (DOM) Level 2 Core Specification</a>.
+ */
+public interface Notation extends Node {
+ /**
+ * The public identifier of this notation. If the public identifier was
+ * not specified, this is <code>null</code>.
+ *
+ * @return the public identifier of this notation, if any.
+ */
+ public String getPublicId();
+
+ /**
+ * The system identifier of this notation. If the system identifier was
+ * not specified, this is <code>null</code>.
+ *
+ * @return the system identifier of this notation, if any.
+ */
+ public String getSystemId();
+
+}
diff --git a/xml/src/main/java/org/w3c/dom/ProcessingInstruction.java b/xml/src/main/java/org/w3c/dom/ProcessingInstruction.java
new file mode 100644
index 0000000..a702aa6
--- /dev/null
+++ b/xml/src/main/java/org/w3c/dom/ProcessingInstruction.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2000 World Wide Web Consortium,
+ * (Massachusetts Institute of Technology, Institut National de
+ * Recherche en Informatique et en Automatique, Keio University). All
+ * Rights Reserved. This program is distributed under the W3C's Software
+ * Intellectual Property License. This program is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.
+ * See W3C License http://www.w3.org/Consortium/Legal/ for more details.
+ */
+
+package org.w3c.dom;
+
+//BEGIN android-note
+//Filled some gaps in the documentation and refactored parts of the existing
+//documentation to make the Doclet happy.
+//END android-note
+
+/**
+ * The <code>ProcessingInstruction</code> interface represents a "processing
+ * instruction", used in XML as a way to keep processor-specific information
+ * in the text of the document.
+ * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113'>Document Object Model (DOM) Level 2 Core Specification</a>.
+ */
+public interface ProcessingInstruction extends Node {
+ /**
+ * The target of this processing instruction. XML defines this as being
+ * the first token following the markup that begins the processing
+ * instruction.
+ *
+ * @return the target of this processing instruction.
+ */
+ public String getTarget();
+
+ /**
+ * Returns the content of this processing instruction. This is from the
+ * first non white space character after the target to the character
+ * immediately preceding the <code>?&gt;</code>.
+ *
+ * @return the data of this processing instruction.
+ */
+ public String getData();
+
+ /**
+ * Sets the content of this processing instruction. This is from the first
+ * non white space character after the target to the character immediately
+ * preceding the <code>?&gt;</code>.
+ *
+ * @param data the new data of the processing instruction.
+ *
+ * @exception DOMException
+ * NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly.
+ */
+ public void setData(String data)
+ throws DOMException;
+
+}
diff --git a/xml/src/main/java/org/w3c/dom/Text.java b/xml/src/main/java/org/w3c/dom/Text.java
new file mode 100644
index 0000000..4d1746b
--- /dev/null
+++ b/xml/src/main/java/org/w3c/dom/Text.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2000 World Wide Web Consortium,
+ * (Massachusetts Institute of Technology, Institut National de
+ * Recherche en Informatique et en Automatique, Keio University). All
+ * Rights Reserved. This program is distributed under the W3C's Software
+ * Intellectual Property License. This program is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.
+ * See W3C License http://www.w3.org/Consortium/Legal/ for more details.
+ */
+
+package org.w3c.dom;
+
+// BEGIN android-note
+// Cleaned up @param tags that seemed to be missing spaces between
+// the parameter name and the start of the description.
+// END android-note
+
+/**
+ * The <code>Text</code> interface inherits from <code>CharacterData</code>
+ * and represents the textual content (termed character data in XML) of an
+ * <code>Element</code> or <code>Attr</code>. If there is no markup inside
+ * an element's content, the text is contained in a single object
+ * implementing the <code>Text</code> interface that is the only child of
+ * the element. If there is markup, it is parsed into the information items
+ * (elements, comments, etc.) and <code>Text</code> nodes that form the list
+ * of children of the element.
+ * <p>When a document is first made available via the DOM, there is only one
+ * <code>Text</code> node for each block of text. Users may create adjacent
+ * <code>Text</code> nodes that represent the contents of a given element
+ * without any intervening markup, but should be aware that there is no way
+ * to represent the separations between these nodes in XML or HTML, so they
+ * will not (in general) persist between DOM editing sessions. The
+ * <code>normalize()</code> method on <code>Node</code> merges any such
+ * adjacent <code>Text</code> objects into a single node for each block of
+ * text.
+ * <p>See also the <a href='http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113'>Document Object Model (DOM) Level 2 Core Specification</a>.
+ */
+public interface Text extends CharacterData {
+ /**
+ * Breaks this node into two nodes at the specified <code>offset</code>,
+ * keeping both in the tree as siblings. After being split, this node
+ * will contain all the content up to the <code>offset</code> point. A
+ * new node of the same type, which contains all the content at and
+ * after the <code>offset</code> point, is returned. If the original
+ * node had a parent node, the new node is inserted as the next sibling
+ * of the original node. When the <code>offset</code> is equal to the
+ * length of this node, the new node has no data.
+ * @param offset The 16-bit unit offset at which to split, starting from
+ * <code>0</code>.
+ * @return The new node, of the same type as this node.
+ * @exception DOMException
+ * INDEX_SIZE_ERR: Raised if the specified offset is negative or greater
+ * than the number of 16-bit units in <code>data</code>.
+ * <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
+ */
+ public Text splitText(int offset)
+ throws DOMException;
+
+}
diff --git a/xml/src/main/java/org/w3c/dom/package.html b/xml/src/main/java/org/w3c/dom/package.html
new file mode 100644
index 0000000..8189944
--- /dev/null
+++ b/xml/src/main/java/org/w3c/dom/package.html
@@ -0,0 +1,12 @@
+<html>
+ <body>
+ <p>
+ Provides the official W3C Java bindings for the Document Object Model,
+ level 2 core. XML documents returned by
+ {@link javax.xml.parsers.DocumentBuilder} are accessed and manipulated
+ through these interfaces.
+ </p>
+
+ @since Android 1.0
+ </body>
+</html> \ No newline at end of file
diff --git a/xml/src/main/java/org/xml/sax/AttributeList.java b/xml/src/main/java/org/xml/sax/AttributeList.java
new file mode 100644
index 0000000..9285eac
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/AttributeList.java
@@ -0,0 +1,193 @@
+// SAX Attribute List Interface.
+// http://www.saxproject.org
+// No warranty; no copyright -- use this as you will.
+// $Id: AttributeList.java,v 1.7 2004/04/26 17:34:34 dmegginson Exp $
+
+package org.xml.sax;
+
+/**
+ * Interface for an element's attribute specifications.
+ *
+ * <blockquote>
+ * <em>This module, both source code and documentation, is in the
+ * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
+ * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
+ * for further information.
+ * </blockquote>
+ *
+ * <p>This is the original SAX1 interface for reporting an element's
+ * attributes. Unlike the new {@link org.xml.sax.Attributes Attributes}
+ * interface, it does not support Namespace-related information.</p>
+ *
+ * <p>When an attribute list is supplied as part of a
+ * {@link org.xml.sax.DocumentHandler#startElement startElement}
+ * event, the list will return valid results only during the
+ * scope of the event; once the event handler returns control
+ * to the parser, the attribute list is invalid. To save a
+ * persistent copy of the attribute list, use the SAX1
+ * {@link org.xml.sax.helpers.AttributeListImpl AttributeListImpl}
+ * helper class.</p>
+ *
+ * <p>An attribute list includes only attributes that have been
+ * specified or defaulted: #IMPLIED attributes will not be included.</p>
+ *
+ * <p>There are two ways for the SAX application to obtain information
+ * from the AttributeList. First, it can iterate through the entire
+ * list:</p>
+ *
+ * <pre>
+ * public void startElement (String name, AttributeList atts) {
+ * for (int i = 0; i < atts.getLength(); i++) {
+ * String name = atts.getName(i);
+ * String type = atts.getType(i);
+ * String value = atts.getValue(i);
+ * [...]
+ * }
+ * }
+ * </pre>
+ *
+ * <p>(Note that the result of getLength() will be zero if there
+ * are no attributes.)
+ *
+ * <p>As an alternative, the application can request the value or
+ * type of specific attributes:</p>
+ *
+ * <pre>
+ * public void startElement (String name, AttributeList atts) {
+ * String identifier = atts.getValue("id");
+ * String label = atts.getValue("label");
+ * [...]
+ * }
+ * </pre>
+ *
+ * @deprecated This interface has been replaced by the SAX2
+ * {@link org.xml.sax.Attributes Attributes}
+ * interface, which includes Namespace support.
+ * @since SAX 1.0
+ * @author David Megginson
+ * @version 2.0.1 (sax2r2)
+ * @see org.xml.sax.DocumentHandler#startElement startElement
+ * @see org.xml.sax.helpers.AttributeListImpl AttributeListImpl
+ */
+public interface AttributeList {
+
+
+ ////////////////////////////////////////////////////////////////////
+ // Iteration methods.
+ ////////////////////////////////////////////////////////////////////
+
+
+ /**
+ * Return the number of attributes in this list.
+ *
+ * <p>The SAX parser may provide attributes in any
+ * arbitrary order, regardless of the order in which they were
+ * declared or specified. The number of attributes may be
+ * zero.</p>
+ *
+ * @return The number of attributes in the list.
+ */
+ public abstract int getLength ();
+
+
+ /**
+ * Return the name of an attribute in this list (by position).
+ *
+ * <p>The names must be unique: the SAX parser shall not include the
+ * same attribute twice. Attributes without values (those declared
+ * #IMPLIED without a value specified in the start tag) will be
+ * omitted from the list.</p>
+ *
+ * <p>If the attribute name has a namespace prefix, the prefix
+ * will still be attached.</p>
+ *
+ * @param i The index of the attribute in the list (starting at 0).
+ * @return The name of the indexed attribute, or null
+ * if the index is out of range.
+ * @see #getLength
+ */
+ public abstract String getName (int i);
+
+
+ /**
+ * Return the type of an attribute in the list (by position).
+ *
+ * <p>The attribute type is one of the strings "CDATA", "ID",
+ * "IDREF", "IDREFS", "NMTOKEN", "NMTOKENS", "ENTITY", "ENTITIES",
+ * or "NOTATION" (always in upper case).</p>
+ *
+ * <p>If the parser has not read a declaration for the attribute,
+ * or if the parser does not report attribute types, then it must
+ * return the value "CDATA" as stated in the XML 1.0 Recommentation
+ * (clause 3.3.3, "Attribute-Value Normalization").</p>
+ *
+ * <p>For an enumerated attribute that is not a notation, the
+ * parser will report the type as "NMTOKEN".</p>
+ *
+ * @param i The index of the attribute in the list (starting at 0).
+ * @return The attribute type as a string, or
+ * null if the index is out of range.
+ * @see #getLength
+ * @see #getType(java.lang.String)
+ */
+ public abstract String getType (int i);
+
+
+ /**
+ * Return the value of an attribute in the list (by position).
+ *
+ * <p>If the attribute value is a list of tokens (IDREFS,
+ * ENTITIES, or NMTOKENS), the tokens will be concatenated
+ * into a single string separated by whitespace.</p>
+ *
+ * @param i The index of the attribute in the list (starting at 0).
+ * @return The attribute value as a string, or
+ * null if the index is out of range.
+ * @see #getLength
+ * @see #getValue(java.lang.String)
+ */
+ public abstract String getValue (int i);
+
+
+
+ ////////////////////////////////////////////////////////////////////
+ // Lookup methods.
+ ////////////////////////////////////////////////////////////////////
+
+
+ /**
+ * Return the type of an attribute in the list (by name).
+ *
+ * <p>The return value is the same as the return value for
+ * getType(int).</p>
+ *
+ * <p>If the attribute name has a namespace prefix in the document,
+ * the application must include the prefix here.</p>
+ *
+ * @param name The name of the attribute.
+ * @return The attribute type as a string, or null if no
+ * such attribute exists.
+ * @see #getType(int)
+ */
+ public abstract String getType (String name);
+
+
+ /**
+ * Return the value of an attribute in the list (by name).
+ *
+ * <p>The return value is the same as the return value for
+ * getValue(int).</p>
+ *
+ * <p>If the attribute name has a namespace prefix in the document,
+ * the application must include the prefix here.</p>
+ *
+ * @param name the name of the attribute to return
+ * @return The attribute value as a string, or null if
+ * no such attribute exists.
+ * @see #getValue(int)
+ */
+ public abstract String getValue (String name);
+
+}
+
+// end of AttributeList.java
diff --git a/xml/src/main/java/org/xml/sax/Attributes.java b/xml/src/main/java/org/xml/sax/Attributes.java
new file mode 100644
index 0000000..b25432d
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/Attributes.java
@@ -0,0 +1,257 @@
+// Attributes.java - attribute list with Namespace support
+// http://www.saxproject.org
+// Written by David Megginson
+// NO WARRANTY! This class is in the public domain.
+// $Id: Attributes.java,v 1.13 2004/03/18 12:28:05 dmegginson Exp $
+
+package org.xml.sax;
+
+
+/**
+ * Interface for a list of XML attributes.
+ *
+ * <blockquote>
+ * <em>This module, both source code and documentation, is in the
+ * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
+ * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
+ * for further information.
+ * </blockquote>
+ *
+ * <p>This interface allows access to a list of attributes in
+ * three different ways:</p>
+ *
+ * <ol>
+ * <li>by attribute index;</li>
+ * <li>by Namespace-qualified name; or</li>
+ * <li>by qualified (prefixed) name.</li>
+ * </ol>
+ *
+ * <p>The list will not contain attributes that were declared
+ * #IMPLIED but not specified in the start tag. It will also not
+ * contain attributes used as Namespace declarations (xmlns*) unless
+ * the <code>http://xml.org/sax/features/namespace-prefixes</code>
+ * feature is set to <var>true</var> (it is <var>false</var> by
+ * default).
+ * Because SAX2 conforms to the original "Namespaces in XML"
+ * recommendation, it normally does not
+ * give namespace declaration attributes a namespace URI.
+ * </p>
+ *
+ * <p>Some SAX2 parsers may support using an optional feature flag
+ * (<code>http://xml.org/sax/features/xmlns-uris</code>) to request
+ * that those attributes be given URIs, conforming to a later
+ * backwards-incompatible revision of that recommendation. (The
+ * attribute's "local name" will be the prefix, or "xmlns" when
+ * defining a default element namespace.) For portability, handler
+ * code should always resolve that conflict, rather than requiring
+ * parsers that can change the setting of that feature flag. </p>
+ *
+ * <p>If the namespace-prefixes feature (see above) is
+ * <var>false</var>, access by qualified name may not be available; if
+ * the <code>http://xml.org/sax/features/namespaces</code> feature is
+ * <var>false</var>, access by Namespace-qualified names may not be
+ * available.</p>
+ *
+ * <p>This interface replaces the now-deprecated SAX1 {@link
+ * org.xml.sax.AttributeList AttributeList} interface, which does not
+ * contain Namespace support. In addition to Namespace support, it
+ * adds the <var>getIndex</var> methods (below).</p>
+ *
+ * <p>The order of attributes in the list is unspecified, and will
+ * vary from implementation to implementation.</p>
+ *
+ * @since SAX 2.0
+ * @author David Megginson
+ * @version 2.0.1 (sax2r2)
+ * @see org.xml.sax.helpers.AttributesImpl
+ * @see org.xml.sax.ext.DeclHandler#attributeDecl
+ */
+public interface Attributes
+{
+
+
+ ////////////////////////////////////////////////////////////////////
+ // Indexed access.
+ ////////////////////////////////////////////////////////////////////
+
+
+ /**
+ * Return the number of attributes in the list.
+ *
+ * <p>Once you know the number of attributes, you can iterate
+ * through the list.</p>
+ *
+ * @return The number of attributes in the list.
+ * @see #getURI(int)
+ * @see #getLocalName(int)
+ * @see #getQName(int)
+ * @see #getType(int)
+ * @see #getValue(int)
+ */
+ public abstract int getLength ();
+
+
+ /**
+ * Look up an attribute's Namespace URI by index.
+ *
+ * @param index The attribute index (zero-based).
+ * @return The Namespace URI, or the empty string if none
+ * is available, or null if the index is out of
+ * range.
+ * @see #getLength
+ */
+ public abstract String getURI (int index);
+
+
+ /**
+ * Look up an attribute's local name by index.
+ *
+ * @param index The attribute index (zero-based).
+ * @return The local name, or the empty string if Namespace
+ * processing is not being performed, or null
+ * if the index is out of range.
+ * @see #getLength
+ */
+ public abstract String getLocalName (int index);
+
+
+ /**
+ * Look up an attribute's XML qualified (prefixed) name by index.
+ *
+ * @param index The attribute index (zero-based).
+ * @return The XML qualified name, or the empty string
+ * if none is available, or null if the index
+ * is out of range.
+ * @see #getLength
+ */
+ public abstract String getQName (int index);
+
+
+ /**
+ * Look up an attribute's type by index.
+ *
+ * <p>The attribute type is one of the strings "CDATA", "ID",
+ * "IDREF", "IDREFS", "NMTOKEN", "NMTOKENS", "ENTITY", "ENTITIES",
+ * or "NOTATION" (always in upper case).</p>
+ *
+ * <p>If the parser has not read a declaration for the attribute,
+ * or if the parser does not report attribute types, then it must
+ * return the value "CDATA" as stated in the XML 1.0 Recommendation
+ * (clause 3.3.3, "Attribute-Value Normalization").</p>
+ *
+ * <p>For an enumerated attribute that is not a notation, the
+ * parser will report the type as "NMTOKEN".</p>
+ *
+ * @param index The attribute index (zero-based).
+ * @return The attribute's type as a string, or null if the
+ * index is out of range.
+ * @see #getLength
+ */
+ public abstract String getType (int index);
+
+
+ /**
+ * Look up an attribute's value by index.
+ *
+ * <p>If the attribute value is a list of tokens (IDREFS,
+ * ENTITIES, or NMTOKENS), the tokens will be concatenated
+ * into a single string with each token separated by a
+ * single space.</p>
+ *
+ * @param index The attribute index (zero-based).
+ * @return The attribute's value as a string, or null if the
+ * index is out of range.
+ * @see #getLength
+ */
+ public abstract String getValue (int index);
+
+
+
+ ////////////////////////////////////////////////////////////////////
+ // Name-based query.
+ ////////////////////////////////////////////////////////////////////
+
+
+ /**
+ * Look up the index of an attribute by Namespace name.
+ *
+ * @param uri The Namespace URI, or the empty string if
+ * the name has no Namespace URI.
+ * @param localName The attribute's local name.
+ * @return The index of the attribute, or -1 if it does not
+ * appear in the list.
+ */
+ public int getIndex (String uri, String localName);
+
+
+ /**
+ * Look up the index of an attribute by XML qualified (prefixed) name.
+ *
+ * @param qName The qualified (prefixed) name.
+ * @return The index of the attribute, or -1 if it does not
+ * appear in the list.
+ */
+ public int getIndex (String qName);
+
+
+ /**
+ * Look up an attribute's type by Namespace name.
+ *
+ * <p>See {@link #getType(int) getType(int)} for a description
+ * of the possible types.</p>
+ *
+ * @param uri The Namespace URI, or the empty String if the
+ * name has no Namespace URI.
+ * @param localName The local name of the attribute.
+ * @return The attribute type as a string, or null if the
+ * attribute is not in the list or if Namespace
+ * processing is not being performed.
+ */
+ public abstract String getType (String uri, String localName);
+
+
+ /**
+ * Look up an attribute's type by XML qualified (prefixed) name.
+ *
+ * <p>See {@link #getType(int) getType(int)} for a description
+ * of the possible types.</p>
+ *
+ * @param qName The XML qualified name.
+ * @return The attribute type as a string, or null if the
+ * attribute is not in the list or if qualified names
+ * are not available.
+ */
+ public abstract String getType (String qName);
+
+
+ /**
+ * Look up an attribute's value by Namespace name.
+ *
+ * <p>See {@link #getValue(int) getValue(int)} for a description
+ * of the possible values.</p>
+ *
+ * @param uri The Namespace URI, or the empty String if the
+ * name has no Namespace URI.
+ * @param localName The local name of the attribute.
+ * @return The attribute value as a string, or null if the
+ * attribute is not in the list.
+ */
+ public abstract String getValue (String uri, String localName);
+
+
+ /**
+ * Look up an attribute's value by XML qualified (prefixed) name.
+ *
+ * <p>See {@link #getValue(int) getValue(int)} for a description
+ * of the possible values.</p>
+ *
+ * @param qName The XML qualified name.
+ * @return The attribute value as a string, or null if the
+ * attribute is not in the list or if qualified names
+ * are not available.
+ */
+ public abstract String getValue (String qName);
+
+}
+
+// end of Attributes.java
diff --git a/xml/src/main/java/org/xml/sax/ContentHandler.java b/xml/src/main/java/org/xml/sax/ContentHandler.java
new file mode 100644
index 0000000..db66c0d
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/ContentHandler.java
@@ -0,0 +1,419 @@
+// ContentHandler.java - handle main document content.
+// http://www.saxproject.org
+// Written by David Megginson
+// NO WARRANTY! This class is in the public domain.
+// $Id: ContentHandler.java,v 1.13 2004/04/26 17:50:49 dmegginson Exp $
+
+package org.xml.sax;
+
+
+/**
+ * Receive notification of the logical content of a document.
+ *
+ * <blockquote>
+ * <em>This module, both source code and documentation, is in the
+ * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
+ * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
+ * for further information.
+ * </blockquote>
+ *
+ * <p>This is the main interface that most SAX applications
+ * implement: if the application needs to be informed of basic parsing
+ * events, it implements this interface and registers an instance with
+ * the SAX parser using the {@link org.xml.sax.XMLReader#setContentHandler
+ * setContentHandler} method. The parser uses the instance to report
+ * basic document-related events like the start and end of elements
+ * and character data.</p>
+ *
+ * <p>The order of events in this interface is very important, and
+ * mirrors the order of information in the document itself. For
+ * example, all of an element's content (character data, processing
+ * instructions, and/or subelements) will appear, in order, between
+ * the startElement event and the corresponding endElement event.</p>
+ *
+ * <p>This interface is similar to the now-deprecated SAX 1.0
+ * DocumentHandler interface, but it adds support for Namespaces
+ * and for reporting skipped entities (in non-validating XML
+ * processors).</p>
+ *
+ * <p>Implementors should note that there is also a
+ * <code>ContentHandler</code> class in the <code>java.net</code>
+ * package; that means that it's probably a bad idea to do</p>
+ *
+ * <pre>import java.net.*;
+ * import org.xml.sax.*;
+ * </pre>
+ *
+ * <p>In fact, "import ...*" is usually a sign of sloppy programming
+ * anyway, so the user should consider this a feature rather than a
+ * bug.</p>
+ *
+ * @since SAX 2.0
+ * @author David Megginson
+ * @version 2.0.1+ (sax2r3pre1)
+ * @see org.xml.sax.XMLReader
+ * @see org.xml.sax.DTDHandler
+ * @see org.xml.sax.ErrorHandler
+ */
+public interface ContentHandler
+{
+
+ /**
+ * Receive an object for locating the origin of SAX document events.
+ *
+ * <p>SAX parsers are strongly encouraged (though not absolutely
+ * required) to supply a locator: if it does so, it must supply
+ * the locator to the application by invoking this method before
+ * invoking any of the other methods in the ContentHandler
+ * interface.</p>
+ *
+ * <p>The locator allows the application to determine the end
+ * position of any document-related event, even if the parser is
+ * not reporting an error. Typically, the application will
+ * use this information for reporting its own errors (such as
+ * character content that does not match an application's
+ * business rules). The information returned by the locator
+ * is probably not sufficient for use with a search engine.</p>
+ *
+ * <p>Note that the locator will return correct information only
+ * during the invocation SAX event callbacks after
+ * {@link #startDocument startDocument} returns and before
+ * {@link #endDocument endDocument} is called. The
+ * application should not attempt to use it at any other time.</p>
+ *
+ * @param locator an object that can return the location of
+ * any SAX document event
+ * @see org.xml.sax.Locator
+ */
+ public void setDocumentLocator (Locator locator);
+
+
+ /**
+ * Receive notification of the beginning of a document.
+ *
+ * <p>The SAX parser will invoke this method only once, before any
+ * other event callbacks (except for {@link #setDocumentLocator
+ * setDocumentLocator}).</p>
+ *
+ * @throws org.xml.sax.SAXException any SAX exception, possibly
+ * wrapping another exception
+ * @see #endDocument
+ */
+ public void startDocument ()
+ throws SAXException;
+
+
+ /**
+ * Receive notification of the end of a document.
+ *
+ * <p><strong>There is an apparent contradiction between the
+ * documentation for this method and the documentation for {@link
+ * org.xml.sax.ErrorHandler#fatalError}. Until this ambiguity is
+ * resolved in a future major release, clients should make no
+ * assumptions about whether endDocument() will or will not be
+ * invoked when the parser has reported a fatalError() or thrown
+ * an exception.</strong></p>
+ *
+ * <p>The SAX parser will invoke this method only once, and it will
+ * be the last method invoked during the parse. The parser shall
+ * not invoke this method until it has either abandoned parsing
+ * (because of an unrecoverable error) or reached the end of
+ * input.</p>
+ *
+ * @throws org.xml.sax.SAXException any SAX exception, possibly
+ * wrapping another exception
+ * @see #startDocument
+ */
+ public void endDocument()
+ throws SAXException;
+
+
+ /**
+ * Begin the scope of a prefix-URI Namespace mapping.
+ *
+ * <p>The information from this event is not necessary for
+ * normal Namespace processing: the SAX XML reader will
+ * automatically replace prefixes for element and attribute
+ * names when the <code>http://xml.org/sax/features/namespaces</code>
+ * feature is <var>true</var> (the default).</p>
+ *
+ * <p>There are cases, however, when applications need to
+ * use prefixes in character data or in attribute values,
+ * where they cannot safely be expanded automatically; the
+ * start/endPrefixMapping event supplies the information
+ * to the application to expand prefixes in those contexts
+ * itself, if necessary.</p>
+ *
+ * <p>Note that start/endPrefixMapping events are not
+ * guaranteed to be properly nested relative to each other:
+ * all startPrefixMapping events will occur immediately before the
+ * corresponding {@link #startElement startElement} event,
+ * and all {@link #endPrefixMapping endPrefixMapping}
+ * events will occur immediately after the corresponding
+ * {@link #endElement endElement} event,
+ * but their order is not otherwise
+ * guaranteed.</p>
+ *
+ * <p>There should never be start/endPrefixMapping events for the
+ * "xml" prefix, since it is predeclared and immutable.</p>
+ *
+ * @param prefix the Namespace prefix being declared.
+ * An empty string is used for the default element namespace,
+ * which has no prefix.
+ * @param uri the Namespace URI the prefix is mapped to
+ * @throws org.xml.sax.SAXException the client may throw
+ * an exception during processing
+ * @see #endPrefixMapping
+ * @see #startElement
+ */
+ public void startPrefixMapping (String prefix, String uri)
+ throws SAXException;
+
+
+ /**
+ * End the scope of a prefix-URI mapping.
+ *
+ * <p>See {@link #startPrefixMapping startPrefixMapping} for
+ * details. These events will always occur immediately after the
+ * corresponding {@link #endElement endElement} event, but the order of
+ * {@link #endPrefixMapping endPrefixMapping} events is not otherwise
+ * guaranteed.</p>
+ *
+ * @param prefix the prefix that was being mapped.
+ * This is the empty string when a default mapping scope ends.
+ * @throws org.xml.sax.SAXException the client may throw
+ * an exception during processing
+ * @see #startPrefixMapping
+ * @see #endElement
+ */
+ public void endPrefixMapping (String prefix)
+ throws SAXException;
+
+
+ /**
+ * Receive notification of the beginning of an element.
+ *
+ * <p>The Parser will invoke this method at the beginning of every
+ * element in the XML document; there will be a corresponding
+ * {@link #endElement endElement} event for every startElement event
+ * (even when the element is empty). All of the element's content will be
+ * reported, in order, before the corresponding endElement
+ * event.</p>
+ *
+ * <p>This event allows up to three name components for each
+ * element:</p>
+ *
+ * <ol>
+ * <li>the Namespace URI;</li>
+ * <li>the local name; and</li>
+ * <li>the qualified (prefixed) name.</li>
+ * </ol>
+ *
+ * <p>Any or all of these may be provided, depending on the
+ * values of the <var>http://xml.org/sax/features/namespaces</var>
+ * and the <var>http://xml.org/sax/features/namespace-prefixes</var>
+ * properties:</p>
+ *
+ * <ul>
+ * <li>the Namespace URI and local name are required when
+ * the namespaces property is <var>true</var> (the default), and are
+ * optional when the namespaces property is <var>false</var> (if one is
+ * specified, both must be);</li>
+ * <li>the qualified name is required when the namespace-prefixes property
+ * is <var>true</var>, and is optional when the namespace-prefixes property
+ * is <var>false</var> (the default).</li>
+ * </ul>
+ *
+ * <p>Note that the attribute list provided will contain only
+ * attributes with explicit values (specified or defaulted):
+ * #IMPLIED attributes will be omitted. The attribute list
+ * will contain attributes used for Namespace declarations
+ * (xmlns* attributes) only if the
+ * <code>http://xml.org/sax/features/namespace-prefixes</code>
+ * property is true (it is false by default, and support for a
+ * true value is optional).</p>
+ *
+ * <p>Like {@link #characters characters()}, attribute values may have
+ * characters that need more than one <code>char</code> value. </p>
+ *
+ * @param uri the Namespace URI, or the empty string if the
+ * element has no Namespace URI or if Namespace
+ * processing is not being performed
+ * @param localName the local name (without prefix), or the
+ * empty string if Namespace processing is not being
+ * performed
+ * @param qName the qualified name (with prefix), or the
+ * empty string if qualified names are not available
+ * @param atts the attributes attached to the element. If
+ * there are no attributes, it shall be an empty
+ * Attributes object. The value of this object after
+ * startElement returns is undefined
+ * @throws org.xml.sax.SAXException any SAX exception, possibly
+ * wrapping another exception
+ * @see #endElement
+ * @see org.xml.sax.Attributes
+ * @see org.xml.sax.helpers.AttributesImpl
+ */
+ public void startElement (String uri, String localName,
+ String qName, Attributes atts)
+ throws SAXException;
+
+
+ /**
+ * Receive notification of the end of an element.
+ *
+ * <p>The SAX parser will invoke this method at the end of every
+ * element in the XML document; there will be a corresponding
+ * {@link #startElement startElement} event for every endElement
+ * event (even when the element is empty).</p>
+ *
+ * <p>For information on the names, see startElement.</p>
+ *
+ * @param uri the Namespace URI, or the empty string if the
+ * element has no Namespace URI or if Namespace
+ * processing is not being performed
+ * @param localName the local name (without prefix), or the
+ * empty string if Namespace processing is not being
+ * performed
+ * @param qName the qualified XML name (with prefix), or the
+ * empty string if qualified names are not available
+ * @throws org.xml.sax.SAXException any SAX exception, possibly
+ * wrapping another exception
+ */
+ public void endElement (String uri, String localName,
+ String qName)
+ throws SAXException;
+
+
+ /**
+ * Receive notification of character data.
+ *
+ * <p>The Parser will call this method to report each chunk of
+ * character data. SAX parsers may return all contiguous character
+ * data in a single chunk, or they may split it into several
+ * chunks; however, all of the characters in any single event
+ * must come from the same external entity so that the Locator
+ * provides useful information.</p>
+ *
+ * <p>The application must not attempt to read from the array
+ * outside of the specified range.</p>
+ *
+ * <p>Individual characters may consist of more than one Java
+ * <code>char</code> value. There are two important cases where this
+ * happens, because characters can't be represented in just sixteen bits.
+ * In one case, characters are represented in a <em>Surrogate Pair</em>,
+ * using two special Unicode values. Such characters are in the so-called
+ * "Astral Planes", with a code point above U+FFFF. A second case involves
+ * composite characters, such as a base character combining with one or
+ * more accent characters. </p>
+ *
+ * <p> Your code should not assume that algorithms using
+ * <code>char</code>-at-a-time idioms will be working in character
+ * units; in some cases they will split characters. This is relevant
+ * wherever XML permits arbitrary characters, such as attribute values,
+ * processing instruction data, and comments as well as in data reported
+ * from this method. It's also generally relevant whenever Java code
+ * manipulates internationalized text; the issue isn't unique to XML.</p>
+ *
+ * <p>Note that some parsers will report whitespace in element
+ * content using the {@link #ignorableWhitespace ignorableWhitespace}
+ * method rather than this one (validating parsers <em>must</em>
+ * do so).</p>
+ *
+ * @param ch the characters from the XML document
+ * @param start the start position in the array
+ * @param length the number of characters to read from the array
+ * @throws org.xml.sax.SAXException any SAX exception, possibly
+ * wrapping another exception
+ * @see #ignorableWhitespace
+ * @see org.xml.sax.Locator
+ */
+ public void characters (char ch[], int start, int length)
+ throws SAXException;
+
+
+ /**
+ * Receive notification of ignorable whitespace in element content.
+ *
+ * <p>Validating Parsers must use this method to report each chunk
+ * of whitespace in element content (see the W3C XML 1.0
+ * recommendation, section 2.10): non-validating parsers may also
+ * use this method if they are capable of parsing and using
+ * content models.</p>
+ *
+ * <p>SAX parsers may return all contiguous whitespace in a single
+ * chunk, or they may split it into several chunks; however, all of
+ * the characters in any single event must come from the same
+ * external entity, so that the Locator provides useful
+ * information.</p>
+ *
+ * <p>The application must not attempt to read from the array
+ * outside of the specified range.</p>
+ *
+ * @param ch the characters from the XML document
+ * @param start the start position in the array
+ * @param length the number of characters to read from the array
+ * @throws org.xml.sax.SAXException any SAX exception, possibly
+ * wrapping another exception
+ * @see #characters
+ */
+ public void ignorableWhitespace (char ch[], int start, int length)
+ throws SAXException;
+
+
+ /**
+ * Receive notification of a processing instruction.
+ *
+ * <p>The Parser will invoke this method once for each processing
+ * instruction found: note that processing instructions may occur
+ * before or after the main document element.</p>
+ *
+ * <p>A SAX parser must never report an XML declaration (XML 1.0,
+ * section 2.8) or a text declaration (XML 1.0, section 4.3.1)
+ * using this method.</p>
+ *
+ * <p>Like {@link #characters characters()}, processing instruction
+ * data may have characters that need more than one <code>char</code>
+ * value. </p>
+ *
+ * @param target the processing instruction target
+ * @param data the processing instruction data, or null if
+ * none was supplied. The data does not include any
+ * whitespace separating it from the target
+ * @throws org.xml.sax.SAXException any SAX exception, possibly
+ * wrapping another exception
+ */
+ public void processingInstruction (String target, String data)
+ throws SAXException;
+
+
+ /**
+ * Receive notification of a skipped entity.
+ * This is not called for entity references within markup constructs
+ * such as element start tags or markup declarations. (The XML
+ * recommendation requires reporting skipped external entities.
+ * SAX also reports internal entity expansion/non-expansion, except
+ * within markup constructs.)
+ *
+ * <p>The Parser will invoke this method each time the entity is
+ * skipped. Non-validating processors may skip entities if they
+ * have not seen the declarations (because, for example, the
+ * entity was declared in an external DTD subset). All processors
+ * may skip external entities, depending on the values of the
+ * <code>http://xml.org/sax/features/external-general-entities</code>
+ * and the
+ * <code>http://xml.org/sax/features/external-parameter-entities</code>
+ * properties.</p>
+ *
+ * @param name the name of the skipped entity. If it is a
+ * parameter entity, the name will begin with '%', and if
+ * it is the external DTD subset, it will be the string
+ * "[dtd]"
+ * @throws org.xml.sax.SAXException any SAX exception, possibly
+ * wrapping another exception
+ */
+ public void skippedEntity (String name)
+ throws SAXException;
+}
+
+// end of ContentHandler.java
diff --git a/xml/src/main/java/org/xml/sax/DTDHandler.java b/xml/src/main/java/org/xml/sax/DTDHandler.java
new file mode 100644
index 0000000..13d5eee
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/DTDHandler.java
@@ -0,0 +1,117 @@
+// SAX DTD handler.
+// http://www.saxproject.org
+// No warranty; no copyright -- use this as you will.
+// $Id: DTDHandler.java,v 1.8 2002/01/30 21:13:43 dbrownell Exp $
+
+package org.xml.sax;
+
+/**
+ * Receive notification of basic DTD-related events.
+ *
+ * <blockquote>
+ * <em>This module, both source code and documentation, is in the
+ * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
+ * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
+ * for further information.
+ * </blockquote>
+ *
+ * <p>If a SAX application needs information about notations and
+ * unparsed entities, then the application implements this
+ * interface and registers an instance with the SAX parser using
+ * the parser's setDTDHandler method. The parser uses the
+ * instance to report notation and unparsed entity declarations to
+ * the application.</p>
+ *
+ * <p>Note that this interface includes only those DTD events that
+ * the XML recommendation <em>requires</em> processors to report:
+ * notation and unparsed entity declarations.</p>
+ *
+ * <p>The SAX parser may report these events in any order, regardless
+ * of the order in which the notations and unparsed entities were
+ * declared; however, all DTD events must be reported after the
+ * document handler's startDocument event, and before the first
+ * startElement event.
+ * (If the {@link org.xml.sax.ext.LexicalHandler LexicalHandler} is
+ * used, these events must also be reported before the endDTD event.)
+ * </p>
+ *
+ * <p>It is up to the application to store the information for
+ * future use (perhaps in a hash table or object tree).
+ * If the application encounters attributes of type "NOTATION",
+ * "ENTITY", or "ENTITIES", it can use the information that it
+ * obtained through this interface to find the entity and/or
+ * notation corresponding with the attribute value.</p>
+ *
+ * @since SAX 1.0
+ * @author David Megginson
+ * @version 2.0.1 (sax2r2)
+ * @see org.xml.sax.XMLReader#setDTDHandler
+ */
+public interface DTDHandler {
+
+
+ /**
+ * Receive notification of a notation declaration event.
+ *
+ * <p>It is up to the application to record the notation for later
+ * reference, if necessary;
+ * notations may appear as attribute values and in unparsed entity
+ * declarations, and are sometime used with processing instruction
+ * target names.</p>
+ *
+ * <p>At least one of publicId and systemId must be non-null.
+ * If a system identifier is present, and it is a URL, the SAX
+ * parser must resolve it fully before passing it to the
+ * application through this event.</p>
+ *
+ * <p>There is no guarantee that the notation declaration will be
+ * reported before any unparsed entities that use it.</p>
+ *
+ * @param name The notation name.
+ * @param publicId The notation's public identifier, or null if
+ * none was given.
+ * @param systemId The notation's system identifier, or null if
+ * none was given.
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ * @see #unparsedEntityDecl
+ * @see org.xml.sax.Attributes
+ */
+ public abstract void notationDecl (String name,
+ String publicId,
+ String systemId)
+ throws SAXException;
+
+
+ /**
+ * Receive notification of an unparsed entity declaration event.
+ *
+ * <p>Note that the notation name corresponds to a notation
+ * reported by the {@link #notationDecl notationDecl} event.
+ * It is up to the application to record the entity for later
+ * reference, if necessary;
+ * unparsed entities may appear as attribute values.
+ * </p>
+ *
+ * <p>If the system identifier is a URL, the parser must resolve it
+ * fully before passing it to the application.</p>
+ *
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ * @param name The unparsed entity's name.
+ * @param publicId The entity's public identifier, or null if none
+ * was given.
+ * @param systemId The entity's system identifier.
+ * @param notationName The name of the associated notation.
+ * @see #notationDecl
+ * @see org.xml.sax.Attributes
+ */
+ public abstract void unparsedEntityDecl (String name,
+ String publicId,
+ String systemId,
+ String notationName)
+ throws SAXException;
+
+}
+
+// end of DTDHandler.java
diff --git a/xml/src/main/java/org/xml/sax/DocumentHandler.java b/xml/src/main/java/org/xml/sax/DocumentHandler.java
new file mode 100644
index 0000000..500fe4c
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/DocumentHandler.java
@@ -0,0 +1,232 @@
+// SAX document handler.
+// http://www.saxproject.org
+// No warranty; no copyright -- use this as you will.
+// $Id: DocumentHandler.java,v 1.6 2002/01/30 21:13:43 dbrownell Exp $
+
+package org.xml.sax;
+
+/**
+ * Receive notification of general document events.
+ *
+ * <blockquote>
+ * <em>This module, both source code and documentation, is in the
+ * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
+ * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
+ * for further information.
+ * </blockquote>
+ *
+ * <p>This was the main event-handling interface for SAX1; in
+ * SAX2, it has been replaced by {@link org.xml.sax.ContentHandler
+ * ContentHandler}, which provides Namespace support and reporting
+ * of skipped entities. This interface is included in SAX2 only
+ * to support legacy SAX1 applications.</p>
+ *
+ * <p>The order of events in this interface is very important, and
+ * mirrors the order of information in the document itself. For
+ * example, all of an element's content (character data, processing
+ * instructions, and/or subelements) will appear, in order, between
+ * the startElement event and the corresponding endElement event.</p>
+ *
+ * <p>Application writers who do not want to implement the entire
+ * interface can derive a class from HandlerBase, which implements
+ * the default functionality; parser writers can instantiate
+ * HandlerBase to obtain a default handler. The application can find
+ * the location of any document event using the Locator interface
+ * supplied by the Parser through the setDocumentLocator method.</p>
+ *
+ * @deprecated This interface has been replaced by the SAX2
+ * {@link org.xml.sax.ContentHandler ContentHandler}
+ * interface, which includes Namespace support.
+ * @since SAX 1.0
+ * @author David Megginson
+ * @version 2.0.1 (sax2r2)
+ * @see org.xml.sax.Parser#setDocumentHandler
+ * @see org.xml.sax.Locator
+ * @see org.xml.sax.HandlerBase
+ */
+public interface DocumentHandler {
+
+
+ /**
+ * Receive an object for locating the origin of SAX document events.
+ *
+ * <p>SAX parsers are strongly encouraged (though not absolutely
+ * required) to supply a locator: if it does so, it must supply
+ * the locator to the application by invoking this method before
+ * invoking any of the other methods in the DocumentHandler
+ * interface.</p>
+ *
+ * <p>The locator allows the application to determine the end
+ * position of any document-related event, even if the parser is
+ * not reporting an error. Typically, the application will
+ * use this information for reporting its own errors (such as
+ * character content that does not match an application's
+ * business rules). The information returned by the locator
+ * is probably not sufficient for use with a search engine.</p>
+ *
+ * <p>Note that the locator will return correct information only
+ * during the invocation of the events in this interface. The
+ * application should not attempt to use it at any other time.</p>
+ *
+ * @param locator An object that can return the location of
+ * any SAX document event.
+ * @see org.xml.sax.Locator
+ */
+ public abstract void setDocumentLocator (Locator locator);
+
+
+ /**
+ * Receive notification of the beginning of a document.
+ *
+ * <p>The SAX parser will invoke this method only once, before any
+ * other methods in this interface or in DTDHandler (except for
+ * setDocumentLocator).</p>
+ *
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ */
+ public abstract void startDocument ()
+ throws SAXException;
+
+
+ /**
+ * Receive notification of the end of a document.
+ *
+ * <p>The SAX parser will invoke this method only once, and it will
+ * be the last method invoked during the parse. The parser shall
+ * not invoke this method until it has either abandoned parsing
+ * (because of an unrecoverable error) or reached the end of
+ * input.</p>
+ *
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ */
+ public abstract void endDocument ()
+ throws SAXException;
+
+
+ /**
+ * Receive notification of the beginning of an element.
+ *
+ * <p>The Parser will invoke this method at the beginning of every
+ * element in the XML document; there will be a corresponding
+ * endElement() event for every startElement() event (even when the
+ * element is empty). All of the element's content will be
+ * reported, in order, before the corresponding endElement()
+ * event.</p>
+ *
+ * <p>If the element name has a namespace prefix, the prefix will
+ * still be attached. Note that the attribute list provided will
+ * contain only attributes with explicit values (specified or
+ * defaulted): #IMPLIED attributes will be omitted.</p>
+ *
+ * @param name The element type name.
+ * @param atts The attributes attached to the element, if any.
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ * @see #endElement
+ * @see org.xml.sax.AttributeList
+ */
+ public abstract void startElement (String name, AttributeList atts)
+ throws SAXException;
+
+
+ /**
+ * Receive notification of the end of an element.
+ *
+ * <p>The SAX parser will invoke this method at the end of every
+ * element in the XML document; there will be a corresponding
+ * startElement() event for every endElement() event (even when the
+ * element is empty).</p>
+ *
+ * <p>If the element name has a namespace prefix, the prefix will
+ * still be attached to the name.</p>
+ *
+ * @param name The element type name
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ */
+ public abstract void endElement (String name)
+ throws SAXException;
+
+
+ /**
+ * Receive notification of character data.
+ *
+ * <p>The Parser will call this method to report each chunk of
+ * character data. SAX parsers may return all contiguous character
+ * data in a single chunk, or they may split it into several
+ * chunks; however, all of the characters in any single event
+ * must come from the same external entity, so that the Locator
+ * provides useful information.</p>
+ *
+ * <p>The application must not attempt to read from the array
+ * outside of the specified range.</p>
+ *
+ * <p>Note that some parsers will report whitespace using the
+ * ignorableWhitespace() method rather than this one (validating
+ * parsers must do so).</p>
+ *
+ * @param ch The characters from the XML document.
+ * @param start The start position in the array.
+ * @param length The number of characters to read from the array.
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ * @see #ignorableWhitespace
+ * @see org.xml.sax.Locator
+ */
+ public abstract void characters (char ch[], int start, int length)
+ throws SAXException;
+
+
+ /**
+ * Receive notification of ignorable whitespace in element content.
+ *
+ * <p>Validating Parsers must use this method to report each chunk
+ * of ignorable whitespace (see the W3C XML 1.0 recommendation,
+ * section 2.10): non-validating parsers may also use this method
+ * if they are capable of parsing and using content models.</p>
+ *
+ * <p>SAX parsers may return all contiguous whitespace in a single
+ * chunk, or they may split it into several chunks; however, all of
+ * the characters in any single event must come from the same
+ * external entity, so that the Locator provides useful
+ * information.</p>
+ *
+ * <p>The application must not attempt to read from the array
+ * outside of the specified range.</p>
+ *
+ * @param ch The characters from the XML document.
+ * @param start The start position in the array.
+ * @param length The number of characters to read from the array.
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ * @see #characters
+ */
+ public abstract void ignorableWhitespace (char ch[], int start, int length)
+ throws SAXException;
+
+
+ /**
+ * Receive notification of a processing instruction.
+ *
+ * <p>The Parser will invoke this method once for each processing
+ * instruction found: note that processing instructions may occur
+ * before or after the main document element.</p>
+ *
+ * <p>A SAX parser should never report an XML declaration (XML 1.0,
+ * section 2.8) or a text declaration (XML 1.0, section 4.3.1)
+ * using this method.</p>
+ *
+ * @param target The processing instruction target.
+ * @param data The processing instruction data, or null if
+ * none was supplied.
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ */
+ public abstract void processingInstruction (String target, String data)
+ throws SAXException;
+
+}
+
+// end of DocumentHandler.java
diff --git a/xml/src/main/java/org/xml/sax/EntityResolver.java b/xml/src/main/java/org/xml/sax/EntityResolver.java
new file mode 100644
index 0000000..06ac725
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/EntityResolver.java
@@ -0,0 +1,119 @@
+// SAX entity resolver.
+// http://www.saxproject.org
+// No warranty; no copyright -- use this as you will.
+// $Id: EntityResolver.java,v 1.10 2002/01/30 21:13:44 dbrownell Exp $
+
+package org.xml.sax;
+
+import java.io.IOException;
+
+
+/**
+ * Basic interface for resolving entities.
+ *
+ * <blockquote>
+ * <em>This module, both source code and documentation, is in the
+ * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
+ * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
+ * for further information.
+ * </blockquote>
+ *
+ * <p>If a SAX application needs to implement customized handling
+ * for external entities, it must implement this interface and
+ * register an instance with the SAX driver using the
+ * {@link org.xml.sax.XMLReader#setEntityResolver setEntityResolver}
+ * method.</p>
+ *
+ * <p>The XML reader will then allow the application to intercept any
+ * external entities (including the external DTD subset and external
+ * parameter entities, if any) before including them.</p>
+ *
+ * <p>Many SAX applications will not need to implement this interface,
+ * but it will be especially useful for applications that build
+ * XML documents from databases or other specialised input sources,
+ * or for applications that use URI types other than URLs.</p>
+ *
+ * <p>The following resolver would provide the application
+ * with a special character stream for the entity with the system
+ * identifier "http://www.myhost.com/today":</p>
+ *
+ * <pre>
+ * import org.xml.sax.EntityResolver;
+ * import org.xml.sax.InputSource;
+ *
+ * public class MyResolver implements EntityResolver {
+ * public InputSource resolveEntity (String publicId, String systemId)
+ * {
+ * if (systemId.equals("http://www.myhost.com/today")) {
+ * // return a special input source
+ * MyReader reader = new MyReader();
+ * return new InputSource(reader);
+ * } else {
+ * // use the default behaviour
+ * return null;
+ * }
+ * }
+ * }
+ * </pre>
+ *
+ * <p>The application can also use this interface to redirect system
+ * identifiers to local URIs or to look up replacements in a catalog
+ * (possibly by using the public identifier).</p>
+ *
+ * @since SAX 1.0
+ * @author David Megginson
+ * @version 2.0.1 (sax2r2)
+ * @see org.xml.sax.XMLReader#setEntityResolver
+ * @see org.xml.sax.InputSource
+ */
+public interface EntityResolver {
+
+
+ /**
+ * Allow the application to resolve external entities.
+ *
+ * <p>The parser will call this method before opening any external
+ * entity except the top-level document entity. Such entities include
+ * the external DTD subset and external parameter entities referenced
+ * within the DTD (in either case, only if the parser reads external
+ * parameter entities), and external general entities referenced
+ * within the document element (if the parser reads external general
+ * entities). The application may request that the parser locate
+ * the entity itself, that it use an alternative URI, or that it
+ * use data provided by the application (as a character or byte
+ * input stream).</p>
+ *
+ * <p>Application writers can use this method to redirect external
+ * system identifiers to secure and/or local URIs, to look up
+ * public identifiers in a catalogue, or to read an entity from a
+ * database or other input source (including, for example, a dialog
+ * box). Neither XML nor SAX specifies a preferred policy for using
+ * public or system IDs to resolve resources. However, SAX specifies
+ * how to interpret any InputSource returned by this method, and that
+ * if none is returned, then the system ID will be dereferenced as
+ * a URL. </p>
+ *
+ * <p>If the system identifier is a URL, the SAX parser must
+ * resolve it fully before reporting it to the application.</p>
+ *
+ * @param publicId The public identifier of the external entity
+ * being referenced, or null if none was supplied.
+ * @param systemId The system identifier of the external entity
+ * being referenced.
+ * @return An InputSource object describing the new input source,
+ * or null to request that the parser open a regular
+ * URI connection to the system identifier.
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ * @exception java.io.IOException A Java-specific IO exception,
+ * possibly the result of creating a new InputStream
+ * or Reader for the InputSource.
+ * @see org.xml.sax.InputSource
+ */
+ public abstract InputSource resolveEntity (String publicId,
+ String systemId)
+ throws SAXException, IOException;
+
+}
+
+// end of EntityResolver.java
diff --git a/xml/src/main/java/org/xml/sax/ErrorHandler.java b/xml/src/main/java/org/xml/sax/ErrorHandler.java
new file mode 100644
index 0000000..e4e4206
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/ErrorHandler.java
@@ -0,0 +1,139 @@
+// SAX error handler.
+// http://www.saxproject.org
+// No warranty; no copyright -- use this as you will.
+// $Id: ErrorHandler.java,v 1.10 2004/03/08 13:01:00 dmegginson Exp $
+
+package org.xml.sax;
+
+
+/**
+ * Basic interface for SAX error handlers.
+ *
+ * <blockquote>
+ * <em>This module, both source code and documentation, is in the
+ * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
+ * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
+ * for further information.
+ * </blockquote>
+ *
+ * <p>If a SAX application needs to implement customized error
+ * handling, it must implement this interface and then register an
+ * instance with the XML reader using the
+ * {@link org.xml.sax.XMLReader#setErrorHandler setErrorHandler}
+ * method. The parser will then report all errors and warnings
+ * through this interface.</p>
+ *
+ * <p><strong>WARNING:</strong> If an application does <em>not</em>
+ * register an ErrorHandler, XML parsing errors will go unreported,
+ * except that <em>SAXParseException</em>s will be thrown for fatal errors.
+ * In order to detect validity errors, an ErrorHandler that does something
+ * with {@link #error error()} calls must be registered.</p>
+ *
+ * <p>For XML processing errors, a SAX driver must use this interface
+ * in preference to throwing an exception: it is up to the application
+ * to decide whether to throw an exception for different types of
+ * errors and warnings. Note, however, that there is no requirement that
+ * the parser continue to report additional errors after a call to
+ * {@link #fatalError fatalError}. In other words, a SAX driver class
+ * may throw an exception after reporting any fatalError.
+ * Also parsers may throw appropriate exceptions for non-XML errors.
+ * For example, {@link XMLReader#parse XMLReader.parse()} would throw
+ * an IOException for errors accessing entities or the document.</p>
+ *
+ * @since SAX 1.0
+ * @author David Megginson
+ * @version 2.0.1+ (sax2r3pre1)
+ * @see org.xml.sax.XMLReader#setErrorHandler
+ * @see org.xml.sax.SAXParseException
+ */
+public interface ErrorHandler {
+
+
+ /**
+ * Receive notification of a warning.
+ *
+ * <p>SAX parsers will use this method to report conditions that
+ * are not errors or fatal errors as defined by the XML
+ * recommendation. The default behaviour is to take no
+ * action.</p>
+ *
+ * <p>The SAX parser must continue to provide normal parsing events
+ * after invoking this method: it should still be possible for the
+ * application to process the document through to the end.</p>
+ *
+ * <p>Filters may use this method to report other, non-XML warnings
+ * as well.</p>
+ *
+ * @param exception The warning information encapsulated in a
+ * SAX parse exception.
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ * @see org.xml.sax.SAXParseException
+ */
+ public abstract void warning (SAXParseException exception)
+ throws SAXException;
+
+
+ /**
+ * Receive notification of a recoverable error.
+ *
+ * <p>This corresponds to the definition of "error" in section 1.2
+ * of the W3C XML 1.0 Recommendation. For example, a validating
+ * parser would use this callback to report the violation of a
+ * validity constraint. The default behaviour is to take no
+ * action.</p>
+ *
+ * <p>The SAX parser must continue to provide normal parsing
+ * events after invoking this method: it should still be possible
+ * for the application to process the document through to the end.
+ * If the application cannot do so, then the parser should report
+ * a fatal error even if the XML recommendation does not require
+ * it to do so.</p>
+ *
+ * <p>Filters may use this method to report other, non-XML errors
+ * as well.</p>
+ *
+ * @param exception The error information encapsulated in a
+ * SAX parse exception.
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ * @see org.xml.sax.SAXParseException
+ */
+ public abstract void error (SAXParseException exception)
+ throws SAXException;
+
+
+ /**
+ * Receive notification of a non-recoverable error.
+ *
+ * <p><strong>There is an apparent contradiction between the
+ * documentation for this method and the documentation for {@link
+ * org.xml.sax.ContentHandler#endDocument}. Until this ambiguity
+ * is resolved in a future major release, clients should make no
+ * assumptions about whether endDocument() will or will not be
+ * invoked when the parser has reported a fatalError() or thrown
+ * an exception.</strong></p>
+ *
+ * <p>This corresponds to the definition of "fatal error" in
+ * section 1.2 of the W3C XML 1.0 Recommendation. For example, a
+ * parser would use this callback to report the violation of a
+ * well-formedness constraint.</p>
+ *
+ * <p>The application must assume that the document is unusable
+ * after the parser has invoked this method, and should continue
+ * (if at all) only for the sake of collecting additional error
+ * messages: in fact, SAX parsers are free to stop reporting any
+ * other events once this method has been invoked.</p>
+ *
+ * @param exception The error information encapsulated in a
+ * SAX parse exception.
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ * @see org.xml.sax.SAXParseException
+ */
+ public abstract void fatalError (SAXParseException exception)
+ throws SAXException;
+
+}
+
+// end of ErrorHandler.java
diff --git a/xml/src/main/java/org/xml/sax/HandlerBase.java b/xml/src/main/java/org/xml/sax/HandlerBase.java
new file mode 100644
index 0000000..15ea2d4
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/HandlerBase.java
@@ -0,0 +1,369 @@
+// SAX default handler base class.
+// http://www.saxproject.org
+// No warranty; no copyright -- use this as you will.
+// $Id: HandlerBase.java,v 1.7 2004/04/26 17:34:34 dmegginson Exp $
+
+package org.xml.sax;
+
+/**
+ * Default base class for handlers.
+ *
+ * <blockquote>
+ * <em>This module, both source code and documentation, is in the
+ * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
+ * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
+ * for further information.
+ * </blockquote>
+ *
+ * <p>This class implements the default behaviour for four SAX1
+ * interfaces: EntityResolver, DTDHandler, DocumentHandler,
+ * and ErrorHandler. It is now obsolete, but is included in SAX2 to
+ * support legacy SAX1 applications. SAX2 applications should use
+ * the {@link org.xml.sax.helpers.DefaultHandler DefaultHandler}
+ * class instead.</p>
+ *
+ * <p>Application writers can extend this class when they need to
+ * implement only part of an interface; parser writers can
+ * instantiate this class to provide default handlers when the
+ * application has not supplied its own.</p>
+ *
+ * <p>Note that the use of this class is optional.</p>
+ *
+ * @deprecated This class works with the deprecated
+ * {@link org.xml.sax.DocumentHandler DocumentHandler}
+ * interface. It has been replaced by the SAX2
+ * {@link org.xml.sax.helpers.DefaultHandler DefaultHandler}
+ * class.
+ * @since SAX 1.0
+ * @author David Megginson
+ * @version 2.0.1 (sax2r2)
+ * @see org.xml.sax.EntityResolver
+ * @see org.xml.sax.DTDHandler
+ * @see org.xml.sax.DocumentHandler
+ * @see org.xml.sax.ErrorHandler
+ */
+public class HandlerBase
+ implements EntityResolver, DTDHandler, DocumentHandler, ErrorHandler
+{
+
+
+ ////////////////////////////////////////////////////////////////////
+ // Default implementation of the EntityResolver interface.
+ ////////////////////////////////////////////////////////////////////
+
+ /**
+ * Resolve an external entity.
+ *
+ * <p>Always return null, so that the parser will use the system
+ * identifier provided in the XML document. This method implements
+ * the SAX default behaviour: application writers can override it
+ * in a subclass to do special translations such as catalog lookups
+ * or URI redirection.</p>
+ *
+ * @param publicId The public identifer, or null if none is
+ * available.
+ * @param systemId The system identifier provided in the XML
+ * document.
+ * @return The new input source, or null to require the
+ * default behaviour.
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ * @see org.xml.sax.EntityResolver#resolveEntity
+ */
+ public InputSource resolveEntity (String publicId, String systemId)
+ throws SAXException
+ {
+ return null;
+ }
+
+
+
+ ////////////////////////////////////////////////////////////////////
+ // Default implementation of DTDHandler interface.
+ ////////////////////////////////////////////////////////////////////
+
+
+ /**
+ * Receive notification of a notation declaration.
+ *
+ * <p>By default, do nothing. Application writers may override this
+ * method in a subclass if they wish to keep track of the notations
+ * declared in a document.</p>
+ *
+ * @param name The notation name.
+ * @param publicId The notation public identifier, or null if not
+ * available.
+ * @param systemId The notation system identifier.
+ * @see org.xml.sax.DTDHandler#notationDecl
+ */
+ public void notationDecl (String name, String publicId, String systemId)
+ {
+ // no op
+ }
+
+
+ /**
+ * Receive notification of an unparsed entity declaration.
+ *
+ * <p>By default, do nothing. Application writers may override this
+ * method in a subclass to keep track of the unparsed entities
+ * declared in a document.</p>
+ *
+ * @param name The entity name.
+ * @param publicId The entity public identifier, or null if not
+ * available.
+ * @param systemId The entity system identifier.
+ * @param notationName The name of the associated notation.
+ * @see org.xml.sax.DTDHandler#unparsedEntityDecl
+ */
+ public void unparsedEntityDecl (String name, String publicId,
+ String systemId, String notationName)
+ {
+ // no op
+ }
+
+
+
+ ////////////////////////////////////////////////////////////////////
+ // Default implementation of DocumentHandler interface.
+ ////////////////////////////////////////////////////////////////////
+
+
+ /**
+ * Receive a Locator object for document events.
+ *
+ * <p>By default, do nothing. Application writers may override this
+ * method in a subclass if they wish to store the locator for use
+ * with other document events.</p>
+ *
+ * @param locator A locator for all SAX document events.
+ * @see org.xml.sax.DocumentHandler#setDocumentLocator
+ * @see org.xml.sax.Locator
+ */
+ public void setDocumentLocator (Locator locator)
+ {
+ // no op
+ }
+
+
+ /**
+ * Receive notification of the beginning of the document.
+ *
+ * <p>By default, do nothing. Application writers may override this
+ * method in a subclass to take specific actions at the beginning
+ * of a document (such as allocating the root node of a tree or
+ * creating an output file).</p>
+ *
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ * @see org.xml.sax.DocumentHandler#startDocument
+ */
+ public void startDocument ()
+ throws SAXException
+ {
+ // no op
+ }
+
+
+ /**
+ * Receive notification of the end of the document.
+ *
+ * <p>By default, do nothing. Application writers may override this
+ * method in a subclass to take specific actions at the beginning
+ * of a document (such as finalising a tree or closing an output
+ * file).</p>
+ *
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ * @see org.xml.sax.DocumentHandler#endDocument
+ */
+ public void endDocument ()
+ throws SAXException
+ {
+ // no op
+ }
+
+
+ /**
+ * Receive notification of the start of an element.
+ *
+ * <p>By default, do nothing. Application writers may override this
+ * method in a subclass to take specific actions at the start of
+ * each element (such as allocating a new tree node or writing
+ * output to a file).</p>
+ *
+ * @param name The element type name.
+ * @param attributes The specified or defaulted attributes.
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ * @see org.xml.sax.DocumentHandler#startElement
+ */
+ public void startElement (String name, AttributeList attributes)
+ throws SAXException
+ {
+ // no op
+ }
+
+
+ /**
+ * Receive notification of the end of an element.
+ *
+ * <p>By default, do nothing. Application writers may override this
+ * method in a subclass to take specific actions at the end of
+ * each element (such as finalising a tree node or writing
+ * output to a file).</p>
+ *
+ * @param name the element name
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ * @see org.xml.sax.DocumentHandler#endElement
+ */
+ public void endElement (String name)
+ throws SAXException
+ {
+ // no op
+ }
+
+
+ /**
+ * Receive notification of character data inside an element.
+ *
+ * <p>By default, do nothing. Application writers may override this
+ * method to take specific actions for each chunk of character data
+ * (such as adding the data to a node or buffer, or printing it to
+ * a file).</p>
+ *
+ * @param ch The characters.
+ * @param start The start position in the character array.
+ * @param length The number of characters to use from the
+ * character array.
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ * @see org.xml.sax.DocumentHandler#characters
+ */
+ public void characters (char ch[], int start, int length)
+ throws SAXException
+ {
+ // no op
+ }
+
+
+ /**
+ * Receive notification of ignorable whitespace in element content.
+ *
+ * <p>By default, do nothing. Application writers may override this
+ * method to take specific actions for each chunk of ignorable
+ * whitespace (such as adding data to a node or buffer, or printing
+ * it to a file).</p>
+ *
+ * @param ch The whitespace characters.
+ * @param start The start position in the character array.
+ * @param length The number of characters to use from the
+ * character array.
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ * @see org.xml.sax.DocumentHandler#ignorableWhitespace
+ */
+ public void ignorableWhitespace (char ch[], int start, int length)
+ throws SAXException
+ {
+ // no op
+ }
+
+
+ /**
+ * Receive notification of a processing instruction.
+ *
+ * <p>By default, do nothing. Application writers may override this
+ * method in a subclass to take specific actions for each
+ * processing instruction, such as setting status variables or
+ * invoking other methods.</p>
+ *
+ * @param target The processing instruction target.
+ * @param data The processing instruction data, or null if
+ * none is supplied.
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ * @see org.xml.sax.DocumentHandler#processingInstruction
+ */
+ public void processingInstruction (String target, String data)
+ throws SAXException
+ {
+ // no op
+ }
+
+
+
+ ////////////////////////////////////////////////////////////////////
+ // Default implementation of the ErrorHandler interface.
+ ////////////////////////////////////////////////////////////////////
+
+
+ /**
+ * Receive notification of a parser warning.
+ *
+ * <p>The default implementation does nothing. Application writers
+ * may override this method in a subclass to take specific actions
+ * for each warning, such as inserting the message in a log file or
+ * printing it to the console.</p>
+ *
+ * @param e The warning information encoded as an exception.
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ * @see org.xml.sax.ErrorHandler#warning
+ * @see org.xml.sax.SAXParseException
+ */
+ public void warning (SAXParseException e)
+ throws SAXException
+ {
+ // no op
+ }
+
+
+ /**
+ * Receive notification of a recoverable parser error.
+ *
+ * <p>The default implementation does nothing. Application writers
+ * may override this method in a subclass to take specific actions
+ * for each error, such as inserting the message in a log file or
+ * printing it to the console.</p>
+ *
+ * @param e The warning information encoded as an exception.
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ * @see org.xml.sax.ErrorHandler#warning
+ * @see org.xml.sax.SAXParseException
+ */
+ public void error (SAXParseException e)
+ throws SAXException
+ {
+ // no op
+ }
+
+
+ /**
+ * Report a fatal XML parsing error.
+ *
+ * <p>The default implementation throws a SAXParseException.
+ * Application writers may override this method in a subclass if
+ * they need to take specific actions for each fatal error (such as
+ * collecting all of the errors into a single report): in any case,
+ * the application must stop all regular processing when this
+ * method is invoked, since the document is no longer reliable, and
+ * the parser may no longer report parsing events.</p>
+ *
+ * @param e The error information encoded as an exception.
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ * @see org.xml.sax.ErrorHandler#fatalError
+ * @see org.xml.sax.SAXParseException
+ */
+ public void fatalError (SAXParseException e)
+ throws SAXException
+ {
+ throw e;
+ }
+
+}
+
+// end of HandlerBase.java
diff --git a/xml/src/main/java/org/xml/sax/InputSource.java b/xml/src/main/java/org/xml/sax/InputSource.java
new file mode 100644
index 0000000..b1342ee
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/InputSource.java
@@ -0,0 +1,337 @@
+// SAX input source.
+// http://www.saxproject.org
+// No warranty; no copyright -- use this as you will.
+// $Id: InputSource.java,v 1.9 2002/01/30 21:13:45 dbrownell Exp $
+
+package org.xml.sax;
+
+import java.io.Reader;
+import java.io.InputStream;
+
+/**
+ * A single input source for an XML entity.
+ *
+ * <blockquote>
+ * <em>This module, both source code and documentation, is in the
+ * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
+ * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
+ * for further information.
+ * </blockquote>
+ *
+ * <p>This class allows a SAX application to encapsulate information
+ * about an input source in a single object, which may include
+ * a public identifier, a system identifier, a byte stream (possibly
+ * with a specified encoding), and/or a character stream.</p>
+ *
+ * <p>There are two places that the application can deliver an
+ * input source to the parser: as the argument to the Parser.parse
+ * method, or as the return value of the EntityResolver.resolveEntity
+ * method.</p>
+ *
+ * <p>The SAX parser will use the InputSource object to determine how
+ * to read XML input. If there is a character stream available, the
+ * parser will read that stream directly, disregarding any text
+ * encoding declaration found in that stream.
+ * If there is no character stream, but there is
+ * a byte stream, the parser will use that byte stream, using the
+ * encoding specified in the InputSource or else (if no encoding is
+ * specified) autodetecting the character encoding using an algorithm
+ * such as the one in the XML specification. If neither a character
+ * stream nor a
+ * byte stream is available, the parser will attempt to open a URI
+ * connection to the resource identified by the system
+ * identifier.</p>
+ *
+ * <p>An InputSource object belongs to the application: the SAX parser
+ * shall never modify it in any way (it may modify a copy if
+ * necessary). However, standard processing of both byte and
+ * character streams is to close them on as part of end-of-parse cleanup,
+ * so applications should not attempt to re-use such streams after they
+ * have been handed to a parser. </p>
+ *
+ * @since SAX 1.0
+ * @author David Megginson
+ * @version 2.0.1 (sax2r2)
+ * @see org.xml.sax.XMLReader#parse(org.xml.sax.InputSource)
+ * @see org.xml.sax.EntityResolver#resolveEntity
+ * @see java.io.InputStream
+ * @see java.io.Reader
+ */
+public class InputSource {
+
+ /**
+ * Zero-argument default constructor.
+ *
+ * @see #setPublicId
+ * @see #setSystemId
+ * @see #setByteStream
+ * @see #setCharacterStream
+ * @see #setEncoding
+ */
+ public InputSource ()
+ {
+ }
+
+
+ /**
+ * Create a new input source with a system identifier.
+ *
+ * <p>Applications may use setPublicId to include a
+ * public identifier as well, or setEncoding to specify
+ * the character encoding, if known.</p>
+ *
+ * <p>If the system identifier is a URL, it must be fully
+ * resolved (it may not be a relative URL).</p>
+ *
+ * @param systemId The system identifier (URI).
+ * @see #setPublicId
+ * @see #setSystemId
+ * @see #setByteStream
+ * @see #setEncoding
+ * @see #setCharacterStream
+ */
+ public InputSource (String systemId)
+ {
+ setSystemId(systemId);
+ }
+
+
+ /**
+ * Create a new input source with a byte stream.
+ *
+ * <p>Application writers should use setSystemId() to provide a base
+ * for resolving relative URIs, may use setPublicId to include a
+ * public identifier, and may use setEncoding to specify the object's
+ * character encoding.</p>
+ *
+ * @param byteStream The raw byte stream containing the document.
+ * @see #setPublicId
+ * @see #setSystemId
+ * @see #setEncoding
+ * @see #setByteStream
+ * @see #setCharacterStream
+ */
+ public InputSource (InputStream byteStream)
+ {
+ setByteStream(byteStream);
+ }
+
+
+ /**
+ * Create a new input source with a character stream.
+ *
+ * <p>Application writers should use setSystemId() to provide a base
+ * for resolving relative URIs, and may use setPublicId to include a
+ * public identifier.</p>
+ *
+ * <p>The character stream shall not include a byte order mark.</p>
+ *
+ * @param characterStream The raw character stream containing the document.
+ * @see #setPublicId
+ * @see #setSystemId
+ * @see #setByteStream
+ * @see #setCharacterStream
+ */
+ public InputSource (Reader characterStream)
+ {
+ setCharacterStream(characterStream);
+ }
+
+
+ /**
+ * Set the public identifier for this input source.
+ *
+ * <p>The public identifier is always optional: if the application
+ * writer includes one, it will be provided as part of the
+ * location information.</p>
+ *
+ * @param publicId The public identifier as a string.
+ * @see #getPublicId
+ * @see org.xml.sax.Locator#getPublicId
+ * @see org.xml.sax.SAXParseException#getPublicId
+ */
+ public void setPublicId (String publicId)
+ {
+ this.publicId = publicId;
+ }
+
+
+ /**
+ * Get the public identifier for this input source.
+ *
+ * @return The public identifier, or null if none was supplied.
+ * @see #setPublicId
+ */
+ public String getPublicId ()
+ {
+ return publicId;
+ }
+
+
+ /**
+ * Set the system identifier for this input source.
+ *
+ * <p>The system identifier is optional if there is a byte stream
+ * or a character stream, but it is still useful to provide one,
+ * since the application can use it to resolve relative URIs
+ * and can include it in error messages and warnings (the parser
+ * will attempt to open a connection to the URI only if
+ * there is no byte stream or character stream specified).</p>
+ *
+ * <p>If the application knows the character encoding of the
+ * object pointed to by the system identifier, it can register
+ * the encoding using the setEncoding method.</p>
+ *
+ * <p>If the system identifier is a URL, it must be fully
+ * resolved (it may not be a relative URL).</p>
+ *
+ * @param systemId The system identifier as a string.
+ * @see #setEncoding
+ * @see #getSystemId
+ * @see org.xml.sax.Locator#getSystemId
+ * @see org.xml.sax.SAXParseException#getSystemId
+ */
+ public void setSystemId (String systemId)
+ {
+ this.systemId = systemId;
+ }
+
+
+ /**
+ * Get the system identifier for this input source.
+ *
+ * <p>The getEncoding method will return the character encoding
+ * of the object pointed to, or null if unknown.</p>
+ *
+ * <p>If the system ID is a URL, it will be fully resolved.</p>
+ *
+ * @return The system identifier, or null if none was supplied.
+ * @see #setSystemId
+ * @see #getEncoding
+ */
+ public String getSystemId ()
+ {
+ return systemId;
+ }
+
+
+ /**
+ * Set the byte stream for this input source.
+ *
+ * <p>The SAX parser will ignore this if there is also a character
+ * stream specified, but it will use a byte stream in preference
+ * to opening a URI connection itself.</p>
+ *
+ * <p>If the application knows the character encoding of the
+ * byte stream, it should set it with the setEncoding method.</p>
+ *
+ * @param byteStream A byte stream containing an XML document or
+ * other entity.
+ * @see #setEncoding
+ * @see #getByteStream
+ * @see #getEncoding
+ * @see java.io.InputStream
+ */
+ public void setByteStream (InputStream byteStream)
+ {
+ this.byteStream = byteStream;
+ }
+
+
+ /**
+ * Get the byte stream for this input source.
+ *
+ * <p>The getEncoding method will return the character
+ * encoding for this byte stream, or null if unknown.</p>
+ *
+ * @return The byte stream, or null if none was supplied.
+ * @see #getEncoding
+ * @see #setByteStream
+ */
+ public InputStream getByteStream ()
+ {
+ return byteStream;
+ }
+
+
+ /**
+ * Set the character encoding, if known.
+ *
+ * <p>The encoding must be a string acceptable for an
+ * XML encoding declaration (see section 4.3.3 of the XML 1.0
+ * recommendation).</p>
+ *
+ * <p>This method has no effect when the application provides a
+ * character stream.</p>
+ *
+ * @param encoding A string describing the character encoding.
+ * @see #setSystemId
+ * @see #setByteStream
+ * @see #getEncoding
+ */
+ public void setEncoding (String encoding)
+ {
+ this.encoding = encoding;
+ }
+
+
+ /**
+ * Get the character encoding for a byte stream or URI.
+ * This value will be ignored when the application provides a
+ * character stream.
+ *
+ * @return The encoding, or null if none was supplied.
+ * @see #setByteStream
+ * @see #getSystemId
+ * @see #getByteStream
+ */
+ public String getEncoding ()
+ {
+ return encoding;
+ }
+
+
+ /**
+ * Set the character stream for this input source.
+ *
+ * <p>If there is a character stream specified, the SAX parser
+ * will ignore any byte stream and will not attempt to open
+ * a URI connection to the system identifier.</p>
+ *
+ * @param characterStream The character stream containing the
+ * XML document or other entity.
+ * @see #getCharacterStream
+ * @see java.io.Reader
+ */
+ public void setCharacterStream (Reader characterStream)
+ {
+ this.characterStream = characterStream;
+ }
+
+
+ /**
+ * Get the character stream for this input source.
+ *
+ * @return The character stream, or null if none was supplied.
+ * @see #setCharacterStream
+ */
+ public Reader getCharacterStream ()
+ {
+ return characterStream;
+ }
+
+
+
+ ////////////////////////////////////////////////////////////////////
+ // Internal state.
+ ////////////////////////////////////////////////////////////////////
+
+ private String publicId;
+ private String systemId;
+ private InputStream byteStream;
+ private String encoding;
+ private Reader characterStream;
+
+}
+
+// end of InputSource.java
diff --git a/xml/src/main/java/org/xml/sax/Locator.java b/xml/src/main/java/org/xml/sax/Locator.java
new file mode 100644
index 0000000..f8f3484
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/Locator.java
@@ -0,0 +1,136 @@
+// SAX locator interface for document events.
+// http://www.saxproject.org
+// No warranty; no copyright -- use this as you will.
+// $Id: Locator.java,v 1.8 2002/01/30 21:13:47 dbrownell Exp $
+
+package org.xml.sax;
+
+
+/**
+ * Interface for associating a SAX event with a document location.
+ *
+ * <blockquote>
+ * <em>This module, both source code and documentation, is in the
+ * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
+ * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
+ * for further information.
+ * </blockquote>
+ *
+ * <p>If a SAX parser provides location information to the SAX
+ * application, it does so by implementing this interface and then
+ * passing an instance to the application using the content
+ * handler's {@link org.xml.sax.ContentHandler#setDocumentLocator
+ * setDocumentLocator} method. The application can use the
+ * object to obtain the location of any other SAX event
+ * in the XML source document.</p>
+ *
+ * <p>Note that the results returned by the object will be valid only
+ * during the scope of each callback method: the application
+ * will receive unpredictable results if it attempts to use the
+ * locator at any other time, or after parsing completes.</p>
+ *
+ * <p>SAX parsers are not required to supply a locator, but they are
+ * very strongly encouraged to do so. If the parser supplies a
+ * locator, it must do so before reporting any other document events.
+ * If no locator has been set by the time the application receives
+ * the {@link org.xml.sax.ContentHandler#startDocument startDocument}
+ * event, the application should assume that a locator is not
+ * available.</p>
+ *
+ * @since SAX 1.0
+ * @author David Megginson
+ * @version 2.0.1 (sax2r2)
+ * @see org.xml.sax.ContentHandler#setDocumentLocator
+ */
+public interface Locator {
+
+
+ /**
+ * Return the public identifier for the current document event.
+ *
+ * <p>The return value is the public identifier of the document
+ * entity or of the external parsed entity in which the markup
+ * triggering the event appears.</p>
+ *
+ * @return A string containing the public identifier, or
+ * null if none is available.
+ * @see #getSystemId
+ */
+ public abstract String getPublicId ();
+
+
+ /**
+ * Return the system identifier for the current document event.
+ *
+ * <p>The return value is the system identifier of the document
+ * entity or of the external parsed entity in which the markup
+ * triggering the event appears.</p>
+ *
+ * <p>If the system identifier is a URL, the parser must resolve it
+ * fully before passing it to the application. For example, a file
+ * name must always be provided as a <em>file:...</em> URL, and other
+ * kinds of relative URI are also resolved against their bases.</p>
+ *
+ * @return A string containing the system identifier, or null
+ * if none is available.
+ * @see #getPublicId
+ */
+ public abstract String getSystemId ();
+
+
+ /**
+ * Return the line number where the current document event ends.
+ * Lines are delimited by line ends, which are defined in
+ * the XML specification.
+ *
+ * <p><strong>Warning:</strong> The return value from the method
+ * is intended only as an approximation for the sake of diagnostics;
+ * it is not intended to provide sufficient information
+ * to edit the character content of the original XML document.
+ * In some cases, these "line" numbers match what would be displayed
+ * as columns, and in others they may not match the source text
+ * due to internal entity expansion. </p>
+ *
+ * <p>The return value is an approximation of the line number
+ * in the document entity or external parsed entity where the
+ * markup triggering the event appears.</p>
+ *
+ * <p>If possible, the SAX driver should provide the line position
+ * of the first character after the text associated with the document
+ * event. The first line is line 1.</p>
+ *
+ * @return The line number, or -1 if none is available.
+ * @see #getColumnNumber
+ */
+ public abstract int getLineNumber ();
+
+
+ /**
+ * Return the column number where the current document event ends.
+ * This is one-based number of Java <code>char</code> values since
+ * the last line end.
+ *
+ * <p><strong>Warning:</strong> The return value from the method
+ * is intended only as an approximation for the sake of diagnostics;
+ * it is not intended to provide sufficient information
+ * to edit the character content of the original XML document.
+ * For example, when lines contain combining character sequences, wide
+ * characters, surrogate pairs, or bi-directional text, the value may
+ * not correspond to the column in a text editor's display. </p>
+ *
+ * <p>The return value is an approximation of the column number
+ * in the document entity or external parsed entity where the
+ * markup triggering the event appears.</p>
+ *
+ * <p>If possible, the SAX driver should provide the line position
+ * of the first character after the text associated with the document
+ * event. The first column in each line is column 1.</p>
+ *
+ * @return The column number, or -1 if none is available.
+ * @see #getLineNumber
+ */
+ public abstract int getColumnNumber ();
+
+}
+
+// end of Locator.java
diff --git a/xml/src/main/java/org/xml/sax/Parser.java b/xml/src/main/java/org/xml/sax/Parser.java
new file mode 100644
index 0000000..67a5512
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/Parser.java
@@ -0,0 +1,209 @@
+// SAX parser interface.
+// http://www.saxproject.org
+// No warranty; no copyright -- use this as you will.
+// $Id: Parser.java,v 1.6 2002/01/30 21:13:47 dbrownell Exp $
+
+package org.xml.sax;
+
+import java.io.IOException;
+import java.util.Locale;
+
+
+/**
+ * Basic interface for SAX (Simple API for XML) parsers.
+ *
+ * <blockquote>
+ * <em>This module, both source code and documentation, is in the
+ * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
+ * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
+ * for further information.
+ * </blockquote>
+ *
+ * <p>This was the main event supplier interface for SAX1; it has
+ * been replaced in SAX2 by {@link org.xml.sax.XMLReader XMLReader},
+ * which includes Namespace support and sophisticated configurability
+ * and extensibility.</p>
+ *
+ * <p>All SAX1 parsers must implement this basic interface: it allows
+ * applications to register handlers for different types of events
+ * and to initiate a parse from a URI, or a character stream.</p>
+ *
+ * <p>All SAX1 parsers must also implement a zero-argument constructor
+ * (though other constructors are also allowed).</p>
+ *
+ * <p>SAX1 parsers are reusable but not re-entrant: the application
+ * may reuse a parser object (possibly with a different input source)
+ * once the first parse has completed successfully, but it may not
+ * invoke the parse() methods recursively within a parse.</p>
+ *
+ * @deprecated This interface has been replaced by the SAX2
+ * {@link org.xml.sax.XMLReader XMLReader}
+ * interface, which includes Namespace support.
+ * @since SAX 1.0
+ * @author David Megginson
+ * @version 2.0.1 (sax2r2)
+ * @see org.xml.sax.EntityResolver
+ * @see org.xml.sax.DTDHandler
+ * @see org.xml.sax.DocumentHandler
+ * @see org.xml.sax.ErrorHandler
+ * @see org.xml.sax.HandlerBase
+ * @see org.xml.sax.InputSource
+ */
+public interface Parser
+{
+
+ /**
+ * Allow an application to request a locale for errors and warnings.
+ *
+ * <p>SAX parsers are not required to provide localisation for errors
+ * and warnings; if they cannot support the requested locale,
+ * however, they must throw a SAX exception. Applications may
+ * not request a locale change in the middle of a parse.</p>
+ *
+ * @param locale A Java Locale object.
+ * @exception org.xml.sax.SAXException Throws an exception
+ * (using the previous or default locale) if the
+ * requested locale is not supported.
+ * @see org.xml.sax.SAXException
+ * @see org.xml.sax.SAXParseException
+ */
+ public abstract void setLocale (Locale locale)
+ throws SAXException;
+
+
+ /**
+ * Allow an application to register a custom entity resolver.
+ *
+ * <p>If the application does not register an entity resolver, the
+ * SAX parser will resolve system identifiers and open connections
+ * to entities itself (this is the default behaviour implemented in
+ * HandlerBase).</p>
+ *
+ * <p>Applications may register a new or different entity resolver
+ * in the middle of a parse, and the SAX parser must begin using
+ * the new resolver immediately.</p>
+ *
+ * @param resolver The object for resolving entities.
+ * @see EntityResolver
+ * @see HandlerBase
+ */
+ public abstract void setEntityResolver (EntityResolver resolver);
+
+
+ /**
+ * Allow an application to register a DTD event handler.
+ *
+ * <p>If the application does not register a DTD handler, all DTD
+ * events reported by the SAX parser will be silently
+ * ignored (this is the default behaviour implemented by
+ * HandlerBase).</p>
+ *
+ * <p>Applications may register a new or different
+ * handler in the middle of a parse, and the SAX parser must
+ * begin using the new handler immediately.</p>
+ *
+ * @param handler The DTD handler.
+ * @see DTDHandler
+ * @see HandlerBase
+ */
+ public abstract void setDTDHandler (DTDHandler handler);
+
+
+ /**
+ * Allow an application to register a document event handler.
+ *
+ * <p>If the application does not register a document handler, all
+ * document events reported by the SAX parser will be silently
+ * ignored (this is the default behaviour implemented by
+ * HandlerBase).</p>
+ *
+ * <p>Applications may register a new or different handler in the
+ * middle of a parse, and the SAX parser must begin using the new
+ * handler immediately.</p>
+ *
+ * @param handler The document handler.
+ * @see DocumentHandler
+ * @see HandlerBase
+ */
+ public abstract void setDocumentHandler (DocumentHandler handler);
+
+
+ /**
+ * Allow an application to register an error event handler.
+ *
+ * <p>If the application does not register an error event handler,
+ * all error events reported by the SAX parser will be silently
+ * ignored, except for fatalError, which will throw a SAXException
+ * (this is the default behaviour implemented by HandlerBase).</p>
+ *
+ * <p>Applications may register a new or different handler in the
+ * middle of a parse, and the SAX parser must begin using the new
+ * handler immediately.</p>
+ *
+ * @param handler The error handler.
+ * @see ErrorHandler
+ * @see SAXException
+ * @see HandlerBase
+ */
+ public abstract void setErrorHandler (ErrorHandler handler);
+
+
+ /**
+ * Parse an XML document.
+ *
+ * <p>The application can use this method to instruct the SAX parser
+ * to begin parsing an XML document from any valid input
+ * source (a character stream, a byte stream, or a URI).</p>
+ *
+ * <p>Applications may not invoke this method while a parse is in
+ * progress (they should create a new Parser instead for each
+ * additional XML document). Once a parse is complete, an
+ * application may reuse the same Parser object, possibly with a
+ * different input source.</p>
+ *
+ * @param source The input source for the top-level of the
+ * XML document.
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ * @exception java.io.IOException An IO exception from the parser,
+ * possibly from a byte stream or character stream
+ * supplied by the application.
+ * @see org.xml.sax.InputSource
+ * @see #parse(java.lang.String)
+ * @see #setEntityResolver
+ * @see #setDTDHandler
+ * @see #setDocumentHandler
+ * @see #setErrorHandler
+ */
+ public abstract void parse (InputSource source)
+ throws SAXException, IOException;
+
+
+ /**
+ * Parse an XML document from a system identifier (URI).
+ *
+ * <p>This method is a shortcut for the common case of reading a
+ * document from a system identifier. It is the exact
+ * equivalent of the following:</p>
+ *
+ * <pre>
+ * parse(new InputSource(systemId));
+ * </pre>
+ *
+ * <p>If the system identifier is a URL, it must be fully resolved
+ * by the application before it is passed to the parser.</p>
+ *
+ * @param systemId The system identifier (URI).
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ * @exception java.io.IOException An IO exception from the parser,
+ * possibly from a byte stream or character stream
+ * supplied by the application.
+ * @see #parse(org.xml.sax.InputSource)
+ */
+ public abstract void parse (String systemId)
+ throws SAXException, IOException;
+
+}
+
+// end of Parser.java
diff --git a/xml/src/main/java/org/xml/sax/SAXException.java b/xml/src/main/java/org/xml/sax/SAXException.java
new file mode 100644
index 0000000..2e5b4cd
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/SAXException.java
@@ -0,0 +1,153 @@
+// SAX exception class.
+// http://www.saxproject.org
+// No warranty; no copyright -- use this as you will.
+// $Id: SAXException.java,v 1.7 2002/01/30 21:13:48 dbrownell Exp $
+
+package org.xml.sax;
+
+/**
+ * Encapsulate a general SAX error or warning.
+ *
+ * <blockquote>
+ * <em>This module, both source code and documentation, is in the
+ * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
+ * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
+ * for further information.
+ * </blockquote>
+ *
+ * <p>This class can contain basic error or warning information from
+ * either the XML parser or the application: a parser writer or
+ * application writer can subclass it to provide additional
+ * functionality. SAX handlers may throw this exception or
+ * any exception subclassed from it.</p>
+ *
+ * <p>If the application needs to pass through other types of
+ * exceptions, it must wrap those exceptions in a SAXException
+ * or an exception derived from a SAXException.</p>
+ *
+ * <p>If the parser or application needs to include information about a
+ * specific location in an XML document, it should use the
+ * {@link org.xml.sax.SAXParseException SAXParseException} subclass.</p>
+ *
+ * @since SAX 1.0
+ * @author David Megginson
+ * @version 2.0.1 (sax2r2)
+ * @see org.xml.sax.SAXParseException
+ */
+public class SAXException extends Exception {
+
+
+ /**
+ * Create a new SAXException.
+ */
+ public SAXException ()
+ {
+ super();
+ this.exception = null;
+ }
+
+
+ /**
+ * Create a new SAXException.
+ *
+ * @param message The error or warning message.
+ */
+ public SAXException (String message) {
+ super(message);
+ this.exception = null;
+ }
+
+
+ /**
+ * Create a new SAXException wrapping an existing exception.
+ *
+ * <p>The existing exception will be embedded in the new
+ * one, and its message will become the default message for
+ * the SAXException.</p>
+ *
+ * @param e The exception to be wrapped in a SAXException.
+ */
+ public SAXException (Exception e)
+ {
+ super();
+ this.exception = e;
+ }
+
+
+ /**
+ * Create a new SAXException from an existing exception.
+ *
+ * <p>The existing exception will be embedded in the new
+ * one, but the new exception will have its own message.</p>
+ *
+ * @param message The detail message.
+ * @param e The exception to be wrapped in a SAXException.
+ */
+ public SAXException (String message, Exception e)
+ {
+ super(message);
+ this.exception = e;
+ }
+
+
+ /**
+ * Return a detail message for this exception.
+ *
+ * <p>If there is an embedded exception, and if the SAXException
+ * has no detail message of its own, this method will return
+ * the detail message from the embedded exception.</p>
+ *
+ * @return The error or warning message.
+ */
+ public String getMessage ()
+ {
+ String message = super.getMessage();
+
+ if (message == null && exception != null) {
+ return exception.getMessage();
+ } else {
+ return message;
+ }
+ }
+
+
+ /**
+ * Return the embedded exception, if any.
+ *
+ * @return The embedded exception, or null if there is none.
+ */
+ public Exception getException ()
+ {
+ return exception;
+ }
+
+
+ /**
+ * Override toString to pick up any embedded exception.
+ *
+ * @return A string representation of this exception.
+ */
+ public String toString ()
+ {
+ if (exception != null) {
+ return exception.toString();
+ } else {
+ return super.toString();
+ }
+ }
+
+
+
+ //////////////////////////////////////////////////////////////////////
+ // Internal state.
+ //////////////////////////////////////////////////////////////////////
+
+
+ /**
+ * @serial The embedded exception if tunnelling, or null.
+ */
+ private Exception exception;
+
+}
+
+// end of SAXException.java
diff --git a/xml/src/main/java/org/xml/sax/SAXNotRecognizedException.java b/xml/src/main/java/org/xml/sax/SAXNotRecognizedException.java
new file mode 100644
index 0000000..69ba807
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/SAXNotRecognizedException.java
@@ -0,0 +1,53 @@
+// SAXNotRecognizedException.java - unrecognized feature or value.
+// http://www.saxproject.org
+// Written by David Megginson
+// NO WARRANTY! This class is in the Public Domain.
+// $Id: SAXNotRecognizedException.java,v 1.7 2002/01/30 21:13:48 dbrownell Exp $
+
+package org.xml.sax;
+
+
+/**
+ * Exception class for an unrecognized identifier.
+ *
+ * <blockquote>
+ * <em>This module, both source code and documentation, is in the
+ * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
+ * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
+ * for further information.
+ * </blockquote>
+ *
+ * <p>An XMLReader will throw this exception when it finds an
+ * unrecognized feature or property identifier; SAX applications and
+ * extensions may use this class for other, similar purposes.</p>
+ *
+ * @since SAX 2.0
+ * @author David Megginson
+ * @version 2.0.1 (sax2r2)
+ * @see org.xml.sax.SAXNotSupportedException
+ */
+public class SAXNotRecognizedException extends SAXException
+{
+
+ /**
+ * Default constructor.
+ */
+ public SAXNotRecognizedException ()
+ {
+ super();
+ }
+
+
+ /**
+ * Construct a new exception with the given message.
+ *
+ * @param message The text message of the exception.
+ */
+ public SAXNotRecognizedException (String message)
+ {
+ super(message);
+ }
+
+}
+
+// end of SAXNotRecognizedException.java
diff --git a/xml/src/main/java/org/xml/sax/SAXNotSupportedException.java b/xml/src/main/java/org/xml/sax/SAXNotSupportedException.java
new file mode 100644
index 0000000..bd5b239
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/SAXNotSupportedException.java
@@ -0,0 +1,53 @@
+// SAXNotSupportedException.java - unsupported feature or value.
+// http://www.saxproject.org
+// Written by David Megginson
+// NO WARRANTY! This class is in the Public Domain.
+// $Id: SAXNotSupportedException.java,v 1.7 2002/01/30 21:13:48 dbrownell Exp $
+
+package org.xml.sax;
+
+/**
+ * Exception class for an unsupported operation.
+ *
+ * <blockquote>
+ * <em>This module, both source code and documentation, is in the
+ * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
+ * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
+ * for further information.
+ * </blockquote>
+ *
+ * <p>An XMLReader will throw this exception when it recognizes a
+ * feature or property identifier, but cannot perform the requested
+ * operation (setting a state or value). Other SAX2 applications and
+ * extensions may use this class for similar purposes.</p>
+ *
+ * @since SAX 2.0
+ * @author David Megginson
+ * @version 2.0.1 (sax2r2)
+ * @see org.xml.sax.SAXNotRecognizedException
+ */
+public class SAXNotSupportedException extends SAXException
+{
+
+ /**
+ * Construct a new exception with no message.
+ */
+ public SAXNotSupportedException ()
+ {
+ super();
+ }
+
+
+ /**
+ * Construct a new exception with the given message.
+ *
+ * @param message The text message of the exception.
+ */
+ public SAXNotSupportedException (String message)
+ {
+ super(message);
+ }
+
+}
+
+// end of SAXNotSupportedException.java
diff --git a/xml/src/main/java/org/xml/sax/SAXParseException.java b/xml/src/main/java/org/xml/sax/SAXParseException.java
new file mode 100644
index 0000000..a6a93e9
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/SAXParseException.java
@@ -0,0 +1,269 @@
+// SAX exception class.
+// http://www.saxproject.org
+// No warranty; no copyright -- use this as you will.
+// $Id: SAXParseException.java,v 1.11 2004/04/21 13:05:02 dmegginson Exp $
+
+package org.xml.sax;
+
+/**
+ * Encapsulate an XML parse error or warning.
+ *
+ * <blockquote>
+ * <em>This module, both source code and documentation, is in the
+ * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
+ * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
+ * for further information.
+ * </blockquote>
+ *
+ * <p>This exception may include information for locating the error
+ * in the original XML document, as if it came from a {@link Locator}
+ * object. Note that although the application
+ * will receive a SAXParseException as the argument to the handlers
+ * in the {@link org.xml.sax.ErrorHandler ErrorHandler} interface,
+ * the application is not actually required to throw the exception;
+ * instead, it can simply read the information in it and take a
+ * different action.</p>
+ *
+ * <p>Since this exception is a subclass of {@link org.xml.sax.SAXException
+ * SAXException}, it inherits the ability to wrap another exception.</p>
+ *
+ * @since SAX 1.0
+ * @author David Megginson
+ * @version 2.0.1 (sax2r2)
+ * @see org.xml.sax.SAXException
+ * @see org.xml.sax.Locator
+ * @see org.xml.sax.ErrorHandler
+ */
+public class SAXParseException extends SAXException {
+
+
+ //////////////////////////////////////////////////////////////////////
+ // Constructors.
+ //////////////////////////////////////////////////////////////////////
+
+
+ /**
+ * Create a new SAXParseException from a message and a Locator.
+ *
+ * <p>This constructor is especially useful when an application is
+ * creating its own exception from within a {@link org.xml.sax.ContentHandler
+ * ContentHandler} callback.</p>
+ *
+ * @param message The error or warning message.
+ * @param locator The locator object for the error or warning (may be
+ * null).
+ * @see org.xml.sax.Locator
+ */
+ public SAXParseException (String message, Locator locator) {
+ super(message);
+ if (locator != null) {
+ init(locator.getPublicId(), locator.getSystemId(),
+ locator.getLineNumber(), locator.getColumnNumber());
+ } else {
+ init(null, null, -1, -1);
+ }
+ }
+
+
+ /**
+ * Wrap an existing exception in a SAXParseException.
+ *
+ * <p>This constructor is especially useful when an application is
+ * creating its own exception from within a {@link org.xml.sax.ContentHandler
+ * ContentHandler} callback, and needs to wrap an existing exception that is not a
+ * subclass of {@link org.xml.sax.SAXException SAXException}.</p>
+ *
+ * @param message The error or warning message, or null to
+ * use the message from the embedded exception.
+ * @param locator The locator object for the error or warning (may be
+ * null).
+ * @param e Any exception.
+ * @see org.xml.sax.Locator
+ */
+ public SAXParseException (String message, Locator locator,
+ Exception e) {
+ super(message, e);
+ if (locator != null) {
+ init(locator.getPublicId(), locator.getSystemId(),
+ locator.getLineNumber(), locator.getColumnNumber());
+ } else {
+ init(null, null, -1, -1);
+ }
+ }
+
+
+ /**
+ * Create a new SAXParseException.
+ *
+ * <p>This constructor is most useful for parser writers.</p>
+ *
+ * <p>All parameters except the message are as if
+ * they were provided by a {@link Locator}. For example, if the
+ * system identifier is a URL (including relative filename), the
+ * caller must resolve it fully before creating the exception.</p>
+ *
+ *
+ * @param message The error or warning message.
+ * @param publicId The public identifier of the entity that generated
+ * the error or warning.
+ * @param systemId The system identifier of the entity that generated
+ * the error or warning.
+ * @param lineNumber The line number of the end of the text that
+ * caused the error or warning.
+ * @param columnNumber The column number of the end of the text that
+ * cause the error or warning.
+ */
+ public SAXParseException (String message, String publicId, String systemId,
+ int lineNumber, int columnNumber)
+ {
+ super(message);
+ init(publicId, systemId, lineNumber, columnNumber);
+ }
+
+
+ /**
+ * Create a new SAXParseException with an embedded exception.
+ *
+ * <p>This constructor is most useful for parser writers who
+ * need to wrap an exception that is not a subclass of
+ * {@link org.xml.sax.SAXException SAXException}.</p>
+ *
+ * <p>All parameters except the message and exception are as if
+ * they were provided by a {@link Locator}. For example, if the
+ * system identifier is a URL (including relative filename), the
+ * caller must resolve it fully before creating the exception.</p>
+ *
+ * @param message The error or warning message, or null to use
+ * the message from the embedded exception.
+ * @param publicId The public identifier of the entity that generated
+ * the error or warning.
+ * @param systemId The system identifier of the entity that generated
+ * the error or warning.
+ * @param lineNumber The line number of the end of the text that
+ * caused the error or warning.
+ * @param columnNumber The column number of the end of the text that
+ * cause the error or warning.
+ * @param e Another exception to embed in this one.
+ */
+ public SAXParseException (String message, String publicId, String systemId,
+ int lineNumber, int columnNumber, Exception e)
+ {
+ super(message, e);
+ init(publicId, systemId, lineNumber, columnNumber);
+ }
+
+
+ /**
+ * Internal initialization method.
+ *
+ * @param publicId The public identifier of the entity which generated the exception,
+ * or null.
+ * @param systemId The system identifier of the entity which generated the exception,
+ * or null.
+ * @param lineNumber The line number of the error, or -1.
+ * @param columnNumber The column number of the error, or -1.
+ */
+ private void init (String publicId, String systemId,
+ int lineNumber, int columnNumber)
+ {
+ this.publicId = publicId;
+ this.systemId = systemId;
+ this.lineNumber = lineNumber;
+ this.columnNumber = columnNumber;
+ }
+
+
+ /**
+ * Get the public identifier of the entity where the exception occurred.
+ *
+ * @return A string containing the public identifier, or null
+ * if none is available.
+ * @see org.xml.sax.Locator#getPublicId
+ */
+ public String getPublicId ()
+ {
+ return this.publicId;
+ }
+
+
+ /**
+ * Get the system identifier of the entity where the exception occurred.
+ *
+ * <p>If the system identifier is a URL, it will have been resolved
+ * fully.</p>
+ *
+ * @return A string containing the system identifier, or null
+ * if none is available.
+ * @see org.xml.sax.Locator#getSystemId
+ */
+ public String getSystemId ()
+ {
+ return this.systemId;
+ }
+
+
+ /**
+ * The line number of the end of the text where the exception occurred.
+ *
+ * <p>The first line is line 1.</p>
+ *
+ * @return An integer representing the line number, or -1
+ * if none is available.
+ * @see org.xml.sax.Locator#getLineNumber
+ */
+ public int getLineNumber ()
+ {
+ return this.lineNumber;
+ }
+
+
+ /**
+ * The column number of the end of the text where the exception occurred.
+ *
+ * <p>The first column in a line is position 1.</p>
+ *
+ * @return An integer representing the column number, or -1
+ * if none is available.
+ * @see org.xml.sax.Locator#getColumnNumber
+ */
+ public int getColumnNumber ()
+ {
+ return this.columnNumber;
+ }
+
+
+ //////////////////////////////////////////////////////////////////////
+ // Internal state.
+ //////////////////////////////////////////////////////////////////////
+
+
+ /**
+ * @serial The public identifier, or null.
+ * @see #getPublicId
+ */
+ private String publicId;
+
+
+ /**
+ * @serial The system identifier, or null.
+ * @see #getSystemId
+ */
+ private String systemId;
+
+
+ /**
+ * @serial The line number, or -1.
+ * @see #getLineNumber
+ */
+ private int lineNumber;
+
+
+ /**
+ * @serial The column number, or -1.
+ * @see #getColumnNumber
+ */
+ private int columnNumber;
+
+}
+
+// end of SAXParseException.java
diff --git a/xml/src/main/java/org/xml/sax/XMLFilter.java b/xml/src/main/java/org/xml/sax/XMLFilter.java
new file mode 100644
index 0000000..5a399fa
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/XMLFilter.java
@@ -0,0 +1,65 @@
+// XMLFilter.java - filter SAX2 events.
+// http://www.saxproject.org
+// Written by David Megginson
+// NO WARRANTY! This class is in the Public Domain.
+// $Id: XMLFilter.java,v 1.6 2002/01/30 21:13:48 dbrownell Exp $
+
+package org.xml.sax;
+
+
+/**
+ * Interface for an XML filter.
+ *
+ * <blockquote>
+ * <em>This module, both source code and documentation, is in the
+ * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
+ * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
+ * for further information.
+ * </blockquote>
+ *
+ * <p>An XML filter is like an XML reader, except that it obtains its
+ * events from another XML reader rather than a primary source like
+ * an XML document or database. Filters can modify a stream of
+ * events as they pass on to the final application.</p>
+ *
+ * <p>The XMLFilterImpl helper class provides a convenient base
+ * for creating SAX2 filters, by passing on all {@link org.xml.sax.EntityResolver
+ * EntityResolver}, {@link org.xml.sax.DTDHandler DTDHandler},
+ * {@link org.xml.sax.ContentHandler ContentHandler} and {@link org.xml.sax.ErrorHandler
+ * ErrorHandler} events automatically.</p>
+ *
+ * @since SAX 2.0
+ * @author David Megginson
+ * @version 2.0.1 (sax2r2)
+ * @see org.xml.sax.helpers.XMLFilterImpl
+ */
+public interface XMLFilter extends XMLReader
+{
+
+ /**
+ * Set the parent reader.
+ *
+ * <p>This method allows the application to link the filter to
+ * a parent reader (which may be another filter). The argument
+ * may not be null.</p>
+ *
+ * @param parent The parent reader.
+ */
+ public abstract void setParent (XMLReader parent);
+
+
+ /**
+ * Get the parent reader.
+ *
+ * <p>This method allows the application to query the parent
+ * reader (which may be another filter). It is generally a
+ * bad idea to perform any operations on the parent reader
+ * directly: they should all pass through this filter.</p>
+ *
+ * @return The parent filter, or null if none has been set.
+ */
+ public abstract XMLReader getParent ();
+
+}
+
+// end of XMLFilter.java
diff --git a/xml/src/main/java/org/xml/sax/XMLReader.java b/xml/src/main/java/org/xml/sax/XMLReader.java
new file mode 100644
index 0000000..d58a4bd
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/XMLReader.java
@@ -0,0 +1,404 @@
+// XMLReader.java - read an XML document.
+// http://www.saxproject.org
+// Written by David Megginson
+// NO WARRANTY! This class is in the Public Domain.
+// $Id: XMLReader.java,v 1.9 2004/04/26 17:34:34 dmegginson Exp $
+
+package org.xml.sax;
+
+import java.io.IOException;
+
+
+/**
+ * Interface for reading an XML document using callbacks.
+ *
+ * <blockquote>
+ * <em>This module, both source code and documentation, is in the
+ * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
+ * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
+ * for further information.
+ * </blockquote>
+ *
+ * <p><strong>Note:</strong> despite its name, this interface does
+ * <em>not</em> extend the standard Java {@link java.io.Reader Reader}
+ * interface, because reading XML is a fundamentally different activity
+ * than reading character data.</p>
+ *
+ * <p>XMLReader is the interface that an XML parser's SAX2 driver must
+ * implement. This interface allows an application to set and
+ * query features and properties in the parser, to register
+ * event handlers for document processing, and to initiate
+ * a document parse.</p>
+ *
+ * <p>All SAX interfaces are assumed to be synchronous: the
+ * {@link #parse parse} methods must not return until parsing
+ * is complete, and readers must wait for an event-handler callback
+ * to return before reporting the next event.</p>
+ *
+ * <p>This interface replaces the (now deprecated) SAX 1.0 {@link
+ * org.xml.sax.Parser Parser} interface. The XMLReader interface
+ * contains two important enhancements over the old Parser
+ * interface (as well as some minor ones):</p>
+ *
+ * <ol>
+ * <li>it adds a standard way to query and set features and
+ * properties; and</li>
+ * <li>it adds Namespace support, which is required for many
+ * higher-level XML standards.</li>
+ * </ol>
+ *
+ * <p>There are adapters available to convert a SAX1 Parser to
+ * a SAX2 XMLReader and vice-versa.</p>
+ *
+ * @since SAX 2.0
+ * @author David Megginson
+ * @version 2.0.1+ (sax2r3pre1)
+ * @see org.xml.sax.XMLFilter
+ * @see org.xml.sax.helpers.ParserAdapter
+ * @see org.xml.sax.helpers.XMLReaderAdapter
+ */
+public interface XMLReader
+{
+
+
+ ////////////////////////////////////////////////////////////////////
+ // Configuration.
+ ////////////////////////////////////////////////////////////////////
+
+
+ /**
+ * Look up the value of a feature flag.
+ *
+ * <p>The feature name is any fully-qualified URI. It is
+ * possible for an XMLReader to recognize a feature name but
+ * temporarily be unable to return its value.
+ * Some feature values may be available only in specific
+ * contexts, such as before, during, or after a parse.
+ * Also, some feature values may not be programmatically accessible.
+ * (In the case of an adapter for SAX1 {@link Parser}, there is no
+ * implementation-independent way to expose whether the underlying
+ * parser is performing validation, expanding external entities,
+ * and so forth.) </p>
+ *
+ * <p>All XMLReaders are required to recognize the
+ * http://xml.org/sax/features/namespaces and the
+ * http://xml.org/sax/features/namespace-prefixes feature names.</p>
+ *
+ * <p>Typical usage is something like this:</p>
+ *
+ * <pre>
+ * XMLReader r = new MySAXDriver();
+ *
+ * // try to activate validation
+ * try {
+ * r.setFeature("http://xml.org/sax/features/validation", true);
+ * } catch (SAXException e) {
+ * System.err.println("Cannot activate validation.");
+ * }
+ *
+ * // register event handlers
+ * r.setContentHandler(new MyContentHandler());
+ * r.setErrorHandler(new MyErrorHandler());
+ *
+ * // parse the first document
+ * try {
+ * r.parse("http://www.foo.com/mydoc.xml");
+ * } catch (IOException e) {
+ * System.err.println("I/O exception reading XML document");
+ * } catch (SAXException e) {
+ * System.err.println("XML exception reading document.");
+ * }
+ * </pre>
+ *
+ * <p>Implementors are free (and encouraged) to invent their own features,
+ * using names built on their own URIs.</p>
+ *
+ * @param name The feature name, which is a fully-qualified URI.
+ * @return The current value of the feature (true or false).
+ * @exception org.xml.sax.SAXNotRecognizedException If the feature
+ * value can't be assigned or retrieved.
+ * @exception org.xml.sax.SAXNotSupportedException When the
+ * XMLReader recognizes the feature name but
+ * cannot determine its value at this time.
+ * @see #setFeature
+ */
+ public boolean getFeature (String name)
+ throws SAXNotRecognizedException, SAXNotSupportedException;
+
+
+ /**
+ * Set the value of a feature flag.
+ *
+ * <p>The feature name is any fully-qualified URI. It is
+ * possible for an XMLReader to expose a feature value but
+ * to be unable to change the current value.
+ * Some feature values may be immutable or mutable only
+ * in specific contexts, such as before, during, or after
+ * a parse.</p>
+ *
+ * <p>All XMLReaders are required to support setting
+ * http://xml.org/sax/features/namespaces to true and
+ * http://xml.org/sax/features/namespace-prefixes to false.</p>
+ *
+ * @param name The feature name, which is a fully-qualified URI.
+ * @param value The requested value of the feature (true or false).
+ * @exception org.xml.sax.SAXNotRecognizedException If the feature
+ * value can't be assigned or retrieved.
+ * @exception org.xml.sax.SAXNotSupportedException When the
+ * XMLReader recognizes the feature name but
+ * cannot set the requested value.
+ * @see #getFeature
+ */
+ public void setFeature (String name, boolean value)
+ throws SAXNotRecognizedException, SAXNotSupportedException;
+
+
+ /**
+ * Look up the value of a property.
+ *
+ * <p>The property name is any fully-qualified URI. It is
+ * possible for an XMLReader to recognize a property name but
+ * temporarily be unable to return its value.
+ * Some property values may be available only in specific
+ * contexts, such as before, during, or after a parse.</p>
+ *
+ * <p>XMLReaders are not required to recognize any specific
+ * property names, though an initial core set is documented for
+ * SAX2.</p>
+ *
+ * <p>Implementors are free (and encouraged) to invent their own properties,
+ * using names built on their own URIs.</p>
+ *
+ * @param name The property name, which is a fully-qualified URI.
+ * @return The current value of the property.
+ * @exception org.xml.sax.SAXNotRecognizedException If the property
+ * value can't be assigned or retrieved.
+ * @exception org.xml.sax.SAXNotSupportedException When the
+ * XMLReader recognizes the property name but
+ * cannot determine its value at this time.
+ * @see #setProperty
+ */
+ public Object getProperty (String name)
+ throws SAXNotRecognizedException, SAXNotSupportedException;
+
+
+ /**
+ * Set the value of a property.
+ *
+ * <p>The property name is any fully-qualified URI. It is
+ * possible for an XMLReader to recognize a property name but
+ * to be unable to change the current value.
+ * Some property values may be immutable or mutable only
+ * in specific contexts, such as before, during, or after
+ * a parse.</p>
+ *
+ * <p>XMLReaders are not required to recognize setting
+ * any specific property names, though a core set is defined by
+ * SAX2.</p>
+ *
+ * <p>This method is also the standard mechanism for setting
+ * extended handlers.</p>
+ *
+ * @param name The property name, which is a fully-qualified URI.
+ * @param value The requested value for the property.
+ * @exception org.xml.sax.SAXNotRecognizedException If the property
+ * value can't be assigned or retrieved.
+ * @exception org.xml.sax.SAXNotSupportedException When the
+ * XMLReader recognizes the property name but
+ * cannot set the requested value.
+ */
+ public void setProperty (String name, Object value)
+ throws SAXNotRecognizedException, SAXNotSupportedException;
+
+
+
+ ////////////////////////////////////////////////////////////////////
+ // Event handlers.
+ ////////////////////////////////////////////////////////////////////
+
+
+ /**
+ * Allow an application to register an entity resolver.
+ *
+ * <p>If the application does not register an entity resolver,
+ * the XMLReader will perform its own default resolution.</p>
+ *
+ * <p>Applications may register a new or different resolver in the
+ * middle of a parse, and the SAX parser must begin using the new
+ * resolver immediately.</p>
+ *
+ * @param resolver The entity resolver.
+ * @see #getEntityResolver
+ */
+ public void setEntityResolver (EntityResolver resolver);
+
+
+ /**
+ * Return the current entity resolver.
+ *
+ * @return The current entity resolver, or null if none
+ * has been registered.
+ * @see #setEntityResolver
+ */
+ public EntityResolver getEntityResolver ();
+
+
+ /**
+ * Allow an application to register a DTD event handler.
+ *
+ * <p>If the application does not register a DTD handler, all DTD
+ * events reported by the SAX parser will be silently ignored.</p>
+ *
+ * <p>Applications may register a new or different handler in the
+ * middle of a parse, and the SAX parser must begin using the new
+ * handler immediately.</p>
+ *
+ * @param handler The DTD handler.
+ * @see #getDTDHandler
+ */
+ public void setDTDHandler (DTDHandler handler);
+
+
+ /**
+ * Return the current DTD handler.
+ *
+ * @return The current DTD handler, or null if none
+ * has been registered.
+ * @see #setDTDHandler
+ */
+ public DTDHandler getDTDHandler ();
+
+
+ /**
+ * Allow an application to register a content event handler.
+ *
+ * <p>If the application does not register a content handler, all
+ * content events reported by the SAX parser will be silently
+ * ignored.</p>
+ *
+ * <p>Applications may register a new or different handler in the
+ * middle of a parse, and the SAX parser must begin using the new
+ * handler immediately.</p>
+ *
+ * @param handler The content handler.
+ * @see #getContentHandler
+ */
+ public void setContentHandler (ContentHandler handler);
+
+
+ /**
+ * Return the current content handler.
+ *
+ * @return The current content handler, or null if none
+ * has been registered.
+ * @see #setContentHandler
+ */
+ public ContentHandler getContentHandler ();
+
+
+ /**
+ * Allow an application to register an error event handler.
+ *
+ * <p>If the application does not register an error handler, all
+ * error events reported by the SAX parser will be silently
+ * ignored; however, normal processing may not continue. It is
+ * highly recommended that all SAX applications implement an
+ * error handler to avoid unexpected bugs.</p>
+ *
+ * <p>Applications may register a new or different handler in the
+ * middle of a parse, and the SAX parser must begin using the new
+ * handler immediately.</p>
+ *
+ * @param handler The error handler.
+ * @see #getErrorHandler
+ */
+ public void setErrorHandler (ErrorHandler handler);
+
+
+ /**
+ * Return the current error handler.
+ *
+ * @return The current error handler, or null if none
+ * has been registered.
+ * @see #setErrorHandler
+ */
+ public ErrorHandler getErrorHandler ();
+
+
+
+ ////////////////////////////////////////////////////////////////////
+ // Parsing.
+ ////////////////////////////////////////////////////////////////////
+
+ /**
+ * Parse an XML document.
+ *
+ * <p>The application can use this method to instruct the XML
+ * reader to begin parsing an XML document from any valid input
+ * source (a character stream, a byte stream, or a URI).</p>
+ *
+ * <p>Applications may not invoke this method while a parse is in
+ * progress (they should create a new XMLReader instead for each
+ * nested XML document). Once a parse is complete, an
+ * application may reuse the same XMLReader object, possibly with a
+ * different input source.
+ * Configuration of the XMLReader object (such as handler bindings and
+ * values established for feature flags and properties) is unchanged
+ * by completion of a parse, unless the definition of that aspect of
+ * the configuration explicitly specifies other behavior.
+ * (For example, feature flags or properties exposing
+ * characteristics of the document being parsed.)
+ * </p>
+ *
+ * <p>During the parse, the XMLReader will provide information
+ * about the XML document through the registered event
+ * handlers.</p>
+ *
+ * <p>This method is synchronous: it will not return until parsing
+ * has ended. If a client application wants to terminate
+ * parsing early, it should throw an exception.</p>
+ *
+ * @param input The input source for the top-level of the
+ * XML document.
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ * @exception java.io.IOException An IO exception from the parser,
+ * possibly from a byte stream or character stream
+ * supplied by the application.
+ * @see org.xml.sax.InputSource
+ * @see #parse(java.lang.String)
+ * @see #setEntityResolver
+ * @see #setDTDHandler
+ * @see #setContentHandler
+ * @see #setErrorHandler
+ */
+ public void parse (InputSource input)
+ throws IOException, SAXException;
+
+
+ /**
+ * Parse an XML document from a system identifier (URI).
+ *
+ * <p>This method is a shortcut for the common case of reading a
+ * document from a system identifier. It is the exact
+ * equivalent of the following:</p>
+ *
+ * <pre>
+ * parse(new InputSource(systemId));
+ * </pre>
+ *
+ * <p>If the system identifier is a URL, it must be fully resolved
+ * by the application before it is passed to the parser.</p>
+ *
+ * @param systemId The system identifier (URI).
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ * @exception java.io.IOException An IO exception from the parser,
+ * possibly from a byte stream or character stream
+ * supplied by the application.
+ * @see #parse(org.xml.sax.InputSource)
+ */
+ public void parse (String systemId)
+ throws IOException, SAXException;
+
+}
diff --git a/xml/src/main/java/org/xml/sax/ext/Attributes2.java b/xml/src/main/java/org/xml/sax/ext/Attributes2.java
new file mode 100644
index 0000000..45cd551
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/ext/Attributes2.java
@@ -0,0 +1,132 @@
+// Attributes2.java - extended Attributes
+// http://www.saxproject.org
+// Public Domain: no warranty.
+// $Id: Attributes2.java,v 1.6 2004/03/08 13:01:00 dmegginson Exp $
+
+package org.xml.sax.ext;
+
+import org.xml.sax.Attributes;
+
+
+/**
+ * SAX2 extension to augment the per-attribute information
+ * provided though {@link Attributes}.
+ * If an implementation supports this extension, the attributes
+ * provided in {@link org.xml.sax.ContentHandler#startElement
+ * ContentHandler.startElement() } will implement this interface,
+ * and the <em>http://xml.org/sax/features/use-attributes2</em>
+ * feature flag will have the value <em>true</em>.
+ *
+ * <blockquote>
+ * <em>This module, both source code and documentation, is in the
+ * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
+ * </blockquote>
+ *
+ * <p> XMLReader implementations are not required to support this
+ * information, and it is not part of core-only SAX2 distributions.</p>
+ *
+ * <p>Note that if an attribute was defaulted (<em>!isSpecified()</em>)
+ * it will of necessity also have been declared (<em>isDeclared()</em>)
+ * in the DTD.
+ * Similarly if an attribute's type is anything except CDATA, then it
+ * must have been declared.
+ * </p>
+ *
+ * @since SAX 2.0 (extensions 1.1 alpha)
+ * @author David Brownell
+ * @version TBS
+ */
+public interface Attributes2 extends Attributes
+{
+ /**
+ * Returns false unless the attribute was declared in the DTD.
+ * This helps distinguish two kinds of attributes that SAX reports
+ * as CDATA: ones that were declared (and hence are usually valid),
+ * and those that were not (and which are never valid).
+ *
+ * @param index The attribute index (zero-based).
+ * @return true if the attribute was declared in the DTD,
+ * false otherwise.
+ * @exception java.lang.ArrayIndexOutOfBoundsException When the
+ * supplied index does not identify an attribute.
+ */
+ public boolean isDeclared (int index);
+
+ /**
+ * Returns false unless the attribute was declared in the DTD.
+ * This helps distinguish two kinds of attributes that SAX reports
+ * as CDATA: ones that were declared (and hence are usually valid),
+ * and those that were not (and which are never valid).
+ *
+ * @param qName The XML qualified (prefixed) name.
+ * @return true if the attribute was declared in the DTD,
+ * false otherwise.
+ * @exception java.lang.IllegalArgumentException When the
+ * supplied name does not identify an attribute.
+ */
+ public boolean isDeclared (String qName);
+
+ /**
+ * Returns false unless the attribute was declared in the DTD.
+ * This helps distinguish two kinds of attributes that SAX reports
+ * as CDATA: ones that were declared (and hence are usually valid),
+ * and those that were not (and which are never valid).
+ *
+ * <p>Remember that since DTDs do not "understand" namespaces, the
+ * namespace URI associated with an attribute may not have come from
+ * the DTD. The declaration will have applied to the attribute's
+ * <em>qName</em>.
+ *
+ * @param uri The Namespace URI, or the empty string if
+ * the name has no Namespace URI.
+ * @param localName The attribute's local name.
+ * @return true if the attribute was declared in the DTD,
+ * false otherwise.
+ * @exception java.lang.IllegalArgumentException When the
+ * supplied names do not identify an attribute.
+ */
+ public boolean isDeclared (String uri, String localName);
+
+ /**
+ * Returns true unless the attribute value was provided
+ * by DTD defaulting.
+ *
+ * @param index The attribute index (zero-based).
+ * @return true if the value was found in the XML text,
+ * false if the value was provided by DTD defaulting.
+ * @exception java.lang.ArrayIndexOutOfBoundsException When the
+ * supplied index does not identify an attribute.
+ */
+ public boolean isSpecified (int index);
+
+ /**
+ * Returns true unless the attribute value was provided
+ * by DTD defaulting.
+ *
+ * <p>Remember that since DTDs do not "understand" namespaces, the
+ * namespace URI associated with an attribute may not have come from
+ * the DTD. The declaration will have applied to the attribute's
+ * <em>qName</em>.
+ *
+ * @param uri The Namespace URI, or the empty string if
+ * the name has no Namespace URI.
+ * @param localName The attribute's local name.
+ * @return true if the value was found in the XML text,
+ * false if the value was provided by DTD defaulting.
+ * @exception java.lang.IllegalArgumentException When the
+ * supplied names do not identify an attribute.
+ */
+ public boolean isSpecified (String uri, String localName);
+
+ /**
+ * Returns true unless the attribute value was provided
+ * by DTD defaulting.
+ *
+ * @param qName The XML qualified (prefixed) name.
+ * @return true if the value was found in the XML text,
+ * false if the value was provided by DTD defaulting.
+ * @exception java.lang.IllegalArgumentException When the
+ * supplied name does not identify an attribute.
+ */
+ public boolean isSpecified (String qName);
+}
diff --git a/xml/src/main/java/org/xml/sax/ext/Attributes2Impl.java b/xml/src/main/java/org/xml/sax/ext/Attributes2Impl.java
new file mode 100644
index 0000000..fc36805
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/ext/Attributes2Impl.java
@@ -0,0 +1,320 @@
+// Attributes2Impl.java - extended AttributesImpl
+// http://www.saxproject.org
+// Public Domain: no warranty.
+// $Id: Attributes2Impl.java,v 1.5 2004/03/08 13:01:01 dmegginson Exp $
+
+package org.xml.sax.ext;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.helpers.AttributesImpl;
+
+
+/**
+ * SAX2 extension helper for additional Attributes information,
+ * implementing the {@link Attributes2} interface.
+ *
+ * <blockquote>
+ * <em>This module, both source code and documentation, is in the
+ * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
+ * </blockquote>
+ *
+ * <p>This is not part of core-only SAX2 distributions.</p>
+ *
+ * <p>The <em>specified</em> flag for each attribute will always
+ * be true, unless it has been set to false in the copy constructor
+ * or using {@link #setSpecified}.
+ * Similarly, the <em>declared</em> flag for each attribute will
+ * always be false, except for defaulted attributes (<em>specified</em>
+ * is false), non-CDATA attributes, or when it is set to true using
+ * {@link #setDeclared}.
+ * If you change an attribute's type by hand, you may need to modify
+ * its <em>declared</em> flag to match.
+ * </p>
+ *
+ * @since SAX 2.0 (extensions 1.1 alpha)
+ * @author David Brownell
+ * @version TBS
+ */
+public class Attributes2Impl extends AttributesImpl implements Attributes2
+{
+ private boolean declared [];
+ private boolean specified [];
+
+
+ /**
+ * Construct a new, empty Attributes2Impl object.
+ */
+ public Attributes2Impl () {
+ // BEGIN android-added
+ declared = new boolean[0];
+ specified = new boolean[0];
+ // END android-added
+ }
+
+
+ /**
+ * Copy an existing Attributes or Attributes2 object.
+ * If the object implements Attributes2, values of the
+ * <em>specified</em> and <em>declared</em> flags for each
+ * attribute are copied.
+ * Otherwise the flag values are defaulted to assume no DTD was used,
+ * unless there is evidence to the contrary (such as attributes with
+ * type other than CDATA, which must have been <em>declared</em>).
+ *
+ * <p>This constructor is especially useful inside a
+ * {@link org.xml.sax.ContentHandler#startElement startElement} event.</p>
+ *
+ * @param atts The existing Attributes object.
+ */
+ public Attributes2Impl (Attributes atts)
+ {
+ super (atts);
+ }
+
+
+ ////////////////////////////////////////////////////////////////////
+ // Implementation of Attributes2
+ ////////////////////////////////////////////////////////////////////
+
+
+ /*
+ * Returns the current value of the attribute's "declared" flag.
+ */
+ // javadoc mostly from interface
+ public boolean isDeclared (int index)
+ {
+ if (index < 0 || index >= getLength ())
+ throw new ArrayIndexOutOfBoundsException (
+ "No attribute at index: " + index);
+ return declared [index];
+ }
+
+
+ /*
+ * Returns the current value of the attribute's "declared" flag.
+ */
+ // javadoc mostly from interface
+ public boolean isDeclared (String uri, String localName)
+ {
+ int index = getIndex (uri, localName);
+
+ if (index < 0)
+ throw new IllegalArgumentException (
+ "No such attribute: local=" + localName
+ + ", namespace=" + uri);
+ return declared [index];
+ }
+
+
+ /*
+ * Returns the current value of the attribute's "declared" flag.
+ */
+ // javadoc mostly from interface
+ public boolean isDeclared (String qName)
+ {
+ int index = getIndex (qName);
+
+ if (index < 0)
+ throw new IllegalArgumentException (
+ "No such attribute: " + qName);
+ return declared [index];
+ }
+
+
+ /**
+ * Returns the current value of an attribute's "specified" flag.
+ *
+ * @param index The attribute index (zero-based).
+ * @return current flag value
+ * @exception java.lang.ArrayIndexOutOfBoundsException When the
+ * supplied index does not identify an attribute.
+ */
+ public boolean isSpecified (int index)
+ {
+ if (index < 0 || index >= getLength ())
+ throw new ArrayIndexOutOfBoundsException (
+ "No attribute at index: " + index);
+ return specified [index];
+ }
+
+
+ /**
+ * Returns the current value of an attribute's "specified" flag.
+ *
+ * @param uri The Namespace URI, or the empty string if
+ * the name has no Namespace URI.
+ * @param localName The attribute's local name.
+ * @return current flag value
+ * @exception java.lang.IllegalArgumentException When the
+ * supplied names do not identify an attribute.
+ */
+ public boolean isSpecified (String uri, String localName)
+ {
+ int index = getIndex (uri, localName);
+
+ if (index < 0)
+ throw new IllegalArgumentException (
+ "No such attribute: local=" + localName
+ + ", namespace=" + uri);
+ return specified [index];
+ }
+
+
+ /**
+ * Returns the current value of an attribute's "specified" flag.
+ *
+ * @param qName The XML qualified (prefixed) name.
+ * @return current flag value
+ * @exception java.lang.IllegalArgumentException When the
+ * supplied name does not identify an attribute.
+ */
+ public boolean isSpecified (String qName)
+ {
+ int index = getIndex (qName);
+
+ if (index < 0)
+ throw new IllegalArgumentException (
+ "No such attribute: " + qName);
+ return specified [index];
+ }
+
+
+ ////////////////////////////////////////////////////////////////////
+ // Manipulators
+ ////////////////////////////////////////////////////////////////////
+
+
+ /**
+ * Copy an entire Attributes object. The "specified" flags are
+ * assigned as true, and "declared" flags as false (except when
+ * an attribute's type is not CDATA),
+ * unless the object is an Attributes2 object.
+ * In that case those flag values are all copied.
+ *
+ * @param atts The attributes to copy.
+ *
+ * @see AttributesImpl#setAttributes
+ */
+ public void setAttributes (Attributes atts)
+ {
+ int length = atts.getLength ();
+
+ super.setAttributes (atts);
+ declared = new boolean [length];
+ specified = new boolean [length];
+
+ if (atts instanceof Attributes2) {
+ Attributes2 a2 = (Attributes2) atts;
+ for (int i = 0; i < length; i++) {
+ declared [i] = a2.isDeclared (i);
+ specified [i] = a2.isSpecified (i);
+ }
+ } else {
+ for (int i = 0; i < length; i++) {
+ declared [i] = !"CDATA".equals (atts.getType (i));
+ specified [i] = true;
+ }
+ }
+ }
+
+
+ /**
+ * Add an attribute to the end of the list, setting its
+ * "specified" flag to true. To set that flag's value
+ * to false, use {@link #setSpecified}.
+ *
+ * <p>Unless the attribute <em>type</em> is CDATA, this attribute
+ * is marked as being declared in the DTD. To set that flag's value
+ * to true for CDATA attributes, use {@link #setDeclared}.
+ *
+ * @param uri The Namespace URI, or the empty string if
+ * none is available or Namespace processing is not
+ * being performed.
+ * @param localName The local name, or the empty string if
+ * Namespace processing is not being performed.
+ * @param qName The qualified (prefixed) name, or the empty string
+ * if qualified names are not available.
+ * @param type The attribute type as a string.
+ * @param value The attribute value.
+ *
+ * @see AttributesImpl#addAttribute
+ */
+ public void addAttribute (String uri, String localName, String qName,
+ String type, String value)
+ {
+ super.addAttribute (uri, localName, qName, type, value);
+
+ int length = getLength ();
+
+ // BEGIN android-changed
+ if (length > specified.length) {
+ // END android-changed
+ boolean newFlags [];
+
+ newFlags = new boolean [length];
+ System.arraycopy (declared, 0, newFlags, 0, declared.length);
+ declared = newFlags;
+
+ newFlags = new boolean [length];
+ System.arraycopy (specified, 0, newFlags, 0, specified.length);
+ specified = newFlags;
+ }
+
+ specified [length - 1] = true;
+ declared [length - 1] = !"CDATA".equals (type);
+ }
+
+
+ // javadoc entirely from superclass
+ public void removeAttribute (int index)
+ {
+ int origMax = getLength () - 1;
+
+ super.removeAttribute (index);
+ if (index != origMax) {
+ System.arraycopy (declared, index + 1, declared, index,
+ origMax - index);
+ System.arraycopy (specified, index + 1, specified, index,
+ origMax - index);
+ }
+ }
+
+
+ /**
+ * Assign a value to the "declared" flag of a specific attribute.
+ * This is normally needed only for attributes of type CDATA,
+ * including attributes whose type is changed to or from CDATA.
+ *
+ * @param index The index of the attribute (zero-based).
+ * @param value The desired flag value.
+ * @exception java.lang.ArrayIndexOutOfBoundsException When the
+ * supplied index does not identify an attribute.
+ * @see #setType
+ */
+ public void setDeclared (int index, boolean value)
+ {
+ if (index < 0 || index >= getLength ())
+ throw new ArrayIndexOutOfBoundsException (
+ "No attribute at index: " + index);
+ declared [index] = value;
+ }
+
+
+ /**
+ * Assign a value to the "specified" flag of a specific attribute.
+ * This is the only way this flag can be cleared, except clearing
+ * by initialization with the copy constructor.
+ *
+ * @param index The index of the attribute (zero-based).
+ * @param value The desired flag value.
+ * @exception java.lang.ArrayIndexOutOfBoundsException When the
+ * supplied index does not identify an attribute.
+ */
+ public void setSpecified (int index, boolean value)
+ {
+ if (index < 0 || index >= getLength ())
+ throw new ArrayIndexOutOfBoundsException (
+ "No attribute at index: " + index);
+ specified [index] = value;
+ }
+}
diff --git a/xml/src/main/java/org/xml/sax/ext/DeclHandler.java b/xml/src/main/java/org/xml/sax/ext/DeclHandler.java
new file mode 100644
index 0000000..26471f3
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/ext/DeclHandler.java
@@ -0,0 +1,146 @@
+// DeclHandler.java - Optional handler for DTD declaration events.
+// http://www.saxproject.org
+// Public Domain: no warranty.
+// $Id: DeclHandler.java,v 1.6 2004/04/22 13:28:49 dmegginson Exp $
+
+package org.xml.sax.ext;
+
+import org.xml.sax.SAXException;
+
+
+/**
+ * SAX2 extension handler for DTD declaration events.
+ *
+ * <blockquote>
+ * <em>This module, both source code and documentation, is in the
+ * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
+ * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
+ * for further information.
+ * </blockquote>
+ *
+ * <p>This is an optional extension handler for SAX2 to provide more
+ * complete information about DTD declarations in an XML document.
+ * XML readers are not required to recognize this handler, and it
+ * is not part of core-only SAX2 distributions.</p>
+ *
+ * <p>Note that data-related DTD declarations (unparsed entities and
+ * notations) are already reported through the {@link
+ * org.xml.sax.DTDHandler DTDHandler} interface.</p>
+ *
+ * <p>If you are using the declaration handler together with a lexical
+ * handler, all of the events will occur between the
+ * {@link org.xml.sax.ext.LexicalHandler#startDTD startDTD} and the
+ * {@link org.xml.sax.ext.LexicalHandler#endDTD endDTD} events.</p>
+ *
+ * <p>To set the DeclHandler for an XML reader, use the
+ * {@link org.xml.sax.XMLReader#setProperty setProperty} method
+ * with the property name
+ * <code>http://xml.org/sax/properties/declaration-handler</code>
+ * and an object implementing this interface (or null) as the value.
+ * If the reader does not report declaration events, it will throw a
+ * {@link org.xml.sax.SAXNotRecognizedException SAXNotRecognizedException}
+ * when you attempt to register the handler.</p>
+ *
+ * @since SAX 2.0 (extensions 1.0)
+ * @author David Megginson
+ * @version 2.0.1 (sax2r2)
+ */
+public interface DeclHandler
+{
+
+ /**
+ * Report an element type declaration.
+ *
+ * <p>The content model will consist of the string "EMPTY", the
+ * string "ANY", or a parenthesised group, optionally followed
+ * by an occurrence indicator. The model will be normalized so
+ * that all parameter entities are fully resolved and all whitespace
+ * is removed,and will include the enclosing parentheses. Other
+ * normalization (such as removing redundant parentheses or
+ * simplifying occurrence indicators) is at the discretion of the
+ * parser.</p>
+ *
+ * @param name The element type name.
+ * @param model The content model as a normalized string.
+ * @exception SAXException The application may raise an exception.
+ */
+ public abstract void elementDecl (String name, String model)
+ throws SAXException;
+
+
+ /**
+ * Report an attribute type declaration.
+ *
+ * <p>Only the effective (first) declaration for an attribute will
+ * be reported. The type will be one of the strings "CDATA",
+ * "ID", "IDREF", "IDREFS", "NMTOKEN", "NMTOKENS", "ENTITY",
+ * "ENTITIES", a parenthesized token group with
+ * the separator "|" and all whitespace removed, or the word
+ * "NOTATION" followed by a space followed by a parenthesized
+ * token group with all whitespace removed.</p>
+ *
+ * <p>The value will be the value as reported to applications,
+ * appropriately normalized and with entity and character
+ * references expanded. </p>
+ *
+ * @param eName The name of the associated element.
+ * @param aName The name of the attribute.
+ * @param type A string representing the attribute type.
+ * @param mode A string representing the attribute defaulting mode
+ * ("#IMPLIED", "#REQUIRED", or "#FIXED") or null if
+ * none of these applies.
+ * @param value A string representing the attribute's default value,
+ * or null if there is none.
+ * @exception SAXException The application may raise an exception.
+ */
+ public abstract void attributeDecl (String eName,
+ String aName,
+ String type,
+ String mode,
+ String value)
+ throws SAXException;
+
+
+ /**
+ * Report an internal entity declaration.
+ *
+ * <p>Only the effective (first) declaration for each entity
+ * will be reported. All parameter entities in the value
+ * will be expanded, but general entities will not.</p>
+ *
+ * @param name The name of the entity. If it is a parameter
+ * entity, the name will begin with '%'.
+ * @param value The replacement text of the entity.
+ * @exception SAXException The application may raise an exception.
+ * @see #externalEntityDecl
+ * @see org.xml.sax.DTDHandler#unparsedEntityDecl
+ */
+ public abstract void internalEntityDecl (String name, String value)
+ throws SAXException;
+
+
+ /**
+ * Report a parsed external entity declaration.
+ *
+ * <p>Only the effective (first) declaration for each entity
+ * will be reported.</p>
+ *
+ * <p>If the system identifier is a URL, the parser must resolve it
+ * fully before passing it to the application.</p>
+ *
+ * @param name The name of the entity. If it is a parameter
+ * entity, the name will begin with '%'.
+ * @param publicId The entity's public identifier, or null if none
+ * was given.
+ * @param systemId The entity's system identifier.
+ * @exception SAXException The application may raise an exception.
+ * @see #internalEntityDecl
+ * @see org.xml.sax.DTDHandler#unparsedEntityDecl
+ */
+ public abstract void externalEntityDecl (String name, String publicId,
+ String systemId)
+ throws SAXException;
+
+}
+
+// end of DeclHandler.java
diff --git a/xml/src/main/java/org/xml/sax/ext/DefaultHandler2.java b/xml/src/main/java/org/xml/sax/ext/DefaultHandler2.java
new file mode 100644
index 0000000..f26564f
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/ext/DefaultHandler2.java
@@ -0,0 +1,185 @@
+// DefaultHandler2.java - extended DefaultHandler
+// http://www.saxproject.org
+// Public Domain: no warranty.
+// $Id: DefaultHandler2.java,v 1.3 2002/01/12 19:04:19 dbrownell Exp $
+
+package org.xml.sax.ext;
+
+import java.io.IOException;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+
+/**
+ * This class extends the SAX2 base handler class to support the
+ * SAX2 {@link LexicalHandler}, {@link DeclHandler}, and
+ * {@link EntityResolver2} extensions. Except for overriding the
+ * original SAX1 {@link DefaultHandler#resolveEntity resolveEntity()}
+ * method the added handler methods just return. Subclassers may
+ * override everything on a method-by-method basis.
+ *
+ * <blockquote>
+ * <em>This module, both source code and documentation, is in the
+ * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
+ * </blockquote>
+ *
+ * <p> <em>Note:</em> this class might yet learn that the
+ * <em>ContentHandler.setDocumentLocator()</em> call might be passed a
+ * {@link Locator2} object, and that the
+ * <em>ContentHandler.startElement()</em> call might be passed a
+ * {@link Attributes2} object.
+ *
+ * @since SAX 2.0 (extensions 1.1 alpha)
+ * @author David Brownell
+ * @version TBS
+ */
+public class DefaultHandler2 extends DefaultHandler
+ implements LexicalHandler, DeclHandler, EntityResolver2
+{
+ /** Constructs a handler which ignores all parsing events. */
+ public DefaultHandler2 () { }
+
+
+ // SAX2 ext-1.0 LexicalHandler
+
+ public void startCDATA ()
+ throws SAXException
+ {}
+
+ public void endCDATA ()
+ throws SAXException
+ {}
+
+ public void startDTD (String name, String publicId, String systemId)
+ throws SAXException
+ {}
+
+ public void endDTD ()
+ throws SAXException
+ {}
+
+ public void startEntity (String name)
+ throws SAXException
+ {}
+
+ public void endEntity (String name)
+ throws SAXException
+ {}
+
+ public void comment (char ch [], int start, int length)
+ throws SAXException
+ { }
+
+
+ // SAX2 ext-1.0 DeclHandler
+
+ public void attributeDecl (String eName, String aName,
+ String type, String mode, String value)
+ throws SAXException
+ {}
+
+ public void elementDecl (String name, String model)
+ throws SAXException
+ {}
+
+ public void externalEntityDecl (String name,
+ String publicId, String systemId)
+ throws SAXException
+ {}
+
+ public void internalEntityDecl (String name, String value)
+ throws SAXException
+ {}
+
+ // SAX2 ext-1.1 EntityResolver2
+
+ /**
+ * Tells the parser that if no external subset has been declared
+ * in the document text, none should be used.
+ *
+ * @param name Identifies the document root element. This name comes
+ * from a DOCTYPE declaration (where available) or from the actual
+ * root element. The parameter is ignored.
+ * @param baseURI The document's base URI, serving as an additional
+ * hint for selecting the external subset. This is always an absolute
+ * URI, unless it is null because the XMLReader was given an InputSource
+ * without one. The parameter is ignored.
+ *
+ * @return null (always).
+ *
+ * @exception SAXException Any SAX exception, possibly wrapping
+ * another exception.
+ * @exception IOException Probably indicating a failure to create
+ * a new InputStream or Reader, or an illegal URL.
+ */
+ public InputSource getExternalSubset (String name, String baseURI)
+ throws SAXException, IOException
+ { return null; }
+
+ /**
+ * Tells the parser to resolve the systemId against the baseURI
+ * and read the entity text from that resulting absolute URI.
+ * Note that because the older
+ * {@link DefaultHandler#resolveEntity DefaultHandler.resolveEntity()},
+ * method is overridden to call this one, this method may sometimes
+ * be invoked with null <em>name</em> and <em>baseURI</em>, and
+ * with the <em>systemId</em> already absolutized.
+ *
+ * @param name Identifies the external entity being resolved.
+ * Either "[dtd]" for the external subset, or a name starting
+ * with "%" to indicate a parameter entity, or else the name of
+ * a general entity. This is never null when invoked by a SAX2
+ * parser.
+ * @param publicId The public identifier of the external entity being
+ * referenced (normalized as required by the XML specification), or
+ * null if none was supplied.
+ * @param baseURI The URI with respect to which relative systemIDs
+ * are interpreted. This is always an absolute URI, unless it is
+ * null (likely because the XMLReader was given an InputSource without
+ * one). This URI is defined by the XML specification to be the one
+ * associated with the "&lt;" starting the relevant declaration.
+ * @param systemId The system identifier of the external entity
+ * being referenced; either a relative or absolute URI.
+ * This is never null when invoked by a SAX2 parser; only declared
+ * entities, and any external subset, are resolved by such parsers.
+ *
+ * @return An InputSource object describing the new input source.
+ *
+ * @exception SAXException Any SAX exception, possibly wrapping
+ * another exception.
+ * @exception IOException Probably indicating a failure to create
+ * a new InputStream or Reader, or an illegal URL.
+ */
+ public InputSource resolveEntity (String name, String publicId,
+ String baseURI, String systemId)
+ throws SAXException, IOException
+ { return null; }
+
+ // SAX1 EntityResolver
+
+ /**
+ * Invokes
+ * {@link EntityResolver2#resolveEntity EntityResolver2.resolveEntity()}
+ * with null entity name and base URI.
+ * You only need to override that method to use this class.
+ *
+ * @param publicId The public identifier of the external entity being
+ * referenced (normalized as required by the XML specification), or
+ * null if none was supplied.
+ * @param systemId The system identifier of the external entity
+ * being referenced; either a relative or absolute URI.
+ * This is never null when invoked by a SAX2 parser; only declared
+ * entities, and any external subset, are resolved by such parsers.
+ *
+ * @return An InputSource object describing the new input source.
+ *
+ * @exception SAXException Any SAX exception, possibly wrapping
+ * another exception.
+ * @exception IOException Probably indicating a failure to create
+ * a new InputStream or Reader, or an illegal URL.
+ */
+ public InputSource resolveEntity (String publicId, String systemId)
+ throws SAXException, IOException
+ { return resolveEntity (null, publicId, null, systemId); }
+}
diff --git a/xml/src/main/java/org/xml/sax/ext/EntityResolver2.java b/xml/src/main/java/org/xml/sax/ext/EntityResolver2.java
new file mode 100644
index 0000000..5437a9b
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/ext/EntityResolver2.java
@@ -0,0 +1,197 @@
+// EntityResolver2.java - Extended SAX entity resolver.
+// http://www.saxproject.org
+// No warranty; no copyright -- use this as you will.
+// $Id: EntityResolver2.java,v 1.2 2002/01/12 19:20:08 dbrownell Exp $
+
+package org.xml.sax.ext;
+
+import java.io.IOException;
+
+import org.xml.sax.EntityResolver;
+import org.xml.sax.InputSource;
+import org.xml.sax.XMLReader;
+import org.xml.sax.SAXException;
+
+
+/**
+ * Extended interface for mapping external entity references to input
+ * sources, or providing a missing external subset. The
+ * {@link XMLReader#setEntityResolver XMLReader.setEntityResolver()} method
+ * is used to provide implementations of this interface to parsers.
+ * When a parser uses the methods in this interface, the
+ * {@link EntityResolver2#resolveEntity EntityResolver2.resolveEntity()}
+ * method (in this interface) is used <em>instead of</em> the older (SAX 1.0)
+ * {@link EntityResolver#resolveEntity EntityResolver.resolveEntity()} method.
+ *
+ * <blockquote>
+ * <em>This module, both source code and documentation, is in the
+ * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
+ * </blockquote>
+ *
+ * <p>If a SAX application requires the customized handling which this
+ * interface defines for external entities, it must ensure that it uses
+ * an XMLReader with the
+ * <em>http://xml.org/sax/features/use-entity-resolver2</em> feature flag
+ * set to <em>true</em> (which is its default value when the feature is
+ * recognized). If that flag is unrecognized, or its value is false,
+ * or the resolver does not implement this interface, then only the
+ * {@link EntityResolver} method will be used.
+ * </p>
+ *
+ * <p>That supports three categories of application that modify entity
+ * resolution. <em>Old Style</em> applications won't know about this interface;
+ * they will provide an EntityResolver.
+ * <em>Transitional Mode</em> provide an EntityResolver2 and automatically
+ * get the benefit of its methods in any systems (parsers or other tools)
+ * supporting it, due to polymorphism.
+ * Both <em>Old Style</em> and <em>Transitional Mode</em> applications will
+ * work with any SAX2 parser.
+ * <em>New style</em> applications will fail to run except on SAX2 parsers
+ * that support this particular feature.
+ * They will insist that feature flag have a value of "true", and the
+ * EntityResolver2 implementation they provide might throw an exception
+ * if the original SAX 1.0 style entity resolution method is invoked.
+ * </p>
+ *
+ * @see org.xml.sax.XMLReader#setEntityResolver
+ *
+ * @since SAX 2.0 (extensions 1.1 alpha)
+ * @author David Brownell
+ * @version TBD
+ */
+public interface EntityResolver2 extends EntityResolver
+{
+ /**
+ * Allows applications to provide an external subset for documents
+ * that don't explicitly define one. Documents with DOCTYPE declarations
+ * that omit an external subset can thus augment the declarations
+ * available for validation, entity processing, and attribute processing
+ * (normalization, defaulting, and reporting types including ID).
+ * This augmentation is reported
+ * through the {@link LexicalHandler#startDTD startDTD()} method as if
+ * the document text had originally included the external subset;
+ * this callback is made before any internal subset data or errors
+ * are reported.</p>
+ *
+ * <p>This method can also be used with documents that have no DOCTYPE
+ * declaration. When the root element is encountered,
+ * but no DOCTYPE declaration has been seen, this method is
+ * invoked. If it returns a value for the external subset, that root
+ * element is declared to be the root element, giving the effect of
+ * splicing a DOCTYPE declaration at the end the prolog of a document
+ * that could not otherwise be valid. The sequence of parser callbacks
+ * in that case logically resembles this:</p>
+ *
+ * <pre>
+ * ... comments and PIs from the prolog (as usual)
+ * startDTD ("rootName", source.getPublicId (), source.getSystemId ());
+ * startEntity ("[dtd]");
+ * ... declarations, comments, and PIs from the external subset
+ * endEntity ("[dtd]");
+ * endDTD ();
+ * ... then the rest of the document (as usual)
+ * startElement (..., "rootName", ...);
+ * </pre>
+ *
+ * <p>Note that the InputSource gets no further resolution.
+ * Implementations of this method may wish to invoke
+ * {@link #resolveEntity resolveEntity()} to gain benefits such as use
+ * of local caches of DTD entities. Also, this method will never be
+ * used by a (non-validating) processor that is not including external
+ * parameter entities. </p>
+ *
+ * <p>Uses for this method include facilitating data validation when
+ * interoperating with XML processors that would always require
+ * undesirable network accesses for external entities, or which for
+ * other reasons adopt a "no DTDs" policy.
+ * Non-validation motives include forcing documents to include DTDs so
+ * that attributes are handled consistently.
+ * For example, an XPath processor needs to know which attibutes have
+ * type "ID" before it can process a widely used type of reference.</p>
+ *
+ * <p><strong>Warning:</strong> Returning an external subset modifies
+ * the input document. By providing definitions for general entities,
+ * it can make a malformed document appear to be well formed.
+ * </p>
+ *
+ * @param name Identifies the document root element. This name comes
+ * from a DOCTYPE declaration (where available) or from the actual
+ * root element.
+ * @param baseURI The document's base URI, serving as an additional
+ * hint for selecting the external subset. This is always an absolute
+ * URI, unless it is null because the XMLReader was given an InputSource
+ * without one.
+ *
+ * @return An InputSource object describing the new external subset
+ * to be used by the parser, or null to indicate that no external
+ * subset is provided.
+ *
+ * @exception SAXException Any SAX exception, possibly wrapping
+ * another exception.
+ * @exception IOException Probably indicating a failure to create
+ * a new InputStream or Reader, or an illegal URL.
+ */
+ public InputSource getExternalSubset (String name, String baseURI)
+ throws SAXException, IOException;
+
+ /**
+ * Allows applications to map references to external entities into input
+ * sources, or tell the parser it should use conventional URI resolution.
+ * This method is only called for external entities which have been
+ * properly declared.
+ * This method provides more flexibility than the {@link EntityResolver}
+ * interface, supporting implementations of more complex catalogue
+ * schemes such as the one defined by the <a href=
+ "http://www.oasis-open.org/committees/entity/spec-2001-08-06.html"
+ >OASIS XML Catalogs</a> specification.</p>
+ *
+ * <p>Parsers configured to use this resolver method will call it
+ * to determine the input source to use for any external entity
+ * being included because of a reference in the XML text.
+ * That excludes the document entity, and any external entity returned
+ * by {@link #getExternalSubset getExternalSubset()}.
+ * When a (non-validating) processor is configured not to include
+ * a class of entities (parameter or general) through use of feature
+ * flags, this method is not invoked for such entities. </p>
+ *
+ * <p>Note that the entity naming scheme used here is the same one
+ * used in the {@link LexicalHandler}, or in the {@link
+ org.xml.sax.ContentHandler#skippedEntity
+ ContentHandler.skippedEntity()}
+ * method. </p>
+ *
+ * @param name Identifies the external entity being resolved.
+ * Either "[dtd]" for the external subset, or a name starting
+ * with "%" to indicate a parameter entity, or else the name of
+ * a general entity. This is never null when invoked by a SAX2
+ * parser.
+ * @param publicId The public identifier of the external entity being
+ * referenced (normalized as required by the XML specification), or
+ * null if none was supplied.
+ * @param baseURI The URI with respect to which relative systemIDs
+ * are interpreted. This is always an absolute URI, unless it is
+ * null (likely because the XMLReader was given an InputSource without
+ * one). This URI is defined by the XML specification to be the one
+ * associated with the "&lt;" starting the relevant declaration.
+ * @param systemId The system identifier of the external entity
+ * being referenced; either a relative or absolute URI.
+ * This is never null when invoked by a SAX2 parser; only declared
+ * entities, and any external subset, are resolved by such parsers.
+ *
+ * @return An InputSource object describing the new input source to
+ * be used by the parser. Returning null directs the parser to
+ * resolve the system ID against the base URI and open a connection
+ * to resulting URI.
+ *
+ * @exception SAXException Any SAX exception, possibly wrapping
+ * another exception.
+ * @exception IOException Probably indicating a failure to create
+ * a new InputStream or Reader, or an illegal URL.
+ */
+ public InputSource resolveEntity (
+ String name,
+ String publicId,
+ String baseURI,
+ String systemId
+ ) throws SAXException, IOException;
+}
diff --git a/xml/src/main/java/org/xml/sax/ext/LexicalHandler.java b/xml/src/main/java/org/xml/sax/ext/LexicalHandler.java
new file mode 100644
index 0000000..e551b61
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/ext/LexicalHandler.java
@@ -0,0 +1,212 @@
+// LexicalHandler.java - optional handler for lexical parse events.
+// http://www.saxproject.org
+// Public Domain: no warranty.
+// $Id: LexicalHandler.java,v 1.5 2002/01/30 21:00:44 dbrownell Exp $
+
+package org.xml.sax.ext;
+
+import org.xml.sax.SAXException;
+
+/**
+ * SAX2 extension handler for lexical events.
+ *
+ * <blockquote>
+ * <em>This module, both source code and documentation, is in the
+ * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
+ * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
+ * for further information.
+ * </blockquote>
+ *
+ * <p>This is an optional extension handler for SAX2 to provide
+ * lexical information about an XML document, such as comments
+ * and CDATA section boundaries.
+ * XML readers are not required to recognize this handler, and it
+ * is not part of core-only SAX2 distributions.</p>
+ *
+ * <p>The events in the lexical handler apply to the entire document,
+ * not just to the document element, and all lexical handler events
+ * must appear between the content handler's startDocument and
+ * endDocument events.</p>
+ *
+ * <p>To set the LexicalHandler for an XML reader, use the
+ * {@link org.xml.sax.XMLReader#setProperty setProperty} method
+ * with the property name
+ * <code>http://xml.org/sax/properties/lexical-handler</code>
+ * and an object implementing this interface (or null) as the value.
+ * If the reader does not report lexical events, it will throw a
+ * {@link org.xml.sax.SAXNotRecognizedException SAXNotRecognizedException}
+ * when you attempt to register the handler.</p>
+ *
+ * @since SAX 2.0 (extensions 1.0)
+ * @author David Megginson
+ * @version 2.0.1 (sax2r2)
+ */
+public interface LexicalHandler
+{
+
+ /**
+ * Report the start of DTD declarations, if any.
+ *
+ * <p>This method is intended to report the beginning of the
+ * DOCTYPE declaration; if the document has no DOCTYPE declaration,
+ * this method will not be invoked.</p>
+ *
+ * <p>All declarations reported through
+ * {@link org.xml.sax.DTDHandler DTDHandler} or
+ * {@link org.xml.sax.ext.DeclHandler DeclHandler} events must appear
+ * between the startDTD and {@link #endDTD endDTD} events.
+ * Declarations are assumed to belong to the internal DTD subset
+ * unless they appear between {@link #startEntity startEntity}
+ * and {@link #endEntity endEntity} events. Comments and
+ * processing instructions from the DTD should also be reported
+ * between the startDTD and endDTD events, in their original
+ * order of (logical) occurrence; they are not required to
+ * appear in their correct locations relative to DTDHandler
+ * or DeclHandler events, however.</p>
+ *
+ * <p>Note that the start/endDTD events will appear within
+ * the start/endDocument events from ContentHandler and
+ * before the first
+ * {@link org.xml.sax.ContentHandler#startElement startElement}
+ * event.</p>
+ *
+ * @param name The document type name.
+ * @param publicId The declared public identifier for the
+ * external DTD subset, or null if none was declared.
+ * @param systemId The declared system identifier for the
+ * external DTD subset, or null if none was declared.
+ * (Note that this is not resolved against the document
+ * base URI.)
+ * @exception SAXException The application may raise an
+ * exception.
+ * @see #endDTD
+ * @see #startEntity
+ */
+ public abstract void startDTD (String name, String publicId,
+ String systemId)
+ throws SAXException;
+
+
+ /**
+ * Report the end of DTD declarations.
+ *
+ * <p>This method is intended to report the end of the
+ * DOCTYPE declaration; if the document has no DOCTYPE declaration,
+ * this method will not be invoked.</p>
+ *
+ * @exception SAXException The application may raise an exception.
+ * @see #startDTD
+ */
+ public abstract void endDTD ()
+ throws SAXException;
+
+
+ /**
+ * Report the beginning of some internal and external XML entities.
+ *
+ * <p>The reporting of parameter entities (including
+ * the external DTD subset) is optional, and SAX2 drivers that
+ * report LexicalHandler events may not implement it; you can use the
+ * <code
+ * >http://xml.org/sax/features/lexical-handler/parameter-entities</code>
+ * feature to query or control the reporting of parameter entities.</p>
+ *
+ * <p>General entities are reported with their regular names,
+ * parameter entities have '%' prepended to their names, and
+ * the external DTD subset has the pseudo-entity name "[dtd]".</p>
+ *
+ * <p>When a SAX2 driver is providing these events, all other
+ * events must be properly nested within start/end entity
+ * events. There is no additional requirement that events from
+ * {@link org.xml.sax.ext.DeclHandler DeclHandler} or
+ * {@link org.xml.sax.DTDHandler DTDHandler} be properly ordered.</p>
+ *
+ * <p>Note that skipped entities will be reported through the
+ * {@link org.xml.sax.ContentHandler#skippedEntity skippedEntity}
+ * event, which is part of the ContentHandler interface.</p>
+ *
+ * <p>Because of the streaming event model that SAX uses, some
+ * entity boundaries cannot be reported under any
+ * circumstances:</p>
+ *
+ * <ul>
+ * <li>general entities within attribute values</li>
+ * <li>parameter entities within declarations</li>
+ * </ul>
+ *
+ * <p>These will be silently expanded, with no indication of where
+ * the original entity boundaries were.</p>
+ *
+ * <p>Note also that the boundaries of character references (which
+ * are not really entities anyway) are not reported.</p>
+ *
+ * <p>All start/endEntity events must be properly nested.
+ *
+ * @param name The name of the entity. If it is a parameter
+ * entity, the name will begin with '%', and if it is the
+ * external DTD subset, it will be "[dtd]".
+ * @exception SAXException The application may raise an exception.
+ * @see #endEntity
+ * @see org.xml.sax.ext.DeclHandler#internalEntityDecl
+ * @see org.xml.sax.ext.DeclHandler#externalEntityDecl
+ */
+ public abstract void startEntity (String name)
+ throws SAXException;
+
+
+ /**
+ * Report the end of an entity.
+ *
+ * @param name The name of the entity that is ending.
+ * @exception SAXException The application may raise an exception.
+ * @see #startEntity
+ */
+ public abstract void endEntity (String name)
+ throws SAXException;
+
+
+ /**
+ * Report the start of a CDATA section.
+ *
+ * <p>The contents of the CDATA section will be reported through
+ * the regular {@link org.xml.sax.ContentHandler#characters
+ * characters} event; this event is intended only to report
+ * the boundary.</p>
+ *
+ * @exception SAXException The application may raise an exception.
+ * @see #endCDATA
+ */
+ public abstract void startCDATA ()
+ throws SAXException;
+
+
+ /**
+ * Report the end of a CDATA section.
+ *
+ * @exception SAXException The application may raise an exception.
+ * @see #startCDATA
+ */
+ public abstract void endCDATA ()
+ throws SAXException;
+
+
+ /**
+ * Report an XML comment anywhere in the document.
+ *
+ * <p>This callback will be used for comments inside or outside the
+ * document element, including comments in the external DTD
+ * subset (if read). Comments in the DTD must be properly
+ * nested inside start/endDTD and start/endEntity events (if
+ * used).</p>
+ *
+ * @param ch An array holding the characters in the comment.
+ * @param start The starting position in the array.
+ * @param length The number of characters to use from the array.
+ * @exception SAXException The application may raise an exception.
+ */
+ public abstract void comment (char ch[], int start, int length)
+ throws SAXException;
+
+}
+
+// end of LexicalHandler.java
diff --git a/xml/src/main/java/org/xml/sax/ext/Locator2.java b/xml/src/main/java/org/xml/sax/ext/Locator2.java
new file mode 100644
index 0000000..6de9a16
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/ext/Locator2.java
@@ -0,0 +1,75 @@
+// Locator2.java - extended Locator
+// http://www.saxproject.org
+// Public Domain: no warranty.
+// $Id: Locator2.java,v 1.5 2004/03/17 14:30:10 dmegginson Exp $
+
+package org.xml.sax.ext;
+
+import org.xml.sax.Locator;
+
+
+/**
+ * SAX2 extension to augment the entity information provided
+ * though a {@link Locator}.
+ * If an implementation supports this extension, the Locator
+ * provided in {@link org.xml.sax.ContentHandler#setDocumentLocator
+ * ContentHandler.setDocumentLocator() } will implement this
+ * interface, and the
+ * <em>http://xml.org/sax/features/use-locator2</em> feature
+ * flag will have the value <em>true</em>.
+ *
+ * <blockquote>
+ * <em>This module, both source code and documentation, is in the
+ * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
+ * </blockquote>
+ *
+ * <p> XMLReader implementations are not required to support this
+ * information, and it is not part of core-only SAX2 distributions.</p>
+ *
+ * @since SAX 2.0 (extensions 1.1 alpha)
+ * @author David Brownell
+ * @version TBS
+ */
+public interface Locator2 extends Locator
+{
+ /**
+ * Returns the version of XML used for the entity. This will
+ * normally be the identifier from the current entity's
+ * <em>&lt;?xml&nbsp;version='...'&nbsp;...?&gt;</em> declaration,
+ * or be defaulted by the parser.
+ *
+ * @return Identifier for the XML version being used to interpret
+ * the entity's text, or null if that information is not yet
+ * available in the current parsing state.
+ */
+ public String getXMLVersion ();
+
+ /**
+ * Returns the name of the character encoding for the entity.
+ * If the encoding was declared externally (for example, in a MIME
+ * Content-Type header), that will be the name returned. Else if there
+ * was an <em>&lt;?xml&nbsp;...encoding='...'?&gt;</em> declaration at
+ * the start of the document, that encoding name will be returned.
+ * Otherwise the encoding will been inferred (normally to be UTF-8, or
+ * some UTF-16 variant), and that inferred name will be returned.
+ *
+ * <p>When an {@link org.xml.sax.InputSource InputSource} is used
+ * to provide an entity's character stream, this method returns the
+ * encoding provided in that input stream.
+ *
+ * <p> Note that some recent W3C specifications require that text
+ * in some encodings be normalized, using Unicode Normalization
+ * Form C, before processing. Such normalization must be performed
+ * by applications, and would normally be triggered based on the
+ * value returned by this method.
+ *
+ * <p> Encoding names may be those used by the underlying JVM,
+ * and comparisons should be case-insensitive.
+ *
+ * @return Name of the character encoding being used to interpret
+ * * the entity's text, or null if this was not provided for a *
+ * character stream passed through an InputSource or is otherwise
+ * not yet available in the current parsing state.
+ */
+ public String getEncoding ();
+}
diff --git a/xml/src/main/java/org/xml/sax/ext/Locator2Impl.java b/xml/src/main/java/org/xml/sax/ext/Locator2Impl.java
new file mode 100644
index 0000000..91f912a
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/ext/Locator2Impl.java
@@ -0,0 +1,105 @@
+// Locator2Impl.java - extended LocatorImpl
+// http://www.saxproject.org
+// Public Domain: no warranty.
+// $Id: Locator2Impl.java,v 1.3 2004/04/26 17:34:35 dmegginson Exp $
+
+package org.xml.sax.ext;
+
+import org.xml.sax.Locator;
+import org.xml.sax.helpers.LocatorImpl;
+
+
+/**
+ * SAX2 extension helper for holding additional Entity information,
+ * implementing the {@link Locator2} interface.
+ *
+ * <blockquote>
+ * <em>This module, both source code and documentation, is in the
+ * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
+ * </blockquote>
+ *
+ * <p> This is not part of core-only SAX2 distributions.</p>
+ *
+ * @since SAX 2.0.2
+ * @author David Brownell
+ * @version TBS
+ */
+public class Locator2Impl extends LocatorImpl implements Locator2
+{
+ private String encoding;
+ private String version;
+
+
+ /**
+ * Construct a new, empty Locator2Impl object.
+ * This will not normally be useful, since the main purpose
+ * of this class is to make a snapshot of an existing Locator.
+ */
+ public Locator2Impl () { }
+
+ /**
+ * Copy an existing Locator or Locator2 object.
+ * If the object implements Locator2, values of the
+ * <em>encoding</em> and <em>version</em>strings are copied,
+ * otherwise they set to <em>null</em>.
+ *
+ * @param locator The existing Locator object.
+ */
+ public Locator2Impl (Locator locator)
+ {
+ super (locator);
+ if (locator instanceof Locator2) {
+ Locator2 l2 = (Locator2) locator;
+
+ version = l2.getXMLVersion ();
+ encoding = l2.getEncoding ();
+ }
+ }
+
+ ////////////////////////////////////////////////////////////////////
+ // Locator2 method implementations
+ ////////////////////////////////////////////////////////////////////
+
+ /**
+ * Returns the current value of the version property.
+ *
+ * @return the current value of the version property.
+ *
+ * @see #setXMLVersion
+ */
+ public String getXMLVersion ()
+ { return version; }
+
+ /**
+ * Returns the current value of the encoding property.
+ *
+ * @return the current value of the encoding property.
+ *
+ * @see #setEncoding
+ */
+ public String getEncoding ()
+ { return encoding; }
+
+
+ ////////////////////////////////////////////////////////////////////
+ // Setters
+ ////////////////////////////////////////////////////////////////////
+
+ /**
+ * Assigns the current value of the version property.
+ *
+ * @param version the new "version" value
+ * @see #getXMLVersion
+ */
+ public void setXMLVersion (String version)
+ { this.version = version; }
+
+ /**
+ * Assigns the current value of the encoding property.
+ *
+ * @param encoding the new "encoding" value
+ * @see #getEncoding
+ */
+ public void setEncoding (String encoding)
+ { this.encoding = encoding; }
+}
diff --git a/xml/src/main/java/org/xml/sax/ext/package.html b/xml/src/main/java/org/xml/sax/ext/package.html
new file mode 100644
index 0000000..9b79d77
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/ext/package.html
@@ -0,0 +1,48 @@
+<HTML><HEAD>
+<!-- $Id: package.html,v 1.8 2002/01/30 21:00:44 dbrownell Exp $ -->
+</HEAD><BODY>
+
+<p>
+This package contains interfaces to SAX2 facilities that
+conformant SAX drivers won't necessarily support.
+
+<p>See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
+for more information about SAX.</p>
+
+<p> This package is independent of the SAX2 core, though the functionality
+exposed generally needs to be implemented within a parser core.
+That independence has several consequences:</p>
+
+<ul>
+
+<li>SAX2 drivers are <em>not</em> required to recognize these handlers.
+</li>
+
+<li>You cannot assume that the class files will be present in every SAX2
+installation.</li>
+
+<li>This package may be updated independently of SAX2 (i.e. new
+handlers and classes may be added without updating SAX2 itself).</li>
+
+<li>The new handlers are not implemented by the SAX2
+<code>org.xml.sax.helpers.DefaultHandler</code> or
+<code>org.xml.sax.helpers.XMLFilterImpl</code> classes.
+You can subclass these if you need such behavior, or
+use the helper classes found here.</li>
+
+<li>The handlers need to be registered differently than core SAX2
+handlers.</li>
+
+</ul>
+
+<p>This package, SAX2-ext, is a standardized extension to SAX2. It is
+designed both to allow SAX parsers to pass certain types of information
+to applications, and to serve as a simple model for other SAX2 parser
+extension packages. Not all such extension packages should need to
+be recognized directly by parsers, however.
+As an example, most validation systems can be cleanly layered on top
+of parsers supporting the standardized SAX2 interfaces. </p>
+
+@since Android 1.0
+
+</BODY></HTML>
diff --git a/xml/src/main/java/org/xml/sax/helpers/AttributeListImpl.java b/xml/src/main/java/org/xml/sax/helpers/AttributeListImpl.java
new file mode 100644
index 0000000..fb4aee3
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/helpers/AttributeListImpl.java
@@ -0,0 +1,314 @@
+// SAX default implementation for AttributeList.
+// http://www.saxproject.org
+// No warranty; no copyright -- use this as you will.
+// $Id: AttributeListImpl.java,v 1.6 2002/01/30 20:52:22 dbrownell Exp $
+
+package org.xml.sax.helpers;
+
+import org.xml.sax.AttributeList;
+
+import java.util.Vector;
+
+
+/**
+ * Default implementation for AttributeList.
+ *
+ * <blockquote>
+ * <em>This module, both source code and documentation, is in the
+ * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
+ * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
+ * for further information.
+ * </blockquote>
+ *
+ * <p>AttributeList implements the deprecated SAX1 {@link
+ * org.xml.sax.AttributeList AttributeList} interface, and has been
+ * replaced by the new SAX2 {@link org.xml.sax.helpers.AttributesImpl
+ * AttributesImpl} interface.</p>
+ *
+ * <p>This class provides a convenience implementation of the SAX
+ * {@link org.xml.sax.AttributeList AttributeList} interface. This
+ * implementation is useful both for SAX parser writers, who can use
+ * it to provide attributes to the application, and for SAX application
+ * writers, who can use it to create a persistent copy of an element's
+ * attribute specifications:</p>
+ *
+ * <pre>
+ * private AttributeList myatts;
+ *
+ * public void startElement (String name, AttributeList atts)
+ * {
+ * // create a persistent copy of the attribute list
+ * // for use outside this method
+ * myatts = new AttributeListImpl(atts);
+ * [...]
+ * }
+ * </pre>
+ *
+ * <p>Please note that SAX parsers are not required to use this
+ * class to provide an implementation of AttributeList; it is
+ * supplied only as an optional convenience. In particular,
+ * parser writers are encouraged to invent more efficient
+ * implementations.</p>
+ *
+ * @deprecated This class implements a deprecated interface,
+ * {@link org.xml.sax.AttributeList AttributeList};
+ * that interface has been replaced by
+ * {@link org.xml.sax.Attributes Attributes},
+ * which is implemented in the
+ * {@link org.xml.sax.helpers.AttributesImpl
+ * AttributesImpl} helper class.
+ * @since SAX 1.0
+ * @author David Megginson
+ * @version 2.0.1 (sax2r2)
+ * @see org.xml.sax.AttributeList
+ * @see org.xml.sax.DocumentHandler#startElement
+ */
+public class AttributeListImpl implements AttributeList
+{
+
+ /**
+ * Create an empty attribute list.
+ *
+ * <p>This constructor is most useful for parser writers, who
+ * will use it to create a single, reusable attribute list that
+ * can be reset with the clear method between elements.</p>
+ *
+ * @see #addAttribute
+ * @see #clear
+ */
+ public AttributeListImpl ()
+ {
+ }
+
+
+ /**
+ * Construct a persistent copy of an existing attribute list.
+ *
+ * <p>This constructor is most useful for application writers,
+ * who will use it to create a persistent copy of an existing
+ * attribute list.</p>
+ *
+ * @param atts The attribute list to copy
+ * @see org.xml.sax.DocumentHandler#startElement
+ */
+ public AttributeListImpl (AttributeList atts)
+ {
+ setAttributeList(atts);
+ }
+
+
+
+ ////////////////////////////////////////////////////////////////////
+ // Methods specific to this class.
+ ////////////////////////////////////////////////////////////////////
+
+
+ /**
+ * Set the attribute list, discarding previous contents.
+ *
+ * <p>This method allows an application writer to reuse an
+ * attribute list easily.</p>
+ *
+ * @param atts The attribute list to copy.
+ */
+ public void setAttributeList (AttributeList atts)
+ {
+ int count = atts.getLength();
+
+ clear();
+
+ for (int i = 0; i < count; i++) {
+ addAttribute(atts.getName(i), atts.getType(i), atts.getValue(i));
+ }
+ }
+
+
+ /**
+ * Add an attribute to an attribute list.
+ *
+ * <p>This method is provided for SAX parser writers, to allow them
+ * to build up an attribute list incrementally before delivering
+ * it to the application.</p>
+ *
+ * @param name The attribute name.
+ * @param type The attribute type ("NMTOKEN" for an enumeration).
+ * @param value The attribute value (must not be null).
+ * @see #removeAttribute
+ * @see org.xml.sax.DocumentHandler#startElement
+ */
+ public void addAttribute (String name, String type, String value)
+ {
+ names.addElement(name);
+ types.addElement(type);
+ values.addElement(value);
+ }
+
+
+ /**
+ * Remove an attribute from the list.
+ *
+ * <p>SAX application writers can use this method to filter an
+ * attribute out of an AttributeList. Note that invoking this
+ * method will change the length of the attribute list and
+ * some of the attribute's indices.</p>
+ *
+ * <p>If the requested attribute is not in the list, this is
+ * a no-op.</p>
+ *
+ * @param name The attribute name.
+ * @see #addAttribute
+ */
+ public void removeAttribute (String name)
+ {
+ int i = names.indexOf(name);
+
+ if (i >= 0) {
+ names.removeElementAt(i);
+ types.removeElementAt(i);
+ values.removeElementAt(i);
+ }
+ }
+
+
+ /**
+ * Clear the attribute list.
+ *
+ * <p>SAX parser writers can use this method to reset the attribute
+ * list between DocumentHandler.startElement events. Normally,
+ * it will make sense to reuse the same AttributeListImpl object
+ * rather than allocating a new one each time.</p>
+ *
+ * @see org.xml.sax.DocumentHandler#startElement
+ */
+ public void clear ()
+ {
+ names.removeAllElements();
+ types.removeAllElements();
+ values.removeAllElements();
+ }
+
+
+
+ ////////////////////////////////////////////////////////////////////
+ // Implementation of org.xml.sax.AttributeList
+ ////////////////////////////////////////////////////////////////////
+
+
+ /**
+ * Return the number of attributes in the list.
+ *
+ * @return The number of attributes in the list.
+ * @see org.xml.sax.AttributeList#getLength
+ */
+ public int getLength ()
+ {
+ return names.size();
+ }
+
+
+ /**
+ * Get the name of an attribute (by position).
+ *
+ * @param i The position of the attribute in the list.
+ * @return The attribute name as a string, or null if there
+ * is no attribute at that position.
+ * @see org.xml.sax.AttributeList#getName(int)
+ */
+ public String getName (int i)
+ {
+ if (i < 0) {
+ return null;
+ }
+ try {
+ return (String)names.elementAt(i);
+ } catch (ArrayIndexOutOfBoundsException e) {
+ return null;
+ }
+ }
+
+
+ /**
+ * Get the type of an attribute (by position).
+ *
+ * @param i The position of the attribute in the list.
+ * @return The attribute type as a string ("NMTOKEN" for an
+ * enumeration, and "CDATA" if no declaration was
+ * read), or null if there is no attribute at
+ * that position.
+ * @see org.xml.sax.AttributeList#getType(int)
+ */
+ public String getType (int i)
+ {
+ if (i < 0) {
+ return null;
+ }
+ try {
+ return (String)types.elementAt(i);
+ } catch (ArrayIndexOutOfBoundsException e) {
+ return null;
+ }
+ }
+
+
+ /**
+ * Get the value of an attribute (by position).
+ *
+ * @param i The position of the attribute in the list.
+ * @return The attribute value as a string, or null if
+ * there is no attribute at that position.
+ * @see org.xml.sax.AttributeList#getValue(int)
+ */
+ public String getValue (int i)
+ {
+ if (i < 0) {
+ return null;
+ }
+ try {
+ return (String)values.elementAt(i);
+ } catch (ArrayIndexOutOfBoundsException e) {
+ return null;
+ }
+ }
+
+
+ /**
+ * Get the type of an attribute (by name).
+ *
+ * @param name The attribute name.
+ * @return The attribute type as a string ("NMTOKEN" for an
+ * enumeration, and "CDATA" if no declaration was
+ * read).
+ * @see org.xml.sax.AttributeList#getType(java.lang.String)
+ */
+ public String getType (String name)
+ {
+ return getType(names.indexOf(name));
+ }
+
+
+ /**
+ * Get the value of an attribute (by name).
+ *
+ * @param name The attribute name.
+ * @return the named attribute's value or null, if the attribute does not
+ * exist.
+ * @see org.xml.sax.AttributeList#getValue(java.lang.String)
+ */
+ public String getValue (String name)
+ {
+ return getValue(names.indexOf(name));
+ }
+
+
+
+ ////////////////////////////////////////////////////////////////////
+ // Internal state.
+ ////////////////////////////////////////////////////////////////////
+
+ Vector names = new Vector();
+ Vector types = new Vector();
+ Vector values = new Vector();
+
+}
+
+// end of AttributeListImpl.java
diff --git a/xml/src/main/java/org/xml/sax/helpers/AttributesImpl.java b/xml/src/main/java/org/xml/sax/helpers/AttributesImpl.java
new file mode 100644
index 0000000..b740e23
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/helpers/AttributesImpl.java
@@ -0,0 +1,618 @@
+// AttributesImpl.java - default implementation of Attributes.
+// http://www.saxproject.org
+// Written by David Megginson
+// NO WARRANTY! This class is in the public domain.
+// $Id: AttributesImpl.java,v 1.9 2002/01/30 20:52:24 dbrownell Exp $
+
+package org.xml.sax.helpers;
+
+import org.xml.sax.Attributes;
+
+
+/**
+ * Default implementation of the Attributes interface.
+ *
+ * <blockquote>
+ * <em>This module, both source code and documentation, is in the
+ * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
+ * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
+ * for further information.
+ * </blockquote>
+ *
+ * <p>This class provides a default implementation of the SAX2
+ * {@link org.xml.sax.Attributes Attributes} interface, with the
+ * addition of manipulators so that the list can be modified or
+ * reused.</p>
+ *
+ * <p>There are two typical uses of this class:</p>
+ *
+ * <ol>
+ * <li>to take a persistent snapshot of an Attributes object
+ * in a {@link org.xml.sax.ContentHandler#startElement startElement} event; or</li>
+ * <li>to construct or modify an Attributes object in a SAX2 driver or filter.</li>
+ * </ol>
+ *
+ * <p>This class replaces the now-deprecated SAX1 {@link
+ * org.xml.sax.helpers.AttributeListImpl AttributeListImpl}
+ * class; in addition to supporting the updated Attributes
+ * interface rather than the deprecated {@link org.xml.sax.AttributeList
+ * AttributeList} interface, it also includes a much more efficient
+ * implementation using a single array rather than a set of Vectors.</p>
+ *
+ * @since SAX 2.0
+ * @author David Megginson
+ * @version 2.0.1 (sax2r2)
+ */
+public class AttributesImpl implements Attributes
+{
+
+
+ ////////////////////////////////////////////////////////////////////
+ // Constructors.
+ ////////////////////////////////////////////////////////////////////
+
+
+ /**
+ * Construct a new, empty AttributesImpl object.
+ */
+ public AttributesImpl ()
+ {
+ length = 0;
+ data = null;
+ }
+
+
+ /**
+ * Copy an existing Attributes object.
+ *
+ * <p>This constructor is especially useful inside a
+ * {@link org.xml.sax.ContentHandler#startElement startElement} event.</p>
+ *
+ * @param atts The existing Attributes object.
+ */
+ public AttributesImpl (Attributes atts)
+ {
+ setAttributes(atts);
+ }
+
+
+
+ ////////////////////////////////////////////////////////////////////
+ // Implementation of org.xml.sax.Attributes.
+ ////////////////////////////////////////////////////////////////////
+
+
+ /**
+ * Return the number of attributes in the list.
+ *
+ * @return The number of attributes in the list.
+ * @see org.xml.sax.Attributes#getLength
+ */
+ public int getLength ()
+ {
+ return length;
+ }
+
+
+ /**
+ * Return an attribute's Namespace URI.
+ *
+ * @param index The attribute's index (zero-based).
+ * @return The Namespace URI, the empty string if none is
+ * available, or null if the index is out of range.
+ * @see org.xml.sax.Attributes#getURI
+ */
+ public String getURI (int index)
+ {
+ if (index >= 0 && index < length) {
+ return data[index*5];
+ } else {
+ return null;
+ }
+ }
+
+
+ /**
+ * Return an attribute's local name.
+ *
+ * @param index The attribute's index (zero-based).
+ * @return The attribute's local name, the empty string if
+ * none is available, or null if the index if out of range.
+ * @see org.xml.sax.Attributes#getLocalName
+ */
+ public String getLocalName (int index)
+ {
+ if (index >= 0 && index < length) {
+ return data[index*5+1];
+ } else {
+ return null;
+ }
+ }
+
+
+ /**
+ * Return an attribute's qualified (prefixed) name.
+ *
+ * @param index The attribute's index (zero-based).
+ * @return The attribute's qualified name, the empty string if
+ * none is available, or null if the index is out of bounds.
+ * @see org.xml.sax.Attributes#getQName
+ */
+ public String getQName (int index)
+ {
+ if (index >= 0 && index < length) {
+ return data[index*5+2];
+ } else {
+ return null;
+ }
+ }
+
+
+ /**
+ * Return an attribute's type by index.
+ *
+ * @param index The attribute's index (zero-based).
+ * @return The attribute's type, "CDATA" if the type is unknown, or null
+ * if the index is out of bounds.
+ * @see org.xml.sax.Attributes#getType(int)
+ */
+ public String getType (int index)
+ {
+ if (index >= 0 && index < length) {
+ return data[index*5+3];
+ } else {
+ return null;
+ }
+ }
+
+
+ /**
+ * Return an attribute's value by index.
+ *
+ * @param index The attribute's index (zero-based).
+ * @return The attribute's value or null if the index is out of bounds.
+ * @see org.xml.sax.Attributes#getValue(int)
+ */
+ public String getValue (int index)
+ {
+ if (index >= 0 && index < length) {
+ return data[index*5+4];
+ } else {
+ return null;
+ }
+ }
+
+
+ /**
+ * Look up an attribute's index by Namespace name.
+ *
+ * <p>In many cases, it will be more efficient to look up the name once and
+ * use the index query methods rather than using the name query methods
+ * repeatedly.</p>
+ *
+ * @param uri The attribute's Namespace URI, or the empty
+ * string if none is available.
+ * @param localName The attribute's local name.
+ * @return The attribute's index, or -1 if none matches.
+ * @see org.xml.sax.Attributes#getIndex(java.lang.String,java.lang.String)
+ */
+ public int getIndex (String uri, String localName)
+ {
+ int max = length * 5;
+ for (int i = 0; i < max; i += 5) {
+ if (data[i].equals(uri) && data[i+1].equals(localName)) {
+ return i / 5;
+ }
+ }
+ return -1;
+ }
+
+
+ /**
+ * Look up an attribute's index by qualified (prefixed) name.
+ *
+ * @param qName The qualified name.
+ * @return The attribute's index, or -1 if none matches.
+ * @see org.xml.sax.Attributes#getIndex(java.lang.String)
+ */
+ public int getIndex (String qName)
+ {
+ int max = length * 5;
+ for (int i = 0; i < max; i += 5) {
+ if (data[i+2].equals(qName)) {
+ return i / 5;
+ }
+ }
+ return -1;
+ }
+
+
+ /**
+ * Look up an attribute's type by Namespace-qualified name.
+ *
+ * @param uri The Namespace URI, or the empty string for a name
+ * with no explicit Namespace URI.
+ * @param localName The local name.
+ * @return The attribute's type, or null if there is no
+ * matching attribute.
+ * @see org.xml.sax.Attributes#getType(java.lang.String,java.lang.String)
+ */
+ public String getType (String uri, String localName)
+ {
+ int max = length * 5;
+ for (int i = 0; i < max; i += 5) {
+ if (data[i].equals(uri) && data[i+1].equals(localName)) {
+ return data[i+3];
+ }
+ }
+ return null;
+ }
+
+
+ /**
+ * Look up an attribute's type by qualified (prefixed) name.
+ *
+ * @param qName The qualified name.
+ * @return The attribute's type, or null if there is no
+ * matching attribute.
+ * @see org.xml.sax.Attributes#getType(java.lang.String)
+ */
+ public String getType (String qName)
+ {
+ int max = length * 5;
+ for (int i = 0; i < max; i += 5) {
+ if (data[i+2].equals(qName)) {
+ return data[i+3];
+ }
+ }
+ return null;
+ }
+
+
+ /**
+ * Look up an attribute's value by Namespace-qualified name.
+ *
+ * @param uri The Namespace URI, or the empty string for a name
+ * with no explicit Namespace URI.
+ * @param localName The local name.
+ * @return The attribute's value, or null if there is no
+ * matching attribute.
+ * @see org.xml.sax.Attributes#getValue(java.lang.String,java.lang.String)
+ */
+ public String getValue (String uri, String localName)
+ {
+ int max = length * 5;
+ for (int i = 0; i < max; i += 5) {
+ if (data[i].equals(uri) && data[i+1].equals(localName)) {
+ return data[i+4];
+ }
+ }
+ return null;
+ }
+
+
+ /**
+ * Look up an attribute's value by qualified (prefixed) name.
+ *
+ * @param qName The qualified name.
+ * @return The attribute's value, or null if there is no
+ * matching attribute.
+ * @see org.xml.sax.Attributes#getValue(java.lang.String)
+ */
+ public String getValue (String qName)
+ {
+ int max = length * 5;
+ for (int i = 0; i < max; i += 5) {
+ if (data[i+2].equals(qName)) {
+ return data[i+4];
+ }
+ }
+ return null;
+ }
+
+
+
+ ////////////////////////////////////////////////////////////////////
+ // Manipulators.
+ ////////////////////////////////////////////////////////////////////
+
+
+ /**
+ * Clear the attribute list for reuse.
+ *
+ * <p>Note that little memory is freed by this call:
+ * the current array is kept so it can be
+ * reused.</p>
+ */
+ public void clear ()
+ {
+ if (data != null) {
+ for (int i = 0; i < (length * 5); i++)
+ data [i] = null;
+ }
+ length = 0;
+ }
+
+
+ /**
+ * Copy an entire Attributes object.
+ *
+ * <p>It may be more efficient to reuse an existing object
+ * rather than constantly allocating new ones.</p>
+ *
+ * @param atts The attributes to copy.
+ */
+ public void setAttributes (Attributes atts)
+ {
+ clear();
+ length = atts.getLength();
+ if (length > 0) {
+ data = new String[length*5];
+ for (int i = 0; i < length; i++) {
+ data[i*5] = atts.getURI(i);
+ data[i*5+1] = atts.getLocalName(i);
+ data[i*5+2] = atts.getQName(i);
+ data[i*5+3] = atts.getType(i);
+ data[i*5+4] = atts.getValue(i);
+ }
+ }
+ }
+
+
+ /**
+ * Add an attribute to the end of the list.
+ *
+ * <p>For the sake of speed, this method does no checking
+ * to see if the attribute is already in the list: that is
+ * the responsibility of the application.</p>
+ *
+ * @param uri The Namespace URI, or the empty string if
+ * none is available or Namespace processing is not
+ * being performed.
+ * @param localName The local name, or the empty string if
+ * Namespace processing is not being performed.
+ * @param qName The qualified (prefixed) name, or the empty string
+ * if qualified names are not available.
+ * @param type The attribute type as a string.
+ * @param value The attribute value.
+ */
+ public void addAttribute (String uri, String localName, String qName,
+ String type, String value)
+ {
+ ensureCapacity(length+1);
+ data[length*5] = uri;
+ data[length*5+1] = localName;
+ data[length*5+2] = qName;
+ data[length*5+3] = type;
+ data[length*5+4] = value;
+ length++;
+ }
+
+
+ /**
+ * Set an attribute in the list.
+ *
+ * <p>For the sake of speed, this method does no checking
+ * for name conflicts or well-formedness: such checks are the
+ * responsibility of the application.</p>
+ *
+ * @param index The index of the attribute (zero-based).
+ * @param uri The Namespace URI, or the empty string if
+ * none is available or Namespace processing is not
+ * being performed.
+ * @param localName The local name, or the empty string if
+ * Namespace processing is not being performed.
+ * @param qName The qualified name, or the empty string
+ * if qualified names are not available.
+ * @param type The attribute type as a string.
+ * @param value The attribute value.
+ * @exception java.lang.ArrayIndexOutOfBoundsException When the
+ * supplied index does not point to an attribute
+ * in the list.
+ */
+ public void setAttribute (int index, String uri, String localName,
+ String qName, String type, String value)
+ {
+ if (index >= 0 && index < length) {
+ data[index*5] = uri;
+ data[index*5+1] = localName;
+ data[index*5+2] = qName;
+ data[index*5+3] = type;
+ data[index*5+4] = value;
+ } else {
+ badIndex(index);
+ }
+ }
+
+
+ /**
+ * Remove an attribute from the list.
+ *
+ * @param index The index of the attribute (zero-based).
+ * @exception java.lang.ArrayIndexOutOfBoundsException When the
+ * supplied index does not point to an attribute
+ * in the list.
+ */
+ public void removeAttribute (int index)
+ {
+ if (index >= 0 && index < length) {
+ if (index < length - 1) {
+ System.arraycopy(data, (index+1)*5, data, index*5,
+ (length-index-1)*5);
+ }
+ index = (length - 1) * 5;
+ data [index++] = null;
+ data [index++] = null;
+ data [index++] = null;
+ data [index++] = null;
+ data [index] = null;
+ length--;
+ } else {
+ badIndex(index);
+ }
+ }
+
+
+ /**
+ * Set the Namespace URI of a specific attribute.
+ *
+ * @param index The index of the attribute (zero-based).
+ * @param uri The attribute's Namespace URI, or the empty
+ * string for none.
+ * @exception java.lang.ArrayIndexOutOfBoundsException When the
+ * supplied index does not point to an attribute
+ * in the list.
+ */
+ public void setURI (int index, String uri)
+ {
+ if (index >= 0 && index < length) {
+ data[index*5] = uri;
+ } else {
+ badIndex(index);
+ }
+ }
+
+
+ /**
+ * Set the local name of a specific attribute.
+ *
+ * @param index The index of the attribute (zero-based).
+ * @param localName The attribute's local name, or the empty
+ * string for none.
+ * @exception java.lang.ArrayIndexOutOfBoundsException When the
+ * supplied index does not point to an attribute
+ * in the list.
+ */
+ public void setLocalName (int index, String localName)
+ {
+ if (index >= 0 && index < length) {
+ data[index*5+1] = localName;
+ } else {
+ badIndex(index);
+ }
+ }
+
+
+ /**
+ * Set the qualified name of a specific attribute.
+ *
+ * @param index The index of the attribute (zero-based).
+ * @param qName The attribute's qualified name, or the empty
+ * string for none.
+ * @exception java.lang.ArrayIndexOutOfBoundsException When the
+ * supplied index does not point to an attribute
+ * in the list.
+ */
+ public void setQName (int index, String qName)
+ {
+ if (index >= 0 && index < length) {
+ data[index*5+2] = qName;
+ } else {
+ badIndex(index);
+ }
+ }
+
+
+ /**
+ * Set the type of a specific attribute.
+ *
+ * @param index The index of the attribute (zero-based).
+ * @param type The attribute's type.
+ * @exception java.lang.ArrayIndexOutOfBoundsException When the
+ * supplied index does not point to an attribute
+ * in the list.
+ */
+ public void setType (int index, String type)
+ {
+ if (index >= 0 && index < length) {
+ data[index*5+3] = type;
+ } else {
+ badIndex(index);
+ }
+ }
+
+
+ /**
+ * Set the value of a specific attribute.
+ *
+ * @param index The index of the attribute (zero-based).
+ * @param value The attribute's value.
+ * @exception java.lang.ArrayIndexOutOfBoundsException When the
+ * supplied index does not point to an attribute
+ * in the list.
+ */
+ public void setValue (int index, String value)
+ {
+ if (index >= 0 && index < length) {
+ data[index*5+4] = value;
+ } else {
+ badIndex(index);
+ }
+ }
+
+
+
+ ////////////////////////////////////////////////////////////////////
+ // Internal methods.
+ ////////////////////////////////////////////////////////////////////
+
+
+ /**
+ * Ensure the internal array's capacity.
+ *
+ * @param n The minimum number of attributes that the array must
+ * be able to hold.
+ */
+ private void ensureCapacity (int n) {
+ if (n <= 0) {
+ return;
+ }
+ int max;
+ if (data == null || data.length == 0) {
+ max = 25;
+ }
+ else if (data.length >= n * 5) {
+ return;
+ }
+ else {
+ max = data.length;
+ }
+ while (max < n * 5) {
+ max *= 2;
+ }
+
+ String newData[] = new String[max];
+ if (length > 0) {
+ System.arraycopy(data, 0, newData, 0, length*5);
+ }
+ data = newData;
+ }
+
+
+ /**
+ * Report a bad array index in a manipulator.
+ *
+ * @param index The index to report.
+ * @exception java.lang.ArrayIndexOutOfBoundsException Always.
+ */
+ private void badIndex (int index)
+ throws ArrayIndexOutOfBoundsException
+ {
+ String msg =
+ "Attempt to modify attribute at illegal index: " + index;
+ throw new ArrayIndexOutOfBoundsException(msg);
+ }
+
+
+
+ ////////////////////////////////////////////////////////////////////
+ // Internal state.
+ ////////////////////////////////////////////////////////////////////
+
+ int length;
+ String data [];
+
+}
+
+// end of AttributesImpl.java
+
diff --git a/xml/src/main/java/org/xml/sax/helpers/DefaultHandler.java b/xml/src/main/java/org/xml/sax/helpers/DefaultHandler.java
new file mode 100644
index 0000000..8308be7
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/helpers/DefaultHandler.java
@@ -0,0 +1,467 @@
+// DefaultHandler.java - default implementation of the core handlers.
+// http://www.saxproject.org
+// Written by David Megginson
+// NO WARRANTY! This class is in the public domain.
+// $Id: DefaultHandler.java,v 1.9 2004/04/26 17:34:35 dmegginson Exp $
+
+package org.xml.sax.helpers;
+
+import java.io.IOException;
+
+import org.xml.sax.InputSource;
+import org.xml.sax.Locator;
+import org.xml.sax.Attributes;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.DTDHandler;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+
+
+/**
+ * Default base class for SAX2 event handlers.
+ *
+ * <blockquote>
+ * <em>This module, both source code and documentation, is in the
+ * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
+ * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
+ * for further information.
+ * </blockquote>
+ *
+ * <p>This class is available as a convenience base class for SAX2
+ * applications: it provides default implementations for all of the
+ * callbacks in the four core SAX2 handler classes:</p>
+ *
+ * <ul>
+ * <li>{@link org.xml.sax.EntityResolver EntityResolver}</li>
+ * <li>{@link org.xml.sax.DTDHandler DTDHandler}</li>
+ * <li>{@link org.xml.sax.ContentHandler ContentHandler}</li>
+ * <li>{@link org.xml.sax.ErrorHandler ErrorHandler}</li>
+ * </ul>
+ *
+ * <p>Application writers can extend this class when they need to
+ * implement only part of an interface; parser writers can
+ * instantiate this class to provide default handlers when the
+ * application has not supplied its own.</p>
+ *
+ * <p>This class replaces the deprecated SAX1
+ * {@link org.xml.sax.HandlerBase HandlerBase} class.</p>
+ *
+ * @since SAX 2.0
+ * @author David Megginson,
+ * @version 2.0.1 (sax2r2)
+ * @see org.xml.sax.EntityResolver
+ * @see org.xml.sax.DTDHandler
+ * @see org.xml.sax.ContentHandler
+ * @see org.xml.sax.ErrorHandler
+ */
+public class DefaultHandler
+ implements EntityResolver, DTDHandler, ContentHandler, ErrorHandler
+{
+
+
+ ////////////////////////////////////////////////////////////////////
+ // Default implementation of the EntityResolver interface.
+ ////////////////////////////////////////////////////////////////////
+
+ /**
+ * Resolve an external entity.
+ *
+ * <p>Always return null, so that the parser will use the system
+ * identifier provided in the XML document. This method implements
+ * the SAX default behaviour: application writers can override it
+ * in a subclass to do special translations such as catalog lookups
+ * or URI redirection.</p>
+ *
+ * @param publicId The public identifer, or null if none is
+ * available.
+ * @param systemId The system identifier provided in the XML
+ * document.
+ * @return The new input source, or null to require the
+ * default behaviour.
+ * @exception java.io.IOException If there is an error setting
+ * up the new input source.
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ * @see org.xml.sax.EntityResolver#resolveEntity
+ */
+ public InputSource resolveEntity (String publicId, String systemId)
+ throws IOException, SAXException
+ {
+ return null;
+ }
+
+
+
+ ////////////////////////////////////////////////////////////////////
+ // Default implementation of DTDHandler interface.
+ ////////////////////////////////////////////////////////////////////
+
+
+ /**
+ * Receive notification of a notation declaration.
+ *
+ * <p>By default, do nothing. Application writers may override this
+ * method in a subclass if they wish to keep track of the notations
+ * declared in a document.</p>
+ *
+ * @param name The notation name.
+ * @param publicId The notation public identifier, or null if not
+ * available.
+ * @param systemId The notation system identifier.
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ * @see org.xml.sax.DTDHandler#notationDecl
+ */
+ public void notationDecl (String name, String publicId, String systemId)
+ throws SAXException
+ {
+ // no op
+ }
+
+
+ /**
+ * Receive notification of an unparsed entity declaration.
+ *
+ * <p>By default, do nothing. Application writers may override this
+ * method in a subclass to keep track of the unparsed entities
+ * declared in a document.</p>
+ *
+ * @param name The entity name.
+ * @param publicId The entity public identifier, or null if not
+ * available.
+ * @param systemId The entity system identifier.
+ * @param notationName The name of the associated notation.
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ * @see org.xml.sax.DTDHandler#unparsedEntityDecl
+ */
+ public void unparsedEntityDecl (String name, String publicId,
+ String systemId, String notationName)
+ throws SAXException
+ {
+ // no op
+ }
+
+
+
+ ////////////////////////////////////////////////////////////////////
+ // Default implementation of ContentHandler interface.
+ ////////////////////////////////////////////////////////////////////
+
+
+ /**
+ * Receive a Locator object for document events.
+ *
+ * <p>By default, do nothing. Application writers may override this
+ * method in a subclass if they wish to store the locator for use
+ * with other document events.</p>
+ *
+ * @param locator A locator for all SAX document events.
+ * @see org.xml.sax.ContentHandler#setDocumentLocator
+ * @see org.xml.sax.Locator
+ */
+ public void setDocumentLocator (Locator locator)
+ {
+ // no op
+ }
+
+
+ /**
+ * Receive notification of the beginning of the document.
+ *
+ * <p>By default, do nothing. Application writers may override this
+ * method in a subclass to take specific actions at the beginning
+ * of a document (such as allocating the root node of a tree or
+ * creating an output file).</p>
+ *
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ * @see org.xml.sax.ContentHandler#startDocument
+ */
+ public void startDocument ()
+ throws SAXException
+ {
+ // no op
+ }
+
+
+ /**
+ * Receive notification of the end of the document.
+ *
+ * <p>By default, do nothing. Application writers may override this
+ * method in a subclass to take specific actions at the end
+ * of a document (such as finalising a tree or closing an output
+ * file).</p>
+ *
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ * @see org.xml.sax.ContentHandler#endDocument
+ */
+ public void endDocument ()
+ throws SAXException
+ {
+ // no op
+ }
+
+
+ /**
+ * Receive notification of the start of a Namespace mapping.
+ *
+ * <p>By default, do nothing. Application writers may override this
+ * method in a subclass to take specific actions at the start of
+ * each Namespace prefix scope (such as storing the prefix mapping).</p>
+ *
+ * @param prefix The Namespace prefix being declared.
+ * @param uri The Namespace URI mapped to the prefix.
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ * @see org.xml.sax.ContentHandler#startPrefixMapping
+ */
+ public void startPrefixMapping (String prefix, String uri)
+ throws SAXException
+ {
+ // no op
+ }
+
+
+ /**
+ * Receive notification of the end of a Namespace mapping.
+ *
+ * <p>By default, do nothing. Application writers may override this
+ * method in a subclass to take specific actions at the end of
+ * each prefix mapping.</p>
+ *
+ * @param prefix The Namespace prefix being declared.
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ * @see org.xml.sax.ContentHandler#endPrefixMapping
+ */
+ public void endPrefixMapping (String prefix)
+ throws SAXException
+ {
+ // no op
+ }
+
+
+ /**
+ * Receive notification of the start of an element.
+ *
+ * <p>By default, do nothing. Application writers may override this
+ * method in a subclass to take specific actions at the start of
+ * each element (such as allocating a new tree node or writing
+ * output to a file).</p>
+ *
+ * @param uri The Namespace URI, or the empty string if the
+ * element has no Namespace URI or if Namespace
+ * processing is not being performed.
+ * @param localName The local name (without prefix), or the
+ * empty string if Namespace processing is not being
+ * performed.
+ * @param qName The qualified name (with prefix), or the
+ * empty string if qualified names are not available.
+ * @param attributes The attributes attached to the element. If
+ * there are no attributes, it shall be an empty
+ * Attributes object.
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ * @see org.xml.sax.ContentHandler#startElement
+ */
+ public void startElement (String uri, String localName,
+ String qName, Attributes attributes)
+ throws SAXException
+ {
+ // no op
+ }
+
+
+ /**
+ * Receive notification of the end of an element.
+ *
+ * <p>By default, do nothing. Application writers may override this
+ * method in a subclass to take specific actions at the end of
+ * each element (such as finalising a tree node or writing
+ * output to a file).</p>
+ *
+ * @param uri The Namespace URI, or the empty string if the
+ * element has no Namespace URI or if Namespace
+ * processing is not being performed.
+ * @param localName The local name (without prefix), or the
+ * empty string if Namespace processing is not being
+ * performed.
+ * @param qName The qualified name (with prefix), or the
+ * empty string if qualified names are not available.
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ * @see org.xml.sax.ContentHandler#endElement
+ */
+ public void endElement (String uri, String localName, String qName)
+ throws SAXException
+ {
+ // no op
+ }
+
+
+ /**
+ * Receive notification of character data inside an element.
+ *
+ * <p>By default, do nothing. Application writers may override this
+ * method to take specific actions for each chunk of character data
+ * (such as adding the data to a node or buffer, or printing it to
+ * a file).</p>
+ *
+ * @param ch The characters.
+ * @param start The start position in the character array.
+ * @param length The number of characters to use from the
+ * character array.
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ * @see org.xml.sax.ContentHandler#characters
+ */
+ public void characters (char ch[], int start, int length)
+ throws SAXException
+ {
+ // no op
+ }
+
+
+ /**
+ * Receive notification of ignorable whitespace in element content.
+ *
+ * <p>By default, do nothing. Application writers may override this
+ * method to take specific actions for each chunk of ignorable
+ * whitespace (such as adding data to a node or buffer, or printing
+ * it to a file).</p>
+ *
+ * @param ch The whitespace characters.
+ * @param start The start position in the character array.
+ * @param length The number of characters to use from the
+ * character array.
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ * @see org.xml.sax.ContentHandler#ignorableWhitespace
+ */
+ public void ignorableWhitespace (char ch[], int start, int length)
+ throws SAXException
+ {
+ // no op
+ }
+
+
+ /**
+ * Receive notification of a processing instruction.
+ *
+ * <p>By default, do nothing. Application writers may override this
+ * method in a subclass to take specific actions for each
+ * processing instruction, such as setting status variables or
+ * invoking other methods.</p>
+ *
+ * @param target The processing instruction target.
+ * @param data The processing instruction data, or null if
+ * none is supplied.
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ * @see org.xml.sax.ContentHandler#processingInstruction
+ */
+ public void processingInstruction (String target, String data)
+ throws SAXException
+ {
+ // no op
+ }
+
+
+ /**
+ * Receive notification of a skipped entity.
+ *
+ * <p>By default, do nothing. Application writers may override this
+ * method in a subclass to take specific actions for each
+ * processing instruction, such as setting status variables or
+ * invoking other methods.</p>
+ *
+ * @param name The name of the skipped entity.
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ * @see org.xml.sax.ContentHandler#processingInstruction
+ */
+ public void skippedEntity (String name)
+ throws SAXException
+ {
+ // no op
+ }
+
+
+
+ ////////////////////////////////////////////////////////////////////
+ // Default implementation of the ErrorHandler interface.
+ ////////////////////////////////////////////////////////////////////
+
+
+ /**
+ * Receive notification of a parser warning.
+ *
+ * <p>The default implementation does nothing. Application writers
+ * may override this method in a subclass to take specific actions
+ * for each warning, such as inserting the message in a log file or
+ * printing it to the console.</p>
+ *
+ * @param e The warning information encoded as an exception.
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ * @see org.xml.sax.ErrorHandler#warning
+ * @see org.xml.sax.SAXParseException
+ */
+ public void warning (SAXParseException e)
+ throws SAXException
+ {
+ // no op
+ }
+
+
+ /**
+ * Receive notification of a recoverable parser error.
+ *
+ * <p>The default implementation does nothing. Application writers
+ * may override this method in a subclass to take specific actions
+ * for each error, such as inserting the message in a log file or
+ * printing it to the console.</p>
+ *
+ * @param e The warning information encoded as an exception.
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ * @see org.xml.sax.ErrorHandler#warning
+ * @see org.xml.sax.SAXParseException
+ */
+ public void error (SAXParseException e)
+ throws SAXException
+ {
+ // no op
+ }
+
+
+ /**
+ * Report a fatal XML parsing error.
+ *
+ * <p>The default implementation throws a SAXParseException.
+ * Application writers may override this method in a subclass if
+ * they need to take specific actions for each fatal error (such as
+ * collecting all of the errors into a single report): in any case,
+ * the application must stop all regular processing when this
+ * method is invoked, since the document is no longer reliable, and
+ * the parser may no longer report parsing events.</p>
+ *
+ * @param e The error information encoded as an exception.
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ * @see org.xml.sax.ErrorHandler#fatalError
+ * @see org.xml.sax.SAXParseException
+ */
+ public void fatalError (SAXParseException e)
+ throws SAXException
+ {
+ throw e;
+ }
+
+}
+
+// end of DefaultHandler.java
diff --git a/xml/src/main/java/org/xml/sax/helpers/LocatorImpl.java b/xml/src/main/java/org/xml/sax/helpers/LocatorImpl.java
new file mode 100644
index 0000000..18445bc
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/helpers/LocatorImpl.java
@@ -0,0 +1,214 @@
+// SAX default implementation for Locator.
+// http://www.saxproject.org
+// No warranty; no copyright -- use this as you will.
+// $Id: LocatorImpl.java,v 1.6 2002/01/30 20:52:27 dbrownell Exp $
+
+package org.xml.sax.helpers;
+
+import org.xml.sax.Locator;
+
+
+/**
+ * Provide an optional convenience implementation of Locator.
+ *
+ * <blockquote>
+ * <em>This module, both source code and documentation, is in the
+ * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
+ * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
+ * for further information.
+ * </blockquote>
+ *
+ * <p>This class is available mainly for application writers, who
+ * can use it to make a persistent snapshot of a locator at any
+ * point during a document parse:</p>
+ *
+ * <pre>
+ * Locator locator;
+ * Locator startloc;
+ *
+ * public void setLocator (Locator locator)
+ * {
+ * // note the locator
+ * this.locator = locator;
+ * }
+ *
+ * public void startDocument ()
+ * {
+ * // save the location of the start of the document
+ * // for future use.
+ * Locator startloc = new LocatorImpl(locator);
+ * }
+ *</pre>
+ *
+ * <p>Normally, parser writers will not use this class, since it
+ * is more efficient to provide location information only when
+ * requested, rather than constantly updating a Locator object.</p>
+ *
+ * @since SAX 1.0
+ * @author David Megginson
+ * @version 2.0.1 (sax2r2)
+ * @see org.xml.sax.Locator Locator
+ */
+public class LocatorImpl implements Locator
+{
+
+
+ /**
+ * Zero-argument constructor.
+ *
+ * <p>This will not normally be useful, since the main purpose
+ * of this class is to make a snapshot of an existing Locator.</p>
+ */
+ public LocatorImpl ()
+ {
+ }
+
+
+ /**
+ * Copy constructor.
+ *
+ * <p>Create a persistent copy of the current state of a locator.
+ * When the original locator changes, this copy will still keep
+ * the original values (and it can be used outside the scope of
+ * DocumentHandler methods).</p>
+ *
+ * @param locator The locator to copy.
+ */
+ public LocatorImpl (Locator locator)
+ {
+ setPublicId(locator.getPublicId());
+ setSystemId(locator.getSystemId());
+ setLineNumber(locator.getLineNumber());
+ setColumnNumber(locator.getColumnNumber());
+ }
+
+
+
+ ////////////////////////////////////////////////////////////////////
+ // Implementation of org.xml.sax.Locator
+ ////////////////////////////////////////////////////////////////////
+
+
+ /**
+ * Return the saved public identifier.
+ *
+ * @return The public identifier as a string, or null if none
+ * is available.
+ * @see org.xml.sax.Locator#getPublicId
+ * @see #setPublicId
+ */
+ public String getPublicId ()
+ {
+ return publicId;
+ }
+
+
+ /**
+ * Return the saved system identifier.
+ *
+ * @return The system identifier as a string, or null if none
+ * is available.
+ * @see org.xml.sax.Locator#getSystemId
+ * @see #setSystemId
+ */
+ public String getSystemId ()
+ {
+ return systemId;
+ }
+
+
+ /**
+ * Return the saved line number (1-based).
+ *
+ * @return The line number as an integer, or -1 if none is available.
+ * @see org.xml.sax.Locator#getLineNumber
+ * @see #setLineNumber
+ */
+ public int getLineNumber ()
+ {
+ return lineNumber;
+ }
+
+
+ /**
+ * Return the saved column number (1-based).
+ *
+ * @return The column number as an integer, or -1 if none is available.
+ * @see org.xml.sax.Locator#getColumnNumber
+ * @see #setColumnNumber
+ */
+ public int getColumnNumber ()
+ {
+ return columnNumber;
+ }
+
+
+
+ ////////////////////////////////////////////////////////////////////
+ // Setters for the properties (not in org.xml.sax.Locator)
+ ////////////////////////////////////////////////////////////////////
+
+
+ /**
+ * Set the public identifier for this locator.
+ *
+ * @param publicId The new public identifier, or null
+ * if none is available.
+ * @see #getPublicId
+ */
+ public void setPublicId (String publicId)
+ {
+ this.publicId = publicId;
+ }
+
+
+ /**
+ * Set the system identifier for this locator.
+ *
+ * @param systemId The new system identifier, or null
+ * if none is available.
+ * @see #getSystemId
+ */
+ public void setSystemId (String systemId)
+ {
+ this.systemId = systemId;
+ }
+
+
+ /**
+ * Set the line number for this locator (1-based).
+ *
+ * @param lineNumber The line number, or -1 if none is available.
+ * @see #getLineNumber
+ */
+ public void setLineNumber (int lineNumber)
+ {
+ this.lineNumber = lineNumber;
+ }
+
+
+ /**
+ * Set the column number for this locator (1-based).
+ *
+ * @param columnNumber The column number, or -1 if none is available.
+ * @see #getColumnNumber
+ */
+ public void setColumnNumber (int columnNumber)
+ {
+ this.columnNumber = columnNumber;
+ }
+
+
+
+ ////////////////////////////////////////////////////////////////////
+ // Internal state.
+ ////////////////////////////////////////////////////////////////////
+
+ private String publicId;
+ private String systemId;
+ private int lineNumber;
+ private int columnNumber;
+
+}
+
+// end of LocatorImpl.java
diff --git a/xml/src/main/java/org/xml/sax/helpers/NamespaceSupport.java b/xml/src/main/java/org/xml/sax/helpers/NamespaceSupport.java
new file mode 100644
index 0000000..a737d1d
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/helpers/NamespaceSupport.java
@@ -0,0 +1,840 @@
+// NamespaceSupport.java - generic Namespace support for SAX.
+// http://www.saxproject.org
+// Written by David Megginson
+// This class is in the Public Domain. NO WARRANTY!
+// $Id: NamespaceSupport.java,v 1.15 2004/04/26 17:34:35 dmegginson Exp $
+
+package org.xml.sax.helpers;
+
+import java.util.EmptyStackException;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+
+/**
+ * Encapsulate Namespace logic for use by applications using SAX,
+ * or internally by SAX drivers.
+ *
+ * <blockquote>
+ * <em>This module, both source code and documentation, is in the
+ * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
+ * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
+ * for further information.
+ * </blockquote>
+ *
+ * <p>This class encapsulates the logic of Namespace processing: it
+ * tracks the declarations currently in force for each context and
+ * automatically processes qualified XML names into their Namespace
+ * parts; it can also be used in reverse for generating XML qnames
+ * from Namespaces.</p>
+ *
+ * <p>Namespace support objects are reusable, but the reset method
+ * must be invoked between each session.</p>
+ *
+ * <p>Here is a simple session:</p>
+ *
+ * <pre>
+ * String parts[] = new String[3];
+ * NamespaceSupport support = new NamespaceSupport();
+ *
+ * support.pushContext();
+ * support.declarePrefix("", "http://www.w3.org/1999/xhtml");
+ * support.declarePrefix("dc", "http://www.purl.org/dc#");
+ *
+ * parts = support.processName("p", parts, false);
+ * System.out.println("Namespace URI: " + parts[0]);
+ * System.out.println("Local name: " + parts[1]);
+ * System.out.println("Raw name: " + parts[2]);
+ *
+ * parts = support.processName("dc:title", parts, false);
+ * System.out.println("Namespace URI: " + parts[0]);
+ * System.out.println("Local name: " + parts[1]);
+ * System.out.println("Raw name: " + parts[2]);
+ *
+ * support.popContext();
+ * </pre>
+ *
+ * <p>Note that this class is optimized for the use case where most
+ * elements do not contain Namespace declarations: if the same
+ * prefix/URI mapping is repeated for each context (for example), this
+ * class will be somewhat less efficient.</p>
+ *
+ * <p>Although SAX drivers (parsers) may choose to use this class to
+ * implement namespace handling, they are not required to do so.
+ * Applications must track namespace information themselves if they
+ * want to use namespace information.
+ *
+ * @since SAX 2.0
+ * @author David Megginson
+ * @version 2.0.1 (sax2r2)
+ */
+public class NamespaceSupport
+{
+
+
+ ////////////////////////////////////////////////////////////////////
+ // Constants.
+ ////////////////////////////////////////////////////////////////////
+
+
+ /**
+ * The XML Namespace URI as a constant.
+ * The value is <code>http://www.w3.org/XML/1998/namespace</code>
+ * as defined in the "Namespaces in XML" * recommendation.
+ *
+ * <p>This is the Namespace URI that is automatically mapped
+ * to the "xml" prefix.</p>
+ */
+ public final static String XMLNS =
+ "http://www.w3.org/XML/1998/namespace";
+
+
+ /**
+ * The namespace declaration URI as a constant.
+ * The value is <code>http://www.w3.org/xmlns/2000/</code>, as defined
+ * in a backwards-incompatible erratum to the "Namespaces in XML"
+ * recommendation. Because that erratum postdated SAX2, SAX2 defaults
+ * to the original recommendation, and does not normally use this URI.
+ *
+ *
+ * <p>This is the Namespace URI that is optionally applied to
+ * <em>xmlns</em> and <em>xmlns:*</em> attributes, which are used to
+ * declare namespaces. </p>
+ *
+ * @since SAX 2.1alpha
+ * @see #setNamespaceDeclUris
+ * @see #isNamespaceDeclUris
+ */
+ public final static String NSDECL =
+ "http://www.w3.org/xmlns/2000/";
+
+
+ /**
+ * An empty enumeration.
+ */
+ private final static Enumeration EMPTY_ENUMERATION =
+ new Vector().elements();
+
+
+ ////////////////////////////////////////////////////////////////////
+ // Constructor.
+ ////////////////////////////////////////////////////////////////////
+
+
+ /**
+ * Create a new Namespace support object.
+ */
+ public NamespaceSupport ()
+ {
+ reset();
+ }
+
+
+
+ ////////////////////////////////////////////////////////////////////
+ // Context management.
+ ////////////////////////////////////////////////////////////////////
+
+
+ /**
+ * Reset this Namespace support object for reuse.
+ *
+ * <p>It is necessary to invoke this method before reusing the
+ * Namespace support object for a new session. If namespace
+ * declaration URIs are to be supported, that flag must also
+ * be set to a non-default value.
+ * </p>
+ *
+ * @see #setNamespaceDeclUris
+ */
+ public void reset ()
+ {
+ contexts = new Context[32];
+ namespaceDeclUris = false;
+ contextPos = 0;
+ contexts[contextPos] = currentContext = new Context();
+ currentContext.declarePrefix("xml", XMLNS);
+ }
+
+
+ /**
+ * Start a new Namespace context.
+ * The new context will automatically inherit
+ * the declarations of its parent context, but it will also keep
+ * track of which declarations were made within this context.
+ *
+ * <p>Event callback code should start a new context once per element.
+ * This means being ready to call this in either of two places.
+ * For elements that don't include namespace declarations, the
+ * <em>ContentHandler.startElement()</em> callback is the right place.
+ * For elements with such a declaration, it'd done in the first
+ * <em>ContentHandler.startPrefixMapping()</em> callback.
+ * A boolean flag can be used to
+ * track whether a context has been started yet. When either of
+ * those methods is called, it checks the flag to see if a new context
+ * needs to be started. If so, it starts the context and sets the
+ * flag. After <em>ContentHandler.startElement()</em>
+ * does that, it always clears the flag.
+ *
+ * <p>Normally, SAX drivers would push a new context at the beginning
+ * of each XML element. Then they perform a first pass over the
+ * attributes to process all namespace declarations, making
+ * <em>ContentHandler.startPrefixMapping()</em> callbacks.
+ * Then a second pass is made, to determine the namespace-qualified
+ * names for all attributes and for the element name.
+ * Finally all the information for the
+ * <em>ContentHandler.startElement()</em> callback is available,
+ * so it can then be made.
+ *
+ * <p>The Namespace support object always starts with a base context
+ * already in force: in this context, only the "xml" prefix is
+ * declared.</p>
+ *
+ * @see org.xml.sax.ContentHandler
+ * @see #popContext
+ */
+ public void pushContext ()
+ {
+ int max = contexts.length;
+
+ contexts [contextPos].declsOK = false;
+ contextPos++;
+
+ // Extend the array if necessary
+ if (contextPos >= max) {
+ Context newContexts[] = new Context[max*2];
+ System.arraycopy(contexts, 0, newContexts, 0, max);
+ max *= 2;
+ contexts = newContexts;
+ }
+
+ // Allocate the context if necessary.
+ currentContext = contexts[contextPos];
+ if (currentContext == null) {
+ contexts[contextPos] = currentContext = new Context();
+ }
+
+ // Set the parent, if any.
+ if (contextPos > 0) {
+ currentContext.setParent(contexts[contextPos - 1]);
+ }
+ }
+
+
+ /**
+ * Revert to the previous Namespace context.
+ *
+ * <p>Normally, you should pop the context at the end of each
+ * XML element. After popping the context, all Namespace prefix
+ * mappings that were previously in force are restored.</p>
+ *
+ * <p>You must not attempt to declare additional Namespace
+ * prefixes after popping a context, unless you push another
+ * context first.</p>
+ *
+ * @see #pushContext
+ */
+ public void popContext ()
+ {
+ contexts[contextPos].clear();
+ contextPos--;
+ if (contextPos < 0) {
+ throw new EmptyStackException();
+ }
+ currentContext = contexts[contextPos];
+ }
+
+
+
+ ////////////////////////////////////////////////////////////////////
+ // Operations within a context.
+ ////////////////////////////////////////////////////////////////////
+
+
+ /**
+ * Declare a Namespace prefix. All prefixes must be declared
+ * before they are referenced. For example, a SAX driver (parser)
+ * would scan an element's attributes
+ * in two passes: first for namespace declarations,
+ * then a second pass using {@link #processName processName()} to
+ * interpret prefixes against (potentially redefined) prefixes.
+ *
+ * <p>This method declares a prefix in the current Namespace
+ * context; the prefix will remain in force until this context
+ * is popped, unless it is shadowed in a descendant context.</p>
+ *
+ * <p>To declare the default element Namespace, use the empty string as
+ * the prefix.</p>
+ *
+ * <p>Note that you must <em>not</em> declare a prefix after
+ * you've pushed and popped another Namespace context, or
+ * treated the declarations phase as complete by processing
+ * a prefixed name.</p>
+ *
+ * <p>Note that there is an asymmetry in this library: {@link
+ * #getPrefix getPrefix} will not return the "" prefix,
+ * even if you have declared a default element namespace.
+ * To check for a default namespace,
+ * you have to look it up explicitly using {@link #getURI getURI}.
+ * This asymmetry exists to make it easier to look up prefixes
+ * for attribute names, where the default prefix is not allowed.</p>
+ *
+ * @param prefix The prefix to declare, or the empty string to
+ * indicate the default element namespace. This may never have
+ * the value "xml" or "xmlns".
+ * @param uri The Namespace URI to associate with the prefix.
+ * @return true if the prefix was legal, false otherwise
+ *
+ * @see #processName
+ * @see #getURI
+ * @see #getPrefix
+ */
+ public boolean declarePrefix (String prefix, String uri)
+ {
+ if (prefix.equals("xml") || prefix.equals("xmlns")) {
+ return false;
+ } else {
+ currentContext.declarePrefix(prefix, uri);
+ return true;
+ }
+ }
+
+
+ /**
+ * Process a raw XML qualified name, after all declarations in the
+ * current context have been handled by {@link #declarePrefix
+ * declarePrefix()}.
+ *
+ * <p>This method processes a raw XML qualified name in the
+ * current context by removing the prefix and looking it up among
+ * the prefixes currently declared. The return value will be the
+ * array supplied by the caller, filled in as follows:</p>
+ *
+ * <dl>
+ * <dt>parts[0]</dt>
+ * <dd>The Namespace URI, or an empty string if none is
+ * in use.</dd>
+ * <dt>parts[1]</dt>
+ * <dd>The local name (without prefix).</dd>
+ * <dt>parts[2]</dt>
+ * <dd>The original raw name.</dd>
+ * </dl>
+ *
+ * <p>All of the strings in the array will be internalized. If
+ * the raw name has a prefix that has not been declared, then
+ * the return value will be null.</p>
+ *
+ * <p>Note that attribute names are processed differently than
+ * element names: an unprefixed element name will receive the
+ * default Namespace (if any), while an unprefixed attribute name
+ * will not.</p>
+ *
+ * @param qName The XML qualified name to be processed.
+ * @param parts An array supplied by the caller, capable of
+ * holding at least three members.
+ * @param isAttribute A flag indicating whether this is an
+ * attribute name (true) or an element name (false).
+ * @return The supplied array holding three internalized strings
+ * representing the Namespace URI (or empty string), the
+ * local name, and the XML qualified name; or null if there
+ * is an undeclared prefix.
+ * @see #declarePrefix
+ * @see java.lang.String#intern */
+ public String [] processName (String qName, String parts[],
+ boolean isAttribute)
+ {
+ String myParts[] = currentContext.processName(qName, isAttribute);
+ if (myParts == null) {
+ return null;
+ } else {
+ parts[0] = myParts[0];
+ parts[1] = myParts[1];
+ parts[2] = myParts[2];
+ return parts;
+ }
+ }
+
+
+ /**
+ * Look up a prefix and get the currently-mapped Namespace URI.
+ *
+ * <p>This method looks up the prefix in the current context.
+ * Use the empty string ("") for the default Namespace.</p>
+ *
+ * @param prefix The prefix to look up.
+ * @return The associated Namespace URI, or null if the prefix
+ * is undeclared in this context.
+ * @see #getPrefix
+ * @see #getPrefixes
+ */
+ public String getURI (String prefix)
+ {
+ return currentContext.getURI(prefix);
+ }
+
+
+ /**
+ * Return an enumeration of all prefixes whose declarations are
+ * active in the current context.
+ * This includes declarations from parent contexts that have
+ * not been overridden.
+ *
+ * <p><strong>Note:</strong> if there is a default prefix, it will not be
+ * returned in this enumeration; check for the default prefix
+ * using the {@link #getURI getURI} with an argument of "".</p>
+ *
+ * @return An enumeration of prefixes (never empty).
+ * @see #getDeclaredPrefixes
+ * @see #getURI
+ */
+ public Enumeration getPrefixes ()
+ {
+ return currentContext.getPrefixes();
+ }
+
+
+ /**
+ * Return one of the prefixes mapped to a Namespace URI.
+ *
+ * <p>If more than one prefix is currently mapped to the same
+ * URI, this method will make an arbitrary selection; if you
+ * want all of the prefixes, use the {@link #getPrefixes}
+ * method instead.</p>
+ *
+ * <p><strong>Note:</strong> this will never return the empty (default) prefix;
+ * to check for a default prefix, use the {@link #getURI getURI}
+ * method with an argument of "".</p>
+ *
+ * @param uri the namespace URI
+ * @return one of the prefixes currently mapped to the URI supplied,
+ * or null if none is mapped or if the URI is assigned to
+ * the default namespace
+ * @see #getPrefixes(java.lang.String)
+ * @see #getURI
+ */
+ public String getPrefix (String uri)
+ {
+ return currentContext.getPrefix(uri);
+ }
+
+
+ /**
+ * Return an enumeration of all prefixes for a given URI whose
+ * declarations are active in the current context.
+ * This includes declarations from parent contexts that have
+ * not been overridden.
+ *
+ * <p>This method returns prefixes mapped to a specific Namespace
+ * URI. The xml: prefix will be included. If you want only one
+ * prefix that's mapped to the Namespace URI, and you don't care
+ * which one you get, use the {@link #getPrefix getPrefix}
+ * method instead.</p>
+ *
+ * <p><strong>Note:</strong> the empty (default) prefix is <em>never</em> included
+ * in this enumeration; to check for the presence of a default
+ * Namespace, use the {@link #getURI getURI} method with an
+ * argument of "".</p>
+ *
+ * @param uri The Namespace URI.
+ * @return An enumeration of prefixes (never empty).
+ * @see #getPrefix
+ * @see #getDeclaredPrefixes
+ * @see #getURI
+ */
+ public Enumeration getPrefixes (String uri)
+ {
+ Vector prefixes = new Vector();
+ Enumeration allPrefixes = getPrefixes();
+ while (allPrefixes.hasMoreElements()) {
+ String prefix = (String)allPrefixes.nextElement();
+ if (uri.equals(getURI(prefix))) {
+ prefixes.addElement(prefix);
+ }
+ }
+ return prefixes.elements();
+ }
+
+
+ /**
+ * Return an enumeration of all prefixes declared in this context.
+ *
+ * <p>The empty (default) prefix will be included in this
+ * enumeration; note that this behaviour differs from that of
+ * {@link #getPrefix} and {@link #getPrefixes}.</p>
+ *
+ * @return An enumeration of all prefixes declared in this
+ * context.
+ * @see #getPrefixes
+ * @see #getURI
+ */
+ public Enumeration getDeclaredPrefixes ()
+ {
+ return currentContext.getDeclaredPrefixes();
+ }
+
+ /**
+ * Controls whether namespace declaration attributes are placed
+ * into the {@link #NSDECL NSDECL} namespace
+ * by {@link #processName processName()}. This may only be
+ * changed before any contexts have been pushed.
+ *
+ * @param value the namespace declaration attribute state. A value of true
+ * enables this feature, a value of false disables it.
+ *
+ * @since SAX 2.1alpha
+ *
+ * @exception IllegalStateException when attempting to set this
+ * after any context has been pushed.
+ */
+ public void setNamespaceDeclUris (boolean value)
+ {
+ if (contextPos != 0)
+ throw new IllegalStateException ();
+ if (value == namespaceDeclUris)
+ return;
+ namespaceDeclUris = value;
+ if (value)
+ currentContext.declarePrefix ("xmlns", NSDECL);
+ else {
+ contexts[contextPos] = currentContext = new Context();
+ currentContext.declarePrefix("xml", XMLNS);
+ }
+ }
+
+ /**
+ * Returns true if namespace declaration attributes are placed into
+ * a namespace. This behavior is not the default.
+ *
+ * @return true if namespace declaration attributes are enabled, false
+ * otherwise.
+ * @since SAX 2.1alpha
+ */
+ public boolean isNamespaceDeclUris ()
+ { return namespaceDeclUris; }
+
+
+
+ ////////////////////////////////////////////////////////////////////
+ // Internal state.
+ ////////////////////////////////////////////////////////////////////
+
+ private Context contexts[];
+ private Context currentContext;
+ private int contextPos;
+ private boolean namespaceDeclUris;
+
+
+ ////////////////////////////////////////////////////////////////////
+ // Internal classes.
+ ////////////////////////////////////////////////////////////////////
+
+ /**
+ * Internal class for a single Namespace context.
+ *
+ * <p>This module caches and reuses Namespace contexts,
+ * so the number allocated
+ * will be equal to the element depth of the document, not to the total
+ * number of elements (i.e. 5-10 rather than tens of thousands).
+ * Also, data structures used to represent contexts are shared when
+ * possible (child contexts without declarations) to further reduce
+ * the amount of memory that's consumed.
+ * </p>
+ */
+ final class Context {
+
+ /**
+ * Create the root-level Namespace context.
+ */
+ Context ()
+ {
+ copyTables();
+ }
+
+
+ /**
+ * (Re)set the parent of this Namespace context.
+ * The context must either have been freshly constructed,
+ * or must have been cleared.
+ *
+ * @param context The parent Namespace context object.
+ */
+ void setParent (Context parent)
+ {
+ this.parent = parent;
+ declarations = null;
+ prefixTable = parent.prefixTable;
+ uriTable = parent.uriTable;
+ elementNameTable = parent.elementNameTable;
+ attributeNameTable = parent.attributeNameTable;
+ defaultNS = parent.defaultNS;
+ declSeen = false;
+ declsOK = true;
+ }
+
+ /**
+ * Makes associated state become collectible,
+ * invalidating this context.
+ * {@link #setParent} must be called before
+ * this context may be used again.
+ */
+ void clear ()
+ {
+ parent = null;
+ prefixTable = null;
+ uriTable = null;
+ elementNameTable = null;
+ attributeNameTable = null;
+ defaultNS = null;
+ }
+
+
+ /**
+ * Declare a Namespace prefix for this context.
+ *
+ * @param prefix The prefix to declare.
+ * @param uri The associated Namespace URI.
+ * @see org.xml.sax.helpers.NamespaceSupport#declarePrefix
+ */
+ void declarePrefix (String prefix, String uri)
+ {
+ // Lazy processing...
+ if (!declsOK)
+ throw new IllegalStateException (
+ "can't declare any more prefixes in this context");
+ if (!declSeen) {
+ copyTables();
+ }
+ if (declarations == null) {
+ declarations = new Vector();
+ }
+
+ prefix = prefix.intern();
+ uri = uri.intern();
+ if ("".equals(prefix)) {
+ if ("".equals(uri)) {
+ defaultNS = null;
+ } else {
+ defaultNS = uri;
+ }
+ } else {
+ prefixTable.put(prefix, uri);
+ uriTable.put(uri, prefix); // may wipe out another prefix
+ }
+ declarations.addElement(prefix);
+ }
+
+
+ /**
+ * Process an XML qualified name in this context.
+ *
+ * @param qName The XML qualified name.
+ * @param isAttribute true if this is an attribute name.
+ * @return An array of three strings containing the
+ * URI part (or empty string), the local part,
+ * and the raw name, all internalized, or null
+ * if there is an undeclared prefix.
+ * @see org.xml.sax.helpers.NamespaceSupport#processName
+ */
+ String [] processName (String qName, boolean isAttribute)
+ {
+ String name[];
+ Hashtable table;
+
+ // detect errors in call sequence
+ declsOK = false;
+
+ // Select the appropriate table.
+ if (isAttribute) {
+ table = attributeNameTable;
+ } else {
+ table = elementNameTable;
+ }
+
+ // Start by looking in the cache, and
+ // return immediately if the name
+ // is already known in this content
+ name = (String[])table.get(qName);
+ if (name != null) {
+ return name;
+ }
+
+ // We haven't seen this name in this
+ // context before. Maybe in the parent
+ // context, but we can't assume prefix
+ // bindings are the same.
+ name = new String[3];
+ name[2] = qName.intern();
+ int index = qName.indexOf(':');
+
+
+ // No prefix.
+ if (index == -1) {
+ if (isAttribute) {
+ if (qName == "xmlns" && namespaceDeclUris)
+ name[0] = NSDECL;
+ else
+ name[0] = "";
+ } else if (defaultNS == null) {
+ name[0] = "";
+ } else {
+ name[0] = defaultNS;
+ }
+ name[1] = name[2];
+ }
+
+ // Prefix
+ else {
+ String prefix = qName.substring(0, index);
+ String local = qName.substring(index+1);
+ String uri;
+ if ("".equals(prefix)) {
+ uri = defaultNS;
+ } else {
+ uri = (String)prefixTable.get(prefix);
+ }
+ if (uri == null
+ || (!isAttribute && "xmlns".equals (prefix))) {
+ return null;
+ }
+ name[0] = uri;
+ name[1] = local.intern();
+ }
+
+ // Save in the cache for future use.
+ // (Could be shared with parent context...)
+ table.put(name[2], name);
+ return name;
+ }
+
+
+ /**
+ * Look up the URI associated with a prefix in this context.
+ *
+ * @param prefix The prefix to look up.
+ * @return The associated Namespace URI, or null if none is
+ * declared.
+ * @see org.xml.sax.helpers.NamespaceSupport#getURI
+ */
+ String getURI (String prefix)
+ {
+ if ("".equals(prefix)) {
+ return defaultNS;
+ } else if (prefixTable == null) {
+ return null;
+ } else {
+ return (String)prefixTable.get(prefix);
+ }
+ }
+
+
+ /**
+ * Look up one of the prefixes associated with a URI in this context.
+ *
+ * <p>Since many prefixes may be mapped to the same URI,
+ * the return value may be unreliable.</p>
+ *
+ * @param uri The URI to look up.
+ * @return The associated prefix, or null if none is declared.
+ * @see org.xml.sax.helpers.NamespaceSupport#getPrefix
+ */
+ String getPrefix (String uri)
+ {
+ if (uriTable == null) {
+ return null;
+ } else {
+ return (String)uriTable.get(uri);
+ }
+ }
+
+
+ /**
+ * Return an enumeration of prefixes declared in this context.
+ *
+ * @return An enumeration of prefixes (possibly empty).
+ * @see org.xml.sax.helpers.NamespaceSupport#getDeclaredPrefixes
+ */
+ Enumeration getDeclaredPrefixes ()
+ {
+ if (declarations == null) {
+ return EMPTY_ENUMERATION;
+ } else {
+ return declarations.elements();
+ }
+ }
+
+
+ /**
+ * Return an enumeration of all prefixes currently in force.
+ *
+ * <p>The default prefix, if in force, is <em>not</em>
+ * returned, and will have to be checked for separately.</p>
+ *
+ * @return An enumeration of prefixes (never empty).
+ * @see org.xml.sax.helpers.NamespaceSupport#getPrefixes
+ */
+ Enumeration getPrefixes ()
+ {
+ if (prefixTable == null) {
+ return EMPTY_ENUMERATION;
+ } else {
+ return prefixTable.keys();
+ }
+ }
+
+
+
+ ////////////////////////////////////////////////////////////////
+ // Internal methods.
+ ////////////////////////////////////////////////////////////////
+
+
+ /**
+ * Copy on write for the internal tables in this context.
+ *
+ * <p>This class is optimized for the normal case where most
+ * elements do not contain Namespace declarations.</p>
+ */
+ private void copyTables ()
+ {
+ if (prefixTable != null) {
+ prefixTable = (Hashtable)prefixTable.clone();
+ } else {
+ prefixTable = new Hashtable();
+ }
+ if (uriTable != null) {
+ uriTable = (Hashtable)uriTable.clone();
+ } else {
+ uriTable = new Hashtable();
+ }
+ elementNameTable = new Hashtable();
+ attributeNameTable = new Hashtable();
+ declSeen = true;
+ }
+
+
+
+ ////////////////////////////////////////////////////////////////
+ // Protected state.
+ ////////////////////////////////////////////////////////////////
+
+ Hashtable prefixTable;
+ Hashtable uriTable;
+ Hashtable elementNameTable;
+ Hashtable attributeNameTable;
+ String defaultNS = null;
+ boolean declsOK = true;
+
+
+
+ ////////////////////////////////////////////////////////////////
+ // Internal state.
+ ////////////////////////////////////////////////////////////////
+
+ private Vector declarations = null;
+ private boolean declSeen = false;
+ private Context parent = null;
+ }
+}
+
+// end of NamespaceSupport.java
diff --git a/xml/src/main/java/org/xml/sax/helpers/NewInstance.java b/xml/src/main/java/org/xml/sax/helpers/NewInstance.java
new file mode 100644
index 0000000..e590192
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/helpers/NewInstance.java
@@ -0,0 +1,79 @@
+// NewInstance.java - create a new instance of a class by name.
+// http://www.saxproject.org
+// Written by Edwin Goei, edwingo@apache.org
+// and by David Brownell, dbrownell@users.sourceforge.net
+// NO WARRANTY! This class is in the Public Domain.
+// $Id: NewInstance.java,v 1.4 2002/01/30 20:52:27 dbrownell Exp $
+
+package org.xml.sax.helpers;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.InvocationTargetException;
+
+/**
+ * Create a new instance of a class by name.
+ *
+ * <blockquote>
+ * <em>This module, both source code and documentation, is in the
+ * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
+ * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
+ * for further information.
+ * </blockquote>
+ *
+ * <p>This class contains a static method for creating an instance of a
+ * class from an explicit class name. It tries to use the thread's context
+ * ClassLoader if possible and falls back to using
+ * Class.forName(String).</p>
+ *
+ * <p>This code is designed to compile and run on JDK version 1.1 and later
+ * including versions of Java 2.</p>
+ *
+ * @author Edwin Goei, David Brownell
+ * @version 2.0.1 (sax2r2)
+ */
+class NewInstance {
+
+ /**
+ * Creates a new instance of the specified class name
+ *
+ * Package private so this code is not exposed at the API level.
+ */
+ static Object newInstance (ClassLoader classLoader, String className)
+ throws ClassNotFoundException, IllegalAccessException,
+ InstantiationException
+ {
+ Class driverClass;
+ if (classLoader == null) {
+ driverClass = Class.forName(className);
+ } else {
+ driverClass = classLoader.loadClass(className);
+ }
+ return driverClass.newInstance();
+ }
+
+ /**
+ * Figure out which ClassLoader to use. For JDK 1.2 and later use
+ * the context ClassLoader.
+ */
+ static ClassLoader getClassLoader ()
+ {
+ Method m = null;
+
+ try {
+ m = Thread.class.getMethod("getContextClassLoader");
+ } catch (NoSuchMethodException e) {
+ // Assume that we are running JDK 1.1, use the current ClassLoader
+ return NewInstance.class.getClassLoader();
+ }
+
+ try {
+ return (ClassLoader) m.invoke(Thread.currentThread());
+ } catch (IllegalAccessException e) {
+ // assert(false)
+ throw new UnknownError(e.getMessage());
+ } catch (InvocationTargetException e) {
+ // assert(e.getTargetException() instanceof SecurityException)
+ throw new UnknownError(e.getMessage());
+ }
+ }
+}
diff --git a/xml/src/main/java/org/xml/sax/helpers/ParserAdapter.java b/xml/src/main/java/org/xml/sax/helpers/ParserAdapter.java
new file mode 100644
index 0000000..7fc3813
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/helpers/ParserAdapter.java
@@ -0,0 +1,1046 @@
+// ParserAdapter.java - adapt a SAX1 Parser to a SAX2 XMLReader.
+// http://www.saxproject.org
+// Written by David Megginson
+// NO WARRANTY! This class is in the public domain.
+// $Id: ParserAdapter.java,v 1.16 2004/04/26 17:34:35 dmegginson Exp $
+
+package org.xml.sax.helpers;
+
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import org.xml.sax.Parser; // deprecated
+import org.xml.sax.InputSource;
+import org.xml.sax.Locator;
+import org.xml.sax.AttributeList; // deprecated
+import org.xml.sax.EntityResolver;
+import org.xml.sax.DTDHandler;
+import org.xml.sax.DocumentHandler; // deprecated
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+
+import org.xml.sax.XMLReader;
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXNotRecognizedException;
+import org.xml.sax.SAXNotSupportedException;
+
+
+/**
+ * Adapt a SAX1 Parser as a SAX2 XMLReader.
+ *
+ * <blockquote>
+ * <em>This module, both source code and documentation, is in the
+ * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
+ * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
+ * for further information.
+ * </blockquote>
+ *
+ * <p>This class wraps a SAX1 {@link org.xml.sax.Parser Parser}
+ * and makes it act as a SAX2 {@link org.xml.sax.XMLReader XMLReader},
+ * with feature, property, and Namespace support. Note
+ * that it is not possible to report {@link org.xml.sax.ContentHandler#skippedEntity
+ * skippedEntity} events, since SAX1 does not make that information available.</p>
+ *
+ * <p>This adapter does not test for duplicate Namespace-qualified
+ * attribute names.</p>
+ *
+ * @since SAX 2.0
+ * @author David Megginson
+ * @version 2.0.1 (sax2r2)
+ * @see org.xml.sax.helpers.XMLReaderAdapter
+ * @see org.xml.sax.XMLReader
+ * @see org.xml.sax.Parser
+ */
+public class ParserAdapter implements XMLReader, DocumentHandler
+{
+
+
+ ////////////////////////////////////////////////////////////////////
+ // Constructors.
+ ////////////////////////////////////////////////////////////////////
+
+
+ /**
+ * Construct a new parser adapter.
+ *
+ * <p>Use the "org.xml.sax.parser" property to locate the
+ * embedded SAX1 driver.</p>
+ *
+ * @exception SAXException If the embedded driver
+ * cannot be instantiated or if the
+ * org.xml.sax.parser property is not specified.
+ */
+ public ParserAdapter ()
+ throws SAXException
+ {
+ super();
+
+ String driver = System.getProperty("org.xml.sax.parser");
+
+ try {
+ setup(ParserFactory.makeParser());
+ } catch (ClassNotFoundException e1) {
+ throw new
+ SAXException("Cannot find SAX1 driver class " +
+ driver, e1);
+ } catch (IllegalAccessException e2) {
+ throw new
+ SAXException("SAX1 driver class " +
+ driver +
+ " found but cannot be loaded", e2);
+ } catch (InstantiationException e3) {
+ throw new
+ SAXException("SAX1 driver class " +
+ driver +
+ " loaded but cannot be instantiated", e3);
+ } catch (ClassCastException e4) {
+ throw new
+ SAXException("SAX1 driver class " +
+ driver +
+ " does not implement org.xml.sax.Parser");
+ } catch (NullPointerException e5) {
+ throw new
+ SAXException("System property org.xml.sax.parser not specified");
+ }
+ }
+
+
+ /**
+ * Construct a new parser adapter.
+ *
+ * <p>Note that the embedded parser cannot be changed once the
+ * adapter is created; to embed a different parser, allocate
+ * a new ParserAdapter.</p>
+ *
+ * @param parser The SAX1 parser to embed.
+ * @exception java.lang.NullPointerException If the parser parameter
+ * is null.
+ */
+ public ParserAdapter (Parser parser)
+ {
+ super();
+ setup(parser);
+ }
+
+
+ /**
+ * Internal setup method.
+ *
+ * @param parser The embedded parser.
+ * @exception java.lang.NullPointerException If the parser parameter
+ * is null.
+ */
+ private void setup (Parser parser)
+ {
+ if (parser == null) {
+ throw new
+ NullPointerException("Parser argument must not be null");
+ }
+ this.parser = parser;
+ atts = new AttributesImpl();
+ nsSupport = new NamespaceSupport();
+ attAdapter = new AttributeListAdapter();
+ }
+
+
+
+ ////////////////////////////////////////////////////////////////////
+ // Implementation of org.xml.sax.XMLReader.
+ ////////////////////////////////////////////////////////////////////
+
+
+ //
+ // Internal constants for the sake of convenience.
+ //
+ private final static String FEATURES = "http://xml.org/sax/features/";
+ private final static String NAMESPACES = FEATURES + "namespaces";
+ private final static String NAMESPACE_PREFIXES = FEATURES + "namespace-prefixes";
+ private final static String XMLNS_URIs = FEATURES + "xmlns-uris";
+
+
+ /**
+ * Set a feature flag for the parser.
+ *
+ * <p>The only features recognized are namespaces and
+ * namespace-prefixes.</p>
+ *
+ * @param name The feature name, as a complete URI.
+ * @param value The requested feature value.
+ * @exception SAXNotRecognizedException If the feature
+ * can't be assigned or retrieved.
+ * @exception SAXNotSupportedException If the feature
+ * can't be assigned that value.
+ * @see org.xml.sax.XMLReader#setFeature
+ */
+ public void setFeature (String name, boolean value)
+ throws SAXNotRecognizedException, SAXNotSupportedException
+ {
+ if (name.equals(NAMESPACES)) {
+ checkNotParsing("feature", name);
+ namespaces = value;
+ if (!namespaces && !prefixes) {
+ prefixes = true;
+ }
+ } else if (name.equals(NAMESPACE_PREFIXES)) {
+ checkNotParsing("feature", name);
+ prefixes = value;
+ if (!prefixes && !namespaces) {
+ namespaces = true;
+ }
+ } else if (name.equals(XMLNS_URIs)) {
+ checkNotParsing("feature", name);
+ uris = value;
+ } else {
+ throw new SAXNotRecognizedException("Feature: " + name);
+ }
+ }
+
+
+ /**
+ * Check a parser feature flag.
+ *
+ * <p>The only features recognized are namespaces and
+ * namespace-prefixes.</p>
+ *
+ * @param name The feature name, as a complete URI.
+ * @return The current feature value.
+ * @exception SAXNotRecognizedException If the feature
+ * value can't be assigned or retrieved.
+ * @exception SAXNotSupportedException If the
+ * feature is not currently readable.
+ * @see org.xml.sax.XMLReader#setFeature
+ */
+ public boolean getFeature (String name)
+ throws SAXNotRecognizedException, SAXNotSupportedException
+ {
+ if (name.equals(NAMESPACES)) {
+ return namespaces;
+ } else if (name.equals(NAMESPACE_PREFIXES)) {
+ return prefixes;
+ } else if (name.equals(XMLNS_URIs)) {
+ return uris;
+ } else {
+ throw new SAXNotRecognizedException("Feature: " + name);
+ }
+ }
+
+
+ /**
+ * Set a parser property.
+ *
+ * <p>No properties are currently recognized.</p>
+ *
+ * @param name The property name.
+ * @param value The property value.
+ * @exception SAXNotRecognizedException If the property
+ * value can't be assigned or retrieved.
+ * @exception SAXNotSupportedException If the property
+ * can't be assigned that value.
+ * @see org.xml.sax.XMLReader#setProperty
+ */
+ public void setProperty (String name, Object value)
+ throws SAXNotRecognizedException, SAXNotSupportedException
+ {
+ throw new SAXNotRecognizedException("Property: " + name);
+ }
+
+
+ /**
+ * Get a parser property.
+ *
+ * <p>No properties are currently recognized.</p>
+ *
+ * @param name The property name.
+ * @return The property value.
+ * @exception SAXNotRecognizedException If the property
+ * value can't be assigned or retrieved.
+ * @exception SAXNotSupportedException If the property
+ * value is not currently readable.
+ * @see org.xml.sax.XMLReader#getProperty
+ */
+ public Object getProperty (String name)
+ throws SAXNotRecognizedException, SAXNotSupportedException
+ {
+ throw new SAXNotRecognizedException("Property: " + name);
+ }
+
+
+ /**
+ * Set the entity resolver.
+ *
+ * @param resolver The new entity resolver.
+ * @see org.xml.sax.XMLReader#setEntityResolver
+ */
+ public void setEntityResolver (EntityResolver resolver)
+ {
+ entityResolver = resolver;
+ }
+
+
+ /**
+ * Return the current entity resolver.
+ *
+ * @return The current entity resolver, or null if none was supplied.
+ * @see org.xml.sax.XMLReader#getEntityResolver
+ */
+ public EntityResolver getEntityResolver ()
+ {
+ return entityResolver;
+ }
+
+
+ /**
+ * Set the DTD handler.
+ *
+ * @param handler the new DTD handler
+ * @see org.xml.sax.XMLReader#setEntityResolver
+ */
+ public void setDTDHandler (DTDHandler handler)
+ {
+ dtdHandler = handler;
+ }
+
+
+ /**
+ * Return the current DTD handler.
+ *
+ * @return the current DTD handler, or null if none was supplied
+ * @see org.xml.sax.XMLReader#getEntityResolver
+ */
+ public DTDHandler getDTDHandler ()
+ {
+ return dtdHandler;
+ }
+
+
+ /**
+ * Set the content handler.
+ *
+ * @param handler the new content handler
+ * @see org.xml.sax.XMLReader#setEntityResolver
+ */
+ public void setContentHandler (ContentHandler handler)
+ {
+ contentHandler = handler;
+ }
+
+
+ /**
+ * Return the current content handler.
+ *
+ * @return The current content handler, or null if none was supplied.
+ * @see org.xml.sax.XMLReader#getEntityResolver
+ */
+ public ContentHandler getContentHandler ()
+ {
+ return contentHandler;
+ }
+
+
+ /**
+ * Set the error handler.
+ *
+ * @param handler The new error handler.
+ * @see org.xml.sax.XMLReader#setEntityResolver
+ */
+ public void setErrorHandler (ErrorHandler handler)
+ {
+ errorHandler = handler;
+ }
+
+
+ /**
+ * Return the current error handler.
+ *
+ * @return The current error handler, or null if none was supplied.
+ * @see org.xml.sax.XMLReader#getEntityResolver
+ */
+ public ErrorHandler getErrorHandler ()
+ {
+ return errorHandler;
+ }
+
+
+ /**
+ * Parse an XML document.
+ *
+ * @param systemId The absolute URL of the document.
+ * @exception java.io.IOException If there is a problem reading
+ * the raw content of the document.
+ * @exception SAXException If there is a problem
+ * processing the document.
+ * @see #parse(org.xml.sax.InputSource)
+ * @see org.xml.sax.Parser#parse(java.lang.String)
+ */
+ public void parse (String systemId)
+ throws IOException, SAXException
+ {
+ parse(new InputSource(systemId));
+ }
+
+
+ /**
+ * Parse an XML document.
+ *
+ * @param input An input source for the document.
+ * @exception java.io.IOException If there is a problem reading
+ * the raw content of the document.
+ * @exception SAXException If there is a problem
+ * processing the document.
+ * @see #parse(java.lang.String)
+ * @see org.xml.sax.Parser#parse(org.xml.sax.InputSource)
+ */
+ public void parse (InputSource input)
+ throws IOException, SAXException
+ {
+ if (parsing) {
+ throw new SAXException("Parser is already in use");
+ }
+ setupParser();
+ parsing = true;
+ try {
+ parser.parse(input);
+ } finally {
+ parsing = false;
+ }
+ parsing = false;
+ }
+
+
+
+ ////////////////////////////////////////////////////////////////////
+ // Implementation of org.xml.sax.DocumentHandler.
+ ////////////////////////////////////////////////////////////////////
+
+
+ /**
+ * Adapter implementation method; do not call.
+ * Adapt a SAX1 document locator event.
+ *
+ * @param locator A document locator.
+ * @see org.xml.sax.ContentHandler#setDocumentLocator
+ */
+ public void setDocumentLocator (Locator locator)
+ {
+ this.locator = locator;
+ if (contentHandler != null) {
+ contentHandler.setDocumentLocator(locator);
+ }
+ }
+
+
+ /**
+ * Adapter implementation method; do not call.
+ * Adapt a SAX1 start document event.
+ *
+ * @exception SAXException The client may raise a
+ * processing exception.
+ * @see org.xml.sax.DocumentHandler#startDocument
+ */
+ public void startDocument ()
+ throws SAXException
+ {
+ if (contentHandler != null) {
+ contentHandler.startDocument();
+ }
+ }
+
+
+ /**
+ * Adapter implementation method; do not call.
+ * Adapt a SAX1 end document event.
+ *
+ * @exception SAXException The client may raise a
+ * processing exception.
+ * @see org.xml.sax.DocumentHandler#endDocument
+ */
+ public void endDocument ()
+ throws SAXException
+ {
+ if (contentHandler != null) {
+ contentHandler.endDocument();
+ }
+ }
+
+
+ /**
+ * Adapter implementation method; do not call.
+ * Adapt a SAX1 startElement event.
+ *
+ * <p>If necessary, perform Namespace processing.</p>
+ *
+ * @param qName The qualified (prefixed) name.
+ * @param qAtts The XML attribute list (with qnames).
+ * @exception SAXException The client may raise a
+ * processing exception.
+ */
+ public void startElement (String qName, AttributeList qAtts)
+ throws SAXException
+ {
+ // These are exceptions from the
+ // first pass; they should be
+ // ignored if there's a second pass,
+ // but reported otherwise.
+ Vector exceptions = null;
+
+ // If we're not doing Namespace
+ // processing, dispatch this quickly.
+ if (!namespaces) {
+ if (contentHandler != null) {
+ attAdapter.setAttributeList(qAtts);
+ contentHandler.startElement("", "", qName.intern(),
+ attAdapter);
+ }
+ return;
+ }
+
+
+ // OK, we're doing Namespace processing.
+ nsSupport.pushContext();
+ int length = qAtts.getLength();
+
+ // First pass: handle NS decls
+ for (int i = 0; i < length; i++) {
+ String attQName = qAtts.getName(i);
+
+ if (!attQName.startsWith("xmlns"))
+ continue;
+ // Could be a declaration...
+ String prefix;
+ int n = attQName.indexOf(':');
+
+ // xmlns=...
+ if (n == -1 && attQName.length () == 5) {
+ prefix = "";
+ } else if (n != 5) {
+ // XML namespaces spec doesn't discuss "xmlnsf:oo"
+ // (and similarly named) attributes ... at most, warn
+ continue;
+ } else // xmlns:foo=...
+ prefix = attQName.substring(n+1);
+
+ String value = qAtts.getValue(i);
+ if (!nsSupport.declarePrefix(prefix, value)) {
+ reportError("Illegal Namespace prefix: " + prefix);
+ continue;
+ }
+ if (contentHandler != null)
+ contentHandler.startPrefixMapping(prefix, value);
+ }
+
+ // Second pass: copy all relevant
+ // attributes into the SAX2 AttributeList
+ // using updated prefix bindings
+ atts.clear();
+ for (int i = 0; i < length; i++) {
+ String attQName = qAtts.getName(i);
+ String type = qAtts.getType(i);
+ String value = qAtts.getValue(i);
+
+ // Declaration?
+ if (attQName.startsWith("xmlns")) {
+ String prefix;
+ int n = attQName.indexOf(':');
+
+ if (n == -1 && attQName.length () == 5) {
+ prefix = "";
+ } else if (n != 5) {
+ // XML namespaces spec doesn't discuss "xmlnsf:oo"
+ // (and similarly named) attributes ... ignore
+ prefix = null;
+ } else {
+ prefix = attQName.substring(6);
+ }
+ // Yes, decl: report or prune
+ if (prefix != null) {
+ if (prefixes) {
+ if (uris)
+ // note funky case: localname can be null
+ // when declaring the default prefix, and
+ // yet the uri isn't null.
+ atts.addAttribute (nsSupport.XMLNS, prefix,
+ attQName.intern(), type, value);
+ else
+ atts.addAttribute ("", "",
+ attQName.intern(), type, value);
+ }
+ continue;
+ }
+ }
+
+ // Not a declaration -- report
+ try {
+ String attName[] = processName(attQName, true, true);
+ atts.addAttribute(attName[0], attName[1], attName[2],
+ type, value);
+ } catch (SAXException e) {
+ if (exceptions == null)
+ exceptions = new Vector();
+ exceptions.addElement(e);
+ atts.addAttribute("", attQName, attQName, type, value);
+ }
+ }
+
+ // now handle the deferred exception reports
+ if (exceptions != null && errorHandler != null) {
+ for (int i = 0; i < exceptions.size(); i++)
+ errorHandler.error((SAXParseException)
+ (exceptions.elementAt(i)));
+ }
+
+ // OK, finally report the event.
+ if (contentHandler != null) {
+ String name[] = processName(qName, false, false);
+ contentHandler.startElement(name[0], name[1], name[2], atts);
+ }
+ }
+
+
+ /**
+ * Adapter implementation method; do not call.
+ * Adapt a SAX1 end element event.
+ *
+ * @param qName The qualified (prefixed) name.
+ * @exception SAXException The client may raise a
+ * processing exception.
+ * @see org.xml.sax.DocumentHandler#endElement
+ */
+ public void endElement (String qName)
+ throws SAXException
+ {
+ // If we're not doing Namespace
+ // processing, dispatch this quickly.
+ if (!namespaces) {
+ if (contentHandler != null) {
+ contentHandler.endElement("", "", qName.intern());
+ }
+ return;
+ }
+
+ // Split the name.
+ String names[] = processName(qName, false, false);
+ if (contentHandler != null) {
+ contentHandler.endElement(names[0], names[1], names[2]);
+ Enumeration prefixes = nsSupport.getDeclaredPrefixes();
+ while (prefixes.hasMoreElements()) {
+ String prefix = (String)prefixes.nextElement();
+ contentHandler.endPrefixMapping(prefix);
+ }
+ }
+ nsSupport.popContext();
+ }
+
+
+ /**
+ * Adapter implementation method; do not call.
+ * Adapt a SAX1 characters event.
+ *
+ * @param ch An array of characters.
+ * @param start The starting position in the array.
+ * @param length The number of characters to use.
+ * @exception SAXException The client may raise a
+ * processing exception.
+ * @see org.xml.sax.DocumentHandler#characters
+ */
+ public void characters (char ch[], int start, int length)
+ throws SAXException
+ {
+ if (contentHandler != null) {
+ contentHandler.characters(ch, start, length);
+ }
+ }
+
+
+ /**
+ * Adapter implementation method; do not call.
+ * Adapt a SAX1 ignorable whitespace event.
+ *
+ * @param ch An array of characters.
+ * @param start The starting position in the array.
+ * @param length The number of characters to use.
+ * @exception SAXException The client may raise a
+ * processing exception.
+ * @see org.xml.sax.DocumentHandler#ignorableWhitespace
+ */
+ public void ignorableWhitespace (char ch[], int start, int length)
+ throws SAXException
+ {
+ if (contentHandler != null) {
+ contentHandler.ignorableWhitespace(ch, start, length);
+ }
+ }
+
+
+ /**
+ * Adapter implementation method; do not call.
+ * Adapt a SAX1 processing instruction event.
+ *
+ * @param target The processing instruction target.
+ * @param data The remainder of the processing instruction
+ * @exception SAXException The client may raise a
+ * processing exception.
+ * @see org.xml.sax.DocumentHandler#processingInstruction
+ */
+ public void processingInstruction (String target, String data)
+ throws SAXException
+ {
+ if (contentHandler != null) {
+ contentHandler.processingInstruction(target, data);
+ }
+ }
+
+
+
+ ////////////////////////////////////////////////////////////////////
+ // Internal utility methods.
+ ////////////////////////////////////////////////////////////////////
+
+
+ /**
+ * Initialize the parser before each run.
+ */
+ private void setupParser ()
+ {
+ // catch an illegal "nonsense" state.
+ if (!prefixes && !namespaces)
+ throw new IllegalStateException ();
+
+ nsSupport.reset();
+ if (uris)
+ nsSupport.setNamespaceDeclUris (true);
+
+ if (entityResolver != null) {
+ parser.setEntityResolver(entityResolver);
+ }
+ if (dtdHandler != null) {
+ parser.setDTDHandler(dtdHandler);
+ }
+ if (errorHandler != null) {
+ parser.setErrorHandler(errorHandler);
+ }
+ parser.setDocumentHandler(this);
+ locator = null;
+ }
+
+
+ /**
+ * Process a qualified (prefixed) name.
+ *
+ * <p>If the name has an undeclared prefix, use only the qname
+ * and make an ErrorHandler.error callback in case the app is
+ * interested.</p>
+ *
+ * @param qName The qualified (prefixed) name.
+ * @param isAttribute true if this is an attribute name.
+ * @return The name split into three parts.
+ * @exception SAXException The client may throw
+ * an exception if there is an error callback.
+ */
+ private String [] processName (String qName, boolean isAttribute,
+ boolean useException)
+ throws SAXException
+ {
+ String parts[] = nsSupport.processName(qName, nameParts,
+ isAttribute);
+ if (parts == null) {
+ if (useException)
+ throw makeException("Undeclared prefix: " + qName);
+ reportError("Undeclared prefix: " + qName);
+ parts = new String[3];
+ parts[0] = parts[1] = "";
+ parts[2] = qName.intern();
+ }
+ return parts;
+ }
+
+
+ /**
+ * Report a non-fatal error.
+ *
+ * @param message The error message.
+ * @exception SAXException The client may throw
+ * an exception.
+ */
+ void reportError (String message)
+ throws SAXException
+ {
+ if (errorHandler != null)
+ errorHandler.error(makeException(message));
+ }
+
+
+ /**
+ * Construct an exception for the current context.
+ *
+ * @param message The error message.
+ */
+ private SAXParseException makeException (String message)
+ {
+ if (locator != null) {
+ return new SAXParseException(message, locator);
+ } else {
+ return new SAXParseException(message, null, null, -1, -1);
+ }
+ }
+
+
+ /**
+ * Throw an exception if we are parsing.
+ *
+ * <p>Use this method to detect illegal feature or
+ * property changes.</p>
+ *
+ * @param type The type of thing (feature or property).
+ * @param name The feature or property name.
+ * @exception SAXNotSupportedException If a
+ * document is currently being parsed.
+ */
+ private void checkNotParsing (String type, String name)
+ throws SAXNotSupportedException
+ {
+ if (parsing) {
+ throw new SAXNotSupportedException("Cannot change " +
+ type + ' ' +
+ name + " while parsing");
+
+ }
+ }
+
+
+
+ ////////////////////////////////////////////////////////////////////
+ // Internal state.
+ ////////////////////////////////////////////////////////////////////
+
+ private NamespaceSupport nsSupport;
+ private AttributeListAdapter attAdapter;
+
+ private boolean parsing = false;
+ private String nameParts[] = new String[3];
+
+ private Parser parser = null;
+
+ private AttributesImpl atts = null;
+
+ // Features
+ private boolean namespaces = true;
+ private boolean prefixes = false;
+ private boolean uris = false;
+
+ // Properties
+
+ // Handlers
+ Locator locator;
+
+ EntityResolver entityResolver = null;
+ DTDHandler dtdHandler = null;
+ ContentHandler contentHandler = null;
+ ErrorHandler errorHandler = null;
+
+
+
+ ////////////////////////////////////////////////////////////////////
+ // Inner class to wrap an AttributeList when not doing NS proc.
+ ////////////////////////////////////////////////////////////////////
+
+
+ /**
+ * Adapt a SAX1 AttributeList as a SAX2 Attributes object.
+ *
+ * <p>This class is in the Public Domain, and comes with NO
+ * WARRANTY of any kind.</p>
+ *
+ * <p>This wrapper class is used only when Namespace support
+ * is disabled -- it provides pretty much a direct mapping
+ * from SAX1 to SAX2, except that names and types are
+ * interned whenever requested.</p>
+ */
+ final class AttributeListAdapter implements Attributes
+ {
+
+ /**
+ * Construct a new adapter.
+ */
+ AttributeListAdapter ()
+ {
+ }
+
+
+ /**
+ * Set the embedded AttributeList.
+ *
+ * <p>This method must be invoked before any of the others
+ * can be used.</p>
+ *
+ * @param The SAX1 attribute list (with qnames).
+ */
+ void setAttributeList (AttributeList qAtts)
+ {
+ this.qAtts = qAtts;
+ }
+
+
+ /**
+ * Return the length of the attribute list.
+ *
+ * @return The number of attributes in the list.
+ * @see org.xml.sax.Attributes#getLength
+ */
+ public int getLength ()
+ {
+ return qAtts.getLength();
+ }
+
+
+ /**
+ * Return the Namespace URI of the specified attribute.
+ *
+ * @param The attribute's index.
+ * @return Always the empty string.
+ * @see org.xml.sax.Attributes#getURI
+ */
+ public String getURI (int i)
+ {
+ return "";
+ }
+
+
+ /**
+ * Return the local name of the specified attribute.
+ *
+ * @param The attribute's index.
+ * @return Always the empty string.
+ * @see org.xml.sax.Attributes#getLocalName
+ */
+ public String getLocalName (int i)
+ {
+ return "";
+ }
+
+
+ /**
+ * Return the qualified (prefixed) name of the specified attribute.
+ *
+ * @param The attribute's index.
+ * @return The attribute's qualified name, internalized.
+ */
+ public String getQName (int i)
+ {
+ return qAtts.getName(i).intern();
+ }
+
+
+ /**
+ * Return the type of the specified attribute.
+ *
+ * @param The attribute's index.
+ * @return The attribute's type as an internalized string.
+ */
+ public String getType (int i)
+ {
+ return qAtts.getType(i).intern();
+ }
+
+
+ /**
+ * Return the value of the specified attribute.
+ *
+ * @param The attribute's index.
+ * @return The attribute's value.
+ */
+ public String getValue (int i)
+ {
+ return qAtts.getValue(i);
+ }
+
+
+ /**
+ * Look up an attribute index by Namespace name.
+ *
+ * @param uri The Namespace URI or the empty string.
+ * @param localName The local name.
+ * @return The attributes index, or -1 if none was found.
+ * @see org.xml.sax.Attributes#getIndex(java.lang.String,java.lang.String)
+ */
+ public int getIndex (String uri, String localName)
+ {
+ return -1;
+ }
+
+
+ /**
+ * Look up an attribute index by qualified (prefixed) name.
+ *
+ * @param qName The qualified name.
+ * @return The attributes index, or -1 if none was found.
+ * @see org.xml.sax.Attributes#getIndex(java.lang.String)
+ */
+ public int getIndex (String qName)
+ {
+ int max = atts.getLength();
+ for (int i = 0; i < max; i++) {
+ if (qAtts.getName(i).equals(qName)) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+
+ /**
+ * Look up the type of an attribute by Namespace name.
+ *
+ * @param uri The Namespace URI
+ * @param localName The local name.
+ * @return The attribute's type as an internalized string.
+ */
+ public String getType (String uri, String localName)
+ {
+ return null;
+ }
+
+
+ /**
+ * Look up the type of an attribute by qualified (prefixed) name.
+ *
+ * @param qName The qualified name.
+ * @return The attribute's type as an internalized string.
+ */
+ public String getType (String qName)
+ {
+ return qAtts.getType(qName).intern();
+ }
+
+
+ /**
+ * Look up the value of an attribute by Namespace name.
+ *
+ * @param uri The Namespace URI
+ * @param localName The local name.
+ * @return The attribute's value.
+ */
+ public String getValue (String uri, String localName)
+ {
+ return null;
+ }
+
+
+ /**
+ * Look up the value of an attribute by qualified (prefixed) name.
+ *
+ * @param qName The qualified name.
+ * @return The attribute's value.
+ */
+ public String getValue (String qName)
+ {
+ return qAtts.getValue(qName);
+ }
+
+ private AttributeList qAtts;
+ }
+}
+
+// end of ParserAdapter.java
diff --git a/xml/src/main/java/org/xml/sax/helpers/ParserFactory.java b/xml/src/main/java/org/xml/sax/helpers/ParserFactory.java
new file mode 100644
index 0000000..ffe2a60
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/helpers/ParserFactory.java
@@ -0,0 +1,133 @@
+// SAX parser factory.
+// http://www.saxproject.org
+// No warranty; no copyright -- use this as you will.
+// $Id: ParserFactory.java,v 1.7 2002/01/30 20:52:36 dbrownell Exp $
+
+package org.xml.sax.helpers;
+
+import java.lang.ClassNotFoundException;
+import java.lang.IllegalAccessException;
+import java.lang.InstantiationException;
+import java.lang.SecurityException;
+import java.lang.ClassCastException;
+
+import org.xml.sax.Parser;
+
+
+/**
+ * Java-specific class for dynamically loading SAX parsers.
+ *
+ * <blockquote>
+ * <em>This module, both source code and documentation, is in the
+ * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
+ * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
+ * for further information.
+ * </blockquote>
+ *
+ * <p><strong>Note:</strong> This class is designed to work with the now-deprecated
+ * SAX1 {@link org.xml.sax.Parser Parser} class. SAX2 applications should use
+ * {@link org.xml.sax.helpers.XMLReaderFactory XMLReaderFactory} instead.</p>
+ *
+ * <p>ParserFactory is not part of the platform-independent definition
+ * of SAX; it is an additional convenience class designed
+ * specifically for Java XML application writers. SAX applications
+ * can use the static methods in this class to allocate a SAX parser
+ * dynamically at run-time based either on the value of the
+ * `org.xml.sax.parser' system property or on a string containing the class
+ * name.</p>
+ *
+ * <p>Note that the application still requires an XML parser that
+ * implements SAX1.</p>
+ *
+ * @deprecated This class works with the deprecated
+ * {@link org.xml.sax.Parser Parser}
+ * interface.
+ * @since SAX 1.0
+ * @author David Megginson
+ * @version 2.0.1 (sax2r2)
+ */
+public class ParserFactory {
+
+
+ /**
+ * Private null constructor.
+ */
+ private ParserFactory ()
+ {
+ }
+
+
+ /**
+ * Create a new SAX parser using the `org.xml.sax.parser' system property.
+ *
+ * <p>The named class must exist and must implement the
+ * {@link org.xml.sax.Parser Parser} interface.</p>
+ *
+ * @return the newly created parser.
+ *
+ * @exception java.lang.NullPointerException There is no value
+ * for the `org.xml.sax.parser' system property.
+ * @exception java.lang.ClassNotFoundException The SAX parser
+ * class was not found (check your CLASSPATH).
+ * @exception IllegalAccessException The SAX parser class was
+ * found, but you do not have permission to load
+ * it.
+ * @exception InstantiationException The SAX parser class was
+ * found but could not be instantiated.
+ * @exception java.lang.ClassCastException The SAX parser class
+ * was found and instantiated, but does not implement
+ * org.xml.sax.Parser.
+ * @see #makeParser(java.lang.String)
+ * @see org.xml.sax.Parser
+ */
+ public static Parser makeParser ()
+ throws ClassNotFoundException,
+ IllegalAccessException,
+ InstantiationException,
+ NullPointerException,
+ ClassCastException
+ {
+ String className = System.getProperty("org.xml.sax.parser");
+ if (className == null) {
+ throw new NullPointerException("No value for sax.parser property");
+ } else {
+ return makeParser(className);
+ }
+ }
+
+
+ /**
+ * Create a new SAX parser object using the class name provided.
+ *
+ * <p>The named class must exist and must implement the
+ * {@link org.xml.sax.Parser Parser} interface.</p>
+ *
+ * @return the newly created parser.
+ *
+ * @param className A string containing the name of the
+ * SAX parser class.
+ * @exception java.lang.ClassNotFoundException The SAX parser
+ * class was not found (check your CLASSPATH).
+ * @exception IllegalAccessException The SAX parser class was
+ * found, but you do not have permission to load
+ * it.
+ * @exception InstantiationException The SAX parser class was
+ * found but could not be instantiated.
+ * @exception java.lang.ClassCastException The SAX parser class
+ * was found and instantiated, but does not implement
+ * org.xml.sax.Parser.
+ * @see #makeParser()
+ * @see org.xml.sax.Parser
+ */
+ public static Parser makeParser (String className)
+ throws ClassNotFoundException,
+ IllegalAccessException,
+ InstantiationException,
+ ClassCastException
+ {
+ return (Parser) NewInstance.newInstance (
+ NewInstance.getClassLoader (), className);
+ }
+
+}
+
diff --git a/xml/src/main/java/org/xml/sax/helpers/XMLFilterImpl.java b/xml/src/main/java/org/xml/sax/helpers/XMLFilterImpl.java
new file mode 100644
index 0000000..68e2579
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/helpers/XMLFilterImpl.java
@@ -0,0 +1,715 @@
+// XMLFilterImpl.java - base SAX2 filter implementation.
+// http://www.saxproject.org
+// Written by David Megginson
+// NO WARRANTY! This class is in the Public Domain.
+// $Id: XMLFilterImpl.java,v 1.9 2004/04/26 17:34:35 dmegginson Exp $
+
+package org.xml.sax.helpers;
+
+import java.io.IOException;
+
+import org.xml.sax.XMLReader;
+import org.xml.sax.XMLFilter;
+import org.xml.sax.InputSource;
+import org.xml.sax.Locator;
+import org.xml.sax.Attributes;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.DTDHandler;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.SAXNotSupportedException;
+import org.xml.sax.SAXNotRecognizedException;
+
+
+/**
+ * Base class for deriving an XML filter.
+ *
+ * <blockquote>
+ * <em>This module, both source code and documentation, is in the
+ * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
+ * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
+ * for further information.
+ * </blockquote>
+ *
+ * <p>This class is designed to sit between an {@link org.xml.sax.XMLReader
+ * XMLReader} and the client application's event handlers. By default, it
+ * does nothing but pass requests up to the reader and events
+ * on to the handlers unmodified, but subclasses can override
+ * specific methods to modify the event stream or the configuration
+ * requests as they pass through.</p>
+ *
+ * @since SAX 2.0
+ * @author David Megginson
+ * @version 2.0.1 (sax2r2)
+ * @see org.xml.sax.XMLFilter
+ * @see org.xml.sax.XMLReader
+ * @see org.xml.sax.EntityResolver
+ * @see org.xml.sax.DTDHandler
+ * @see org.xml.sax.ContentHandler
+ * @see org.xml.sax.ErrorHandler
+ */
+public class XMLFilterImpl
+ implements XMLFilter, EntityResolver, DTDHandler, ContentHandler, ErrorHandler
+{
+
+
+ ////////////////////////////////////////////////////////////////////
+ // Constructors.
+ ////////////////////////////////////////////////////////////////////
+
+
+ /**
+ * Construct an empty XML filter, with no parent.
+ *
+ * <p>This filter will have no parent: you must assign a parent
+ * before you start a parse or do any configuration with
+ * setFeature or setProperty, unless you use this as a pure event
+ * consumer rather than as an {@link XMLReader}.</p>
+ *
+ * @see org.xml.sax.XMLReader#setFeature
+ * @see org.xml.sax.XMLReader#setProperty
+ * @see #setParent
+ */
+ public XMLFilterImpl ()
+ {
+ super();
+ }
+
+
+ /**
+ * Construct an XML filter with the specified parent.
+ *
+ * @param parent the XML reader from which this filter receives its events.
+ *
+ * @see #setParent
+ * @see #getParent
+ */
+ public XMLFilterImpl (XMLReader parent)
+ {
+ super();
+ setParent(parent);
+ }
+
+
+
+ ////////////////////////////////////////////////////////////////////
+ // Implementation of org.xml.sax.XMLFilter.
+ ////////////////////////////////////////////////////////////////////
+
+
+ /**
+ * Set the parent reader.
+ *
+ * <p>This is the {@link org.xml.sax.XMLReader XMLReader} from which
+ * this filter will obtain its events and to which it will pass its
+ * configuration requests. The parent may itself be another filter.</p>
+ *
+ * <p>If there is no parent reader set, any attempt to parse
+ * or to set or get a feature or property will fail.</p>
+ *
+ * @param parent The parent XML reader.
+ * @see #getParent
+ */
+ public void setParent (XMLReader parent)
+ {
+ this.parent = parent;
+ }
+
+
+ /**
+ * Get the parent reader.
+ *
+ * @return The parent XML reader, or null if none is set.
+ * @see #setParent
+ */
+ public XMLReader getParent ()
+ {
+ return parent;
+ }
+
+
+
+ ////////////////////////////////////////////////////////////////////
+ // Implementation of org.xml.sax.XMLReader.
+ ////////////////////////////////////////////////////////////////////
+
+
+ /**
+ * Set the value of a feature.
+ *
+ * <p>This will always fail if the parent is null.</p>
+ *
+ * @param name The feature name.
+ * @param value The requested feature value.
+ * @exception org.xml.sax.SAXNotRecognizedException If the feature
+ * value can't be assigned or retrieved from the parent.
+ * @exception org.xml.sax.SAXNotSupportedException When the
+ * parent recognizes the feature name but
+ * cannot set the requested value.
+ */
+ public void setFeature (String name, boolean value)
+ throws SAXNotRecognizedException, SAXNotSupportedException
+ {
+ if (parent != null) {
+ parent.setFeature(name, value);
+ } else {
+ throw new SAXNotRecognizedException("Feature: " + name);
+ }
+ }
+
+
+ /**
+ * Look up the value of a feature.
+ *
+ * <p>This will always fail if the parent is null.</p>
+ *
+ * @param name The feature name.
+ * @return The current value of the feature.
+ * @exception org.xml.sax.SAXNotRecognizedException If the feature
+ * value can't be assigned or retrieved from the parent.
+ * @exception org.xml.sax.SAXNotSupportedException When the
+ * parent recognizes the feature name but
+ * cannot determine its value at this time.
+ */
+ public boolean getFeature (String name)
+ throws SAXNotRecognizedException, SAXNotSupportedException
+ {
+ if (parent != null) {
+ return parent.getFeature(name);
+ } else {
+ throw new SAXNotRecognizedException("Feature: " + name);
+ }
+ }
+
+
+ /**
+ * Set the value of a property.
+ *
+ * <p>This will always fail if the parent is null.</p>
+ *
+ * @param name The property name.
+ * @param value The requested property value.
+ * @exception org.xml.sax.SAXNotRecognizedException If the property
+ * value can't be assigned or retrieved from the parent.
+ * @exception org.xml.sax.SAXNotSupportedException When the
+ * parent recognizes the property name but
+ * cannot set the requested value.
+ */
+ public void setProperty (String name, Object value)
+ throws SAXNotRecognizedException, SAXNotSupportedException
+ {
+ if (parent != null) {
+ parent.setProperty(name, value);
+ } else {
+ throw new SAXNotRecognizedException("Property: " + name);
+ }
+ }
+
+
+ /**
+ * Look up the value of a property.
+ *
+ * @param name The property name.
+ * @return The current value of the property.
+ * @exception org.xml.sax.SAXNotRecognizedException If the property
+ * value can't be assigned or retrieved from the parent.
+ * @exception org.xml.sax.SAXNotSupportedException When the
+ * parent recognizes the property name but
+ * cannot determine its value at this time.
+ */
+ public Object getProperty (String name)
+ throws SAXNotRecognizedException, SAXNotSupportedException
+ {
+ if (parent != null) {
+ return parent.getProperty(name);
+ } else {
+ throw new SAXNotRecognizedException("Property: " + name);
+ }
+ }
+
+
+ /**
+ * Set the entity resolver.
+ *
+ * @param resolver The new entity resolver.
+ */
+ public void setEntityResolver (EntityResolver resolver)
+ {
+ entityResolver = resolver;
+ }
+
+
+ /**
+ * Get the current entity resolver.
+ *
+ * @return The current entity resolver, or null if none was set.
+ */
+ public EntityResolver getEntityResolver ()
+ {
+ return entityResolver;
+ }
+
+
+ /**
+ * Set the DTD event handler.
+ *
+ * @param handler the new DTD handler
+ */
+ public void setDTDHandler (DTDHandler handler)
+ {
+ dtdHandler = handler;
+ }
+
+
+ /**
+ * Get the current DTD event handler.
+ *
+ * @return The current DTD handler, or null if none was set.
+ */
+ public DTDHandler getDTDHandler ()
+ {
+ return dtdHandler;
+ }
+
+
+ /**
+ * Set the content event handler.
+ *
+ * @param handler the new content handler
+ */
+ public void setContentHandler (ContentHandler handler)
+ {
+ contentHandler = handler;
+ }
+
+
+ /**
+ * Get the content event handler.
+ *
+ * @return The current content handler, or null if none was set.
+ */
+ public ContentHandler getContentHandler ()
+ {
+ return contentHandler;
+ }
+
+
+ /**
+ * Set the error event handler.
+ *
+ * @param handler the new error handler
+ */
+ public void setErrorHandler (ErrorHandler handler)
+ {
+ errorHandler = handler;
+ }
+
+
+ /**
+ * Get the current error event handler.
+ *
+ * @return The current error handler, or null if none was set.
+ */
+ public ErrorHandler getErrorHandler ()
+ {
+ return errorHandler;
+ }
+
+
+ /**
+ * Parse a document.
+ *
+ * @param input The input source for the document entity.
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ * @exception java.io.IOException An IO exception from the parser,
+ * possibly from a byte stream or character stream
+ * supplied by the application.
+ */
+ public void parse (InputSource input)
+ throws SAXException, IOException
+ {
+ setupParse();
+ parent.parse(input);
+ }
+
+
+ /**
+ * Parse a document.
+ *
+ * @param systemId The system identifier as a fully-qualified URI.
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ * @exception java.io.IOException An IO exception from the parser,
+ * possibly from a byte stream or character stream
+ * supplied by the application.
+ */
+ public void parse (String systemId)
+ throws SAXException, IOException
+ {
+ parse(new InputSource(systemId));
+ }
+
+
+
+ ////////////////////////////////////////////////////////////////////
+ // Implementation of org.xml.sax.EntityResolver.
+ ////////////////////////////////////////////////////////////////////
+
+
+ /**
+ * Filter an external entity resolution.
+ *
+ * @param publicId The entity's public identifier, or null.
+ * @param systemId The entity's system identifier.
+ * @return A new InputSource or null for the default.
+ * @exception org.xml.sax.SAXException The client may throw
+ * an exception during processing.
+ * @exception java.io.IOException The client may throw an
+ * I/O-related exception while obtaining the
+ * new InputSource.
+ */
+ public InputSource resolveEntity (String publicId, String systemId)
+ throws SAXException, IOException
+ {
+ if (entityResolver != null) {
+ return entityResolver.resolveEntity(publicId, systemId);
+ } else {
+ return null;
+ }
+ }
+
+
+
+ ////////////////////////////////////////////////////////////////////
+ // Implementation of org.xml.sax.DTDHandler.
+ ////////////////////////////////////////////////////////////////////
+
+
+ /**
+ * Filter a notation declaration event.
+ *
+ * @param name The notation name.
+ * @param publicId The notation's public identifier, or null.
+ * @param systemId The notation's system identifier, or null.
+ * @exception org.xml.sax.SAXException The client may throw
+ * an exception during processing.
+ */
+ public void notationDecl (String name, String publicId, String systemId)
+ throws SAXException
+ {
+ if (dtdHandler != null) {
+ dtdHandler.notationDecl(name, publicId, systemId);
+ }
+ }
+
+
+ /**
+ * Filter an unparsed entity declaration event.
+ *
+ * @param name The entity name.
+ * @param publicId The entity's public identifier, or null.
+ * @param systemId The entity's system identifier, or null.
+ * @param notationName The name of the associated notation.
+ * @exception org.xml.sax.SAXException The client may throw
+ * an exception during processing.
+ */
+ public void unparsedEntityDecl (String name, String publicId,
+ String systemId, String notationName)
+ throws SAXException
+ {
+ if (dtdHandler != null) {
+ dtdHandler.unparsedEntityDecl(name, publicId, systemId,
+ notationName);
+ }
+ }
+
+
+
+ ////////////////////////////////////////////////////////////////////
+ // Implementation of org.xml.sax.ContentHandler.
+ ////////////////////////////////////////////////////////////////////
+
+
+ /**
+ * Filter a new document locator event.
+ *
+ * @param locator The document locator.
+ */
+ public void setDocumentLocator (Locator locator)
+ {
+ this.locator = locator;
+ if (contentHandler != null) {
+ contentHandler.setDocumentLocator(locator);
+ }
+ }
+
+
+ /**
+ * Filter a start document event.
+ *
+ * @exception org.xml.sax.SAXException The client may throw
+ * an exception during processing.
+ */
+ public void startDocument ()
+ throws SAXException
+ {
+ if (contentHandler != null) {
+ contentHandler.startDocument();
+ }
+ }
+
+
+ /**
+ * Filter an end document event.
+ *
+ * @exception org.xml.sax.SAXException The client may throw
+ * an exception during processing.
+ */
+ public void endDocument ()
+ throws SAXException
+ {
+ if (contentHandler != null) {
+ contentHandler.endDocument();
+ }
+ }
+
+
+ /**
+ * Filter a start Namespace prefix mapping event.
+ *
+ * @param prefix The Namespace prefix.
+ * @param uri The Namespace URI.
+ * @exception org.xml.sax.SAXException The client may throw
+ * an exception during processing.
+ */
+ public void startPrefixMapping (String prefix, String uri)
+ throws SAXException
+ {
+ if (contentHandler != null) {
+ contentHandler.startPrefixMapping(prefix, uri);
+ }
+ }
+
+
+ /**
+ * Filter an end Namespace prefix mapping event.
+ *
+ * @param prefix The Namespace prefix.
+ * @exception org.xml.sax.SAXException The client may throw
+ * an exception during processing.
+ */
+ public void endPrefixMapping (String prefix)
+ throws SAXException
+ {
+ if (contentHandler != null) {
+ contentHandler.endPrefixMapping(prefix);
+ }
+ }
+
+
+ /**
+ * Filter a start element event.
+ *
+ * @param uri The element's Namespace URI, or the empty string.
+ * @param localName The element's local name, or the empty string.
+ * @param qName The element's qualified (prefixed) name, or the empty
+ * string.
+ * @param atts The element's attributes.
+ * @exception org.xml.sax.SAXException The client may throw
+ * an exception during processing.
+ */
+ public void startElement (String uri, String localName, String qName,
+ Attributes atts)
+ throws SAXException
+ {
+ if (contentHandler != null) {
+ contentHandler.startElement(uri, localName, qName, atts);
+ }
+ }
+
+
+ /**
+ * Filter an end element event.
+ *
+ * @param uri The element's Namespace URI, or the empty string.
+ * @param localName The element's local name, or the empty string.
+ * @param qName The element's qualified (prefixed) name, or the empty
+ * string.
+ * @exception org.xml.sax.SAXException The client may throw
+ * an exception during processing.
+ */
+ public void endElement (String uri, String localName, String qName)
+ throws SAXException
+ {
+ if (contentHandler != null) {
+ contentHandler.endElement(uri, localName, qName);
+ }
+ }
+
+
+ /**
+ * Filter a character data event.
+ *
+ * @param ch An array of characters.
+ * @param start The starting position in the array.
+ * @param length The number of characters to use from the array.
+ * @exception org.xml.sax.SAXException The client may throw
+ * an exception during processing.
+ */
+ public void characters (char ch[], int start, int length)
+ throws SAXException
+ {
+ if (contentHandler != null) {
+ contentHandler.characters(ch, start, length);
+ }
+ }
+
+
+ /**
+ * Filter an ignorable whitespace event.
+ *
+ * @param ch An array of characters.
+ * @param start The starting position in the array.
+ * @param length The number of characters to use from the array.
+ * @exception org.xml.sax.SAXException The client may throw
+ * an exception during processing.
+ */
+ public void ignorableWhitespace (char ch[], int start, int length)
+ throws SAXException
+ {
+ if (contentHandler != null) {
+ contentHandler.ignorableWhitespace(ch, start, length);
+ }
+ }
+
+
+ /**
+ * Filter a processing instruction event.
+ *
+ * @param target The processing instruction target.
+ * @param data The text following the target.
+ * @exception org.xml.sax.SAXException The client may throw
+ * an exception during processing.
+ */
+ public void processingInstruction (String target, String data)
+ throws SAXException
+ {
+ if (contentHandler != null) {
+ contentHandler.processingInstruction(target, data);
+ }
+ }
+
+
+ /**
+ * Filter a skipped entity event.
+ *
+ * @param name The name of the skipped entity.
+ * @exception org.xml.sax.SAXException The client may throw
+ * an exception during processing.
+ */
+ public void skippedEntity (String name)
+ throws SAXException
+ {
+ if (contentHandler != null) {
+ contentHandler.skippedEntity(name);
+ }
+ }
+
+
+
+ ////////////////////////////////////////////////////////////////////
+ // Implementation of org.xml.sax.ErrorHandler.
+ ////////////////////////////////////////////////////////////////////
+
+
+ /**
+ * Filter a warning event.
+ *
+ * @param e The warning as an exception.
+ * @exception org.xml.sax.SAXException The client may throw
+ * an exception during processing.
+ */
+ public void warning (SAXParseException e)
+ throws SAXException
+ {
+ if (errorHandler != null) {
+ errorHandler.warning(e);
+ }
+ }
+
+
+ /**
+ * Filter an error event.
+ *
+ * @param e The error as an exception.
+ * @exception org.xml.sax.SAXException The client may throw
+ * an exception during processing.
+ */
+ public void error (SAXParseException e)
+ throws SAXException
+ {
+ if (errorHandler != null) {
+ errorHandler.error(e);
+ }
+ }
+
+
+ /**
+ * Filter a fatal error event.
+ *
+ * @param e The error as an exception.
+ * @exception org.xml.sax.SAXException The client may throw
+ * an exception during processing.
+ */
+ public void fatalError (SAXParseException e)
+ throws SAXException
+ {
+ if (errorHandler != null) {
+ errorHandler.fatalError(e);
+ }
+ }
+
+
+
+ ////////////////////////////////////////////////////////////////////
+ // Internal methods.
+ ////////////////////////////////////////////////////////////////////
+
+
+ /**
+ * Set up before a parse.
+ *
+ * <p>Before every parse, check whether the parent is
+ * non-null, and re-register the filter for all of the
+ * events.</p>
+ */
+ private void setupParse ()
+ {
+ if (parent == null) {
+ throw new NullPointerException("No parent for filter");
+ }
+ parent.setEntityResolver(this);
+ parent.setDTDHandler(this);
+ parent.setContentHandler(this);
+ parent.setErrorHandler(this);
+ }
+
+
+
+ ////////////////////////////////////////////////////////////////////
+ // Internal state.
+ ////////////////////////////////////////////////////////////////////
+
+ private XMLReader parent = null;
+ private Locator locator = null;
+ private EntityResolver entityResolver = null;
+ private DTDHandler dtdHandler = null;
+ private ContentHandler contentHandler = null;
+ private ErrorHandler errorHandler = null;
+
+}
+
+// end of XMLFilterImpl.java
diff --git a/xml/src/main/java/org/xml/sax/helpers/XMLReaderAdapter.java b/xml/src/main/java/org/xml/sax/helpers/XMLReaderAdapter.java
new file mode 100644
index 0000000..cc8f431
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/helpers/XMLReaderAdapter.java
@@ -0,0 +1,538 @@
+// XMLReaderAdapter.java - adapt an SAX2 XMLReader to a SAX1 Parser
+// http://www.saxproject.org
+// Written by David Megginson
+// NO WARRANTY! This class is in the public domain.
+// $Id: XMLReaderAdapter.java,v 1.9 2004/04/26 17:34:35 dmegginson Exp $
+
+package org.xml.sax.helpers;
+
+import java.io.IOException;
+import java.util.Locale;
+
+import org.xml.sax.Parser; // deprecated
+import org.xml.sax.Locator;
+import org.xml.sax.InputSource;
+import org.xml.sax.AttributeList; // deprecated
+import org.xml.sax.EntityResolver;
+import org.xml.sax.DTDHandler;
+import org.xml.sax.DocumentHandler; // deprecated
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.SAXException;
+
+import org.xml.sax.XMLReader;
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXNotSupportedException;
+
+
+/**
+ * Adapt a SAX2 XMLReader as a SAX1 Parser.
+ *
+ * <blockquote>
+ * <em>This module, both source code and documentation, is in the
+ * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
+ * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
+ * for further information.
+ * </blockquote>
+ *
+ * <p>This class wraps a SAX2 {@link org.xml.sax.XMLReader XMLReader}
+ * and makes it act as a SAX1 {@link org.xml.sax.Parser Parser}. The XMLReader
+ * must support a true value for the
+ * http://xml.org/sax/features/namespace-prefixes property or parsing will fail
+ * with a {@link org.xml.sax.SAXException SAXException}; if the XMLReader
+ * supports a false value for the http://xml.org/sax/features/namespaces
+ * property, that will also be used to improve efficiency.</p>
+ *
+ * @since SAX 2.0
+ * @author David Megginson
+ * @version 2.0.1 (sax2r2)
+ * @see org.xml.sax.Parser
+ * @see org.xml.sax.XMLReader
+ */
+public class XMLReaderAdapter implements Parser, ContentHandler
+{
+
+
+ ////////////////////////////////////////////////////////////////////
+ // Constructor.
+ ////////////////////////////////////////////////////////////////////
+
+
+ /**
+ * Create a new adapter.
+ *
+ * <p>Use the "org.xml.sax.driver" property to locate the SAX2
+ * driver to embed.</p>
+ *
+ * @exception org.xml.sax.SAXException If the embedded driver
+ * cannot be instantiated or if the
+ * org.xml.sax.driver property is not specified.
+ */
+ public XMLReaderAdapter ()
+ throws SAXException
+ {
+ setup(XMLReaderFactory.createXMLReader());
+ }
+
+
+ /**
+ * Create a new adapter.
+ *
+ * <p>Create a new adapter, wrapped around a SAX2 XMLReader.
+ * The adapter will make the XMLReader act like a SAX1
+ * Parser.</p>
+ *
+ * @param xmlReader The SAX2 XMLReader to wrap.
+ * @exception java.lang.NullPointerException If the argument is null.
+ */
+ public XMLReaderAdapter (XMLReader xmlReader)
+ {
+ setup(xmlReader);
+ }
+
+
+
+ /**
+ * Internal setup.
+ *
+ * @param xmlReader The embedded XMLReader.
+ */
+ private void setup (XMLReader xmlReader)
+ {
+ if (xmlReader == null) {
+ throw new NullPointerException("XMLReader must not be null");
+ }
+ this.xmlReader = xmlReader;
+ qAtts = new AttributesAdapter();
+ }
+
+
+
+ ////////////////////////////////////////////////////////////////////
+ // Implementation of org.xml.sax.Parser.
+ ////////////////////////////////////////////////////////////////////
+
+
+ /**
+ * Set the locale for error reporting.
+ *
+ * <p>This is not supported in SAX2, and will always throw
+ * an exception.</p>
+ *
+ * @param locale the locale for error reporting.
+ * @see org.xml.sax.Parser#setLocale
+ * @exception org.xml.sax.SAXException Thrown unless overridden.
+ */
+ public void setLocale (Locale locale)
+ throws SAXException
+ {
+ throw new SAXNotSupportedException("setLocale not supported");
+ }
+
+
+ /**
+ * Register the entity resolver.
+ *
+ * @param resolver The new resolver.
+ * @see org.xml.sax.Parser#setEntityResolver
+ */
+ public void setEntityResolver (EntityResolver resolver)
+ {
+ xmlReader.setEntityResolver(resolver);
+ }
+
+
+ /**
+ * Register the DTD event handler.
+ *
+ * @param handler The new DTD event handler.
+ * @see org.xml.sax.Parser#setDTDHandler
+ */
+ public void setDTDHandler (DTDHandler handler)
+ {
+ xmlReader.setDTDHandler(handler);
+ }
+
+
+ /**
+ * Register the SAX1 document event handler.
+ *
+ * <p>Note that the SAX1 document handler has no Namespace
+ * support.</p>
+ *
+ * @param handler The new SAX1 document event handler.
+ * @see org.xml.sax.Parser#setDocumentHandler
+ */
+ public void setDocumentHandler (DocumentHandler handler)
+ {
+ documentHandler = handler;
+ }
+
+
+ /**
+ * Register the error event handler.
+ *
+ * @param handler The new error event handler.
+ * @see org.xml.sax.Parser#setErrorHandler
+ */
+ public void setErrorHandler (ErrorHandler handler)
+ {
+ xmlReader.setErrorHandler(handler);
+ }
+
+
+ /**
+ * Parse the document.
+ *
+ * <p>This method will throw an exception if the embedded
+ * XMLReader does not support the
+ * http://xml.org/sax/features/namespace-prefixes property.</p>
+ *
+ * @param systemId The absolute URL of the document.
+ * @exception java.io.IOException If there is a problem reading
+ * the raw content of the document.
+ * @exception org.xml.sax.SAXException If there is a problem
+ * processing the document.
+ * @see #parse(org.xml.sax.InputSource)
+ * @see org.xml.sax.Parser#parse(java.lang.String)
+ */
+ public void parse (String systemId)
+ throws IOException, SAXException
+ {
+ parse(new InputSource(systemId));
+ }
+
+
+ /**
+ * Parse the document.
+ *
+ * <p>This method will throw an exception if the embedded
+ * XMLReader does not support the
+ * http://xml.org/sax/features/namespace-prefixes property.</p>
+ *
+ * @param input An input source for the document.
+ * @exception java.io.IOException If there is a problem reading
+ * the raw content of the document.
+ * @exception org.xml.sax.SAXException If there is a problem
+ * processing the document.
+ * @see #parse(java.lang.String)
+ * @see org.xml.sax.Parser#parse(org.xml.sax.InputSource)
+ */
+ public void parse (InputSource input)
+ throws IOException, SAXException
+ {
+ setupXMLReader();
+ xmlReader.parse(input);
+ }
+
+
+ /**
+ * Set up the XML reader.
+ */
+ private void setupXMLReader ()
+ throws SAXException
+ {
+ xmlReader.setFeature("http://xml.org/sax/features/namespace-prefixes", true);
+ try {
+ xmlReader.setFeature("http://xml.org/sax/features/namespaces",
+ false);
+ } catch (SAXException e) {
+ // NO OP: it's just extra information, and we can ignore it
+ }
+ xmlReader.setContentHandler(this);
+ }
+
+
+
+ ////////////////////////////////////////////////////////////////////
+ // Implementation of org.xml.sax.ContentHandler.
+ ////////////////////////////////////////////////////////////////////
+
+
+ /**
+ * Set a document locator.
+ *
+ * @param locator The document locator.
+ * @see org.xml.sax.ContentHandler#setDocumentLocator
+ */
+ public void setDocumentLocator (Locator locator)
+ {
+ if (documentHandler != null)
+ documentHandler.setDocumentLocator(locator);
+ }
+
+
+ /**
+ * Start document event.
+ *
+ * @exception org.xml.sax.SAXException The client may raise a
+ * processing exception.
+ * @see org.xml.sax.ContentHandler#startDocument
+ */
+ public void startDocument ()
+ throws SAXException
+ {
+ if (documentHandler != null)
+ documentHandler.startDocument();
+ }
+
+
+ /**
+ * End document event.
+ *
+ * @exception org.xml.sax.SAXException The client may raise a
+ * processing exception.
+ * @see org.xml.sax.ContentHandler#endDocument
+ */
+ public void endDocument ()
+ throws SAXException
+ {
+ if (documentHandler != null)
+ documentHandler.endDocument();
+ }
+
+
+ /**
+ * Adapt a SAX2 start prefix mapping event.
+ *
+ * @param prefix The prefix being mapped.
+ * @param uri The Namespace URI being mapped to.
+ * @see org.xml.sax.ContentHandler#startPrefixMapping
+ */
+ public void startPrefixMapping (String prefix, String uri)
+ {
+ }
+
+
+ /**
+ * Adapt a SAX2 end prefix mapping event.
+ *
+ * @param prefix The prefix being mapped.
+ * @see org.xml.sax.ContentHandler#endPrefixMapping
+ */
+ public void endPrefixMapping (String prefix)
+ {
+ }
+
+
+ /**
+ * Adapt a SAX2 start element event.
+ *
+ * @param uri The Namespace URI.
+ * @param localName The Namespace local name.
+ * @param qName The qualified (prefixed) name.
+ * @param atts The SAX2 attributes.
+ * @exception org.xml.sax.SAXException The client may raise a
+ * processing exception.
+ * @see org.xml.sax.ContentHandler#endDocument
+ */
+ public void startElement (String uri, String localName,
+ String qName, Attributes atts)
+ throws SAXException
+ {
+ if (documentHandler != null) {
+ qAtts.setAttributes(atts);
+ documentHandler.startElement(qName, qAtts);
+ }
+ }
+
+
+ /**
+ * Adapt a SAX2 end element event.
+ *
+ * @param uri The Namespace URI.
+ * @param localName The Namespace local name.
+ * @param qName The qualified (prefixed) name.
+ * @exception org.xml.sax.SAXException The client may raise a
+ * processing exception.
+ * @see org.xml.sax.ContentHandler#endElement
+ */
+ public void endElement (String uri, String localName,
+ String qName)
+ throws SAXException
+ {
+ if (documentHandler != null)
+ documentHandler.endElement(qName);
+ }
+
+
+ /**
+ * Adapt a SAX2 characters event.
+ *
+ * @param ch An array of characters.
+ * @param start The starting position in the array.
+ * @param length The number of characters to use.
+ * @exception org.xml.sax.SAXException The client may raise a
+ * processing exception.
+ * @see org.xml.sax.ContentHandler#characters
+ */
+ public void characters (char ch[], int start, int length)
+ throws SAXException
+ {
+ if (documentHandler != null)
+ documentHandler.characters(ch, start, length);
+ }
+
+
+ /**
+ * Adapt a SAX2 ignorable whitespace event.
+ *
+ * @param ch An array of characters.
+ * @param start The starting position in the array.
+ * @param length The number of characters to use.
+ * @exception org.xml.sax.SAXException The client may raise a
+ * processing exception.
+ * @see org.xml.sax.ContentHandler#ignorableWhitespace
+ */
+ public void ignorableWhitespace (char ch[], int start, int length)
+ throws SAXException
+ {
+ if (documentHandler != null)
+ documentHandler.ignorableWhitespace(ch, start, length);
+ }
+
+
+ /**
+ * Adapt a SAX2 processing instruction event.
+ *
+ * @param target The processing instruction target.
+ * @param data The remainder of the processing instruction
+ * @exception org.xml.sax.SAXException The client may raise a
+ * processing exception.
+ * @see org.xml.sax.ContentHandler#processingInstruction
+ */
+ public void processingInstruction (String target, String data)
+ throws SAXException
+ {
+ if (documentHandler != null)
+ documentHandler.processingInstruction(target, data);
+ }
+
+
+ /**
+ * Adapt a SAX2 skipped entity event.
+ *
+ * @param name The name of the skipped entity.
+ * @see org.xml.sax.ContentHandler#skippedEntity
+ * @exception org.xml.sax.SAXException Throwable by subclasses.
+ */
+ public void skippedEntity (String name)
+ throws SAXException
+ {
+ }
+
+
+
+ ////////////////////////////////////////////////////////////////////
+ // Internal state.
+ ////////////////////////////////////////////////////////////////////
+
+ XMLReader xmlReader;
+ DocumentHandler documentHandler;
+ AttributesAdapter qAtts;
+
+
+
+ ////////////////////////////////////////////////////////////////////
+ // Internal class.
+ ////////////////////////////////////////////////////////////////////
+
+
+ /**
+ * Internal class to wrap a SAX2 Attributes object for SAX1.
+ */
+ final class AttributesAdapter implements AttributeList
+ {
+ AttributesAdapter ()
+ {
+ }
+
+
+ /**
+ * Set the embedded Attributes object.
+ *
+ * @param The embedded SAX2 Attributes.
+ */
+ void setAttributes (Attributes attributes)
+ {
+ this.attributes = attributes;
+ }
+
+
+ /**
+ * Return the number of attributes.
+ *
+ * @return The length of the attribute list.
+ * @see org.xml.sax.AttributeList#getLength
+ */
+ public int getLength ()
+ {
+ return attributes.getLength();
+ }
+
+
+ /**
+ * Return the qualified (prefixed) name of an attribute by position.
+ *
+ * @return The qualified name.
+ * @see org.xml.sax.AttributeList#getName
+ */
+ public String getName (int i)
+ {
+ return attributes.getQName(i);
+ }
+
+
+ /**
+ * Return the type of an attribute by position.
+ *
+ * @return The type.
+ * @see org.xml.sax.AttributeList#getType(int)
+ */
+ public String getType (int i)
+ {
+ return attributes.getType(i);
+ }
+
+
+ /**
+ * Return the value of an attribute by position.
+ *
+ * @return The value.
+ * @see org.xml.sax.AttributeList#getValue(int)
+ */
+ public String getValue (int i)
+ {
+ return attributes.getValue(i);
+ }
+
+
+ /**
+ * Return the type of an attribute by qualified (prefixed) name.
+ *
+ * @return The type.
+ * @see org.xml.sax.AttributeList#getType(java.lang.String)
+ */
+ public String getType (String qName)
+ {
+ return attributes.getType(qName);
+ }
+
+
+ /**
+ * Return the value of an attribute by qualified (prefixed) name.
+ *
+ * @return The value.
+ * @see org.xml.sax.AttributeList#getValue(java.lang.String)
+ */
+ public String getValue (String qName)
+ {
+ return attributes.getValue(qName);
+ }
+
+ private Attributes attributes;
+ }
+
+}
+
+// end of XMLReaderAdapter.java
diff --git a/xml/src/main/java/org/xml/sax/helpers/XMLReaderFactory.java b/xml/src/main/java/org/xml/sax/helpers/XMLReaderFactory.java
new file mode 100644
index 0000000..96151a1
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/helpers/XMLReaderFactory.java
@@ -0,0 +1,206 @@
+// XMLReaderFactory.java - factory for creating a new reader.
+// http://www.saxproject.org
+// Written by David Megginson
+// and by David Brownell
+// NO WARRANTY! This class is in the Public Domain.
+// $Id: XMLReaderFactory.java,v 1.10 2002/04/22 01:00:13 dbrownell Exp $
+
+package org.xml.sax.helpers;
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import org.xml.sax.XMLReader;
+import org.xml.sax.SAXException;
+
+
+/**
+ * Factory for creating an XML reader.
+ *
+ * <blockquote>
+ * <em>This module, both source code and documentation, is in the
+ * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
+ * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
+ * for further information.
+ * </blockquote>
+ *
+ * <p>This class contains static methods for creating an XML reader
+ * from an explicit class name, or based on runtime defaults:</p>
+ *
+ * <pre>
+ * try {
+ * XMLReader myReader = XMLReaderFactory.createXMLReader();
+ * } catch (SAXException e) {
+ * System.err.println(e.getMessage());
+ * }
+ * </pre>
+ *
+ * <p><strong>Note to Distributions bundled with parsers:</strong>
+ * You should modify the implementation of the no-arguments
+ * <em>createXMLReader</em> to handle cases where the external
+ * configuration mechanisms aren't set up. That method should do its
+ * best to return a parser when one is in the class path, even when
+ * nothing bound its class name to <code>org.xml.sax.driver</code> so
+ * those configuration mechanisms would see it.</p>
+ *
+ * @since SAX 2.0
+ * @author David Megginson, David Brownell
+ * @version 2.0.1 (sax2r2)
+ */
+final public class XMLReaderFactory
+{
+ /**
+ * Private constructor.
+ *
+ * <p>This constructor prevents the class from being instantiated.</p>
+ */
+ private XMLReaderFactory ()
+ {
+ }
+
+ private static final String property = "org.xml.sax.driver";
+
+ /**
+ * Attempt to create an XMLReader from system defaults.
+ * In environments which can support it, the name of the XMLReader
+ * class is determined by trying each these options in order, and
+ * using the first one which succeeds:</p> <ul>
+ *
+ * <li>If the system property <code>org.xml.sax.driver</code>
+ * has a value, that is used as an XMLReader class name. </li>
+ *
+ * <li>The JAR "Services API" is used to look for a class name
+ * in the <em>META-INF/services/org.xml.sax.driver</em> file in
+ * jarfiles available to the runtime.</li>
+ *
+ * <li> SAX parser distributions are strongly encouraged to provide
+ * a default XMLReader class name that will take effect only when
+ * previous options (on this list) are not successful.</li>
+ *
+ * <li>Finally, if {@link ParserFactory#makeParser()} can
+ * return a system default SAX1 parser, that parser is wrapped in
+ * a {@link ParserAdapter}. (This is a migration aid for SAX1
+ * environments, where the <code>org.xml.sax.parser</code> system
+ * property will often be usable.) </li>
+ *
+ * </ul>
+ *
+ * <p> In environments such as small embedded systems, which can not
+ * support that flexibility, other mechanisms to determine the default
+ * may be used. </p>
+ *
+ * <p>Note that many Java environments allow system properties to be
+ * initialized on a command line. This means that <em>in most cases</em>
+ * setting a good value for that property ensures that calls to this
+ * method will succeed, except when security policies intervene.
+ * This will also maximize application portability to older SAX
+ * environments, with less robust implementations of this method.
+ * </p>
+ *
+ * @return A new XMLReader.
+ * @exception org.xml.sax.SAXException If no default XMLReader class
+ * can be identified and instantiated.
+ * @see #createXMLReader(java.lang.String)
+ */
+ public static XMLReader createXMLReader ()
+ throws SAXException
+ {
+ String className = null;
+ ClassLoader loader = NewInstance.getClassLoader ();
+
+ // 1. try the JVM-instance-wide system property
+ try { className = System.getProperty (property); }
+ catch (RuntimeException e) { /* normally fails for applets */ }
+
+ // 2. if that fails, try META-INF/services/
+ if (className == null) {
+ try {
+ String service = "META-INF/services/" + property;
+ InputStream in;
+ BufferedReader reader;
+
+ if (loader == null)
+ in = ClassLoader.getSystemResourceAsStream (service);
+ else
+ in = loader.getResourceAsStream (service);
+
+ if (in != null) {
+ // BEGIN android-modified
+ reader = new BufferedReader (
+ new InputStreamReader (in, "UTF8"), 8192);
+ // END android-modified
+ className = reader.readLine ();
+ in.close ();
+ }
+ } catch (Exception e) {
+ }
+ }
+
+ // 3. Distro-specific fallback
+ if (className == null) {
+// BEGIN DISTRIBUTION-SPECIFIC
+
+ // EXAMPLE:
+ // className = "com.example.sax.XmlReader";
+ // or a $JAVA_HOME/jre/lib/*properties setting...
+
+// END DISTRIBUTION-SPECIFIC
+ }
+
+ // do we know the XMLReader implementation class yet?
+ if (className != null)
+ return loadClass (loader, className);
+
+ // 4. panic -- adapt any SAX1 parser
+ try {
+ return new ParserAdapter (ParserFactory.makeParser ());
+ } catch (Exception e) {
+ throw new SAXException ("Can't create default XMLReader; "
+ + "is system property org.xml.sax.driver set?");
+ }
+ }
+
+
+ /**
+ * Attempt to create an XML reader from a class name.
+ *
+ * <p>Given a class name, this method attempts to load
+ * and instantiate the class as an XML reader.</p>
+ *
+ * @param className the name of the class that should be instantiated.
+ *
+ * <p>Note that this method will not be usable in environments where
+ * the caller (perhaps an applet) is not permitted to load classes
+ * dynamically.</p>
+ *
+ * @return A new XML reader.
+ * @exception org.xml.sax.SAXException If the class cannot be
+ * loaded, instantiated, and cast to XMLReader.
+ * @see #createXMLReader()
+ */
+ public static XMLReader createXMLReader (String className)
+ throws SAXException
+ {
+ return loadClass (NewInstance.getClassLoader (), className);
+ }
+
+ private static XMLReader loadClass (ClassLoader loader, String className)
+ throws SAXException
+ {
+ try {
+ return (XMLReader) NewInstance.newInstance (loader, className);
+ } catch (ClassNotFoundException e1) {
+ throw new SAXException("SAX2 driver class " + className +
+ " not found", e1);
+ } catch (IllegalAccessException e2) {
+ throw new SAXException("SAX2 driver class " + className +
+ " found but cannot be loaded", e2);
+ } catch (InstantiationException e3) {
+ throw new SAXException("SAX2 driver class " + className +
+ " loaded but cannot be instantiated (no empty public constructor?)",
+ e3);
+ } catch (ClassCastException e4) {
+ throw new SAXException("SAX2 driver class " + className +
+ " does not implement XMLReader", e4);
+ }
+ }
+}
diff --git a/xml/src/main/java/org/xml/sax/helpers/package.html b/xml/src/main/java/org/xml/sax/helpers/package.html
new file mode 100644
index 0000000..3a265fd
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/helpers/package.html
@@ -0,0 +1,13 @@
+<HTML><HEAD>
+<!-- $Id: package.html,v 1.6 2002/01/30 20:52:39 dbrownell Exp $ -->
+</HEAD><BODY>
+
+<p>This package contains "helper" classes, including
+support for bootstrapping SAX-based applications.
+
+<p>See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
+for more information about SAX.</p>
+
+@since Android 1.0
+
+</BODY></HTML>
diff --git a/xml/src/main/java/org/xml/sax/package.html b/xml/src/main/java/org/xml/sax/package.html
new file mode 100644
index 0000000..fbe7108
--- /dev/null
+++ b/xml/src/main/java/org/xml/sax/package.html
@@ -0,0 +1,299 @@
+<html><head>
+<!-- $Id: package.html,v 1.18 2004/04/21 13:06:01 dmegginson Exp $ -->
+</head><body>
+
+<p> This package provides the core SAX APIs.
+Some SAX1 APIs are deprecated to encourage integration of
+namespace-awareness into designs of new applications
+and into maintenance of existing infrastructure. </p>
+
+<p>See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
+for more information about SAX.</p>
+
+
+<h2> SAX2 Standard Feature Flags </h2>
+
+<p> One of the essential characteristics of SAX2 is that it added
+feature flags which can be used to examine and perhaps modify
+parser modes, in particular modes such as validation.
+Since features are identified by (absolute) URIs, anyone
+can define such features.
+Currently defined standard feature URIs have the prefix
+<code>http://xml.org/sax/features/</code> before an identifier such as
+<code>validation</code>. Turn features on or off using
+<em>setFeature</em>. Those standard identifiers are: </p>
+
+
+<table border="1" cellpadding="3" cellspacing="0" width="100%">
+ <tr align="center" bgcolor="#ccccff">
+ <th>Feature ID</th>
+ <th>Access</th>
+ <th>Default</th>
+ <th>Description</th>
+ </tr>
+
+ <tr>
+ <td>external-general-entities</td>
+ <td><em>read/write</em></td>
+ <td><em>unspecified</em></td>
+ <td> Reports whether this parser processes external
+ general entities; always true if validating.
+ </td>
+ </tr>
+
+ <tr>
+ <td>external-parameter-entities</td>
+ <td><em>read/write</em></td>
+ <td><em>unspecified</em></td>
+ <td> Reports whether this parser processes external
+ parameter entities; always true if validating.
+ </td>
+ </tr>
+
+ <tr>
+ <td>is-standalone</td>
+ <td>(parsing) <em>read-only</em>, (not parsing) <em>none</em></td>
+ <td>not applicable</td>
+ <td> May be examined only during a parse, after the
+ <em>startDocument()</em> callback has been completed; read-only.
+ The value is true if the document specified standalone="yes" in
+ its XML declaration, and otherwise is false.
+ </td>
+ </tr>
+
+ <tr>
+ <td>lexical-handler/parameter-entities</td>
+ <td><em>read/write</em></td>
+ <td><em>unspecified</em></td>
+ <td> A value of "true" indicates that the LexicalHandler will report
+ the beginning and end of parameter entities.
+ </td>
+ </tr>
+
+ <tr>
+ <td>namespaces</td>
+ <td><em>read/write</em></td>
+ <td>true</td>
+ <td> A value of "true" indicates namespace URIs and unprefixed local names
+ for element and attribute names will be available.
+ </td>
+ </tr>
+
+ <tr>
+ <td>namespace-prefixes</td>
+ <td><em>read/write</em></td>
+ <td>false</td>
+ <td> A value of "true" indicates that XML qualified names (with prefixes) and
+ attributes (including <em>xmlns*</em> attributes) will be available.
+ </td>
+ </tr>
+
+ <tr>
+ <td>resolve-dtd-uris</td>
+ <td><em>read/write</em></td>
+ <td><em>true</em></td>
+ <td> A value of "true" indicates that system IDs in declarations will
+ be absolutized (relative to their base URIs) before reporting.
+ (That is the default behavior for all SAX2 XML parsers.)
+ A value of "false" indicates those IDs will not be absolutized;
+ parsers will provide the base URI from
+ <em>Locator.getSystemId()</em>.
+ This applies to system IDs passed in <ul>
+ <li><em>DTDHandler.notationDecl()</em>,
+ <li><em>DTDHandler.unparsedEntityDecl()</em>, and
+ <li><em>DeclHandler.externalEntityDecl()</em>.
+ </ul>
+ It does not apply to <em>EntityResolver.resolveEntity()</em>,
+ which is not used to report declarations, or to
+ <em>LexicalHandler.startDTD()</em>, which already provides
+ the non-absolutized URI.
+ </td>
+ </tr>
+
+ <tr>
+ <td>string-interning</td>
+ <td><em>read/write</em></td>
+ <td><em>unspecified</em></td>
+ <td> Has a value of "true" if all XML names (for elements, prefixes,
+ attributes, entities, notations, and local names),
+ as well as Namespace URIs, will have been interned
+ using <em>java.lang.String.intern</em>. This supports fast
+ testing of equality/inequality against string constants,
+ rather than forcing slower calls to <em>String.equals()</em>.
+ </td>
+ </tr>
+
+ <tr>
+ <td>unicode-normalization-checking</td>
+ <td><em>read/write</em></td>
+ <td><em>false</em></td>
+ <td> Controls whether the parser reports Unicode normalization
+ errors as described in section 2.13 and Appendix B of the
+ XML 1.1 Recommendation. If true, Unicode normalization
+ errors are reported using the ErrorHandler.error() callback.
+ Such errors are not fatal in themselves (though, obviously,
+ other Unicode-related encoding errors may be).
+ </td>
+ </tr>
+
+ <tr>
+ <td>use-attributes2</td>
+ <td><em>read-only</em></td>
+ <td>not applicable</td>
+ <td> Returns "true" if the <em>Attributes</em> objects passed by
+ this parser in <em>ContentHandler.startElement()</em>
+ implement the <a href="ext/Attributes2.html"
+ ><em>org.xml.sax.ext.Attributes2</em></a> interface.
+ That interface exposes additional DTD-related information,
+ such as whether the attribute was specified in the
+ source text rather than defaulted.
+ </td>
+ </tr>
+
+ <tr>
+ <td>use-locator2</td>
+ <td><em>read-only</em></td>
+ <td>not applicable</td>
+ <td> Returns "true" if the <em>Locator</em> objects passed by
+ this parser in <em>ContentHandler.setDocumentLocator()</em>
+ implement the <a href="ext/Locator2.html"
+ ><em>org.xml.sax.ext.Locator2</em></a> interface.
+ That interface exposes additional entity information,
+ such as the character encoding and XML version used.
+ </td>
+ </tr>
+
+ <tr>
+ <td>use-entity-resolver2</td>
+ <td><em>read/write</em></td>
+ <td><em>true</em></td>
+ <td> Returns "true" if, when <em>setEntityResolver</em> is given
+ an object implementing the <a href="ext/EntityResolver2.html"
+ ><em>org.xml.sax.ext.EntityResolver2</em></a> interface,
+ those new methods will be used.
+ Returns "false" to indicate that those methods will not be used.
+ </td>
+ </tr>
+
+ <tr>
+ <td>validation</td>
+ <td><em>read/write</em></td>
+ <td><em>unspecified</em></td>
+ <td> Controls whether the parser is reporting all validity
+ errors; if true, all external entities will be read.
+ </td>
+ </tr>
+
+ <tr>
+ <td>xmlns-uris</td>
+ <td><em>read/write</em></td>
+ <td><em>false</em></td>
+ <td> Controls whether, when the <em>namespace-prefixes</em> feature
+ is set, the parser treats namespace declaration attributes as
+ being in the <em>http://www.w3.org/2000/xmlns/</em> namespace.
+ By default, SAX2 conforms to the original "Namespaces in XML"
+ Recommendation, which explicitly states that such attributes are
+ not in any namespace.
+ Setting this optional flag to "true" makes the SAX2 events conform to
+ a later backwards-incompatible revision of that recommendation,
+ placing those attributes in a namespace.
+ </td>
+ </tr>
+
+ <tr>
+ <td>xml-1.1</td>
+ <td><em>read-only</em></td>
+ <td>not applicable</td>
+ <td> Returns "true" if the parser supports both XML 1.1 and XML 1.0.
+ Returns "false" if the parser supports only XML 1.0.
+ </td>
+ </tr>
+
+</table>
+
+<p> Support for the default values of the
+<em>namespaces</em> and <em>namespace-prefixes</em>
+properties is required.
+Support for any other feature flags is entirely optional.
+</p>
+
+<p> For default values not specified by SAX2,
+each XMLReader implementation specifies its default,
+or may choose not to expose the feature flag.
+Unless otherwise specified here,
+implementations may support changing current values
+of these standard feature flags, but not while parsing.
+</p>
+
+<h2> SAX2 Standard Handler and Property IDs </h2>
+
+<p> For parser interface characteristics that are described
+as objects, a separate namespace is defined. The
+objects in this namespace are again identified by URI, and
+the standard property URIs have the prefix
+<code>http://xml.org/sax/properties/</code> before an identifier such as
+<code>lexical-handler</code> or
+<code>dom-node</code>. Manage those properties using
+<em>setProperty()</em>. Those identifiers are: </p>
+
+<table border="1" cellpadding="3" cellspacing="0" width="100%">
+ <tr align="center" bgcolor="#ccccff">
+ <th>Property ID</th>
+ <th>Description</th>
+ </tr>
+
+ <tr>
+ <td>declaration-handler</td>
+ <td> Used to see most DTD declarations except those treated
+ as lexical ("document element name is ...") or which are
+ mandatory for all SAX parsers (<em>DTDHandler</em>).
+ The Object must implement <a href="ext/DeclHandler.html"
+ ><em>org.xml.sax.ext.DeclHandler</em></a>.
+ </td>
+ </tr>
+
+ <tr>
+ <td>document-xml-version</td>
+ <td> May be examined only during a parse, after the startDocument()
+ callback has been completed; read-only. This property is a
+ literal string describing the actual XML version of the document,
+ such as "1.0" or "1.1".
+ </td>
+ </tr>
+
+ <tr>
+ <td>dom-node</td>
+ <td> For "DOM Walker" style parsers, which ignore their
+ <em>parser.parse()</em> parameters, this is used to
+ specify the DOM (sub)tree being walked by the parser.
+ The Object must implement the
+ <em>org.w3c.dom.Node</em> interface.
+ </td>
+ </tr>
+
+ <tr>
+ <td>lexical-handler</td>
+ <td> Used to see some syntax events that are essential in some
+ applications: comments, CDATA delimiters, selected general
+ entity inclusions, and the start and end of the DTD
+ (and declaration of document element name).
+ The Object must implement <a href="ext/LexicalHandler.html"
+ ><em>org.xml.sax.ext.LexicalHandler</em></a>.
+ </td>
+ </tr>
+
+ <tr>
+ <td>xml-string</td>
+ <td> Readable only during a parser callback, this exposes a <b>TBS</b>
+ chunk of characters responsible for the current event. </td>
+ </tr>
+
+</table>
+
+<p> All of these standard properties are optional;
+XMLReader implementations need not support them.
+</p>
+
+@since Android 1.0
+
+</body></html> \ No newline at end of file
diff --git a/xml/src/main/java/org/xmlpull/v1/XmlPullParser.java b/xml/src/main/java/org/xmlpull/v1/XmlPullParser.java
new file mode 100644
index 0000000..2c2946f
--- /dev/null
+++ b/xml/src/main/java/org/xmlpull/v1/XmlPullParser.java
@@ -0,0 +1,1116 @@
+/* -*- c-basic-offset: 4; indent-tabs-mode: nil; -*- //------100-columns-wide------>|*/
+// for license please see accompanying LICENSE.txt file (available also at http://www.xmlpull.org/)
+
+package org.xmlpull.v1;
+
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.Reader;
+
+/**
+ * XML Pull Parser is an interface that defines parsing functionlity provided
+ * in <a href="http://www.xmlpull.org/">XMLPULL V1 API</a> (visit this website to
+ * learn more about API and its implementations).
+ *
+ * <p>There are following different
+ * kinds of parser depending on which features are set:<ul>
+ * <li><b>non-validating</b> parser as defined in XML 1.0 spec when
+ * FEATURE_PROCESS_DOCDECL is set to true
+ * <li><b>validating parser</b> as defined in XML 1.0 spec when
+ * FEATURE_VALIDATION is true (and that implies that FEATURE_PROCESS_DOCDECL is true)
+ * <li>when FEATURE_PROCESS_DOCDECL is false (this is default and
+ * if different value is required necessary must be changed before parsing is started)
+ * then parser behaves like XML 1.0 compliant non-validating parser under condition that
+ * <em>no DOCDECL is present</em> in XML documents
+ * (internal entites can still be defined with defineEntityReplacementText()).
+ * This mode of operation is intened <b>for operation in constrained environments</b> such as J2ME.
+ * </ul>
+ *
+ *
+ * <p>There are two key methods: next() and nextToken(). While next() provides
+ * access to high level parsing events, nextToken() allows access to lower
+ * level tokens.
+ *
+ * <p>The current event state of the parser
+ * can be determined by calling the
+ * <a href="#getEventType()">getEventType()</a> method.
+ * Initially, the parser is in the <a href="#START_DOCUMENT">START_DOCUMENT</a>
+ * state.
+ *
+ * <p>The method <a href="#next()">next()</a> advances the parser to the
+ * next event. The int value returned from next determines the current parser
+ * state and is identical to the value returned from following calls to
+ * getEventType ().
+ *
+ * <p>Th following event types are seen by next()<dl>
+ * <dt><a href="#START_TAG">START_TAG</a><dd> An XML start tag was read.
+ * <dt><a href="#TEXT">TEXT</a><dd> Text content was read;
+ * the text content can be retreived using the getText() method.
+ * (when in validating mode next() will not report ignorable whitespaces, use nextToken() instead)
+ * <dt><a href="#END_TAG">END_TAG</a><dd> An end tag was read
+ * <dt><a href="#END_DOCUMENT">END_DOCUMENT</a><dd> No more events are available
+ * </dl>
+ *
+ * <p>after first next() or nextToken() (or any other next*() method)
+ * is called user application can obtain
+ * XML version, standalone and encoding from XML declaration
+ * in following ways:<ul>
+ * <li><b>version</b>:
+ * getProperty(&quot;<a href="http://xmlpull.org/v1/doc/properties.html#xmldecl-version">http://xmlpull.org/v1/doc/properties.html#xmldecl-version</a>&quot;)
+ * returns String ("1.0") or null if XMLDecl was not read or if property is not supported
+ * <li><b>standalone</b>:
+ * getProperty(&quot;<a href="http://xmlpull.org/v1/doc/features.html#xmldecl-standalone">http://xmlpull.org/v1/doc/features.html#xmldecl-standalone</a>&quot;)
+ * returns Boolean: null if there was no standalone declaration
+ * or if property is not supported
+ * otherwise returns Boolean(true) if standalon="yes" and Boolean(false) when standalone="no"
+ * <li><b>encoding</b>: obtained from getInputEncoding()
+ * null if stream had unknown encoding (not set in setInputStream)
+ * and it was not declared in XMLDecl
+ * </ul>
+ *
+ * A minimal example for using this API may look as follows:
+ * <pre>
+ * import java.io.IOException;
+ * import java.io.StringReader;
+ *
+ * import org.xmlpull.v1.XmlPullParser;
+ * import org.xmlpull.v1.<a href="XmlPullParserException.html">XmlPullParserException.html</a>;
+ * import org.xmlpull.v1.<a href="XmlPullParserFactory.html">XmlPullParserFactory</a>;
+ *
+ * public class SimpleXmlPullApp
+ * {
+ *
+ * public static void main (String args[])
+ * throws XmlPullParserException, IOException
+ * {
+ * XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
+ * factory.setNamespaceAware(true);
+ * XmlPullParser xpp = factory.newPullParser();
+ *
+ * xpp.<a href="#setInput">setInput</a>( new StringReader ( "&lt;foo>Hello World!&lt;/foo>" ) );
+ * int eventType = xpp.getEventType();
+ * while (eventType != XmlPullParser.END_DOCUMENT) {
+ * if(eventType == XmlPullParser.START_DOCUMENT) {
+ * System.out.println("Start document");
+ * } else if(eventType == XmlPullParser.END_DOCUMENT) {
+ * System.out.println("End document");
+ * } else if(eventType == XmlPullParser.START_TAG) {
+ * System.out.println("Start tag "+xpp.<a href="#getName()">getName()</a>);
+ * } else if(eventType == XmlPullParser.END_TAG) {
+ * System.out.println("End tag "+xpp.getName());
+ * } else if(eventType == XmlPullParser.TEXT) {
+ * System.out.println("Text "+xpp.<a href="#getText()">getText()</a>);
+ * }
+ * eventType = xpp.next();
+ * }
+ * }
+ * }
+ * </pre>
+ *
+ * <p>The above example will generate the following output:
+ * <pre>
+ * Start document
+ * Start tag foo
+ * Text Hello World!
+ * End tag foo
+ * </pre>
+ *
+ * <p>For more details on API usage, please refer to the
+ * quick Introduction available at <a href="http://www.xmlpull.org">http://www.xmlpull.org</a>
+ *
+ * @see XmlPullParserFactory
+ * @see #defineEntityReplacementText
+ * @see #getName
+ * @see #getNamespace
+ * @see #getText
+ * @see #next
+ * @see #nextToken
+ * @see #setInput
+ * @see #FEATURE_PROCESS_DOCDECL
+ * @see #FEATURE_VALIDATION
+ * @see #START_DOCUMENT
+ * @see #START_TAG
+ * @see #TEXT
+ * @see #END_TAG
+ * @see #END_DOCUMENT
+ *
+ * @author <a href="http://www-ai.cs.uni-dortmund.de/PERSONAL/haustein.html">Stefan Haustein</a>
+ * @author <a href="http://www.extreme.indiana.edu/~aslom/">Aleksander Slominski</a>
+ */
+
+public interface XmlPullParser {
+
+ /** This constant represents the default namespace (empty string "") */
+ String NO_NAMESPACE = "";
+
+ // ----------------------------------------------------------------------------
+ // EVENT TYPES as reported by next()
+
+ /**
+ * Signalize that parser is at the very beginning of the document
+ * and nothing was read yet.
+ * This event type can only be observed by calling getEvent()
+ * before the first call to next(), nextToken, or nextTag()</a>).
+ *
+ * @see #next
+ * @see #nextToken
+ */
+ int START_DOCUMENT = 0;
+
+ /**
+ * Logical end of the xml document. Returned from getEventType, next()
+ * and nextToken()
+ * when the end of the input document has been reached.
+ * <p><strong>NOTE:</strong> calling again
+ * <a href="#next()">next()</a> or <a href="#nextToken()">nextToken()</a>
+ * will result in exception being thrown.
+ *
+ * @see #next
+ * @see #nextToken
+ */
+ int END_DOCUMENT = 1;
+
+ /**
+ * Returned from getEventType(),
+ * <a href="#next()">next()</a>, <a href="#nextToken()">nextToken()</a> when
+ * a start tag was read.
+ * The name of start tag is available from getName(), its namespace and prefix are
+ * available from getNamespace() and getPrefix()
+ * if <a href='#FEATURE_PROCESS_NAMESPACES'>namespaces are enabled</a>.
+ * See getAttribute* methods to retrieve element attributes.
+ * See getNamespace* methods to retrieve newly declared namespaces.
+ *
+ * @see #next
+ * @see #nextToken
+ * @see #getName
+ * @see #getPrefix
+ * @see #getNamespace
+ * @see #getAttributeCount
+ * @see #getDepth
+ * @see #getNamespaceCount
+ * @see #getNamespace
+ * @see #FEATURE_PROCESS_NAMESPACES
+ */
+ int START_TAG = 2;
+
+ /**
+ * Returned from getEventType(), <a href="#next()">next()</a>, or
+ * <a href="#nextToken()">nextToken()</a> when an end tag was read.
+ * The name of start tag is available from getName(), its
+ * namespace and prefix are
+ * available from getNamespace() and getPrefix().
+ *
+ * @see #next
+ * @see #nextToken
+ * @see #getName
+ * @see #getPrefix
+ * @see #getNamespace
+ * @see #FEATURE_PROCESS_NAMESPACES
+ */
+ int END_TAG = 3;
+
+
+ /**
+ * Character data was read and will is available by calling getText().
+ * <p><strong>Please note:</strong> <a href="#next()">next()</a> will
+ * accumulate multiple
+ * events into one TEXT event, skipping IGNORABLE_WHITESPACE,
+ * PROCESSING_INSTRUCTION and COMMENT events,
+ * In contrast, <a href="#nextToken()">nextToken()</a> will stop reading
+ * text when any other event is observed.
+ * Also, when the state was reached by calling next(), the text value will
+ * be normalized, whereas getText() will
+ * return unnormalized content in the case of nextToken(). This allows
+ * an exact roundtrip without chnanging line ends when examining low
+ * level events, whereas for high level applications the text is
+ * normalized apropriately.
+ *
+ * @see #next
+ * @see #nextToken
+ * @see #getText
+ */
+ int TEXT = 4;
+
+ // ----------------------------------------------------------------------------
+ // additional events exposed by lower level nextToken()
+
+ /**
+ * A CDATA sections was just read;
+ * this token is available only from calls to <a href="#nextToken()">nextToken()</a>.
+ * A call to next() will accumulate various text events into a single event
+ * of type TEXT. The text contained in the CDATA section is available
+ * by callling getText().
+ *
+ * @see #nextToken
+ * @see #getText
+ */
+ int CDSECT = 5;
+
+ /**
+ * An entity reference was just read;
+ * this token is available from <a href="#nextToken()">nextToken()</a>
+ * only. The entity name is available by calling getName(). If available,
+ * the replacement text can be obtained by calling getTextt(); otherwise,
+ * the user is responsibile for resolving the entity reference.
+ * This event type is never returned from next(); next() will
+ * accumulate the replacement text and other text
+ * events to a single TEXT event.
+ *
+ * @see #nextToken
+ * @see #getText
+ */
+ int ENTITY_REF = 6;
+
+ /**
+ * Ignorable whitespace was just read.
+ * This token is available only from <a href="#nextToken()">nextToken()</a>).
+ * For non-validating
+ * parsers, this event is only reported by nextToken() when outside
+ * the root element.
+ * Validating parsers may be able to detect ignorable whitespace at
+ * other locations.
+ * The ignorable whitespace string is available by calling getText()
+ *
+ * <p><strong>NOTE:</strong> this is different from calling the
+ * isWhitespace() method, since text content
+ * may be whitespace but not ignorable.
+ *
+ * Ignorable whitespace is skipped by next() automatically; this event
+ * type is never returned from next().
+ *
+ * @see #nextToken
+ * @see #getText
+ */
+ int IGNORABLE_WHITESPACE = 7;
+
+ /**
+ * An XML processing instruction declaration was just read. This
+ * event type is available only via <a href="#nextToken()">nextToken()</a>.
+ * getText() will return text that is inside the processing instruction.
+ * Calls to next() will skip processing instructions automatically.
+ * @see #nextToken
+ * @see #getText
+ */
+ int PROCESSING_INSTRUCTION = 8;
+
+ /**
+ * An XML comment was just read. This event type is this token is
+ * available via <a href="#nextToken()">nextToken()</a> only;
+ * calls to next() will skip comments automatically.
+ * The content of the comment can be accessed using the getText()
+ * method.
+ *
+ * @see #nextToken
+ * @see #getText
+ */
+ int COMMENT = 9;
+
+ /**
+ * An XML document type declaration was just read. This token is
+ * available from <a href="#nextToken()">nextToken()</a> only.
+ * The unparsed text inside the doctype is available via
+ * the getText() method.
+ *
+ * @see #nextToken
+ * @see #getText
+ */
+ int DOCDECL = 10;
+
+ /**
+ * This array can be used to convert the event type integer constants
+ * such as START_TAG or TEXT to
+ * to a string. For example, the value of TYPES[START_TAG] is
+ * the string "START_TAG".
+ *
+ * This array is intended for diagnostic output only. Relying
+ * on the contents of the array may be dangerous since malicous
+ * applications may alter the array, although it is final, due
+ * to limitations of the Java language.
+ */
+ String [] TYPES = {
+ "START_DOCUMENT",
+ "END_DOCUMENT",
+ "START_TAG",
+ "END_TAG",
+ "TEXT",
+ "CDSECT",
+ "ENTITY_REF",
+ "IGNORABLE_WHITESPACE",
+ "PROCESSING_INSTRUCTION",
+ "COMMENT",
+ "DOCDECL"
+ };
+
+
+ // ----------------------------------------------------------------------------
+ // namespace related features
+
+ /**
+ * This feature determines whether the parser processes
+ * namespaces. As for all features, the default value is false.
+ * <p><strong>NOTE:</strong> The value can not be changed during
+ * parsing an must be set before parsing.
+ *
+ * @see #getFeature
+ * @see #setFeature
+ */
+ String FEATURE_PROCESS_NAMESPACES =
+ "http://xmlpull.org/v1/doc/features.html#process-namespaces";
+
+ /**
+ * This feature determines whether namespace attributes are
+ * exposed via the attribute access methods. Like all features,
+ * the default value is false. This feature cannot be changed
+ * during parsing.
+ *
+ * @see #getFeature
+ * @see #setFeature
+ */
+ String FEATURE_REPORT_NAMESPACE_ATTRIBUTES =
+ "http://xmlpull.org/v1/doc/features.html#report-namespace-prefixes";
+
+ /**
+ * This feature determines whether the document declaration
+ * is processed. If set to false,
+ * the DOCDECL event type is reported by nextToken()
+ * and ignored by next().
+ *
+ * If this featue is activated, then the document declaration
+ * must be processed by the parser.
+ *
+ * <p><strong>Please note:</strong> If the document type declaration
+ * was ignored, entity references may cause exceptions
+ * later in the parsing process.
+ * The default value of this feature is false. It cannot be changed
+ * during parsing.
+ *
+ * @see #getFeature
+ * @see #setFeature
+ */
+ String FEATURE_PROCESS_DOCDECL =
+ "http://xmlpull.org/v1/doc/features.html#process-docdecl";
+
+ /**
+ * If this feature is activated, all validation errors as
+ * defined in the XML 1.0 sepcification are reported.
+ * This implies that FEATURE_PROCESS_DOCDECL is true and both, the
+ * internal and external document type declaration will be processed.
+ * <p><strong>Please Note:</strong> This feature can not be changed
+ * during parsing. The default value is false.
+ *
+ * @see #getFeature
+ * @see #setFeature
+ */
+ String FEATURE_VALIDATION =
+ "http://xmlpull.org/v1/doc/features.html#validation";
+
+ /**
+ * Use this call to change the general behaviour of the parser,
+ * such as namespace processing or doctype declaration handling.
+ * This method must be called before the first call to next or
+ * nextToken. Otherwise, an exception is thrown.
+ * <p>Example: call setFeature(FEATURE_PROCESS_NAMESPACES, true) in order
+ * to switch on namespace processing. The initial settings correspond
+ * to the properties requested from the XML Pull Parser factory.
+ * If none were requested, all feautures are deactivated by default.
+ *
+ * @exception XmlPullParserException If the feature is not supported or can not be set
+ * @exception IllegalArgumentException If string with the feature name is null
+ */
+ void setFeature(String name,
+ boolean state) throws XmlPullParserException;
+
+ /**
+ * Returns the current value of the given feature.
+ * <p><strong>Please note:</strong> unknown features are
+ * <strong>always</strong> returned as false.
+ *
+ * @param name The name of feature to be retrieved.
+ * @return The value of the feature.
+ * @exception IllegalArgumentException if string the feature name is null
+ */
+
+ boolean getFeature(String name);
+
+ /**
+ * Set the value of a property.
+ *
+ * The property name is any fully-qualified URI.
+ *
+ * @exception XmlPullParserException If the property is not supported or can not be set
+ * @exception IllegalArgumentException If string with the property name is null
+ */
+ void setProperty(String name,
+ Object value) throws XmlPullParserException;
+
+ /**
+ * Look up the value of a property.
+ *
+ * The property name is any fully-qualified URI.
+ * <p><strong>NOTE:</strong> unknown properties are <strong>always</strong>
+ * returned as null.
+ *
+ * @param name The name of property to be retrieved.
+ * @return The value of named property.
+ */
+ Object getProperty(String name);
+
+
+ /**
+ * Set the input source for parser to the given reader and
+ * resets the parser. The event type is set to the initial value
+ * START_DOCUMENT.
+ * Setting the reader to null will just stop parsing and
+ * reset parser state,
+ * allowing the parser to free internal resources
+ * such as parsing buffers.
+ */
+ void setInput(Reader in) throws XmlPullParserException;
+
+
+ /**
+ * Sets the input stream the parser is going to process.
+ * This call resets the parser state and sets the event type
+ * to the initial value START_DOCUMENT.
+ *
+ * <p><strong>NOTE:</strong> If an input encoding string is passed,
+ * it MUST be used. Otherwise,
+ * if inputEncoding is null, the parser SHOULD try to determine
+ * input encoding following XML 1.0 specification (see below).
+ * If encoding detection is supported then following feature
+ * <a href="http://xmlpull.org/v1/doc/features.html#detect-encoding">http://xmlpull.org/v1/doc/features.html#detect-encoding</a>
+ * MUST be true amd otherwise it must be false
+ *
+ * @param inputStream contains a raw byte input stream of possibly
+ * unknown encoding (when inputEncoding is null).
+ *
+ * @param inputEncoding if not null it MUST be used as encoding for inputStream
+ */
+ void setInput(InputStream inputStream, String inputEncoding)
+ throws XmlPullParserException;
+
+ /**
+ * Returns the input encoding if known, null otherwise.
+ * If setInput(InputStream, inputEncoding) was called with an inputEncoding
+ * value other than null, this value must be returned
+ * from this method. Otherwise, if inputEncoding is null and
+ * the parser suppports the encoding detection feature
+ * (http://xmlpull.org/v1/doc/features.html#detect-encoding),
+ * it must return the detected encoding.
+ * If setInput(Reader) was called, null is returned.
+ * After first call to next if XML declaration was present this method
+ * will return encoding declared.
+ */
+ String getInputEncoding();
+
+ /**
+ * Set new value for entity replacement text as defined in
+ * <a href="http://www.w3.org/TR/REC-xml#intern-replacement">XML 1.0 Section 4.5
+ * Construction of Internal Entity Replacement Text</a>.
+ * If FEATURE_PROCESS_DOCDECL or FEATURE_VALIDATION are set, calling this
+ * function will result in an exception -- when processing of DOCDECL is
+ * enabled, there is no need to the entity replacement text manually.
+ *
+ * <p>The motivation for this function is to allow very small
+ * implementations of XMLPULL that will work in J2ME environments.
+ * Though these implementations may not be able to process the document type
+ * declaration, they still can work with known DTDs by using this function.
+ *
+ * <p><b>Please notes:</b> The given value is used literally as replacement text
+ * and it corresponds to declaring entity in DTD that has all special characters
+ * escaped: left angle bracket is replaced with &amp;lt;, ampersnad with &amp;amp;
+ * and so on.
+ *
+ * <p><b>Note:</b> The given value is the literal replacement text and must not
+ * contain any other entity reference (if it contains any entity reference
+ * there will be no further replacement).
+ *
+ * <p><b>Note:</b> The list of pre-defined entity names will
+ * always contain standard XML entities such as
+ * amp (&amp;amp;), lt (&amp;lt;), gt (&amp;gt;), quot (&amp;quot;), and apos (&amp;apos;).
+ * Those cannot be redefined by this method!
+ *
+ * @see #setInput
+ * @see #FEATURE_PROCESS_DOCDECL
+ * @see #FEATURE_VALIDATION
+ */
+ void defineEntityReplacementText( String entityName,
+ String replacementText ) throws XmlPullParserException;
+
+ /**
+ * Returns the numbers of elements in the namespace stack for the given
+ * depth.
+ * If namespaces are not enabled, 0 is returned.
+ *
+ * <p><b>NOTE:</b> when parser is on END_TAG then it is allowed to call
+ * this function with getDepth()+1 argument to retrieve position of namespace
+ * prefixes and URIs that were declared on corresponding START_TAG.
+ * <p><b>NOTE:</b> to retrieve lsit of namespaces declared in current element:<pre>
+ * XmlPullParser pp = ...
+ * int nsStart = pp.getNamespaceCount(pp.getDepth()-1);
+ * int nsEnd = pp.getNamespaceCount(pp.getDepth());
+ * for (int i = nsStart; i < nsEnd; i++) {
+ * String prefix = pp.getNamespacePrefix(i);
+ * String ns = pp.getNamespaceUri(i);
+ * // ...
+ * }
+ * </pre>
+ *
+ * @see #getNamespacePrefix
+ * @see #getNamespaceUri
+ * @see #getNamespace()
+ * @see #getNamespace(String)
+ */
+ int getNamespaceCount(int depth) throws XmlPullParserException;
+
+ /**
+ * Returns the namespace prefixe for the given position
+ * in the namespace stack.
+ * Default namespace declaration (xmlns='...') will have null as prefix.
+ * If the given index is out of range, an exception is thrown.
+ * <p><b>Please note:</b> when the parser is on an END_TAG,
+ * namespace prefixes that were declared
+ * in the corresponding START_TAG are still accessible
+ * although they are no longer in scope.
+ */
+ String getNamespacePrefix(int pos) throws XmlPullParserException;
+
+ /**
+ * Returns the namespace URI for the given position in the
+ * namespace stack
+ * If the position is out of range, an exception is thrown.
+ * <p><b>NOTE:</b> when parser is on END_TAG then namespace prefixes that were declared
+ * in corresponding START_TAG are still accessible even though they are not in scope
+ */
+ String getNamespaceUri(int pos) throws XmlPullParserException;
+
+ /**
+ * Returns the URI corresponding to the given prefix,
+ * depending on current state of the parser.
+ *
+ * <p>If the prefix was not declared in the current scope,
+ * null is returned. The default namespace is included
+ * in the namespace table and is available via
+ * getNamespace (null).
+ *
+ * <p>This method is a convenience method for
+ *
+ * <pre>
+ * for (int i = getNamespaceCount(getDepth ())-1; i >= 0; i--) {
+ * if (getNamespacePrefix(i).equals( prefix )) {
+ * return getNamespaceUri(i);
+ * }
+ * }
+ * return null;
+ * </pre>
+ *
+ * <p><strong>Please note:</strong> parser implementations
+ * may provide more efifcient lookup, e.g. using a Hashtable.
+ * The 'xml' prefix is bound to "http://www.w3.org/XML/1998/namespace", as
+ * defined in the
+ * <a href="http://www.w3.org/TR/REC-xml-names/#ns-using">Namespaces in XML</a>
+ * specification. Analogous, the 'xmlns' prefix is resolved to
+ * <a href="http://www.w3.org/2000/xmlns/">http://www.w3.org/2000/xmlns/</a>
+ *
+ * @see #getNamespaceCount
+ * @see #getNamespacePrefix
+ * @see #getNamespaceUri
+ */
+ String getNamespace (String prefix);
+
+
+ // --------------------------------------------------------------------------
+ // miscellaneous reporting methods
+
+ /**
+ * Returns the current depth of the element.
+ * Outside the root element, the depth is 0. The
+ * depth is incremented by 1 when a start tag is reached.
+ * The depth is decremented AFTER the end tag
+ * event was observed.
+ *
+ * <pre>
+ * &lt;!-- outside --&gt; 0
+ * &lt;root> 1
+ * sometext 1
+ * &lt;foobar&gt; 2
+ * &lt;/foobar&gt; 2
+ * &lt;/root&gt; 1
+ * &lt;!-- outside --&gt; 0
+ * </pre>
+ */
+ int getDepth();
+
+ /**
+ * Returns a short text describing the current parser state, including
+ * the position, a
+ * description of the current event and the data source if known.
+ * This method is especially useful to provide meaningful
+ * error messages and for debugging purposes.
+ */
+ String getPositionDescription ();
+
+
+ /**
+ * Returns the current line number, starting from 1.
+ * When the parser does not know the current line number
+ * or can not determine it, -1 is returned (e.g. for WBXML).
+ *
+ * @return current line number or -1 if unknown.
+ */
+ int getLineNumber();
+
+ /**
+ * Returns the current column number, starting from 0.
+ * When the parser does not know the current column number
+ * or can not determine it, -1 is returned (e.g. for WBXML).
+ *
+ * @return current column number or -1 if unknown.
+ */
+ int getColumnNumber();
+
+
+ // --------------------------------------------------------------------------
+ // TEXT related methods
+
+ /**
+ * Checks whether the current TEXT event contains only whitespace
+ * characters.
+ * For IGNORABLE_WHITESPACE, this is always true.
+ * For TEXT and CDSECT, false is returned when the current event text
+ * contains at least one non-white space character. For any other
+ * event type an exception is thrown.
+ *
+ * <p><b>Please note:</b> non-validating parsers are not
+ * able to distinguish whitespace and ignorable whitespace,
+ * except from whitespace outside the root element. Ignorable
+ * whitespace is reported as separate event, which is exposed
+ * via nextToken only.
+ *
+ */
+ boolean isWhitespace() throws XmlPullParserException;
+
+ /**
+ * Returns the text content of the current event as String.
+ * The value returned depends on current event type,
+ * for example for TEXT event it is element content
+ * (this is typical case when next() is used).
+ *
+ * See description of nextToken() for detailed description of
+ * possible returned values for different types of events.
+ *
+ * <p><strong>NOTE:</strong> in case of ENTITY_REF, this method returns
+ * the entity replacement text (or null if not available). This is
+ * the only case where
+ * getText() and getTextCharacters() return different values.
+ *
+ * @see #getEventType
+ * @see #next
+ * @see #nextToken
+ */
+ String getText ();
+
+
+ /**
+ * Returns the buffer that contains the text of the current event,
+ * as well as the start offset and length relevant for the current
+ * event. See getText(), next() and nextToken() for description of possible returned values.
+ *
+ * <p><strong>Please note:</strong> this buffer must not
+ * be modified and its content MAY change after a call to
+ * next() or nextToken(). This method will always return the
+ * same value as getText(), except for ENTITY_REF. In the case
+ * of ENTITY ref, getText() returns the replacement text and
+ * this method returns the actual input buffer containing the
+ * entity name.
+ * If getText() returns null, this method returns null as well and
+ * the values returned in the holder array MUST be -1 (both start
+ * and length).
+ *
+ * @see #getText
+ * @see #next
+ * @see #nextToken
+ *
+ * @param holderForStartAndLength Must hold an 2-element int array
+ * into which the start offset and length values will be written.
+ * @return char buffer that contains the text of the current event
+ * (null if the current event has no text associated).
+ */
+ char[] getTextCharacters(int [] holderForStartAndLength);
+
+ // --------------------------------------------------------------------------
+ // START_TAG / END_TAG shared methods
+
+ /**
+ * Returns the namespace URI of the current element.
+ * The default namespace is represented
+ * as empty string.
+ * If namespaces are not enabled, an empty String ("") is always returned.
+ * The current event must be START_TAG or END_TAG; otherwise,
+ * null is returned.
+ */
+ String getNamespace ();
+
+ /**
+ * For START_TAG or END_TAG events, the (local) name of the current
+ * element is returned when namespaces are enabled. When namespace
+ * processing is disabled, the raw name is returned.
+ * For ENTITY_REF events, the entity name is returned.
+ * If the current event is not START_TAG, END_TAG, or ENTITY_REF,
+ * null is returned.
+ * <p><b>Please note:</b> To reconstruct the raw element name
+ * when namespaces are enabled and the prefix is not null,
+ * you will need to add the prefix and a colon to localName..
+ *
+ */
+ String getName();
+
+ /**
+ * Returns the prefix of the current element.
+ * If the element is in the default namespace (has no prefix),
+ * null is returned.
+ * If namespaces are not enabled, or the current event
+ * is not START_TAG or END_TAG, null is returned.
+ */
+ String getPrefix();
+
+ /**
+ * Returns true if the current event is START_TAG and the tag
+ * is degenerated
+ * (e.g. &lt;foobar/&gt;).
+ * <p><b>NOTE:</b> if the parser is not on START_TAG, an exception
+ * will be thrown.
+ */
+ boolean isEmptyElementTag() throws XmlPullParserException;
+
+ // --------------------------------------------------------------------------
+ // START_TAG Attributes retrieval methods
+
+ /**
+ * Returns the number of attributes of the current start tag, or
+ * -1 if the current event type is not START_TAG
+ *
+ * @see #getAttributeNamespace
+ * @see #getAttributeName
+ * @see #getAttributePrefix
+ * @see #getAttributeValue
+ */
+ int getAttributeCount();
+
+ /**
+ * Returns the namespace URI of the attribute
+ * with the given index (starts from 0).
+ * Returns an empty string ("") if namespaces are not enabled
+ * or the attribute has no namespace.
+ * Throws an IndexOutOfBoundsException if the index is out of range
+ * or the current event type is not START_TAG.
+ *
+ * <p><strong>NOTE:</strong> if FEATURE_REPORT_NAMESPACE_ATTRIBUTES is set
+ * then namespace attributes (xmlns:ns='...') must be reported
+ * with namespace
+ * <a href="http://www.w3.org/2000/xmlns/">http://www.w3.org/2000/xmlns/</a>
+ * (visit this URL for description!).
+ * The default namespace attribute (xmlns="...") will be reported with empty namespace.
+ * <p><strong>NOTE:</strong>The xml prefix is bound as defined in
+ * <a href="http://www.w3.org/TR/REC-xml-names/#ns-using">Namespaces in XML</a>
+ * specification to "http://www.w3.org/XML/1998/namespace".
+ *
+ * @param index zero-based index of attribute
+ * @return attribute namespace,
+ * empty string ("") is returned if namesapces processing is not enabled or
+ * namespaces processing is enabled but attribute has no namespace (it has no prefix).
+ */
+ String getAttributeNamespace (int index);
+
+ /**
+ * Returns the local name of the specified attribute
+ * if namespaces are enabled or just attribute name if namespaces are disabled.
+ * Throws an IndexOutOfBoundsException if the index is out of range
+ * or current event type is not START_TAG.
+ *
+ * @param index zero-based index of attribute
+ * @return attribute name (null is never returned)
+ */
+ String getAttributeName (int index);
+
+ /**
+ * Returns the prefix of the specified attribute
+ * Returns null if the element has no prefix.
+ * If namespaces are disabled it will always return null.
+ * Throws an IndexOutOfBoundsException if the index is out of range
+ * or current event type is not START_TAG.
+ *
+ * @param index zero-based index of attribute
+ * @return attribute prefix or null if namespaces processing is not enabled.
+ */
+ String getAttributePrefix(int index);
+
+ /**
+ * Returns the type of the specified attribute
+ * If parser is non-validating it MUST return CDATA.
+ *
+ * @param index zero-based index of attribute
+ * @return attribute type (null is never returned)
+ */
+ String getAttributeType(int index);
+
+ /**
+ * Returns if the specified attribute was not in input was declared in XML.
+ * If parser is non-validating it MUST always return false.
+ * This information is part of XML infoset:
+ *
+ * @param index zero-based index of attribute
+ * @return false if attribute was in input
+ */
+ boolean isAttributeDefault(int index);
+
+ /**
+ * Returns the given attributes value.
+ * Throws an IndexOutOfBoundsException if the index is out of range
+ * or current event type is not START_TAG.
+ *
+ * <p><strong>NOTE:</strong> attribute value must be normalized
+ * (including entity replacement text if PROCESS_DOCDECL is false) as described in
+ * <a href="http://www.w3.org/TR/REC-xml#AVNormalize">XML 1.0 section
+ * 3.3.3 Attribute-Value Normalization</a>
+ *
+ * @see #defineEntityReplacementText
+ *
+ * @param index zero-based index of attribute
+ * @return value of attribute (null is never returned)
+ */
+ String getAttributeValue(int index);
+
+ /**
+ * Returns the attributes value identified by namespace URI and namespace localName.
+ * If namespaces are disabled namespace must be null.
+ * If current event type is not START_TAG then IndexOutOfBoundsException will be thrown.
+ *
+ * <p><strong>NOTE:</strong> attribute value must be normalized
+ * (including entity replacement text if PROCESS_DOCDECL is false) as described in
+ * <a href="http://www.w3.org/TR/REC-xml#AVNormalize">XML 1.0 section
+ * 3.3.3 Attribute-Value Normalization</a>
+ *
+ * @see #defineEntityReplacementText
+ *
+ * @param namespace Namespace of the attribute if namespaces are enabled otherwise must be null
+ * @param name If namespaces enabled local name of attribute otherwise just attribute name
+ * @return value of attribute or null if attribute with given name does not exist
+ */
+ String getAttributeValue(String namespace,
+ String name);
+
+ // --------------------------------------------------------------------------
+ // actual parsing methods
+
+ /**
+ * Returns the type of the current event (START_TAG, END_TAG, TEXT, etc.)
+ *
+ * @see #next()
+ * @see #nextToken()
+ */
+ int getEventType()
+ throws XmlPullParserException;
+
+ /**
+ * Get next parsing event - element content wil be coalesced and only one
+ * TEXT event must be returned for whole element content
+ * (comments and processing instructions will be ignored and emtity references
+ * must be expanded or exception mus be thrown if entity reerence can not be exapnded).
+ * If element content is empty (content is "") then no TEXT event will be reported.
+ *
+ * <p><b>NOTE:</b> empty element (such as &lt;tag/>) will be reported
+ * with two separate events: START_TAG, END_TAG - it must be so to preserve
+ * parsing equivalency of empty element to &lt;tag>&lt;/tag>.
+ * (see isEmptyElementTag ())
+ *
+ * @see #isEmptyElementTag
+ * @see #START_TAG
+ * @see #TEXT
+ * @see #END_TAG
+ * @see #END_DOCUMENT
+ */
+
+ int next()
+ throws XmlPullParserException, IOException;
+
+
+ /**
+ * This method works similarly to next() but will expose
+ * additional event types (COMMENT, CDSECT, DOCDECL, ENTITY_REF, PROCESSING_INSTRUCTION, or
+ * IGNORABLE_WHITESPACE) if they are available in input.
+ *
+ * <p>If special feature
+ * <a href="http://xmlpull.org/v1/doc/features.html#xml-roundtrip">FEATURE_XML_ROUNDTRIP</a>
+ * (identified by URI: http://xmlpull.org/v1/doc/features.html#xml-roundtrip)
+ * is enabled it is possible to do XML document round trip ie. reproduce
+ * exectly on output the XML input using getText():
+ * returned content is always unnormalized (exactly as in input).
+ * Otherwise returned content is end-of-line normalized as described
+ * <a href="http://www.w3.org/TR/REC-xml#sec-line-ends">XML 1.0 End-of-Line Handling</a>
+ * and. Also when this feature is enabled exact content of START_TAG, END_TAG,
+ * DOCDECL and PROCESSING_INSTRUCTION is available.
+ *
+ * <p>Here is the list of tokens that can be returned from nextToken()
+ * and what getText() and getTextCharacters() returns:<dl>
+ * <dt>START_DOCUMENT<dd>null
+ * <dt>END_DOCUMENT<dd>null
+ * <dt>START_TAG<dd>null unless FEATURE_XML_ROUNDTRIP
+ * enabled and then returns XML tag, ex: &lt;tag attr='val'>
+ * <dt>END_TAG<dd>null unless FEATURE_XML_ROUNDTRIP
+ * id enabled and then returns XML tag, ex: &lt;/tag>
+ * <dt>TEXT<dd>return element content.
+ * <br>Note: that element content may be delivered in multiple consecutive TEXT events.
+ * <dt>IGNORABLE_WHITESPACE<dd>return characters that are determined to be ignorable white
+ * space. If the FEATURE_XML_ROUNDTRIP is enabled all whitespace content outside root
+ * element will always reported as IGNORABLE_WHITESPACE otherise rteporting is optional.
+ * <br>Note: that element content may be delevered in multiple consecutive IGNORABLE_WHITESPACE events.
+ * <dt>CDSECT<dd>
+ * return text <em>inside</em> CDATA
+ * (ex. 'fo&lt;o' from &lt;!CDATA[fo&lt;o]]>)
+ * <dt>PROCESSING_INSTRUCTION<dd>
+ * if FEATURE_XML_ROUNDTRIP is true
+ * return exact PI content ex: 'pi foo' from &lt;?pi foo?>
+ * otherwise it may be exact PI content or concatenation of PI target,
+ * space and data so for example for
+ * &lt;?target data?> string &quot;target data&quot; may
+ * be returned if FEATURE_XML_ROUNDTRIP is false.
+ * <dt>COMMENT<dd>return comment content ex. 'foo bar' from &lt;!--foo bar-->
+ * <dt>ENTITY_REF<dd>getText() MUST return entity replacement text if PROCESS_DOCDECL is false
+ * otherwise getText() MAY return null,
+ * additionally getTextCharacters() MUST return entity name
+ * (for example 'entity_name' for &amp;entity_name;).
+ * <br><b>NOTE:</b> this is the only place where value returned from getText() and
+ * getTextCharacters() <b>are different</b>
+ * <br><b>NOTE:</b> it is user responsibility to resolve entity reference
+ * if PROCESS_DOCDECL is false and there is no entity replacement text set in
+ * defineEntityReplacementText() method (getText() will be null)
+ * <br><b>NOTE:</b> character entities (ex. &amp;#32;) and standard entities such as
+ * &amp;amp; &amp;lt; &amp;gt; &amp;quot; &amp;apos; are reported as well
+ * and are <b>not</b> reported as TEXT tokens but as ENTITY_REF tokens!
+ * This requirement is added to allow to do roundtrip of XML documents!
+ * <dt>DOCDECL<dd>
+ * if FEATURE_XML_ROUNDTRIP is true or PROCESS_DOCDECL is false
+ * then return what is inside of DOCDECL for example it returns:<pre>
+ * &quot; titlepage SYSTEM "http://www.foo.bar/dtds/typo.dtd"
+ * [&lt;!ENTITY % active.links "INCLUDE">]&quot;</pre>
+ * <p>for input document that contained:<pre>
+ * &lt;!DOCTYPE titlepage SYSTEM "http://www.foo.bar/dtds/typo.dtd"
+ * [&lt;!ENTITY % active.links "INCLUDE">]></pre>
+ * otherwise if FEATURE_XML_ROUNDTRIP is false and PROCESS_DOCDECL is true
+ * then what is returned is undefined (it may be even null)
+ * </dd>
+ * </dl>
+ *
+ * <p><strong>NOTE:</strong> there is no gurantee that there will only one TEXT or
+ * IGNORABLE_WHITESPACE event from nextToken() as parser may chose to deliver element content in
+ * multiple tokens (dividing element content into chunks)
+ *
+ * <p><strong>NOTE:</strong> whether returned text of token is end-of-line normalized
+ * is depending on FEATURE_XML_ROUNDTRIP.
+ *
+ * <p><strong>NOTE:</strong> XMLDecl (&lt;?xml ...?&gt;) is not reported but its content
+ * is available through optional properties (see class description above).
+ *
+ * @see #next
+ * @see #START_TAG
+ * @see #TEXT
+ * @see #END_TAG
+ * @see #END_DOCUMENT
+ * @see #COMMENT
+ * @see #DOCDECL
+ * @see #PROCESSING_INSTRUCTION
+ * @see #ENTITY_REF
+ * @see #IGNORABLE_WHITESPACE
+ */
+ int nextToken()
+ throws XmlPullParserException, IOException;
+
+ //-----------------------------------------------------------------------------
+ // utility methods to mak XML parsing easier ...
+
+ /**
+ * Test if the current event is of the given type and if the
+ * namespace and name do match. null will match any namespace
+ * and any name. If the test is not passed, an exception is
+ * thrown. The exception text indicates the parser position,
+ * the expected event and the current event that is not meeting the
+ * requirement.
+ *
+ * <p>Essentially it does this
+ * <pre>
+ * if (type != getEventType()
+ * || (namespace != null &amp;&amp; !namespace.equals( getNamespace () ) )
+ * || (name != null &amp;&amp; !name.equals( getName() ) ) )
+ * throw new XmlPullParserException( "expected "+ TYPES[ type ]+getPositionDescription());
+ * </pre>
+ */
+ void require(int type, String namespace, String name)
+ throws XmlPullParserException, IOException;
+
+ /**
+ * If current event is START_TAG then if next element is TEXT then element content is returned
+ * or if next event is END_TAG then empty string is returned, otherwise exception is thrown.
+ * After calling this function successfully parser will be positioned on END_TAG.
+ *
+ * <p>The motivation for this function is to allow to parse consistently both
+ * empty elements and elements that has non empty content, for example for input: <ol>
+ * <li>&lt;tag&gt;foo&lt;/tag&gt;
+ * <li>&lt;tag&gt;&lt;/tag&gt; (which is equivalent to &lt;tag/&gt;
+ * both input can be parsed with the same code:
+ * <pre>
+ * p.nextTag()
+ * p.requireEvent(p.START_TAG, "", "tag");
+ * String content = p.nextText();
+ * p.requireEvent(p.END_TAG, "", "tag");
+ * </pre>
+ * This function together with nextTag make it very easy to parse XML that has
+ * no mixed content.
+ *
+ *
+ * <p>Essentially it does this
+ * <pre>
+ * if(getEventType() != START_TAG) {
+ * throw new XmlPullParserException(
+ * "parser must be on START_TAG to read next text", this, null);
+ * }
+ * int eventType = next();
+ * if(eventType == TEXT) {
+ * String result = getText();
+ * eventType = next();
+ * if(eventType != END_TAG) {
+ * throw new XmlPullParserException(
+ * "event TEXT it must be immediately followed by END_TAG", this, null);
+ * }
+ * return result;
+ * } else if(eventType == END_TAG) {
+ * return "";
+ * } else {
+ * throw new XmlPullParserException(
+ * "parser must be on START_TAG or TEXT to read text", this, null);
+ * }
+ * </pre>
+ */
+ String nextText() throws XmlPullParserException, IOException;
+
+ /**
+ * Call next() and return event if it is START_TAG or END_TAG
+ * otherwise throw an exception.
+ * It will skip whitespace TEXT before actual tag if any.
+ *
+ * <p>essentially it does this
+ * <pre>
+ * int eventType = next();
+ * if(eventType == TEXT &amp;&amp; isWhitespace()) { // skip whitespace
+ * eventType = next();
+ * }
+ * if (eventType != START_TAG &amp;&amp; eventType != END_TAG) {
+ * throw new XmlPullParserException("expected start or end tag", this, null);
+ * }
+ * return eventType;
+ * </pre>
+ */
+ int nextTag() throws XmlPullParserException, IOException;
+
+}
+
diff --git a/xml/src/main/java/org/xmlpull/v1/XmlPullParserException.java b/xml/src/main/java/org/xmlpull/v1/XmlPullParserException.java
new file mode 100644
index 0000000..b4b4b71
--- /dev/null
+++ b/xml/src/main/java/org/xmlpull/v1/XmlPullParserException.java
@@ -0,0 +1,76 @@
+/* -*- c-basic-offset: 4; indent-tabs-mode: nil; -*- //------100-columns-wide------>|*/
+// for license please see accompanying LICENSE.txt file (available also at http://www.xmlpull.org/)
+
+package org.xmlpull.v1;
+
+/**
+ * This exception is thrown to signal XML Pull Parser related faults.
+ *
+ * @author <a href="http://www.extreme.indiana.edu/~aslom/">Aleksander Slominski</a>
+ */
+public class XmlPullParserException extends Exception {
+ protected Throwable detail;
+ protected int row = -1;
+ protected int column = -1;
+
+ /* public XmlPullParserException() {
+ }*/
+
+ public XmlPullParserException(String s) {
+ super(s);
+ }
+
+ /*
+ public XmlPullParserException(String s, Throwable thrwble) {
+ super(s);
+ this.detail = thrwble;
+ }
+
+ public XmlPullParserException(String s, int row, int column) {
+ super(s);
+ this.row = row;
+ this.column = column;
+ }
+ */
+
+ public XmlPullParserException(String msg, XmlPullParser parser, Throwable chain) {
+ super ((msg == null ? "" : msg+" ")
+ + (parser == null ? "" : "(position:"+parser.getPositionDescription()+") ")
+ + (chain == null ? "" : "caused by: "+chain));
+
+ if (parser != null) {
+ this.row = parser.getLineNumber();
+ this.column = parser.getColumnNumber();
+ }
+ this.detail = chain;
+ }
+
+ public Throwable getDetail() { return detail; }
+ // public void setDetail(Throwable cause) { this.detail = cause; }
+ public int getLineNumber() { return row; }
+ public int getColumnNumber() { return column; }
+
+ /*
+ public String getMessage() {
+ if(detail == null)
+ return super.getMessage();
+ else
+ return super.getMessage() + "; nested exception is: \n\t"
+ + detail.getMessage();
+ }
+ */
+
+ //NOTE: code that prints this and detail is difficult in J2ME
+ public void printStackTrace() {
+ if (detail == null) {
+ super.printStackTrace();
+ } else {
+ synchronized(System.err) {
+ System.err.println(super.getMessage() + "; nested exception is:");
+ detail.printStackTrace();
+ }
+ }
+ }
+
+}
+
diff --git a/xml/src/main/java/org/xmlpull/v1/XmlPullParserFactory.java b/xml/src/main/java/org/xmlpull/v1/XmlPullParserFactory.java
new file mode 100644
index 0000000..7b786f6
--- /dev/null
+++ b/xml/src/main/java/org/xmlpull/v1/XmlPullParserFactory.java
@@ -0,0 +1,349 @@
+/* -*- c-basic-offset: 4; indent-tabs-mode: nil; -*- //------100-columns-wide------>|*/
+// for license please see accompanying LICENSE.txt file (available also at http://www.xmlpull.org/)
+
+package org.xmlpull.v1;
+
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+
+/**
+ * This class is used to create implementations of XML Pull Parser defined in XMPULL V1 API.
+ * The name of actual factory class will be determined based on several parameters.
+ * It works similar to JAXP but tailored to work in J2ME environments
+ * (no access to system properties or file system) so name of parser class factory to use
+ * and its class used for loading (no class loader - on J2ME no access to context class loaders)
+ * must be passed explicitly. If no name of parser factory was passed (or is null)
+ * it will try to find name by searching in CLASSPATH for
+ * META-INF/services/org.xmlpull.v1.XmlPullParserFactory resource that should contain
+ * a comma separated list of class names of factories or parsers to try (in order from
+ * left to the right). If none found, it will throw an exception.
+ *
+ * <br /><strong>NOTE:</strong>In J2SE or J2EE environments, you may want to use
+ * <code>newInstance(property, classLoaderCtx)</code>
+ * where first argument is
+ * <code>System.getProperty(XmlPullParserFactory.PROPERTY_NAME)</code>
+ * and second is <code>Thread.getContextClassLoader().getClass()</code> .
+ *
+ * @see XmlPullParser
+ *
+ * @author <a href="http://www.extreme.indiana.edu/~aslom/">Aleksander Slominski</a>
+ * @author Stefan Haustein
+ */
+
+public class XmlPullParserFactory {
+ /** used as default class to server as context class in newInstance() */
+ final static Class referenceContextClass;
+
+ static {
+ XmlPullParserFactory f = new XmlPullParserFactory();
+ referenceContextClass = f.getClass();
+ }
+
+ /** Name of the system or midlet property that should be used for
+ a system property containing a comma separated list of factory
+ or parser class names (value:
+ org.xmlpull.v1.XmlPullParserFactory). */
+
+
+ public static final String PROPERTY_NAME =
+ "org.xmlpull.v1.XmlPullParserFactory";
+
+ private static final String RESOURCE_NAME =
+ "/META-INF/services/" + PROPERTY_NAME;
+
+
+ // public static final String DEFAULT_PROPERTY =
+ // "org.xmlpull.xpp3.XmlPullParser,org.kxml2.io.KXmlParser";
+
+
+ protected ArrayList parserClasses;
+ protected String classNamesLocation;
+
+ protected ArrayList serializerClasses;
+
+
+ // features are kept there
+ protected HashMap features = new HashMap();
+
+
+ /**
+ * Protected constructor to be called by factory implementations.
+ */
+
+ protected XmlPullParserFactory() {
+ }
+
+
+
+ /**
+ * Set the features to be set when XML Pull Parser is created by this factory.
+ * <p><b>NOTE:</b> factory features are not used for XML Serializer.
+ *
+ * @param name string with URI identifying feature
+ * @param state if true feature will be set; if false will be ignored
+ */
+
+ public void setFeature(String name,
+ boolean state) throws XmlPullParserException {
+
+ features.put(name, new Boolean(state));
+ }
+
+
+ /**
+ * Return the current value of the feature with given name.
+ * <p><b>NOTE:</b> factory features are not used for XML Serializer.
+ *
+ * @param name The name of feature to be retrieved.
+ * @return The value of named feature.
+ * Unknown features are <string>always</strong> returned as false
+ */
+
+ public boolean getFeature (String name) {
+ Boolean value = (Boolean) features.get(name);
+ return value != null ? value.booleanValue() : false;
+ }
+
+ /**
+ * Specifies that the parser produced by this factory will provide
+ * support for XML namespaces.
+ * By default the value of this is set to false.
+ *
+ * @param awareness true if the parser produced by this code
+ * will provide support for XML namespaces; false otherwise.
+ */
+
+ public void setNamespaceAware(boolean awareness) {
+ features.put (XmlPullParser.FEATURE_PROCESS_NAMESPACES, new Boolean (awareness));
+ }
+
+ /**
+ * Indicates whether or not the factory is configured to produce
+ * parsers which are namespace aware
+ * (it simply set feature XmlPullParser.FEATURE_PROCESS_NAMESPACES to true or false).
+ *
+ * @return true if the factory is configured to produce parsers
+ * which are namespace aware; false otherwise.
+ */
+
+ public boolean isNamespaceAware() {
+ return getFeature (XmlPullParser.FEATURE_PROCESS_NAMESPACES);
+ }
+
+
+ /**
+ * Specifies that the parser produced by this factory will be validating
+ * (it simply set feature XmlPullParser.FEATURE_VALIDATION to true or false).
+ *
+ * By default the value of this is set to false.
+ *
+ * @param validating - if true the parsers created by this factory must be validating.
+ */
+
+ public void setValidating(boolean validating) {
+ features.put (XmlPullParser.FEATURE_VALIDATION, new Boolean (validating));
+ }
+
+ /**
+ * Indicates whether or not the factory is configured to produce parsers
+ * which validate the XML content during parse.
+ *
+ * @return true if the factory is configured to produce parsers
+ * which validate the XML content during parse; false otherwise.
+ */
+
+ public boolean isValidating() {
+ return getFeature (XmlPullParser.FEATURE_VALIDATION);
+ }
+
+ /**
+ * Creates a new instance of a XML Pull Parser
+ * using the currently configured factory features.
+ *
+ * @return A new instance of a XML Pull Parser.
+ * @throws XmlPullParserException if a parser cannot be created which satisfies the
+ * requested configuration.
+ */
+
+ public XmlPullParser newPullParser() throws XmlPullParserException {
+
+ if (parserClasses == null) throw new XmlPullParserException
+ ("Factory initialization was incomplete - has not tried "+classNamesLocation);
+
+ if (parserClasses.size() == 0) throw new XmlPullParserException
+ ("No valid parser classes found in "+classNamesLocation);
+
+ final StringBuffer issues = new StringBuffer ();
+
+ for (int i = 0; i < parserClasses.size(); i++) {
+ final Class ppClass = (Class) parserClasses.get(i);
+ try {
+ final XmlPullParser pp = (XmlPullParser) ppClass.newInstance();
+
+ for (Iterator iter = features.keySet().iterator(); iter.hasNext(); ) {
+ final String key = (String) iter.next();
+ final Boolean value = (Boolean) features.get(key);
+ if(value != null && value.booleanValue()) {
+ pp.setFeature(key, true);
+ }
+ }
+ return pp;
+
+ } catch(Exception ex) {
+ issues.append (ppClass.getName () + ": "+ ex.toString ()+"; ");
+ }
+ }
+
+ throw new XmlPullParserException ("could not create parser: "+issues);
+ }
+
+
+ /**
+ * Creates a new instance of a XML Serializer.
+ *
+ * <p><b>NOTE:</b> factory features are not used for XML Serializer.
+ *
+ * @return A new instance of a XML Serializer.
+ * @throws XmlPullParserException if a parser cannot be created which satisfies the
+ * requested configuration.
+ */
+
+ public XmlSerializer newSerializer() throws XmlPullParserException {
+
+ if (serializerClasses == null) {
+ throw new XmlPullParserException
+ ("Factory initialization incomplete - has not tried "+classNamesLocation);
+ }
+ if(serializerClasses.size() == 0) {
+ throw new XmlPullParserException
+ ("No valid serializer classes found in "+classNamesLocation);
+ }
+
+ final StringBuffer issues = new StringBuffer ();
+
+ for (int i = 0; i < serializerClasses.size (); i++) {
+ final Class ppClass = (Class) serializerClasses.get(i);
+ try {
+ final XmlSerializer ser = (XmlSerializer) ppClass.newInstance();
+
+ return ser;
+
+ } catch(Exception ex) {
+ issues.append (ppClass.getName () + ": "+ ex.toString ()+"; ");
+ }
+ }
+
+ throw new XmlPullParserException ("could not create serializer: "+issues);
+ }
+
+ /**
+ * Create a new instance of a PullParserFactory that can be used
+ * to create XML pull parsers (see class description for more
+ * details).
+ *
+ * @return a new instance of a PullParserFactory, as returned by newInstance (null, null);
+ */
+ public static XmlPullParserFactory newInstance () throws XmlPullParserException {
+ return newInstance(null, null);
+ }
+
+ public static XmlPullParserFactory newInstance (String classNames, Class context)
+ throws XmlPullParserException {
+
+ if (context == null) {
+ //NOTE: make sure context uses the same class loader as API classes
+ // this is the best we can do without having access to context classloader in J2ME
+ // if API is in the same classloader as implementation then this will work
+ context = referenceContextClass;
+ }
+
+ /*
+ String classNamesLocation = null;
+
+ if (classNames == null || classNames.length() == 0 || "DEFAULT".equals(classNames)) {
+ try {
+ InputStream is = context.getResourceAsStream (RESOURCE_NAME);
+
+ if (is == null) throw new XmlPullParserException
+ ("resource not found: "+RESOURCE_NAME
+ +" make sure that parser implementing XmlPull API is available");
+ final StringBuffer sb = new StringBuffer();
+
+ while (true) {
+ final int ch = is.read();
+ if (ch < 0) break;
+ else if (ch > ' ')
+ sb.append((char) ch);
+ }
+ is.close ();
+
+ classNames = sb.toString ();
+ }
+ catch (Exception e) {
+ throw new XmlPullParserException (null, null, e);
+ }
+ classNamesLocation = "resource "+RESOURCE_NAME+" that contained '"+classNames+"'";
+ } else {
+ classNamesLocation =
+ "parameter classNames to newInstance() that contained '"+classNames+"'";
+ }
+ */
+ classNames = "org.kxml2.io.KXmlParser,org.kxml2.io.KXmlSerializer";
+
+ XmlPullParserFactory factory = null;
+ final ArrayList parserClasses = new ArrayList();
+ final ArrayList serializerClasses = new ArrayList();
+ int pos = 0;
+
+ while (pos < classNames.length ()) {
+ int cut = classNames.indexOf (',', pos);
+
+ if (cut == -1) cut = classNames.length ();
+ final String name = classNames.substring (pos, cut);
+
+ Class candidate = null;
+ Object instance = null;
+
+ try {
+ candidate = Class.forName (name);
+ // necessary because of J2ME .class issue
+ instance = candidate.newInstance ();
+ }
+ catch (Exception e) {}
+
+ if (candidate != null) {
+ boolean recognized = false;
+ if (instance instanceof XmlPullParser) {
+ parserClasses.add(candidate);
+ recognized = true;
+ }
+ if (instance instanceof XmlSerializer) {
+ serializerClasses.add(candidate);
+ recognized = true;
+ }
+ if (instance instanceof XmlPullParserFactory) {
+ if (factory == null) {
+ factory = (XmlPullParserFactory) instance;
+ }
+ recognized = true;
+ }
+ if (!recognized) {
+ throw new XmlPullParserException ("incompatible class: "+name);
+ }
+ }
+ pos = cut + 1;
+ }
+
+ if (factory == null) {
+ factory = new XmlPullParserFactory ();
+ }
+ factory.parserClasses = parserClasses;
+ factory.serializerClasses = serializerClasses;
+ factory.classNamesLocation = "org.kxml2.io.kXmlParser,org.kxml2.io.KXmlSerializer";
+ return factory;
+ }
+}
+
+
diff --git a/xml/src/main/java/org/xmlpull/v1/XmlSerializer.java b/xml/src/main/java/org/xmlpull/v1/XmlSerializer.java
new file mode 100644
index 0000000..8e85e2f
--- /dev/null
+++ b/xml/src/main/java/org/xmlpull/v1/XmlSerializer.java
@@ -0,0 +1,326 @@
+package org.xmlpull.v1;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.Writer;
+
+/**
+ * Define an interface to serialziation of XML Infoset.
+ * This interface abstracts away if serialized XML is XML 1.0 comaptible text or
+ * other formats of XML 1.0 serializations (such as binary XML for example with WBXML).
+ *
+ * <p><b>PLEASE NOTE:</b> This interface will be part of XmlPull 1.2 API.
+ * It is included as basis for discussion. It may change in any way.
+ *
+ * <p>Exceptions that may be thrown are: IOException or runtime exception
+ * (more runtime exceptions can be thrown but are not declared and as such
+ * have no semantics defined for this interface):
+ * <ul>
+ * <li><em>IllegalArgumentException</em> - for almost all methods to signal that
+ * argument is illegal
+ * <li><em>IllegalStateException</em> - to signal that call has good arguments but
+ * is not expected here (violation of contract) and for features/properties
+ * when requesting setting unimplemented feature/property
+ * (UnsupportedOperationException would be better but it is not in MIDP)
+ * </ul>
+ *
+ * <p><b>NOTE:</b> writing CDSECT, ENTITY_REF, IGNORABLE_WHITESPACE,
+ * PROCESSING_INSTRUCTION, COMMENT, and DOCDECL in some implementations
+ * may not be supported (for example when serializing to WBXML).
+ * In such case IllegalStateException will be thrown and it is recommened
+ * to use an optional feature to signal that implementation is not
+ * supporting this kind of output.
+ */
+
+public interface XmlSerializer {
+
+ /**
+ * Set feature identified by name (recommended to be URI for uniqueness).
+ * Some well known optional features are defined in
+ * <a href="http://www.xmlpull.org/v1/doc/features.html">
+ * http://www.xmlpull.org/v1/doc/features.html</a>.
+ *
+ * If feature is not recocgnized or can not be set
+ * then IllegalStateException MUST be thrown.
+ *
+ * @exception IllegalStateException If the feature is not supported or can not be set
+ */
+ void setFeature(String name,
+ boolean state)
+ throws IllegalArgumentException, IllegalStateException;
+
+
+ /**
+ * Return the current value of the feature with given name.
+ * <p><strong>NOTE:</strong> unknown properties are <strong>always</strong> returned as null
+ *
+ * @param name The name of feature to be retrieved.
+ * @return The value of named feature.
+ * @exception IllegalArgumentException if feature string is null
+ */
+ boolean getFeature(String name);
+
+
+ /**
+ * Set the value of a property.
+ * (the property name is recommened to be URI for uniqueness).
+ * Some well known optional properties are defined in
+ * <a href="http://www.xmlpull.org/v1/doc/properties.html">
+ * http://www.xmlpull.org/v1/doc/properties.html</a>.
+ *
+ * If property is not recocgnized or can not be set
+ * then IllegalStateException MUST be thrown.
+ *
+ * @exception IllegalStateException if the property is not supported or can not be set
+ */
+ void setProperty(String name,
+ Object value)
+ throws IllegalArgumentException, IllegalStateException;
+
+ /**
+ * Look up the value of a property.
+ *
+ * The property name is any fully-qualified URI. I
+ * <p><strong>NOTE:</strong> unknown properties are <string>always</strong> returned as null
+ *
+ * @param name The name of property to be retrieved.
+ * @return The value of named property.
+ */
+ Object getProperty(String name);
+
+ /**
+ * Set to use binary output stream with given encoding.
+ */
+ void setOutput (OutputStream os, String encoding)
+ throws IOException, IllegalArgumentException, IllegalStateException;
+
+ /**
+ * Set the output to the given writer.
+ * <p><b>WARNING</b> no information about encoding is available!
+ */
+ void setOutput (Writer writer)
+ throws IOException, IllegalArgumentException, IllegalStateException;
+
+ /**
+ * Write &lt;&#63;xml declaration with encoding (if encoding not null)
+ * and standalone flag (if standalone not null)
+ * This method can only be called just after setOutput.
+ */
+ void startDocument (String encoding, Boolean standalone)
+ throws IOException, IllegalArgumentException, IllegalStateException;
+
+ /**
+ * Finish writing. All unclosed start tags will be closed and output
+ * will be flushed. After calling this method no more output can be
+ * serialized until next call to setOutput()
+ */
+ void endDocument ()
+ throws IOException, IllegalArgumentException, IllegalStateException;
+
+ /**
+ * Binds the given prefix to the given namespace.
+ * This call is valid for the next element including child elements.
+ * The prefix and namespace MUST be always declared even if prefix
+ * is not used in element (startTag() or attribute()) - for XML 1.0
+ * it must result in declaring <code>xmlns:prefix='namespace'</code>
+ * (or <code>xmlns:prefix="namespace"</code> depending what character is used
+ * to quote attribute value).
+ *
+ * <p><b>NOTE:</b> this method MUST be called directly before startTag()
+ * and if anything but startTag() or setPrefix() is called next there will be exception.
+ * <p><b>NOTE:</b> prefixes "xml" and "xmlns" are already bound
+ * and can not be redefined see:
+ * <a href="http://www.w3.org/XML/xml-names-19990114-errata#NE05">Namespaces in XML Errata</a>.
+ * <p><b>NOTE:</b> to set default namespace use as prefix empty string.
+ *
+ * @param prefix must be not null (or IllegalArgumentException is thrown)
+ * @param namespace must be not null
+ */
+ void setPrefix (String prefix, String namespace)
+ throws IOException, IllegalArgumentException, IllegalStateException;
+
+ /**
+ * Return namespace that corresponds to given prefix
+ * If there is no prefix bound to this namespace return null
+ * but if generatePrefix is false then return generated prefix.
+ *
+ * <p><b>NOTE:</b> if the prefix is empty string "" and defualt namespace is bound
+ * to this prefix then empty string ("") is returned.
+ *
+ * <p><b>NOTE:</b> prefixes "xml" and "xmlns" are already bound
+ * will have values as defined
+ * <a href="http://www.w3.org/TR/REC-xml-names/">Namespaces in XML specification</a>
+ */
+ String getPrefix (String namespace, boolean generatePrefix)
+ throws IllegalArgumentException;
+
+ /**
+ * Returns the current depth of the element.
+ * Outside the root element, the depth is 0. The
+ * depth is incremented by 1 when startTag() is called.
+ * The depth is decremented after the call to endTag()
+ * event was observed.
+ *
+ * <pre>
+ * &lt;!-- outside --&gt; 0
+ * &lt;root&gt; 1
+ * sometext 1
+ * &lt;foobar&gt; 2
+ * &lt;/foobar&gt; 2
+ * &lt;/root&gt; 1
+ * &lt;!-- outside --&gt; 0
+ * </pre>
+ */
+ int getDepth();
+
+ /**
+ * Returns the namespace URI of the current element as set by startTag().
+ *
+ * <p><b>NOTE:</b> that measn in particaulr that: <ul>
+ * <li>if there was startTag("", ...) then getNamespace() returns ""
+ * <li>if there was startTag(null, ...) then getNamespace() returns null
+ * </ul>
+ *
+ * @return namespace set by startTag() that is currently in scope
+ */
+ String getNamespace ();
+
+ /**
+ * Returns the name of the current element as set by startTag().
+ * It can only be null before first call to startTag()
+ * or when last endTag() is called to close first startTag().
+ *
+ * @return namespace set by startTag() that is currently in scope
+ */
+ String getName();
+
+ /**
+ * Writes a start tag with the given namespace and name.
+ * If there is no prefix defined for the given namespace,
+ * a prefix will be defined automatically.
+ * The explicit prefixes for namespaces can be established by calling setPrefix()
+ * immediately before this method.
+ * If namespace is null no namespace prefix is printed but just name.
+ * If namespace is empty string then serialzier will make sure that
+ * default empty namespace is declared (in XML 1.0 xmlns='')
+ * or throw IllegalStateException if default namespace is already bound
+ * to non-empty string.
+ */
+ XmlSerializer startTag (String namespace, String name)
+ throws IOException, IllegalArgumentException, IllegalStateException;
+
+ /**
+ * Write an attribute. Calls to attribute() MUST follow a call to
+ * startTag() immediately. If there is no prefix defined for the
+ * given namespace, a prefix will be defined automatically.
+ * If namespace is null or empty string
+ * no namespace prefix is printed but just name.
+ */
+ XmlSerializer attribute (String namespace, String name, String value)
+ throws IOException, IllegalArgumentException, IllegalStateException;
+
+ /**
+ * Write end tag. Repetition of namespace and name is just for avoiding errors.
+ * <p><b>Background:</b> in kXML endTag had no arguments, and non matching tags were
+ * very difficult to find...
+ * If namespace is null no namespace prefix is printed but just name.
+ * If namespace is empty string then serialzier will make sure that
+ * default empty namespace is declared (in XML 1.0 xmlns='').
+ */
+ XmlSerializer endTag (String namespace, String name)
+ throws IOException, IllegalArgumentException, IllegalStateException;
+
+
+ // /**
+ // * Writes a start tag with the given namespace and name.
+ // * <br />If there is no prefix defined (prefix == null) for the given namespace,
+ // * a prefix will be defined automatically.
+ // * <br />If explicit prefixes is passed (prefix != null) then it will be used
+ // *and namespace declared if not already declared or
+ // * throw IllegalStateException the same prefix was already set on this
+ // * element (setPrefix()) and was bound to different namespace.
+ // * <br />If namespace is null then prefix must be null too or IllegalStateException is thrown.
+ // * <br />If namespace is null then no namespace prefix is printed but just name.
+ // * <br />If namespace is empty string then serializer will make sure that
+ // * default empty namespace is declared (in XML 1.0 xmlns='')
+ // * or throw IllegalStateException if default namespace is already bound
+ // * to non-empty string.
+ // */
+ // XmlSerializer startTag (String prefix, String namespace, String name)
+ // throws IOException, IllegalArgumentException, IllegalStateException;
+ //
+ // /**
+ // * Write an attribute. Calls to attribute() MUST follow a call to
+ // * startTag() immediately.
+ // * <br />If there is no prefix defined (prefix == null) for the given namespace,
+ // * a prefix will be defined automatically.
+ // * <br />If explicit prefixes is passed (prefix != null) then it will be used
+ // * and namespace declared if not already declared or
+ // * throw IllegalStateException the same prefix was already set on this
+ // * element (setPrefix()) and was bound to different namespace.
+ // * <br />If namespace is null then prefix must be null too or IllegalStateException is thrown.
+ // * <br />If namespace is null then no namespace prefix is printed but just name.
+ // * <br />If namespace is empty string then serializer will make sure that
+ // * default empty namespace is declared (in XML 1.0 xmlns='')
+ // * or throw IllegalStateException if default namespace is already bound
+ // * to non-empty string.
+ // */
+ // XmlSerializer attribute (String prefix, String namespace, String name, String value)
+ // throws IOException, IllegalArgumentException, IllegalStateException;
+ //
+ // /**
+ // * Write end tag. Repetition of namespace, prefix, and name is just for avoiding errors.
+ // * <br />If namespace or name arguments are different from corresponding startTag call
+ // * then IllegalArgumentException is thrown, if prefix argument is not null and is different
+ // * from corresponding starTag then IllegalArgumentException is thrown.
+ // * <br />If namespace is null then prefix must be null too or IllegalStateException is thrown.
+ // * <br />If namespace is null then no namespace prefix is printed but just name.
+ // * <br />If namespace is empty string then serializer will make sure that
+ // * default empty namespace is declared (in XML 1.0 xmlns='').
+ // * <p><b>Background:</b> in kXML endTag had no arguments, and non matching tags were
+ // * very difficult to find...</p>
+ // */
+ // ALEK: This is really optional as prefix in end tag MUST correspond to start tag but good for error checking
+ // XmlSerializer endTag (String prefix, String namespace, String name)
+ // throws IOException, IllegalArgumentException, IllegalStateException;
+
+ /**
+ * Writes text, where special XML chars are escaped automatically
+ */
+ XmlSerializer text (String text)
+ throws IOException, IllegalArgumentException, IllegalStateException;
+
+ /**
+ * Writes text, where special XML chars are escaped automatically
+ */
+ XmlSerializer text (char [] buf, int start, int len)
+ throws IOException, IllegalArgumentException, IllegalStateException;
+
+ void cdsect (String text)
+ throws IOException, IllegalArgumentException, IllegalStateException;
+ void entityRef (String text) throws IOException,
+ IllegalArgumentException, IllegalStateException;
+ void processingInstruction (String text)
+ throws IOException, IllegalArgumentException, IllegalStateException;
+ void comment (String text)
+ throws IOException, IllegalArgumentException, IllegalStateException;
+ void docdecl (String text)
+ throws IOException, IllegalArgumentException, IllegalStateException;
+ void ignorableWhitespace (String text)
+ throws IOException, IllegalArgumentException, IllegalStateException;
+
+ /**
+ * Write all pending output to the stream.
+ * If method startTag() or attribute() was called then start tag is closed (final &gt;)
+ * before flush() is called on underlying output stream.
+ *
+ * <p><b>NOTE:</b> if there is need to close start tag
+ * (so no more attribute() calls are allowed) but without flushinging output
+ * call method text() with empty string (text("")).
+ *
+ */
+ void flush ()
+ throws IOException;
+
+}
+
diff --git a/xml/src/main/java/org/xmlpull/v1/sax2/Driver.java b/xml/src/main/java/org/xmlpull/v1/sax2/Driver.java
new file mode 100644
index 0000000..0bd2d4f
--- /dev/null
+++ b/xml/src/main/java/org/xmlpull/v1/sax2/Driver.java
@@ -0,0 +1,469 @@
+/* -*- c-basic-offset: 4; indent-tabs-mode: nil; -*- //------100-columns-wide------>|*/
+// for license please see accompanying LICENSE.txt file (available also at http://www.xmlpull.org/)
+
+package org.xmlpull.v1.sax2;
+
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.Reader;
+
+// not J2ME classes -- remove if you want to run in MIDP devices
+import java.net.URL;
+import java.net.MalformedURLException;
+
+
+// not J2ME classes
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.DTDHandler;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.SAXNotRecognizedException;
+import org.xml.sax.SAXNotSupportedException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.DefaultHandler;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlPullParserFactory;
+
+/**
+ * SAX2 Driver that pulls events from XmlPullParser
+ * and comverts them into SAX2 callbacks.
+ *
+ * @author <a href="http://www.extreme.indiana.edu/~aslom/">Aleksander Slominski</a>
+ */
+
+public class Driver implements Locator, XMLReader, Attributes
+{
+
+ protected static final String DECLARATION_HANDLER_PROPERTY =
+ "http://xml.org/sax/properties/declaration-handler";
+
+ protected static final String LEXICAL_HANDLER_PROPERTY =
+ "http://xml.org/sax/properties/lexical-handler";
+
+ protected static final String NAMESPACES_FEATURE =
+ "http://xml.org/sax/features/namespaces";
+
+ protected static final String NAMESPACE_PREFIXES_FEATURE =
+ "http://xml.org/sax/features/namespace-prefixes";
+
+ protected static final String VALIDATION_FEATURE =
+ "http://xml.org/sax/features/validation";
+
+ protected static final String APACHE_SCHEMA_VALIDATION_FEATURE =
+ "http://apache.org/xml/features/validation/schema";
+
+ protected static final String APACHE_DYNAMIC_VALIDATION_FEATURE =
+ "http://apache.org/xml/features/validation/dynamic";
+
+ protected ContentHandler contentHandler = new DefaultHandler();
+ protected ErrorHandler errorHandler = new DefaultHandler();;
+
+ protected String systemId;
+
+ protected XmlPullParser pp;
+
+ //private final static boolean DEBUG = false;
+
+ /**
+ */
+ public Driver() throws XmlPullParserException {
+ final XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
+ factory.setNamespaceAware(true);
+ pp = factory.newPullParser();
+ }
+
+ public Driver(XmlPullParser pp) throws XmlPullParserException {
+ this.pp = pp;
+ }
+
+ // -- Attributes interface
+
+ public int getLength() { return pp.getAttributeCount(); }
+ public String getURI(int index) { return pp.getAttributeNamespace(index); }
+ public String getLocalName(int index) { return pp.getAttributeName(index); }
+ public String getQName(int index) {
+ final String prefix = pp.getAttributePrefix(index);
+ if(prefix != null) {
+ return prefix+':'+pp.getAttributeName(index);
+ } else {
+ return pp.getAttributeName(index);
+ }
+ }
+ public String getType(int index) { return pp.getAttributeType(index); }
+ public String getValue(int index) { return pp.getAttributeValue(index); }
+
+ public int getIndex(String uri, String localName) {
+ for (int i = 0; i < pp.getAttributeCount(); i++)
+ {
+ if(pp.getAttributeNamespace(i).equals(uri)
+ && pp.getAttributeName(i).equals(localName))
+ {
+ return i;
+ }
+
+ }
+ return -1;
+ }
+
+ public int getIndex(String qName) {
+ for (int i = 0; i < pp.getAttributeCount(); i++)
+ {
+ if(pp.getAttributeName(i).equals(qName))
+ {
+ return i;
+ }
+
+ }
+ return -1;
+ }
+
+ public String getType(String uri, String localName) {
+ for (int i = 0; i < pp.getAttributeCount(); i++)
+ {
+ if(pp.getAttributeNamespace(i).equals(uri)
+ && pp.getAttributeName(i).equals(localName))
+ {
+ return pp.getAttributeType(i);
+ }
+
+ }
+ return null;
+ }
+ public String getType(String qName) {
+ for (int i = 0; i < pp.getAttributeCount(); i++)
+ {
+ if(pp.getAttributeName(i).equals(qName))
+ {
+ return pp.getAttributeType(i);
+ }
+
+ }
+ return null;
+ }
+ public String getValue(String uri, String localName) {
+ return pp.getAttributeValue(uri, localName);
+ }
+ public String getValue(String qName) {
+ return pp.getAttributeValue(null, qName);
+ }
+
+ // -- Locator interface
+
+ public String getPublicId() { return null; }
+ public String getSystemId() { return systemId; }
+ public int getLineNumber() { return pp.getLineNumber(); }
+ public int getColumnNumber() { return pp.getColumnNumber(); }
+
+ // --- XMLReader interface
+
+ public boolean getFeature(String name)
+ throws SAXNotRecognizedException, SAXNotSupportedException
+ {
+ if(NAMESPACES_FEATURE.equals(name)) {
+ return pp.getFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES);
+ } else if(NAMESPACE_PREFIXES_FEATURE.equals(name)) {
+ return pp.getFeature(XmlPullParser.FEATURE_REPORT_NAMESPACE_ATTRIBUTES);
+ } else if(VALIDATION_FEATURE.equals(name)) {
+ return pp.getFeature(XmlPullParser.FEATURE_VALIDATION);
+ // } else if(APACHE_SCHEMA_VALIDATION_FEATURE.equals(name)) {
+ // return false; //TODO
+ // } else if(APACHE_DYNAMIC_VALIDATION_FEATURE.equals(name)) {
+ // return false; //TODO
+ } else {
+ return pp.getFeature(name);
+ //throw new SAXNotRecognizedException("unrecognized feature "+name);
+ }
+ }
+
+ public void setFeature (String name, boolean value)
+ throws SAXNotRecognizedException, SAXNotSupportedException
+ {
+ try {
+ if(NAMESPACES_FEATURE.equals(name)) {
+ pp.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, value);
+ } else if(NAMESPACE_PREFIXES_FEATURE.equals(name)) {
+ if(pp.getFeature(XmlPullParser.FEATURE_REPORT_NAMESPACE_ATTRIBUTES) != value) {
+ pp.setFeature(XmlPullParser.FEATURE_REPORT_NAMESPACE_ATTRIBUTES, value);
+ }
+ } else if(VALIDATION_FEATURE.equals(name)) {
+ pp.setFeature(XmlPullParser.FEATURE_VALIDATION, value);
+ // } else if(APACHE_SCHEMA_VALIDATION_FEATURE.equals(name)) {
+ // // can ignore as validation must be false ...
+ // // if(true == value) {
+ // // throw new SAXNotSupportedException("schema validation is not supported");
+ // // }
+ // } else if(APACHE_DYNAMIC_VALIDATION_FEATURE.equals(name)) {
+ // if(true == value) {
+ // throw new SAXNotSupportedException("dynamic validation is not supported");
+ // }
+ } else {
+ pp.setFeature(name, value);
+ //throw new SAXNotRecognizedException("unrecognized feature "+name);
+ }
+ } catch(XmlPullParserException ex) {
+ // throw new SAXNotSupportedException("problem with setting feature "+name+": "+ex);
+ }
+ }
+
+ public Object getProperty (String name)
+ throws SAXNotRecognizedException, SAXNotSupportedException
+ {
+ if(DECLARATION_HANDLER_PROPERTY.equals(name)) {
+ return null;
+ } else if(LEXICAL_HANDLER_PROPERTY.equals(name)) {
+ return null;
+ } else {
+ return pp.getProperty(name);
+ //throw new SAXNotRecognizedException("not recognized get property "+name);
+ }
+ }
+
+ public void setProperty (String name, Object value)
+ throws SAXNotRecognizedException, SAXNotSupportedException
+ {
+ //
+ if(DECLARATION_HANDLER_PROPERTY.equals(name)) {
+ throw new SAXNotSupportedException("not supported setting property "+name);//+" to "+value);
+ } else if(LEXICAL_HANDLER_PROPERTY.equals(name)) {
+ throw new SAXNotSupportedException("not supported setting property "+name);//+" to "+value);
+ } else {
+ try {
+ pp.setProperty(name, value);
+ } catch(XmlPullParserException ex) {
+ throw new SAXNotSupportedException("not supported set property "+name+": "+ ex);
+ }
+ //throw new SAXNotRecognizedException("not recognized set property "+name);
+ }
+ }
+
+ public void setEntityResolver (EntityResolver resolver) {}
+
+ public EntityResolver getEntityResolver () { return null; }
+
+ public void setDTDHandler (DTDHandler handler) {}
+
+ public DTDHandler getDTDHandler () { return null; }
+
+ public void setContentHandler (ContentHandler handler)
+ {
+ this.contentHandler = handler;
+ }
+
+ public ContentHandler getContentHandler() { return contentHandler; }
+
+ public void setErrorHandler(ErrorHandler handler) {
+ this.errorHandler = handler;
+ }
+
+ public ErrorHandler getErrorHandler() { return errorHandler; }
+
+ public void parse(InputSource source) throws SAXException, IOException
+ {
+
+ systemId = source.getSystemId();
+ contentHandler.setDocumentLocator(this);
+
+ final Reader reader = source.getCharacterStream();
+ try {
+ if (reader == null) {
+ InputStream stream = source.getByteStream();
+ final String encoding = source.getEncoding();
+
+ if (stream == null) {
+ systemId = source.getSystemId();
+ if(systemId == null) {
+ SAXParseException saxException = new SAXParseException(
+ "null source systemId" , this);
+ errorHandler.fatalError(saxException);
+ return;
+ }
+ // NOTE: replace with Connection to run in J2ME environment
+ try {
+ final URL url = new URL(systemId);
+ stream = url.openStream();
+ } catch (MalformedURLException nue) {
+ try {
+ stream = new FileInputStream(systemId);
+ } catch (FileNotFoundException fnfe) {
+ final SAXParseException saxException = new SAXParseException(
+ "could not open file with systemId "+systemId, this, fnfe);
+ errorHandler.fatalError(saxException);
+ return;
+ }
+ }
+ }
+ pp.setInput(stream, encoding);
+ } else {
+ pp.setInput(reader);
+ }
+ } catch (XmlPullParserException ex) {
+ final SAXParseException saxException = new SAXParseException(
+ "parsing initialization error: "+ex, this, ex);
+ //if(DEBUG) ex.printStackTrace();
+ errorHandler.fatalError(saxException);
+ return;
+ }
+
+ // start parsing - move to first start tag
+ try {
+ contentHandler.startDocument();
+ // get first event
+ pp.next();
+ // it should be start tag...
+ if(pp.getEventType() != XmlPullParser.START_TAG) {
+ final SAXParseException saxException = new SAXParseException(
+ "expected start tag not"+pp.getPositionDescription(), this);
+ //throw saxException;
+ errorHandler.fatalError(saxException);
+ return;
+ }
+ } catch (XmlPullParserException ex) {
+ final SAXParseException saxException = new SAXParseException(
+ "parsing initialization error: "+ex, this, ex);
+ //ex.printStackTrace();
+ errorHandler.fatalError(saxException);
+ return;
+ }
+
+ // now real parsing can start!
+
+ parseSubTree(pp);
+
+ // and finished ...
+
+ contentHandler.endDocument();
+ }
+
+ public void parse(String systemId) throws SAXException, IOException {
+ parse(new InputSource(systemId));
+ }
+
+
+ public void parseSubTree(XmlPullParser pp) throws SAXException, IOException {
+ this.pp = pp;
+ final boolean namespaceAware = pp.getFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES);
+ try {
+ if(pp.getEventType() != XmlPullParser.START_TAG) {
+ throw new SAXException(
+ "start tag must be read before skiping subtree"+pp.getPositionDescription());
+ }
+ final int[] holderForStartAndLength = new int[2];
+ final StringBuffer rawName = new StringBuffer(16);
+ String prefix = null;
+ String name = null;
+ int level = pp.getDepth() - 1;
+ int type = XmlPullParser.START_TAG;
+
+ LOOP:
+ do {
+ switch(type) {
+ case XmlPullParser.START_TAG:
+ if(namespaceAware) {
+ final int depth = pp.getDepth() - 1;
+ final int countPrev =
+ (level > depth) ? pp.getNamespaceCount(depth) : 0;
+ //int countPrev = pp.getNamespaceCount(pp.getDepth() - 1);
+ final int count = pp.getNamespaceCount(depth + 1);
+ for (int i = countPrev; i < count; i++)
+ {
+ contentHandler.startPrefixMapping(
+ pp.getNamespacePrefix(i),
+ pp.getNamespaceUri(i)
+ );
+ }
+ name = pp.getName();
+ prefix = pp.getPrefix();
+ if(prefix != null) {
+ rawName.setLength(0);
+ rawName.append(prefix);
+ rawName.append(':');
+ rawName.append(name);
+ }
+ startElement(pp.getNamespace(),
+ name,
+ // TODO Fixed this. Was "not equals".
+ prefix == null ? name : rawName.toString());
+ } else {
+ startElement(pp.getNamespace(),
+ pp.getName(),
+ pp.getName());
+ }
+ //++level;
+
+ break;
+ case XmlPullParser.TEXT:
+ final char[] chars = pp.getTextCharacters(holderForStartAndLength);
+ contentHandler.characters(chars,
+ holderForStartAndLength[0], //start
+ holderForStartAndLength[1] //len
+ );
+ break;
+ case XmlPullParser.END_TAG:
+ //--level;
+ if(namespaceAware) {
+ name = pp.getName();
+ prefix = pp.getPrefix();
+ if(prefix != null) {
+ rawName.setLength(0);
+ rawName.append(prefix);
+ rawName.append(':');
+ rawName.append(name);
+ }
+ contentHandler.endElement(pp.getNamespace(),
+ name,
+ prefix != null ? name : rawName.toString()
+ );
+ // when entering show prefixes for all levels!!!!
+ final int depth = pp.getDepth();
+ final int countPrev =
+ (level > depth) ? pp.getNamespaceCount(pp.getDepth()) : 0;
+ int count = pp.getNamespaceCount(pp.getDepth() - 1);
+ // undeclare them in reverse order
+ for (int i = count - 1; i >= countPrev; i--)
+ {
+ contentHandler.endPrefixMapping(
+ pp.getNamespacePrefix(i)
+ );
+ }
+ } else {
+ contentHandler.endElement(pp.getNamespace(),
+ pp.getName(),
+ pp.getName()
+ );
+
+ }
+ break;
+ case XmlPullParser.END_DOCUMENT:
+ break LOOP;
+ }
+ type = pp.next();
+ } while(pp.getDepth() > level);
+ } catch (XmlPullParserException ex) {
+ final SAXParseException saxException = new SAXParseException("parsing error: "+ex, this, ex);
+ ex.printStackTrace();
+ errorHandler.fatalError(saxException);
+ }
+ }
+
+ /**
+ * Calls {@link ContentHandler#startElement(String, String, String, Attributes) startElement}
+ * on the <code>ContentHandler</code> with <code>this</code> driver object as the
+ * {@link Attributes} implementation. In default implementation
+ * {@link Attributes} object is valid only during this method call and may not
+ * be stored. Sub-classes can overwrite this method to cache attributes.
+ */
+ protected void startElement(String namespace, String localName, String qName) throws SAXException {
+ contentHandler.startElement(namespace, localName, qName, this);
+ }
+
+}
diff --git a/xml/src/main/native/org_apache_harmony_xml_ExpatParser.cpp b/xml/src/main/native/org_apache_harmony_xml_ExpatParser.cpp
new file mode 100644
index 0000000..7149272
--- /dev/null
+++ b/xml/src/main/native/org_apache_harmony_xml_ExpatParser.cpp
@@ -0,0 +1,1530 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "ExpatParser"
+
+#include "jni.h"
+#include "utils/Log.h"
+#include "JNIHelp.h"
+
+#include <string.h>
+#include <utils/misc.h>
+#include <expat.h>
+#include <cutils/jstring.h>
+
+#define BUCKET_COUNT 128
+
+/**
+ * Wrapper around an interned string.
+ */
+typedef struct {
+
+ /** The interned string itself. */
+ jstring interned;
+
+ /** UTF-8 equivalent of the interned string. */
+ const char* bytes;
+
+ /** Hash code of the interned string. */
+ int hash;
+} InternedString;
+
+/**
+ * Keeps track of strings between start and end events.
+ */
+typedef struct {
+
+ jstring* array;
+ int capacity;
+ int size;
+} StringStack;
+
+/**
+ * Data passed to parser handler method by the parser.
+ */
+typedef struct {
+
+ /**
+ * The JNI environment for the current thread. This should only be used
+ * to keep a reference to the env for use in Expat callbacks.
+ */
+ JNIEnv* env;
+
+ /** The Java parser object. */
+ jobject object;
+
+ /** Buffer for text events. */
+ jcharArray buffer;
+
+ /** The size of our buffer in jchars. */
+ int bufferSize;
+
+ /** Current attributes. */
+ const char** attributes;
+
+ /** Number of attributes. */
+ int attributeCount;
+
+ /** True if namespace support is enabled. */
+ bool processNamespaces;
+
+ /** Keep track of names. */
+ StringStack stringStack;
+
+ /** Cache of interned strings. */
+ InternedString** internedStrings[BUCKET_COUNT];
+} ParsingContext;
+
+static jmethodID startElementMethod;
+static jmethodID endElementMethod;
+static jmethodID textMethod;
+static jmethodID commentMethod;
+static jmethodID startCdataMethod;
+static jmethodID endCdataMethod;
+static jmethodID startDtdMethod;
+static jmethodID endDtdMethod;
+static jmethodID startNamespaceMethod;
+static jmethodID endNamespaceMethod;
+static jmethodID processingInstructionMethod;
+static jmethodID handleExternalEntityMethod;
+static jmethodID internMethod;
+static jclass stringClass;
+static jstring emptyString;
+
+/**
+ * Throws a NullPointerException.
+ *
+ * @param msg exception message
+ */
+static void throw_NullPointerException(JNIEnv* env, const char* msg) {
+ jniThrowException(env, "java/lang/NullPointerException", msg);
+}
+
+/**
+ * Throw a NullPointerException.
+ */
+static void throw_OutOfMemoryError(JNIEnv* env) {
+ jniThrowException(env, "java/lang/OutOfMemoryError", "Out of memory.");
+}
+
+/**
+ * Calculates a hash code for a null-terminated string. This is *not* equivalent
+ * to Java's String.hashCode(). This hashes the bytes while String.hashCode()
+ * hashes UTF-16 chars.
+ *
+ * @param s null-terminated string to hash
+ * @returns hash code
+ */
+static int hashString(const char* s) {
+ int hash = 0;
+ if (s) {
+ while (*s) {
+ hash = hash * 31 + *s++;
+ }
+ }
+ return hash;
+}
+
+/**
+ * Creates a new interned string wrapper. Looks up the interned string
+ * representing the given UTF-8 bytes.
+ *
+ * @param bytes null-terminated string to intern
+ * @param hash of bytes
+ * @returns wrapper of interned Java string
+ */
+static InternedString* newInternedString(JNIEnv* env,
+ ParsingContext* parsingContext, const char* bytes, int hash) {
+ // Allocate a new wrapper.
+ InternedString* wrapper
+ = (InternedString* ) malloc(sizeof(InternedString));
+ if (wrapper == NULL) {
+ throw_OutOfMemoryError(env);
+ return NULL;
+ }
+
+ // Create a copy of the UTF-8 bytes.
+ // TODO: sometimes we already know the length. Reuse it if so.
+ char* copy = strdup(bytes);
+ wrapper->bytes = copy;
+ if (wrapper->bytes == NULL) {
+ throw_OutOfMemoryError(env);
+ free(wrapper);
+ return NULL;
+ }
+
+ // Save the hash.
+ wrapper->hash = hash;
+
+ // To intern a string, we must first create a new string and then call
+ // intern() on it. We then keep a global reference to the interned string.
+ jstring newString = env->NewStringUTF(bytes);
+ if (env->ExceptionCheck()) {
+ free(copy);
+ free(wrapper);
+ return NULL;
+ }
+
+ // Call intern().
+ jstring interned =
+ (jstring) env->CallObjectMethod(newString, internMethod);
+ if (env->ExceptionCheck()) {
+ free(copy);
+ free(wrapper);
+ return NULL;
+ }
+
+ // Create a global reference to the interned string.
+ wrapper->interned = (jstring) env->NewGlobalRef(interned);
+ if (env->ExceptionCheck()) {
+ free(copy);
+ free(wrapper);
+ return NULL;
+ }
+
+ env->DeleteLocalRef(interned);
+ env->DeleteLocalRef(newString);
+
+ return wrapper;
+}
+
+/**
+ * Allocates a new bucket with one entry.
+ *
+ * @param entry to store in the bucket
+ * @returns a reference to the bucket
+ */
+static InternedString** newInternedStringBucket(InternedString* entry) {
+ InternedString** bucket
+ = (InternedString**) malloc(sizeof(InternedString*) * 2);
+ if (bucket == NULL) return NULL;
+
+ bucket[0] = entry;
+ bucket[1] = NULL;
+ return bucket;
+}
+
+/**
+ * Expands an interned string bucket and adds the given entry. Frees the
+ * provided bucket and returns a new one.
+ *
+ * @param existingBucket the bucket to replace
+ * @param entry to add to the bucket
+ * @returns a reference to the newly-allocated bucket containing the given entry
+ */
+static InternedString** expandInternedStringBucket(
+ InternedString** existingBucket, InternedString* entry) {
+ // Determine the size of the existing bucket.
+ int size = 0;
+ while (existingBucket[size]) size++;
+
+ // Allocate the new bucket with enough space for one more entry and
+ // a null terminator.
+ InternedString** newBucket = (InternedString**) realloc(existingBucket,
+ sizeof(InternedString*) * (size + 2));
+ if (newBucket == NULL) return NULL;
+
+ newBucket[size] = entry;
+ newBucket[size + 1] = NULL;
+
+ return newBucket;
+}
+
+/**
+ * Returns an interned string for the given UTF-8 string.
+ *
+ * @param bucket to search for s
+ * @param s null-terminated string to find
+ * @param hash of s
+ * @returns interned Java string equivalent of s or null if not found
+ */
+static jstring findInternedString(InternedString** bucket, const char* s,
+ int hash) {
+ InternedString* current;
+ while ((current = *(bucket++)) != NULL) {
+ if (current->hash != hash) continue;
+ if (!strcmp(s, current->bytes)) return current->interned;
+ }
+ return NULL;
+}
+
+/**
+ * Returns an interned string for the given UTF-8 string.
+ *
+ * @param s null-terminated string to intern
+ * @returns interned Java string equivelent of s or NULL if s is null
+ */
+static jstring internString(JNIEnv* env, ParsingContext* parsingContext,
+ const char* s) {
+ if (s == NULL) return NULL;
+
+ int hash = hashString(s);
+ int bucketIndex = hash & (BUCKET_COUNT - 1);
+
+ InternedString*** buckets = parsingContext->internedStrings;
+ InternedString** bucket = buckets[bucketIndex];
+ InternedString* internedString;
+
+ if (bucket) {
+ // We have a bucket already. Look for the given string.
+ jstring found = findInternedString(bucket, s, hash);
+ if (found) {
+ // We found it!
+ return found;
+ }
+
+ // We didn't find it. :(
+ // Create a new entry.
+ internedString = newInternedString(env, parsingContext, s, hash);
+ if (internedString == NULL) return NULL;
+
+ // Expand the bucket.
+ bucket = expandInternedStringBucket(bucket, internedString);
+ if (bucket == NULL) {
+ throw_OutOfMemoryError(env);
+ return NULL;
+ }
+
+ buckets[bucketIndex] = bucket;
+
+ return internedString->interned;
+ } else {
+ // We don't even have a bucket yet. Create an entry.
+ internedString = newInternedString(env, parsingContext, s, hash);
+ if (internedString == NULL) return NULL;
+
+ // Create a new bucket with one entry.
+ bucket = newInternedStringBucket(internedString);
+ if (bucket == NULL) {
+ throw_OutOfMemoryError(env);
+ return NULL;
+ }
+
+ buckets[bucketIndex] = bucket;
+
+ return internedString->interned;
+ }
+}
+
+/**
+ * Returns an interned string for the given UTF-8 string.
+ *
+ * @param s string to intern
+ * @param length of s
+ * @returns interned Java string equivelent of s
+ */
+static jstring internStringOfLength(JNIEnv* env, ParsingContext* parsingContext,
+ const char* s, int length) {
+ // Create a null-terminated version.
+ char nullTerminated[length + 1];
+ memcpy(nullTerminated, s, length);
+ nullTerminated[length] = 0;
+
+ return internString(env, parsingContext, nullTerminated);
+}
+
+/**
+ * Throw an assertion error.
+ *
+ * @param message to show
+ */
+static void fail(JNIEnv* env, const char* message) {
+ jclass clazz;
+ clazz = env->FindClass("java/lang/AssertionError");
+ env->ThrowNew(clazz, message);
+}
+
+/**
+ * Allocates a new parsing context.
+ *
+ * @param jobject the Java ExpatParser instance
+ * @returns a newly-allocated ParsingContext
+ */
+ParsingContext* newParsingContext(JNIEnv* env, jobject object) {
+ ParsingContext* result = (ParsingContext*) malloc(sizeof(ParsingContext));
+ if (result == NULL) {
+ throw_OutOfMemoryError(env);
+ return NULL;
+ }
+
+ result->env = NULL;
+ result->buffer = NULL;
+ result->bufferSize = -1;
+ result->object = object;
+
+ int stackSize = 10;
+ result->stringStack.capacity = stackSize;
+ result->stringStack.size = 0;
+ result->stringStack.array
+ = (jstring*) malloc(stackSize * sizeof(jstring));
+
+ for (int i = 0; i < BUCKET_COUNT; i++) {
+ result->internedStrings[i] = NULL;
+ }
+
+ return result;
+}
+
+/**
+ * Frees the char[] buffer if it exists.
+ */
+static void freeBuffer(JNIEnv* env, ParsingContext* parsingContext) {
+ if (parsingContext->buffer != NULL) {
+ env->DeleteGlobalRef(parsingContext->buffer);
+ parsingContext->buffer = NULL;
+ parsingContext->bufferSize = -1;
+ }
+}
+
+/**
+ * Ensures our buffer is big enough.
+ *
+ * @param length in jchars
+ * @returns a reference to the buffer
+ */
+static jcharArray ensureCapacity(ParsingContext* parsingContext, int length) {
+ if (parsingContext->bufferSize < length) {
+ JNIEnv* env = parsingContext->env;
+
+ // Free the existing char[].
+ freeBuffer(env, parsingContext);
+
+ // Allocate a new char[].
+ jcharArray javaBuffer = env->NewCharArray(length);
+ if (javaBuffer == NULL) return NULL;
+
+ // Create a global reference.
+ javaBuffer = (jcharArray) env->NewGlobalRef(javaBuffer);
+ if (javaBuffer == NULL) return NULL;
+
+ parsingContext->buffer = javaBuffer;
+ parsingContext->bufferSize = length;
+ }
+
+ return parsingContext->buffer;
+}
+
+/**
+ * Copies UTF-8 characters into the buffer. Returns the number of Java chars
+ * which were buffered.
+ *
+ * @param characters to copy into the buffer
+ * @param length of characters to copy (in bytes)
+ * @returns number of UTF-16 characters which were copied
+ */
+static size_t fillBuffer(ParsingContext* parsingContext, const char* characters,
+ int length) {
+ JNIEnv* env = parsingContext->env;
+
+ // Grow buffer if necessary.
+ jcharArray buffer = ensureCapacity(parsingContext, length);
+ if (buffer == NULL) return -1;
+
+ // Get a native reference to our buffer.
+ jchar* nativeBuffer = env->GetCharArrayElements(buffer, NULL);
+
+ // Decode UTF-8 characters into our buffer.
+ size_t utf16length;
+ strcpylen8to16((char16_t*) nativeBuffer, characters, length, &utf16length);
+
+ // Release our native reference.
+ env->ReleaseCharArrayElements(buffer, nativeBuffer, 0);
+
+ return utf16length;
+}
+
+/**
+ * Buffers the given text and passes it to the given method.
+ *
+ * @param method to pass the characters and length to with signature
+ * (char[], int)
+ * @param data parsing context
+ * @param text to copy into the buffer
+ * @param length of text to copy (in bytes)
+ */
+static void bufferAndInvoke(jmethodID method, void* data, const char* text,
+ size_t length) {
+ ParsingContext* parsingContext = (ParsingContext*) data;
+ JNIEnv* env = parsingContext->env;
+
+ // Bail out if a previously called handler threw an exception.
+ if (env->ExceptionCheck()) return;
+
+ // Buffer the element name.
+ size_t utf16length = fillBuffer(parsingContext, text, length);
+
+ // Invoke given method.
+ jobject javaParser = parsingContext->object;
+ jcharArray buffer = parsingContext->buffer;
+ env->CallVoidMethod(javaParser, method, buffer, utf16length);
+}
+
+/**
+ * Finds the '|' in a null-terminated string. Returns -1 if none is found.
+ *
+ * @param s string to search
+ * @returns index of the separator
+ */
+static int findSeparator(const char* s) {
+ char* pointer = strchr(s, '|');
+ return pointer == NULL ? -1 : pointer - s;
+}
+
+/**
+ * Parses the URI out of an Expat element name and turns it into a Java string.
+ * Expat element names follow the format: "uri|localName".
+ *
+ * @param s string to parse from
+ * @param separatorIndex index of separator in s
+ * @returns interned Java string containing the URI
+ */
+static jstring parseUri(JNIEnv* env, ParsingContext* parsingContext, const char* s,
+ int separatorIndex) {
+ return separatorIndex == -1 ? emptyString
+ : internStringOfLength(env, parsingContext, s, separatorIndex);
+}
+
+/**
+ * Parses the local name out of an Expat element name and turns it into a Java
+ * string. Expat element names follow the format: "uri|localName".
+ *
+ * @param s string to parse from
+ * @param separatorIndex index of separator in s
+ * @returns interned Java string containing the local name
+ */
+static jstring parseLocalName(JNIEnv* env, ParsingContext* parsingContext,
+ const char* s, int separatorIndex) {
+ return internString(env, parsingContext, s + separatorIndex + 1);
+}
+
+/**
+ * Pushes a string onto the stack.
+ */
+static void stringStackPush(ParsingContext* parsingContext, jstring s) {
+ StringStack* stringStack = &parsingContext->stringStack;
+
+ // Expand if necessary.
+ if (stringStack->size == stringStack->capacity) {
+ int newCapacity = stringStack->capacity * 2;
+ stringStack->array = (jstring*) realloc(stringStack->array,
+ newCapacity * sizeof(jstring));
+
+ if (stringStack->array == NULL) {
+ throw_OutOfMemoryError(parsingContext->env);
+ return;
+ }
+
+ stringStack->capacity = newCapacity;
+ }
+
+ stringStack->array[stringStack->size++] = s;
+}
+
+/**
+ * Pops a string off the stack.
+ */
+static jstring stringStackPop(ParsingContext* parsingContext) {
+ StringStack* stringStack = &parsingContext->stringStack;
+
+ if (stringStack->size == 0) {
+ return NULL;
+ }
+
+ return stringStack->array[--stringStack->size];
+}
+
+/**
+ * Called by Expat at the start of an element. Delegates to the same method
+ * on the Java parser.
+ *
+ * @param data parsing context
+ * @param elementName "uri|localName" or "localName" for the current element
+ * @param attributes alternating attribute names and values. Like element
+ * names, attribute names follow the format "uri|localName" or "localName".
+ */
+static void startElement(void* data, const char* elementName,
+ const char** attributes) {
+ ParsingContext* parsingContext = (ParsingContext*) data;
+ JNIEnv* env = parsingContext->env;
+
+ // Bail out if a previously called handler threw an exception.
+ if (env->ExceptionCheck()) return;
+
+ // Count the number of attributes.
+ int count = 0;
+ while (attributes[count << 1]) count++;
+
+ // Make the attributes available for the duration of this call.
+ parsingContext->attributes = attributes;
+ parsingContext->attributeCount = count;
+
+ jobject javaParser = parsingContext->object;
+
+ if (parsingContext->processNamespaces) {
+ // Break down Expat's element name into two Java strings.
+ int separatorIndex = findSeparator(elementName);
+ jstring uri = parseUri(
+ env, parsingContext, elementName, separatorIndex);
+ jstring localName = parseLocalName(
+ env, parsingContext, elementName, separatorIndex);
+
+ stringStackPush(parsingContext, uri);
+ stringStackPush(parsingContext, localName);
+
+ env->CallVoidMethod(javaParser, startElementMethod, uri, localName,
+ emptyString, attributes, count);
+ } else {
+ jstring qName = internString(env, parsingContext, elementName);
+
+ stringStackPush(parsingContext, qName);
+
+ env->CallVoidMethod(javaParser, startElementMethod,
+ emptyString, emptyString, qName, attributes, count);
+ }
+
+ parsingContext->attributes = NULL;
+ parsingContext->attributeCount = -1;
+}
+
+/**
+ * Called by Expat at the end of an element. Delegates to the same method
+ * on the Java parser.
+ *
+ * @param data parsing context
+ * @param elementName "uri|localName" or "localName" for the current element
+ */
+static void endElement(void* data, const char* elementName) {
+ ParsingContext* parsingContext = (ParsingContext*) data;
+ JNIEnv* env = parsingContext->env;
+
+ // Bail out if a previously called handler threw an exception.
+ if (env->ExceptionCheck()) return;
+
+ jobject javaParser = parsingContext->object;
+
+ if (parsingContext->processNamespaces) {
+ jstring localName = stringStackPop(parsingContext);
+ jstring uri = stringStackPop(parsingContext);
+
+ env->CallVoidMethod(javaParser, endElementMethod, uri, localName,
+ emptyString);
+ } else {
+ jstring qName = stringStackPop(parsingContext);
+
+ env->CallVoidMethod(javaParser, endElementMethod,
+ emptyString, emptyString, qName);
+ }
+}
+
+/**
+ * Called by Expat when it encounters text. Delegates to the same method
+ * on the Java parser. This may be called mutiple times with incremental pieces
+ * of the same contiguous block of text.
+ *
+ * @param data parsing context
+ * @param characters buffer containing encountered text
+ * @param length number of characters in the buffer
+ */
+static void text(void* data, const char* characters, int length) {
+ bufferAndInvoke(textMethod, data, characters, length);
+}
+
+/**
+ * Called by Expat when it encounters a comment. Delegates to the same method
+ * on the Java parser.
+
+ * @param data parsing context
+ * @param comment 0-terminated
+ */
+static void comment(void* data, const char* comment) {
+ bufferAndInvoke(commentMethod, data, comment, strlen(comment));
+}
+
+/**
+ * Called by Expat at the beginning of a namespace mapping.
+ *
+ * @param data parsing context
+ * @param prefix null-terminated namespace prefix used in the XML
+ * @param uri of the namespace
+ */
+static void startNamespace(void* data, const char* prefix, const char* uri) {
+ ParsingContext* parsingContext = (ParsingContext*) data;
+ JNIEnv* env = parsingContext->env;
+
+ // Bail out if a previously called handler threw an exception.
+ if (env->ExceptionCheck()) return;
+
+ jstring internedPrefix = emptyString;
+ if (prefix != NULL) {
+ internedPrefix = internString(env, parsingContext, prefix);
+ if (env->ExceptionCheck()) return;
+ }
+
+ jstring internedUri = emptyString;
+ if (uri != NULL) {
+ internedUri = internString(env, parsingContext, uri);
+ if (env->ExceptionCheck()) return;
+ }
+
+ stringStackPush(parsingContext, internedPrefix);
+
+ jobject javaParser = parsingContext->object;
+ env->CallVoidMethod(javaParser, startNamespaceMethod, internedPrefix,
+ internedUri);
+}
+
+/**
+ * Called by Expat at the end of a namespace mapping.
+ *
+ * @param data parsing context
+ * @param prefix null-terminated namespace prefix used in the XML
+ */
+static void endNamespace(void* data, const char* prefix) {
+ ParsingContext* parsingContext = (ParsingContext*) data;
+ JNIEnv* env = parsingContext->env;
+
+ // Bail out if a previously called handler threw an exception.
+ if (env->ExceptionCheck()) return;
+
+ jstring internedPrefix = stringStackPop(parsingContext);
+
+ jobject javaParser = parsingContext->object;
+ env->CallVoidMethod(javaParser, endNamespaceMethod, internedPrefix);
+}
+
+/**
+ * Called by Expat at the beginning of a CDATA section.
+ *
+ * @param data parsing context
+ */
+static void startCdata(void* data) {
+ ParsingContext* parsingContext = (ParsingContext*) data;
+ JNIEnv* env = parsingContext->env;
+
+ // Bail out if a previously called handler threw an exception.
+ if (env->ExceptionCheck()) return;
+
+ jobject javaParser = parsingContext->object;
+ env->CallVoidMethod(javaParser, startCdataMethod);
+}
+
+/**
+ * Called by Expat at the end of a CDATA section.
+ *
+ * @param data parsing context
+ */
+static void endCdata(void* data) {
+ ParsingContext* parsingContext = (ParsingContext*) data;
+ JNIEnv* env = parsingContext->env;
+
+ // Bail out if a previously called handler threw an exception.
+ if (env->ExceptionCheck()) return;
+
+ jobject javaParser = parsingContext->object;
+ env->CallVoidMethod(javaParser, endCdataMethod);
+}
+
+/**
+ * Called by Expat at the beginning of a DOCTYPE section.
+ *
+ * @param data parsing context
+ */
+static void startDtd(void* data, const char* name,
+ const char* systemId, const char* publicId, int hasInternalSubset) {
+ ParsingContext* parsingContext = (ParsingContext*) data;
+ JNIEnv* env = parsingContext->env;
+
+ // Bail out if a previously called handler threw an exception.
+ if (env->ExceptionCheck()) return;
+
+ jstring javaName = internString(env, parsingContext, name);
+ if (env->ExceptionCheck()) return;
+
+ jstring javaPublicId = internString(env, parsingContext, publicId);
+ if (env->ExceptionCheck()) return;
+
+ jstring javaSystemId = internString(env, parsingContext, systemId);
+ if (env->ExceptionCheck()) return;
+
+ jobject javaParser = parsingContext->object;
+ env->CallVoidMethod(javaParser, startDtdMethod, javaName, javaPublicId,
+ javaSystemId);
+}
+
+/**
+ * Called by Expat at the end of a DOCTYPE section.
+ *
+ * @param data parsing context
+ */
+static void endDtd(void* data) {
+ ParsingContext* parsingContext = (ParsingContext*) data;
+ JNIEnv* env = parsingContext->env;
+
+ // Bail out if a previously called handler threw an exception.
+ if (env->ExceptionCheck()) return;
+
+ jobject javaParser = parsingContext->object;
+ env->CallVoidMethod(javaParser, endDtdMethod);
+}
+
+/**
+ * Called by Expat when it encounters processing instructions.
+ *
+ * @param data parsing context
+ * @param target of the instruction
+ * @param instructionData
+ */
+static void processingInstruction(void* data, const char* target,
+ const char* instructionData) {
+ ParsingContext* parsingContext = (ParsingContext*) data;
+ JNIEnv* env = parsingContext->env;
+
+ // Bail out if a previously called handler threw an exception.
+ if (env->ExceptionCheck()) return;
+
+ jstring javaTarget = internString(env, parsingContext, target);
+ if (env->ExceptionCheck()) return;
+
+ jstring javaInstructionData = env->NewStringUTF(instructionData);
+ if (env->ExceptionCheck()) return;
+
+ jobject javaParser = parsingContext->object;
+ env->CallVoidMethod(javaParser, processingInstructionMethod, javaTarget,
+ javaInstructionData);
+
+ // We have to temporarily clear an exception before we can release local
+ // references.
+ jthrowable exception = env->ExceptionOccurred();
+ if (exception != NULL) {
+ env->ExceptionClear();
+ }
+
+ env->DeleteLocalRef(javaInstructionData);
+
+ if (exception != NULL) {
+ env->Throw(exception);
+ }
+}
+
+/**
+ * Creates a new entity parser.
+ *
+ * @param object the Java ExpatParser instance
+ * @param parentParser pointer
+ * @param javaEncoding the character encoding name
+ * @param javaContext that was provided to handleExternalEntity
+ * @returns the pointer to the C Expat entity parser
+ */
+static jint createEntityParser(JNIEnv* env, jobject object, jint parentParser,
+ jstring javaEncoding, jstring javaContext) {
+ const char* encoding = env->GetStringUTFChars(javaEncoding, NULL);
+ if (encoding == NULL) {
+ return 0;
+ }
+
+ const char* context = env->GetStringUTFChars(javaContext, NULL);
+ if (context == NULL) {
+ env->ReleaseStringUTFChars(javaEncoding, encoding);
+ return 0;
+ }
+
+ XML_Parser parent = (XML_Parser) parentParser;
+ XML_Parser entityParser
+ = XML_ExternalEntityParserCreate(parent, context, NULL);
+ env->ReleaseStringUTFChars(javaEncoding, encoding);
+ env->ReleaseStringUTFChars(javaContext, context);
+
+ if (entityParser == NULL) {
+ throw_OutOfMemoryError(env);
+ }
+
+ return (jint) entityParser;
+}
+
+/**
+ * Handles external entities. We ignore the "base" URI and keep track of it
+ * ourselves.
+ */
+static int handleExternalEntity(XML_Parser parser, const char* context,
+ const char* ignored, const char* systemId, const char* publicId) {
+ ParsingContext* parsingContext = (ParsingContext*) XML_GetUserData(parser);
+ jobject javaParser = parsingContext->object;
+ JNIEnv* env = parsingContext->env;
+ jobject object = parsingContext->object;
+
+ // Bail out if a previously called handler threw an exception.
+ if (env->ExceptionCheck()) {
+ return XML_STATUS_ERROR;
+ }
+
+ jstring javaSystemId = env->NewStringUTF(systemId);
+ if (env->ExceptionCheck()) {
+ return XML_STATUS_ERROR;
+ }
+ jstring javaPublicId = env->NewStringUTF(publicId);
+ if (env->ExceptionCheck()) {
+ return XML_STATUS_ERROR;
+ }
+ jstring javaContext = env->NewStringUTF(context);
+ if (env->ExceptionCheck()) {
+ return XML_STATUS_ERROR;
+ }
+
+ // Pass the wrapped parser and both strings to java.
+ env->CallVoidMethod(javaParser, handleExternalEntityMethod, javaContext,
+ javaPublicId, javaSystemId);
+
+ /*
+ * Parsing the external entity leaves parsingContext->env and object set to
+ * NULL, so we need to restore both.
+ *
+ * TODO: consider restoring the original env and object instead of setting
+ * them to NULL in the append() functions.
+ */
+ parsingContext->env = env;
+ parsingContext->object = object;
+
+ env->DeleteLocalRef(javaSystemId);
+ env->DeleteLocalRef(javaPublicId);
+ env->DeleteLocalRef(javaContext);
+
+ return env->ExceptionCheck() ? XML_STATUS_ERROR : XML_STATUS_OK;
+}
+
+/**
+ * Releases the parsing context.
+ */
+static void releaseParsingContext(JNIEnv* env, ParsingContext* context) {
+ free(context->stringStack.array);
+
+ freeBuffer(env, context);
+
+ // Free interned string cache.
+ for (int i = 0; i < BUCKET_COUNT; i++) {
+ if (context->internedStrings[i]) {
+ InternedString** bucket = context->internedStrings[i];
+ InternedString* current;
+ while ((current = *(bucket++)) != NULL) {
+ // Free the UTF-8 bytes.
+ free((void*) (current->bytes));
+
+ // Free the interned string reference.
+ env->DeleteGlobalRef(current->interned);
+
+ // Free the bucket.
+ free(current);
+ }
+
+ // Free the buckets.
+ free(context->internedStrings[i]);
+ }
+ }
+
+ free(context);
+}
+
+/**
+ * Creates a new Expat parser. Called from the Java ExpatParser contructor.
+ *
+ * @param object the Java ExpatParser instance
+ * @param javaEncoding the character encoding name
+ * @param processNamespaces true if the parser should handle namespaces
+ * @returns the pointer to the C Expat parser
+ */
+static jint initialize(JNIEnv* env, jobject object, jstring javaEncoding,
+ jboolean processNamespaces) {
+ // Allocate parsing context.
+ ParsingContext* context = newParsingContext(env, object);
+ if (context == NULL) {
+ return 0;
+ }
+
+ context->processNamespaces = (bool) processNamespaces;
+
+ // Create a parser.
+ XML_Parser parser;
+ const char* encoding = env->GetStringUTFChars(javaEncoding, NULL);
+ if (processNamespaces) {
+ // Use '|' to separate URIs from local names.
+ parser = XML_ParserCreateNS(encoding, '|');
+ } else {
+ parser = XML_ParserCreate(encoding);
+ }
+ env->ReleaseStringUTFChars(javaEncoding, encoding);
+
+ if (parser != NULL) {
+ if (processNamespaces) {
+ XML_SetNamespaceDeclHandler(parser, startNamespace, endNamespace);
+ }
+
+ XML_SetCommentHandler(parser, comment);
+ XML_SetCdataSectionHandler(parser, startCdata, endCdata);
+
+ XML_SetElementHandler(parser, startElement, endElement);
+ XML_SetCharacterDataHandler(parser, text);
+ XML_SetDoctypeDeclHandler(parser, startDtd, endDtd);
+ XML_SetProcessingInstructionHandler(parser, processingInstruction);
+ XML_SetExternalEntityRefHandler(parser, handleExternalEntity);
+
+ XML_SetUserData(parser, context);
+ } else {
+ releaseParsingContext(env, context);
+ throw_OutOfMemoryError(env);
+ return 0;
+ }
+
+ return (jint) parser;
+}
+
+/**
+ * Passes some XML to the parser.
+ *
+ * @param object the Java ExpatParser instance
+ * @param pointer to the C expat parser
+ * @param xml Java string containing an XML snippet
+ * @param isFinal whether or not this is the last snippet; enables more error
+ * checking, i.e. is the document complete?
+ */
+static void appendString(JNIEnv* env, jobject object, jint pointer, jstring xml,
+ jboolean isFinal) {
+ XML_Parser parser = (XML_Parser) pointer;
+ ParsingContext* context = (ParsingContext*) XML_GetUserData(parser);
+ context->env = env;
+ context->object = object;
+
+ int length = env->GetStringLength(xml) << 1; // in bytes
+ const jchar* characters = env->GetStringChars(xml, NULL);
+
+ if (!XML_Parse(parser, (char*) characters, length, isFinal)
+ && !env->ExceptionCheck()) {
+ jclass clazz = env->FindClass("org/apache/harmony/xml/ExpatException");
+ const char* errorMessage = XML_ErrorString(XML_GetErrorCode(parser));
+ env->ThrowNew(clazz, errorMessage);
+ }
+
+ // We have to temporarily clear an exception before we can release local
+ // references.
+ jthrowable exception = env->ExceptionOccurred();
+ if (exception) {
+ env->ExceptionClear();
+ env->ReleaseStringChars(xml, characters);
+ env->Throw(exception);
+ } else {
+ env->ReleaseStringChars(xml, characters);
+ }
+
+ context->object = NULL;
+ context->env = NULL;
+}
+
+/**
+ * Passes some XML to the parser.
+ *
+ * @param object the Java ExpatParser instance
+ * @param pointer to the C expat parser
+ * @param xml Java char[] containing XML
+ * @param offset into the xml buffer
+ * @param length of text in the xml buffer
+ */
+static void appendCharacters(JNIEnv* env, jobject object, jint pointer,
+ jcharArray xml, jint offset, jint length) {
+ XML_Parser parser = (XML_Parser) pointer;
+ ParsingContext* context = (ParsingContext*) XML_GetUserData(parser);
+ context->env = env;
+ context->object = object;
+
+ jchar* characters = env->GetCharArrayElements(xml, NULL);
+
+ if (!XML_Parse(parser, ((char*) characters) + (offset << 1),
+ length << 1, XML_FALSE) && !env->ExceptionCheck()) {
+ jclass clazz = env->FindClass("org/apache/harmony/xml/ExpatException");
+ const char* errorMessage = XML_ErrorString(XML_GetErrorCode(parser));
+ env->ThrowNew(clazz, errorMessage);
+ }
+
+ // We have to temporarily clear an exception before we can release local
+ // references.
+ jthrowable exception = env->ExceptionOccurred();
+ if (exception) {
+ env->ExceptionClear();
+ env->ReleaseCharArrayElements(xml, characters, JNI_ABORT);
+ env->Throw(exception);
+ } else {
+ env->ReleaseCharArrayElements(xml, characters, JNI_ABORT);
+ }
+
+ context->object = NULL;
+ context->env = NULL;
+}
+
+/**
+ * Passes some XML to the parser.
+ *
+ * @param object the Java ExpatParser instance
+ * @param pointer to the C expat parser
+ * @param xml Java byte[] containing XML
+ * @param offset into the xml buffer
+ * @param length of text in the xml buffer
+ */
+static void appendBytes(JNIEnv* env, jobject object, jint pointer,
+ jbyteArray xml, jint offset, jint length) {
+ XML_Parser parser = (XML_Parser) pointer;
+ ParsingContext* context = (ParsingContext*) XML_GetUserData(parser);
+ context->env = env;
+ context->object = object;
+
+ jbyte* bytes = env->GetByteArrayElements(xml, NULL);
+
+ if (!XML_Parse(parser, ((char*) bytes) + offset, length, XML_FALSE)
+ && !env->ExceptionCheck()) {
+ jclass clazz = env->FindClass("org/apache/harmony/xml/ExpatException");
+ const char* errorMessage = XML_ErrorString(XML_GetErrorCode(parser));
+ env->ThrowNew(clazz, errorMessage);
+ }
+
+ // We have to temporarily clear an exception before we can release local
+ // references.
+ jthrowable exception = env->ExceptionOccurred();
+ if (exception) {
+ env->ExceptionClear();
+ env->ReleaseByteArrayElements(xml, bytes, JNI_ABORT);
+ env->Throw(exception);
+ } else {
+ env->ReleaseByteArrayElements(xml, bytes, JNI_ABORT);
+ }
+
+ context->object = NULL;
+ context->env = NULL;
+}
+
+/**
+ * Releases parser only.
+ *
+ * @param object the Java ExpatParser instance
+ * @param i pointer to the C expat parser
+ */
+static void releaseParser(JNIEnv* env, jobject object, jint i) {
+ XML_Parser parser = (XML_Parser) i;
+ XML_ParserFree(parser);
+}
+
+/**
+ * Cleans up after the parser. Called at garbage collection time.
+ *
+ * @param object the Java ExpatParser instance
+ * @param i pointer to the C expat parser
+ */
+static void release(JNIEnv* env, jobject object, jint i) {
+ XML_Parser parser = (XML_Parser) i;
+
+ ParsingContext* context = (ParsingContext*) XML_GetUserData(parser);
+ releaseParsingContext(env, context);
+
+ XML_ParserFree(parser);
+}
+
+/**
+ * Gets the current line.
+ *
+ * @param object the Java ExpatParser instance
+ * @param pointer to the C expat parser
+ * @returns current line number
+ */
+static int line(JNIEnv* env, jobject clazz, jint pointer) {
+ XML_Parser parser = (XML_Parser) pointer;
+ return XML_GetCurrentLineNumber(parser);
+}
+
+/**
+ * Gets the current column.
+ *
+ * @param object the Java ExpatParser instance
+ * @param pointer to the C expat parser
+ * @returns current column number
+ */
+static int column(JNIEnv* env, jobject clazz, jint pointer) {
+ XML_Parser parser = (XML_Parser) pointer;
+ return XML_GetCurrentColumnNumber(parser);
+}
+
+/**
+ * Gets the URI of the attribute at the given index.
+ *
+ * @param object Java ExpatParser instance
+ * @param pointer to the C expat parser
+ * @param attributePointer to the attribute array
+ * @param index of the attribute
+ * @returns interned Java string containing attribute's URI
+ */
+static jstring getAttributeURI(JNIEnv* env, jobject clazz, jint pointer,
+ jint attributePointer, jint index) {
+ XML_Parser parser = (XML_Parser) pointer;
+ ParsingContext* context = (ParsingContext*) XML_GetUserData(parser);
+
+ if (!context->processNamespaces) {
+ return emptyString;
+ }
+
+ const char** attributes = (const char**) attributePointer;
+
+ const char* name = attributes[index << 1];
+ int separatorIndex = findSeparator(name);
+ return parseUri(env, context, name, separatorIndex);
+}
+
+/**
+ * Gets the local name of the attribute at the given index.
+ *
+ * @param object Java ExpatParser instance
+ * @param pointer to the C expat parser
+ * @param attributePointer to the attribute array
+ * @param index of the attribute
+ * @returns interned Java string containing attribute's local name
+ */
+static jstring getAttributeLocalName(JNIEnv* env, jobject clazz, jint pointer,
+ jint attributePointer, jint index) {
+ XML_Parser parser = (XML_Parser) pointer;
+ ParsingContext* context = (ParsingContext*) XML_GetUserData(parser);
+
+ if (!context->processNamespaces) {
+ return emptyString;
+ }
+
+ const char** attributes = (const char**) attributePointer;
+ const char* name = attributes[index << 1];
+
+ int separatorIndex = findSeparator(name);
+ return parseLocalName(env, context, name, separatorIndex);
+}
+
+/**
+ * Gets the qualified name of the attribute at the given index.
+ *
+ * @param object Java ExpatParser instance
+ * @param pointer to the C expat parser
+ * @param attributePointer to the attribute array
+ * @param index of the attribute
+ * @returns interned Java string containing attribute's local name
+ */
+static jstring getAttributeQName(JNIEnv* env, jobject clazz, jint pointer,
+ jint attributePointer, jint index) {
+ XML_Parser parser = (XML_Parser) pointer;
+ ParsingContext* context = (ParsingContext*) XML_GetUserData(parser);
+
+ if (context->processNamespaces) {
+ return emptyString;
+ }
+
+ const char** attributes = (const char**) attributePointer;
+
+ const char* name = attributes[index << 1];
+ return internString(env, context, name);
+}
+
+/**
+ * Gets the value of the attribute at the given index.
+ *
+ * @param object Java ExpatParser instance
+ * @param attributePointer to the attribute array
+ * @param index of the attribute
+ * @returns Java string containing attribute's value
+ */
+static jstring getAttributeValueByIndex(JNIEnv* env, jobject clazz,
+ jint attributePointer, jint index) {
+ const char** attributes = (const char**) attributePointer;
+ const char* value = attributes[(index << 1) + 1];
+ return env->NewStringUTF(value);
+}
+
+/**
+ * Searches the attributes for the given name and returns the attribute's
+ * index or -1 if not found.
+ *
+ * @param attributes alternating name/value pairs
+ * @param name of attribute to look for
+ * @returns index of found attribute or -1 if not found
+ */
+static jint findAttributeByName(const char** attributes,
+ const char* name) {
+ int index;
+ for (index = 0; attributes[index]; index += 2) {
+ if (strcmp(attributes[index], name) == 0)
+ return index >> 1;
+ }
+
+ // Not found.
+ return -1;
+}
+
+/**
+ * Gets the index of the attribute with the given qualified name.
+ *
+ * @param attributePointer to the attribute array
+ * @param qName to look for
+ * @returns index of attribute with the given uri and local name or -1 if not
+ * found
+ */
+static jint getAttributeIndexForQName(JNIEnv* env, jobject clazz,
+ jint attributePointer, jstring qName) {
+ const char** attributes = (const char**) attributePointer;
+ int length = env->GetStringUTFLength(qName);
+
+ const char* qNameBytes = env->GetStringUTFChars(qName, NULL);
+ if (qNameBytes == NULL) return -1;
+ int found = findAttributeByName(attributes, qNameBytes);
+ env->ReleaseStringUTFChars(qName, qNameBytes);
+ return found;
+}
+
+/**
+ * Gets the index of the attribute with the given URI and name.
+ *
+ * @param attributePointer to the attribute array
+ * @param uri to look for
+ * @param localName to look for
+ * @returns index of attribute with the given uri and local name or -1 if not
+ * found
+ */
+static jint getAttributeIndex(JNIEnv* env, jobject clazz,
+ jint attributePointer, jstring uri, jstring localName) {
+ const char** attributes = (const char**) attributePointer;
+ int uriLength = env->GetStringUTFLength(uri);
+
+ if (uriLength == 0) {
+ // If there's no URI, then a local name works just like a qName.
+ return getAttributeIndexForQName(
+ env, clazz, attributePointer, localName);
+ }
+
+ int localNameLength = env->GetStringUTFLength(localName);
+
+ // Create string in the same format used by Expat: "uri|localName"
+ char concatenated[uriLength + localNameLength + 2];
+
+ // Append uri.
+ const char* uriBytes = env->GetStringUTFChars(uri, NULL);
+ if (uriBytes == NULL) return -1;
+ strcpy(concatenated, uriBytes);
+ env->ReleaseStringUTFChars(uri, uriBytes);
+
+ // Separarator.
+ concatenated[uriLength] = '|';
+
+ // Append local name.
+ const char* localNameBytes = env->GetStringUTFChars(localName, NULL);
+ if (localNameBytes == NULL) return -1;
+ strcpy(concatenated + uriLength + 1, localNameBytes);
+ env->ReleaseStringUTFChars(localName, localNameBytes);
+
+ return findAttributeByName(attributes, concatenated);
+}
+
+/**
+ * Gets the value of the attribute with the given qualified name.
+ *
+ * @param attributePointer to the attribute array
+ * @param uri to look for
+ * @param localName to look for
+ * @returns value of attribute with the given uri and local name or NULL if not
+ * found
+ */
+static jstring getAttributeValueForQName(JNIEnv* env, jobject clazz,
+ jint attributePointer, jstring qName) {
+ jint index = getAttributeIndexForQName(
+ env, clazz, attributePointer, qName);
+ return index == -1 ? NULL
+ : getAttributeValueByIndex(env, clazz, attributePointer, index);
+}
+
+/**
+ * Gets the value of the attribute with the given URI and name.
+ *
+ * @param attributePointer to the attribute array
+ * @param uri to look for
+ * @param localName to look for
+ * @returns value of attribute with the given uri and local name or NULL if not
+ * found
+ */
+static jstring getAttributeValue(JNIEnv* env, jobject clazz,
+ jint attributePointer, jstring uri, jstring localName) {
+ jint index = getAttributeIndex(
+ env, clazz, attributePointer, uri, localName);
+ return index == -1 ? NULL
+ : getAttributeValueByIndex(env, clazz, attributePointer, index);
+}
+
+/**
+ * Clones an array of strings. Uses one contiguous block of memory so as to
+ * maximize performance.
+ */
+static char** cloneStrings(const char** source, int count) {
+ // Figure out how big the buffer needs to be.
+ int arraySize = (count + 1) * sizeof(char*);
+ int totalSize = arraySize;
+ int stringLengths[count];
+ for (int i = 0; i < count; i++) {
+ int length = strlen(source[i]);
+ stringLengths[i] = length;
+ totalSize += length + 1;
+ }
+
+ char* buffer = (char*) malloc(totalSize);
+ if (buffer == NULL) {
+ return NULL;
+ }
+
+ // Array is at the beginning of the buffer.
+ char** clonedArray = (char**) buffer;
+ clonedArray[count] = NULL; // null terminate
+
+ // First string is immediately after.
+ char* destinationString = buffer + arraySize;
+
+ for (int i = 0; i < count; i++) {
+ const char* sourceString = source[i];
+ int stringLength = stringLengths[i];
+ memcpy(destinationString, sourceString, stringLength + 1);
+ clonedArray[i] = destinationString;
+ destinationString += stringLength + 1;
+ }
+
+ return clonedArray;
+}
+
+/**
+ * Clones attributes.
+ *
+ * @param pointer to char** to clone
+ * @param count number of attributes
+ */
+static jint cloneAttributes(JNIEnv* env, jobject clazz,
+ jint pointer, jint count) {
+ return (int) cloneStrings((const char**) pointer, count << 1);
+}
+
+/**
+ * Frees cloned attributes.
+ */
+static void freeAttributes(JNIEnv* env, jobject clazz, jint pointer) {
+ free((void*) pointer);
+}
+
+/**
+ * Called when we initialize our Java parser class.
+ *
+ * @param clazz Java ExpatParser class
+ */
+static void staticInitialize(JNIEnv* env, jobject clazz, jstring empty) {
+ startElementMethod = env->GetMethodID((jclass) clazz, "startElement",
+ "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;II)V");
+ if (startElementMethod == NULL) return;
+
+ endElementMethod = env->GetMethodID((jclass) clazz, "endElement",
+ "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
+ if (endElementMethod == NULL) return;
+
+ textMethod = env->GetMethodID((jclass) clazz, "text", "([CI)V");
+ if (textMethod == NULL) return;
+
+ commentMethod = env->GetMethodID((jclass) clazz, "comment", "([CI)V");
+ if (commentMethod == NULL) return;
+
+ startCdataMethod = env->GetMethodID((jclass) clazz, "startCdata", "()V");
+ if (startCdataMethod == NULL) return;
+
+ endCdataMethod = env->GetMethodID((jclass) clazz, "endCdata", "()V");
+ if (endCdataMethod == NULL) return;
+
+ startDtdMethod = env->GetMethodID((jclass) clazz, "startDtd",
+ "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
+ if (startDtdMethod == NULL) return;
+
+ endDtdMethod = env->GetMethodID((jclass) clazz, "endDtd", "()V");
+ if (endDtdMethod == NULL) return;
+
+ startNamespaceMethod = env->GetMethodID((jclass) clazz, "startNamespace",
+ "(Ljava/lang/String;Ljava/lang/String;)V");
+ if (startNamespaceMethod == NULL) return;
+
+ endNamespaceMethod = env->GetMethodID((jclass) clazz, "endNamespace",
+ "(Ljava/lang/String;)V");
+ if (endNamespaceMethod == NULL) return;
+
+ processingInstructionMethod = env->GetMethodID((jclass) clazz,
+ "processingInstruction", "(Ljava/lang/String;Ljava/lang/String;)V");
+ if (processingInstructionMethod == NULL) return;
+
+ handleExternalEntityMethod = env->GetMethodID((jclass) clazz,
+ "handleExternalEntity",
+ "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
+ if (handleExternalEntityMethod == NULL) return;
+
+ // Look up String class.
+ stringClass = env->FindClass("java/lang/String");
+
+ internMethod = env->GetMethodID(stringClass, "intern",
+ "()Ljava/lang/String;");
+ if (internMethod == NULL) return;
+
+ // Reference to "".
+ emptyString = (jstring) env->NewGlobalRef(empty);
+}
+
+static JNINativeMethod parserMethods[] = {
+ { "line", "(I)I", (void*) line },
+ { "column", "(I)I", (void*) column },
+ { "release", "(I)V", (void*) release },
+ { "releaseParser", "(I)V", (void*) releaseParser },
+ { "append", "(ILjava/lang/String;Z)V", (void*) appendString },
+ { "append", "(I[CII)V", (void*) appendCharacters },
+ { "append", "(I[BII)V", (void*) appendBytes },
+ { "initialize", "(Ljava/lang/String;Z)I",
+ (void*) initialize},
+ { "createEntityParser", "(ILjava/lang/String;Ljava/lang/String;)I",
+ (void*) createEntityParser},
+ { "staticInitialize", "(Ljava/lang/String;)V", (void*) staticInitialize},
+ { "cloneAttributes", "(II)I", (void*) cloneAttributes },
+};
+
+static JNINativeMethod attributeMethods[] = {
+ { "getURI", "(III)Ljava/lang/String;", (void*) getAttributeURI },
+ { "getLocalName", "(III)Ljava/lang/String;", (void*) getAttributeLocalName },
+ { "getQName", "(III)Ljava/lang/String;", (void*) getAttributeQName },
+ { "getValue", "(II)Ljava/lang/String;", (void*) getAttributeValueByIndex },
+ { "getIndex", "(ILjava/lang/String;Ljava/lang/String;)I",
+ (void*) getAttributeIndex },
+ { "getIndex", "(ILjava/lang/String;)I",
+ (void*) getAttributeIndexForQName },
+ { "getValue", "(ILjava/lang/String;Ljava/lang/String;)Ljava/lang/String;",
+ (void*) getAttributeValue },
+ { "getValue", "(ILjava/lang/String;)Ljava/lang/String;",
+ (void*) getAttributeValueForQName },
+ { "freeAttributes", "(I)V", (void*) freeAttributes },
+};
+
+/**
+ * Called from Register.c.
+ */
+extern "C" int register_org_apache_harmony_xml_ExpatParser(JNIEnv* env) {
+ int result = jniRegisterNativeMethods(env, "org/apache/harmony/xml/ExpatParser",
+ parserMethods, NELEM(parserMethods));
+ if (result != 0) {
+ return result;
+ }
+
+ return jniRegisterNativeMethods(env, "org/apache/harmony/xml/ExpatAttributes",
+ attributeMethods, NELEM(attributeMethods));
+}
diff --git a/xml/src/main/native/sub.mk b/xml/src/main/native/sub.mk
new file mode 100644
index 0000000..e48d12e
--- /dev/null
+++ b/xml/src/main/native/sub.mk
@@ -0,0 +1,20 @@
+# This file is included by the top-level libcore Android.mk.
+# It's not a normal makefile, so we don't include CLEAR_VARS
+# or BUILD_*_LIBRARY.
+
+LOCAL_SRC_FILES := org_apache_harmony_xml_ExpatParser.cpp
+
+LOCAL_C_INCLUDES += \
+ external/expat/lib
+
+# Any shared/static libs that are listed here must also
+# be listed in libs/nativehelper/Android.mk.
+# TODO: fix this requirement
+
+LOCAL_SHARED_LIBRARIES += \
+ libcutils \
+ libexpat \
+ libutils
+
+#LOCAL_STATIC_LIBRARIES +=
+
diff --git a/xml/src/test/java/org/apache/harmony/xml/ExpatParserTest.java b/xml/src/test/java/org/apache/harmony/xml/ExpatParserTest.java
new file mode 100644
index 0000000..480bca3
--- /dev/null
+++ b/xml/src/test/java/org/apache/harmony/xml/ExpatParserTest.java
@@ -0,0 +1,839 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xml;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+import org.kxml2.io.KXmlParser;
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.ext.DefaultHandler2;
+import org.xml.sax.helpers.DefaultHandler;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.net.ServerSocket;
+import java.net.Socket;
+
+public class ExpatParserTest extends TestCase {
+
+ private static final String SNIPPET = "<dagny dad=\"bob\">hello</dagny>";
+
+ public void testExceptions() {
+ // From startElement().
+ ContentHandler contentHandler = new DefaultHandler() {
+ @Override
+ public void startElement(String uri, String localName,
+ String qName, Attributes attributes)
+ throws SAXException {
+ throw new SAXException();
+ }
+ };
+ try {
+ parse(SNIPPET, contentHandler);
+ fail();
+ } catch (SAXException checked) { /* expected */ }
+
+ // From endElement().
+ contentHandler = new DefaultHandler() {
+ @Override
+ public void endElement(String uri, String localName,
+ String qName)
+ throws SAXException {
+ throw new SAXException();
+ }
+ };
+ try {
+ parse(SNIPPET, contentHandler);
+ fail();
+ } catch (SAXException checked) { /* expected */ }
+
+ // From characters().
+ contentHandler = new DefaultHandler() {
+ @Override
+ public void characters(char ch[], int start, int length)
+ throws SAXException {
+ throw new SAXException();
+ }
+ };
+ try {
+ parse(SNIPPET, contentHandler);
+ fail();
+ } catch (SAXException checked) { /* expected */ }
+ }
+
+ public void testSax() {
+ try {
+ // Parse String.
+ TestHandler handler = new TestHandler();
+ parse(SNIPPET, handler);
+ validate(handler);
+
+ // Parse Reader.
+ handler = new TestHandler();
+ parse(new StringReader(SNIPPET), handler);
+ validate(handler);
+
+ // Parse InputStream.
+ handler = new TestHandler();
+ parse(new ByteArrayInputStream(SNIPPET.getBytes()),
+ Encoding.UTF_8, handler);
+ validate(handler);
+ } catch (SAXException e) {
+ throw new RuntimeException(e);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ static void validate(TestHandler handler) {
+ assertEquals("dagny", handler.startElementName);
+ assertEquals("dagny", handler.endElementName);
+ assertEquals("hello", handler.text.toString());
+ }
+
+ static class TestHandler extends DefaultHandler {
+
+ String startElementName;
+ String endElementName;
+ StringBuilder text = new StringBuilder();
+
+ @Override
+ public void startElement(String uri, String localName, String qName,
+ Attributes attributes) throws SAXException {
+
+ assertNull(this.startElementName);
+ this.startElementName = localName;
+
+ // Validate attributes.
+ assertEquals(1, attributes.getLength());
+ assertEquals("", attributes.getURI(0));
+ assertEquals("dad", attributes.getLocalName(0));
+ assertEquals("bob", attributes.getValue(0));
+ assertEquals(0, attributes.getIndex("", "dad"));
+ assertEquals("bob", attributes.getValue("", "dad"));
+ }
+
+ @Override
+ public void endElement(String uri, String localName, String qName)
+ throws SAXException {
+ assertNull(this.endElementName);
+ this.endElementName = localName;
+ }
+
+ @Override
+ public void characters(char ch[], int start, int length)
+ throws SAXException {
+ this.text.append(ch, start, length);
+ }
+ }
+
+ public void testPullParser() {
+ try {
+ XmlPullParser parser = newPullParser();
+
+ // Test reader.
+ parser.setInput(new StringReader(SNIPPET));
+ validate(parser);
+
+ // Test input stream.
+ parser.setInput(new ByteArrayInputStream(SNIPPET.getBytes()),
+ "UTF-8");
+ validate(parser);
+ } catch (XmlPullParserException e) {
+ throw new RuntimeException(e);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ static void validate(XmlPullParser parser)
+ throws XmlPullParserException, IOException {
+ assertEquals(XmlPullParser.START_DOCUMENT, parser.getEventType());
+
+ assertEquals(0, parser.getDepth());
+
+ assertEquals(XmlPullParser.START_TAG, parser.next());
+
+ assertEquals(1, parser.getDepth());
+
+ assertEquals("dagny", parser.getName());
+ assertEquals(1, parser.getAttributeCount());
+ assertEquals("dad", parser.getAttributeName(0));
+ assertEquals("bob", parser.getAttributeValue(0));
+ assertEquals("bob", parser.getAttributeValue(null, "dad"));
+
+ assertEquals(XmlPullParser.TEXT, parser.next());
+
+ assertEquals(1, parser.getDepth());
+
+ assertEquals("hello", parser.getText());
+
+ assertEquals(XmlPullParser.END_TAG, parser.next());
+
+ assertEquals(1, parser.getDepth());
+
+ assertEquals("dagny", parser.getName());
+
+ assertEquals(XmlPullParser.END_DOCUMENT, parser.next());
+
+ assertEquals(0, parser.getDepth());
+ }
+
+ static final String XML =
+ "<one xmlns='ns:default' xmlns:n1='ns:1' a='b'>\n"
+ + " <n1:two c='d' n1:e='f' xmlns:n2='ns:2'>text</n1:two>\n"
+ + "</one>";
+
+ public void testExpatPullParserNamespaces() throws Exception {
+ XmlPullParser pullParser = newPullParser();
+ pullParser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
+ pullParser.setInput(new StringReader(XML));
+ testPullParserNamespaces(pullParser);
+ }
+
+ public void testKxmlPullParserNamespaces() throws Exception {
+ XmlPullParser pullParser = new KXmlParser();
+ pullParser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
+ pullParser.setInput(new StringReader(XML));
+ testPullParserNamespaces(pullParser);
+ }
+
+ private void testPullParserNamespaces(XmlPullParser parser) throws Exception {
+ assertEquals(0, parser.getDepth());
+ assertEquals(0, parser.getNamespaceCount(0));
+
+ try {
+ parser.getNamespaceCount(1);
+ fail();
+ } catch (IndexOutOfBoundsException e) { /* expected */ }
+
+ // one
+ assertEquals(XmlPullParser.START_TAG, parser.next());
+ assertEquals(1, parser.getDepth());
+
+ checkNamespacesInOne(parser);
+
+ // n1:two
+ assertEquals(XmlPullParser.START_TAG, parser.nextTag());
+
+ assertEquals(2, parser.getDepth());
+ checkNamespacesInTwo(parser);
+
+ // Body of two.
+ assertEquals(XmlPullParser.TEXT, parser.next());
+
+ // End of two.
+ assertEquals(XmlPullParser.END_TAG, parser.nextTag());
+
+ // Depth should still be 2.
+ assertEquals(2, parser.getDepth());
+
+ // We should still be able to see the namespaces from two.
+ checkNamespacesInTwo(parser);
+
+ // End of one.
+ assertEquals(XmlPullParser.END_TAG, parser.nextTag());
+
+ // Depth should be back to 1.
+ assertEquals(1, parser.getDepth());
+
+ // We can still see the namespaces in one.
+ checkNamespacesInOne(parser);
+
+ // We shouldn't be able to see the namespaces in two anymore.
+ try {
+ parser.getNamespaceCount(2);
+ fail();
+ } catch (IndexOutOfBoundsException e) { /* expected */ }
+
+ assertEquals(XmlPullParser.END_DOCUMENT, parser.next());
+
+ // We shouldn't be able to see the namespaces in one anymore.
+ try {
+ parser.getNamespaceCount(1);
+ fail();
+ } catch (IndexOutOfBoundsException e) { /* expected */ }
+
+ assertEquals(0, parser.getNamespaceCount(0));
+ }
+
+ private void checkNamespacesInOne(XmlPullParser parser) throws XmlPullParserException {
+ assertEquals(2, parser.getNamespaceCount(1));
+
+ // Prefix for default namespace is null.
+ assertNull(parser.getNamespacePrefix(0));
+ assertEquals("ns:default", parser.getNamespaceUri(0));
+
+ assertEquals("n1", parser.getNamespacePrefix(1));
+ assertEquals("ns:1", parser.getNamespaceUri(1));
+
+ assertEquals("ns:default", parser.getNamespace(null));
+
+ // KXML returns null.
+ // assertEquals("ns:default", parser.getNamespace(""));
+ }
+
+ private void checkNamespacesInTwo(XmlPullParser parser) throws XmlPullParserException {
+ // These should still be valid.
+ checkNamespacesInOne(parser);
+
+ assertEquals(3, parser.getNamespaceCount(2));
+
+ // Default ns should still be in the stack
+ assertNull(parser.getNamespacePrefix(0));
+ assertEquals("ns:default", parser.getNamespaceUri(0));
+ }
+
+ public void testNamespaces() {
+ try {
+ NamespaceHandler handler = new NamespaceHandler();
+ parse(XML, handler);
+ handler.validate();
+ } catch (SAXException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ static class NamespaceHandler implements ContentHandler {
+
+ Locator locator;
+ boolean documentStarted;
+ boolean documentEnded;
+ Map<String, String> prefixMappings = new HashMap<String, String>();
+
+ boolean oneStarted;
+ boolean twoStarted;
+ boolean oneEnded;
+ boolean twoEnded;
+
+ public void validate() {
+ assertTrue(documentEnded);
+ }
+
+ public void setDocumentLocator(Locator locator) {
+ this.locator = locator;
+ }
+
+ public void startDocument() throws SAXException {
+ documentStarted = true;
+ assertNotNull(locator);
+ assertEquals(0, prefixMappings.size());
+ assertFalse(documentEnded);
+ }
+
+ public void endDocument() throws SAXException {
+ assertTrue(documentStarted);
+ assertTrue(oneEnded);
+ assertTrue(twoEnded);
+ assertEquals(0, prefixMappings.size());
+ documentEnded = true;
+ }
+
+ public void startPrefixMapping(String prefix, String uri)
+ throws SAXException {
+ prefixMappings.put(prefix, uri);
+ }
+
+ public void endPrefixMapping(String prefix) throws SAXException {
+ assertNotNull(prefixMappings.remove(prefix));
+ }
+
+ public void startElement(String uri, String localName, String qName,
+ Attributes atts) throws SAXException {
+
+ if (localName == "one") {
+ assertEquals(2, prefixMappings.size());
+
+ assertEquals(1, locator.getLineNumber());
+
+ assertFalse(oneStarted);
+ assertFalse(twoStarted);
+ assertFalse(oneEnded);
+ assertFalse(twoEnded);
+
+ oneStarted = true;
+
+ assertSame("ns:default", uri);
+ // TODO The result of the RI is "one"
+ assertEquals("", qName);
+
+ // Check atts.
+ assertEquals(1, atts.getLength());
+
+ assertSame("", atts.getURI(0));
+ assertSame("a", atts.getLocalName(0));
+ assertEquals("b", atts.getValue(0));
+ assertEquals(0, atts.getIndex("", "a"));
+ assertEquals("b", atts.getValue("", "a"));
+
+ return;
+ }
+
+ if (localName == "two") {
+ assertEquals(3, prefixMappings.size());
+
+ assertTrue(oneStarted);
+ assertFalse(twoStarted);
+ assertFalse(oneEnded);
+ assertFalse(twoEnded);
+
+ twoStarted = true;
+
+ assertSame("ns:1", uri);
+ // TODO The result of the RI is "n1:two"
+ Assert.assertEquals("", qName);
+
+ // Check atts.
+ assertEquals(2, atts.getLength());
+
+ assertSame("", atts.getURI(0));
+ assertSame("c", atts.getLocalName(0));
+ assertEquals("d", atts.getValue(0));
+ assertEquals(0, atts.getIndex("", "c"));
+ assertEquals("d", atts.getValue("", "c"));
+
+ assertSame("ns:1", atts.getURI(1));
+ assertSame("e", atts.getLocalName(1));
+ assertEquals("f", atts.getValue(1));
+ assertEquals(1, atts.getIndex("ns:1", "e"));
+ assertEquals("f", atts.getValue("ns:1", "e"));
+
+ // We shouldn't find these.
+ assertEquals(-1, atts.getIndex("ns:default", "e"));
+ assertEquals(null, atts.getValue("ns:default", "e"));
+
+ return;
+ }
+
+ fail();
+ }
+
+ public void endElement(String uri, String localName, String qName)
+ throws SAXException {
+ if (localName == "one") {
+ assertEquals(3, locator.getLineNumber());
+
+ assertTrue(oneStarted);
+ assertTrue(twoStarted);
+ assertTrue(twoEnded);
+ assertFalse(oneEnded);
+
+ oneEnded = true;
+
+ assertSame("ns:default", uri);
+ assertEquals("", qName);
+
+ return;
+ }
+
+ if (localName == "two") {
+ assertTrue(oneStarted);
+ assertTrue(twoStarted);
+ assertFalse(twoEnded);
+ assertFalse(oneEnded);
+
+ twoEnded = true;
+
+ assertSame("ns:1", uri);
+ assertEquals("", qName);
+
+ return;
+ }
+
+ fail();
+ }
+
+ public void characters(char ch[], int start, int length)
+ throws SAXException {
+ String s = new String(ch, start, length).trim();
+
+ if (!s.equals("")) {
+ assertTrue(oneStarted);
+ assertTrue(twoStarted);
+ assertFalse(oneEnded);
+ assertFalse(twoEnded);
+ assertEquals("text", s);
+ }
+ }
+
+ public void ignorableWhitespace(char ch[], int start, int length)
+ throws SAXException {
+ fail();
+ }
+
+ public void processingInstruction(String target, String data)
+ throws SAXException {
+ fail();
+ }
+
+ public void skippedEntity(String name) throws SAXException {
+ fail();
+ }
+ }
+
+ public void testDtd() throws Exception {
+ Reader in = new StringReader(
+ "<?xml version=\"1.0\"?><!DOCTYPE foo PUBLIC 'bar' 'tee'><a></a>");
+ ExpatReader reader = new ExpatReader();
+ TestDtdHandler handler = new TestDtdHandler();
+ reader.setContentHandler(handler);
+ reader.setLexicalHandler(handler);
+ reader.parse(new InputSource(in));
+
+ assertEquals("foo", handler.name);
+ assertEquals("bar", handler.publicId);
+ assertEquals("tee", handler.systemId);
+
+ assertTrue(handler.ended);
+ }
+
+ static class TestDtdHandler extends DefaultHandler2 {
+
+ String name;
+ String publicId;
+ String systemId;
+
+ boolean ended;
+
+ Locator locator;
+
+ @Override
+ public void startDTD(String name, String publicId, String systemId) {
+ this.name = name;
+ this.publicId = publicId;
+ this.systemId = systemId;
+ }
+
+ @Override
+ public void endDTD() {
+ ended = true;
+ }
+
+ @Override
+ public void setDocumentLocator(Locator locator) {
+ this.locator = locator;
+ }
+ }
+
+ public void testCdata() throws Exception {
+ Reader in = new StringReader(
+ "<a><![CDATA[<b></b>]]> <![CDATA[<c></c>]]></a>");
+
+ ExpatReader reader = new ExpatReader();
+ TestCdataHandler handler = new TestCdataHandler();
+ reader.setContentHandler(handler);
+ reader.setLexicalHandler(handler);
+
+ reader.parse(new InputSource(in));
+
+ assertEquals(2, handler.startCdata);
+ assertEquals(2, handler.endCdata);
+ assertEquals("<b></b> <c></c>", handler.buffer.toString());
+ }
+
+ static class TestCdataHandler extends DefaultHandler2 {
+
+ int startCdata, endCdata;
+ StringBuffer buffer = new StringBuffer();
+
+ @Override
+ public void characters(char ch[], int start, int length) {
+ buffer.append(ch, start, length);
+ }
+
+ @Override
+ public void startCDATA() throws SAXException {
+ startCdata++;
+ }
+
+ @Override
+ public void endCDATA() throws SAXException {
+ endCdata++;
+ }
+ }
+
+ public void testProcessingInstructions() throws IOException, SAXException {
+ Reader in = new StringReader(
+ "<?bob lee?><a></a>");
+
+ ExpatReader reader = new ExpatReader();
+ TestProcessingInstrutionHandler handler
+ = new TestProcessingInstrutionHandler();
+ reader.setContentHandler(handler);
+
+ reader.parse(new InputSource(in));
+
+ assertEquals("bob", handler.target);
+ assertEquals("lee", handler.data);
+ }
+
+ static class TestProcessingInstrutionHandler extends DefaultHandler2 {
+
+ String target;
+ String data;
+
+ @Override
+ public void processingInstruction(String target, String data) {
+ this.target = target;
+ this.data = data;
+ }
+ }
+
+ public void testExternalEntity() throws IOException, SAXException {
+ class Handler extends DefaultHandler {
+
+ List<String> elementNames = new ArrayList<String>();
+ StringBuilder text = new StringBuilder();
+
+ public InputSource resolveEntity(String publicId, String systemId)
+ throws IOException, SAXException {
+ if (publicId.equals("publicA") && systemId.equals("systemA")) {
+ return new InputSource(new StringReader("<a/>"));
+ } else if (publicId.equals("publicB")
+ && systemId.equals("systemB")) {
+ /*
+ * Explicitly set the encoding here or else the parser will
+ * try to use the parent parser's encoding which is utf-16.
+ */
+ InputSource inputSource = new InputSource(
+ new ByteArrayInputStream("bob".getBytes("utf-8")));
+ inputSource.setEncoding("utf-8");
+ return inputSource;
+ }
+
+ throw new AssertionError();
+ }
+
+ @Override
+ public void startElement(String uri, String localName, String qName,
+ Attributes attributes) throws SAXException {
+ elementNames.add(localName);
+ }
+
+ @Override
+ public void endElement(String uri, String localName, String qName)
+ throws SAXException {
+ elementNames.add("/" + localName);
+ }
+
+ @Override
+ public void characters(char ch[], int start, int length)
+ throws SAXException {
+ text.append(ch, start, length);
+ }
+ }
+
+ Reader in = new StringReader("<?xml version=\"1.0\"?>\n"
+ + "<!DOCTYPE foo [\n"
+ + " <!ENTITY a PUBLIC 'publicA' 'systemA'>\n"
+ + " <!ENTITY b PUBLIC 'publicB' 'systemB'>\n"
+ + "]>\n"
+ + "<foo>\n"
+ + " &a;<b>&b;</b></foo>");
+
+ ExpatReader reader = new ExpatReader();
+ Handler handler = new Handler();
+ reader.setContentHandler(handler);
+ reader.setEntityResolver(handler);
+
+ reader.parse(new InputSource(in));
+
+ assertEquals(Arrays.asList("foo", "a", "/a", "b", "/b", "/foo"),
+ handler.elementNames);
+ assertEquals("bob", handler.text.toString().trim());
+ }
+
+ public void testExternalEntityDownload() throws IOException, SAXException {
+ class Server implements Runnable {
+
+ private final ServerSocket serverSocket;
+
+ Server() throws IOException {
+ serverSocket = new ServerSocket(8080);
+ }
+
+ public void run() {
+ try {
+ Socket socket = serverSocket.accept();
+
+ final InputStream in = socket.getInputStream();
+ Thread inputThread = new Thread() {
+ public void run() {
+ try {
+ byte[] buffer = new byte[1024];
+ while (in.read(buffer) > -1) { /* ignore */ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ };
+ inputThread.setDaemon(true);
+ inputThread.start();
+
+ OutputStream out = socket.getOutputStream();
+
+ String body = "<bar></bar>";
+ String response = "HTTP/1.0 200 OK\n"
+ + "Content-Length: " + body.length() + "\n"
+ + "\n"
+ + body;
+
+ out.write(response.getBytes("UTF-8"));
+ out.close();
+ serverSocket.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ class Handler extends DefaultHandler {
+
+ List<String> elementNames = new ArrayList<String>();
+
+ public InputSource resolveEntity(String publicId, String systemId)
+ throws IOException, SAXException {
+ // The parser should have resolved the systemId.
+ assertEquals("http://localhost:8080/systemBar", systemId);
+ return new InputSource(systemId);
+ }
+
+ @Override
+ public void startElement(String uri, String localName, String qName,
+ Attributes attributes) throws SAXException {
+ elementNames.add(localName);
+ }
+
+ @Override
+ public void endElement(String uri, String localName, String qName)
+ throws SAXException {
+ elementNames.add("/" + localName);
+ }
+ }
+
+ // Start server to serve up the XML for 'systemBar'.
+ Thread serverThread = new Thread(new Server());
+ serverThread.setDaemon(true);
+ serverThread.start();
+
+ // 'systemBar', the external entity, is relative to 'systemFoo':
+ Reader in = new StringReader("<?xml version=\"1.0\"?>\n"
+ + "<!DOCTYPE foo [\n"
+ + " <!ENTITY bar SYSTEM 'systemBar'>\n"
+ + "]>\n"
+ + "<foo>&bar;</foo>");
+
+ ExpatReader reader = new ExpatReader();
+
+ Handler handler = new Handler();
+
+ reader.setContentHandler(handler);
+ reader.setEntityResolver(handler);
+
+ InputSource source = new InputSource(in);
+ source.setSystemId("http://localhost:8080/systemFoo");
+ reader.parse(source);
+
+ assertEquals(Arrays.asList("foo", "bar", "/bar", "/foo"),
+ handler.elementNames);
+ }
+
+ /**
+ * Parses the given xml string and fires events on the given SAX handler.
+ */
+ private static void parse(String xml, ContentHandler contentHandler)
+ throws SAXException {
+ try {
+ XMLReader reader = new ExpatReader();
+ reader.setContentHandler(contentHandler);
+ reader.parse(new InputSource(new StringReader(xml)));
+ }
+ catch (IOException e) {
+ throw new AssertionError(e);
+ }
+ }
+
+ /**
+ * Parses xml from the given reader and fires events on the given SAX
+ * handler.
+ */
+ private static void parse(Reader in, ContentHandler contentHandler)
+ throws IOException, SAXException {
+ XMLReader reader = new ExpatReader();
+ reader.setContentHandler(contentHandler);
+ reader.parse(new InputSource(in));
+ }
+
+ /**
+ * Parses xml from the given input stream and fires events on the given SAX
+ * handler.
+ */
+ private static void parse(InputStream in, Encoding encoding,
+ ContentHandler contentHandler) throws IOException, SAXException {
+ try {
+ XMLReader reader = new ExpatReader();
+ reader.setContentHandler(contentHandler);
+ InputSource source = new InputSource(in);
+ source.setEncoding(encoding.expatName);
+ reader.parse(source);
+ } catch (IOException e) {
+ throw new AssertionError(e);
+ }
+ }
+
+ /**
+ * Supported character encodings.
+ */
+ private enum Encoding {
+
+ US_ASCII("US-ASCII"),
+ UTF_8("UTF-8"),
+ UTF_16("UTF-16"),
+ ISO_8859_1("ISO-8859-1");
+
+ final String expatName;
+
+ Encoding(String expatName) {
+ this.expatName = expatName;
+ }
+ }
+
+ /**
+ * Creates a new pull parser with namespace support.
+ */
+ private static XmlPullParser newPullParser() {
+ ExpatPullParser parser = new ExpatPullParser();
+ parser.setNamespaceProcessingEnabled(true);
+ return parser;
+ }
+}
diff --git a/xml/src/test/java/tests/api/javax/xml/parsers/AllTests.java b/xml/src/test/java/tests/api/javax/xml/parsers/AllTests.java
new file mode 100644
index 0000000..f0e8ebd
--- /dev/null
+++ b/xml/src/test/java/tests/api/javax/xml/parsers/AllTests.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.api.javax.xml.parsers;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import org.apache.harmony.xml.ExpatParserTest;
+
+/**
+ * This is autogenerated source file. Includes tests for package tests.api.javax.xml.parsers;
+ */
+
+public class AllTests {
+
+ public static void main(String[] args) {
+ junit.textui.TestRunner.run(AllTests.suite());
+ }
+
+ public static Test suite() {
+ TestSuite suite = tests.TestSuiteFactory.createTestSuite("All tests for package tests.api.javax.xml.parsers;");
+ // $JUnit-BEGIN$
+
+ suite.addTestSuite(DocumentBuilderFactoryTest.class);
+ suite.addTestSuite(DocumentBuilderTest.class);
+ suite.addTestSuite(FactoryConfigurationErrorTest.class);
+ suite.addTestSuite(ParserConfigurationExceptionTest.class);
+ suite.addTestSuite(SAXParserFactoryTest.class);
+ suite.addTestSuite(SAXParserTest.class);
+ suite.addTestSuite(ExpatParserTest.class);
+
+ // $JUnit-END$
+ return suite;
+ }
+}
diff --git a/xml/src/test/java/tests/api/javax/xml/parsers/DocumentBuilderFactoryTest.java b/xml/src/test/java/tests/api/javax/xml/parsers/DocumentBuilderFactoryTest.java
new file mode 100644
index 0000000..1e1ffdd
--- /dev/null
+++ b/xml/src/test/java/tests/api/javax/xml/parsers/DocumentBuilderFactoryTest.java
@@ -0,0 +1,1121 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package tests.api.javax.xml.parsers;
+
+import dalvik.annotation.KnownFailure;
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import junit.framework.TestCase;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+
+import tests.api.javax.xml.parsers.SAXParserFactoryTest.MyHandler;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.FactoryConfigurationError;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+
+@TestTargetClass(DocumentBuilderFactory.class)
+public class DocumentBuilderFactoryTest extends TestCase {
+
+ DocumentBuilderFactory dbf;
+
+ List<String> cdataElements;
+
+ List<String> textElements;
+
+ List<String> commentElements;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ dbf = DocumentBuilderFactory.newInstance();
+
+ cdataElements = new ArrayList<String>();
+ textElements = new ArrayList<String>();
+ commentElements = new ArrayList<String>();
+ }
+
+ protected void tearDown() throws Exception {
+ dbf = null;
+ cdataElements = null;
+ textElements = null;
+ commentElements = null;
+ super.tearDown();
+ }
+
+ /**
+ * @tests javax.xml.parsers.DocumentBuilderFactory#DocumentBuilderFactory().
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "DocumentBuilderFactory",
+ args = {}
+ )
+ public void test_Constructor() {
+ try {
+ new DocumentBuilderFactoryChild();
+ } catch (Exception e) {
+ fail("Unexpected exception " + e.toString());
+ }
+ }
+
+ /**
+ * @tests javax.xml.parsers.DocumentBuilderFactory#getAttribute(String).
+ */
+// public void test_getAttributeLjava_lang_String() {
+// String[] attributes = {
+// "http://java.sun.com/xml/jaxp/properties/schemaLanguage",
+// "http://java.sun.com/xml/jaxp/properties/schemaSource" };
+// Object[] values = { "http://www.w3.org/2001/XMLSchema", "source" };
+//
+// try {
+// for (int i = 0; i < attributes.length; i++) {
+// dbf.setAttribute(attributes[i], values[i]);
+// assertEquals(values[i], dbf.getAttribute(attributes[i]));
+// }
+// } catch (IllegalArgumentException e) {
+// fail("Unexpected IllegalArgumentException" + e.getMessage());
+// } catch (Exception e) {
+// fail("Unexpected exception" + e.getMessage());
+// }
+//
+// try {
+// for (int i = 0; i < attributes.length; i++) {
+// dbf.setAttribute(null, null);
+// fail("NullPointerException expected");
+// }
+// } catch (NullPointerException e) {
+// // expected
+// }
+//
+// String[] badAttributes = {"bad1", "bad2", ""};
+// try {
+// for (int i = 0; i < badAttributes.length; i++) {
+// dbf.getAttribute(badAttributes[i]);
+// fail("IllegalArgumentException expected");
+// }
+// } catch (IllegalArgumentException e) {
+// // expected
+// }
+// }
+
+ /**
+ * @tests javax.xml.parsers.DocumentBuilderFactory#getFeature(String).
+ */
+// TODO Fails on JDK. Why?
+// public void test_getFeatureLjava_lang_String() {
+// String[] features = { "http://xml.org/sax/features/namespaces",
+// "http://xml.org/sax/features/validation",
+// "http://xml.org/sax/features/external-general-entities" };
+// try {
+// for (int i = 0; i < features.length; i++) {
+// dbf.setFeature(features[i], true);
+// assertTrue(dbf.getFeature(features[i]));
+// }
+// } catch (ParserConfigurationException e) {
+// fail("Unexpected ParserConfigurationException " + e.getMessage());
+// }
+//
+// try {
+// for (int i = 0; i < features.length; i++) {
+// dbf.setFeature(features[i], false);
+// assertFalse(dbf.getFeature(features[i]));
+// }
+// } catch (ParserConfigurationException e) {
+// fail("Unexpected ParserConfigurationException " + e.getMessage());
+// }
+//
+// try {
+// for (int i = 0; i < features.length; i++) {
+// dbf.setFeature(null, false);
+// fail("NullPointerException expected");
+// }
+// } catch (NullPointerException e) {
+// // expected
+// } catch (ParserConfigurationException e) {
+// fail("Unexpected ParserConfigurationException" + e.getMessage());
+// }
+//
+// String[] badFeatures = {"bad1", "bad2", ""};
+// try {
+// for (int i = 0; i < badFeatures.length; i++) {
+// dbf.getFeature(badFeatures[i]);
+// fail("ParserConfigurationException expected");
+// }
+// } catch (ParserConfigurationException e) {
+// // expected
+// }
+//
+// }
+
+ /**
+ * @tests javax.xml.parsers.DocumentBuilderFactory#getSchema().
+ * TBD getSchemas() IS NOT SUPPORTED
+ */
+/* public void test_getSchema() {
+ assertNull(dbf.getSchema());
+ SchemaFactory sf =
+ SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
+ try {
+ Schema schema = sf.newSchema();
+ dbf.setSchema(schema);
+ assertNotNull(dbf.getSchema());
+ } catch (SAXException sax) {
+ fail("Unexpected exception " + sax.toString());
+ }
+ }
+ */
+
+ /**
+ * @tests javax.xml.parsers.DocumentBuilderFactory#isCoalescing().
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "isCoalescing",
+ args = {}
+ )
+ public void test_isCoalescing() {
+ dbf.setCoalescing(true);
+ assertTrue(dbf.isCoalescing());
+
+ dbf.setCoalescing(false);
+ assertFalse(dbf.isCoalescing());
+ }
+
+ /**
+ * @tests javax.xml.parsers.DocumentBuilderFactory#isExpandEntityReferences().
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "isExpandEntityReferences",
+ args = {}
+ )
+ public void test_isExpandEntityReferences() {
+ dbf.setExpandEntityReferences(true);
+ assertTrue(dbf.isExpandEntityReferences());
+
+ dbf.setExpandEntityReferences(false);
+ assertFalse(dbf.isExpandEntityReferences());
+ }
+
+ /**
+ * @tests javax.xml.parsers.DocumentBuilderFactory#isIgnoringComments().
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "isIgnoringComments",
+ args = {}
+ )
+ public void test_isIgnoringComments() {
+ dbf.setIgnoringComments(true);
+ assertTrue(dbf.isIgnoringComments());
+
+ dbf.setIgnoringComments(false);
+ assertFalse(dbf.isIgnoringComments());
+ }
+
+ /**
+ * @tests javax.xml.parsers.DocumentBuilderFactory#isIgnoringElementContentWhitespace().
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "isIgnoringElementContentWhitespace",
+ args = {}
+ )
+ public void test_isIgnoringElementContentWhitespace() {
+ dbf.setIgnoringElementContentWhitespace(true);
+ assertTrue(dbf.isIgnoringElementContentWhitespace());
+
+ dbf.setIgnoringElementContentWhitespace(false);
+ assertFalse(dbf.isIgnoringElementContentWhitespace());
+ }
+
+ /**
+ * @tests javax.xml.parsers.DocumentBuilderFactory#isNamespaceAware().
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "isNamespaceAware",
+ args = {}
+ )
+ public void test_isNamespaceAware() {
+ dbf.setNamespaceAware(true);
+ assertTrue(dbf.isNamespaceAware());
+
+ dbf.setNamespaceAware(false);
+ assertFalse(dbf.isNamespaceAware());
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "isValidating",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.SUFFICIENT,
+ notes = "",
+ method = "setValidating",
+ args = {boolean.class}
+ )
+ })
+ public void test_setIsValidating() {
+ dbf.setValidating(true);
+ assertTrue(dbf.isValidating());
+
+ dbf.setValidating(false);
+ assertFalse(dbf.isValidating());
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "isXIncludeAware",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.SUFFICIENT,
+ notes = "",
+ method = "setXIncludeAware",
+ args = {boolean.class}
+ )
+ })
+ @KnownFailure("Should handle XIncludeAware flag more gracefully")
+ public void test_isSetXIncludeAware() {
+ dbf.setXIncludeAware(true);
+ assertTrue(dbf.isXIncludeAware());
+
+ dbf.setXIncludeAware(false);
+ assertFalse(dbf.isXIncludeAware());
+ }
+
+ /**
+ * @tests javax.xml.parsers.DocumentBuilderFactory#newInstance().
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "newInstance",
+ args = {}
+ )
+ public void test_newInstance() {
+ String className = null;
+ try {
+ // case 1: Try to obtain a new instance of factory by default.
+ DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+ assertNotNull(dbf);
+
+ // case 2: Try to create a new instance of factory using
+ // property DATATYPEFACTORY_PROPERTY
+ className = System.getProperty("javax.xml.parsers.DocumentBuilderFactory");
+ System.setProperty("javax.xml.parsers.DocumentBuilderFactory",
+ "org.apache.harmony.xml.parsers.DocumentBuilderFactoryImpl");
+
+ dbf = DocumentBuilderFactory.newInstance();
+ assertNotNull(dbf);
+ assertTrue(dbf instanceof org.apache.harmony.xml.parsers.DocumentBuilderFactoryImpl);
+
+ // case 3: Try to create a new instance of factory using Property
+ String keyValuePair = "javax.xml.parsers.DocumentBuilderFactory"
+ + "=" + "org.apache.harmony.xml.parsers.DocumentBuilderFactoryImpl";
+ ByteArrayInputStream bis = new ByteArrayInputStream(keyValuePair
+ .getBytes());
+ Properties prop = System.getProperties();
+ prop.load(bis);
+ dbf = DocumentBuilderFactory.newInstance();
+ assertNotNull(dbf);
+ assertTrue(dbf instanceof org.apache.harmony.xml.parsers.DocumentBuilderFactoryImpl);
+
+ // case 4: Check FactoryConfiguration error
+ System.setProperty("javax.xml.parsers.DocumentBuilderFactory", "");
+ try {
+ DocumentBuilderFactory.newInstance();
+ } catch (FactoryConfigurationError fce) {
+ // expected
+ }
+
+ } catch (Exception e) {
+ fail("Unexpected exception " + e.toString());
+ } finally {
+ // Set default value of Datatype factory,
+ // because of this test modifies it.
+ if (className == null) {
+ System.clearProperty("javax.xml.parsers.DocumentBuilderFactory");
+ } else {
+ System.setProperty("javax.xml.parsers.DocumentBuilderFactory",
+ className);
+ }
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.SUFFICIENT,
+ notes = "SAXException untested; unused on Android",
+ method = "newDocumentBuilder",
+ args = {}
+ )
+ public void test_newDocumentBuilder() {
+ // Ordinary case
+ try {
+ DocumentBuilder db = dbf.newDocumentBuilder();
+ assertTrue(db instanceof DocumentBuilder);
+ db.parse(getClass().getResourceAsStream("/simple.xml"));
+ } catch(Exception e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ // Exception case
+ dbf.setValidating(true);
+ try {
+ DocumentBuilder db = dbf.newDocumentBuilder();
+ } catch(ParserConfigurationException e) {
+ // Expected, since Android doesn't have a validating parser.
+ }
+ }
+
+ /**
+ * @tests javax.xml.parsers.DocumentBuilderFactory#setAttribute(java.lang.String,
+ * java.lang.Object).
+ */
+// public void test_setAttributeLjava_lang_StringLjava_lang_Object() {
+// String[] attributes = {
+// "http://java.sun.com/xml/jaxp/properties/schemaLanguage",
+// "http://java.sun.com/xml/jaxp/properties/schemaSource" };
+// Object[] values = { "http://www.w3.org/2001/XMLSchema", "source" };
+//
+// try {
+// for (int i = 0; i < attributes.length; i++) {
+// dbf.setAttribute(attributes[i], values[i]);
+// assertEquals(values[i], dbf.getAttribute(attributes[i]));
+// }
+// } catch (IllegalArgumentException e) {
+// fail("Unexpected IllegalArgumentException" + e.getMessage());
+// } catch (Exception e) {
+// fail("Unexpected exception" + e.getMessage());
+// }
+//
+// String[] badAttributes = {"bad1", "bad2", ""};
+// try {
+// for (int i = 0; i < badAttributes.length; i++) {
+// dbf.setAttribute(badAttributes[i], "");
+// fail("IllegalArgumentException expected");
+// }
+// } catch (IllegalArgumentException iae) {
+// // expected
+// }
+//
+// try {
+// for (int i = 0; i < attributes.length; i++) {
+// dbf.setAttribute(null, null);
+// fail("NullPointerException expected");
+// }
+// } catch (NullPointerException e) {
+// // expected
+// }
+// }
+
+ /**
+ * @tests javax.xml.parsers.DocumentBuilderFactory#setCoalescing(boolean).
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "setCoalescing",
+ args = {boolean.class}
+ )
+ @KnownFailure("Should support coalescing")
+ public void test_setCoalescingZ() {
+ dbf.setCoalescing(true);
+ assertTrue(dbf.isCoalescing());
+
+ textElements.clear();
+ cdataElements.clear();
+ Exception parseException = null;
+ DocumentBuilder parser = null;
+
+ try {
+ parser = dbf.newDocumentBuilder();
+ ValidationErrorHandler errorHandler = new ValidationErrorHandler();
+ parser.setErrorHandler(errorHandler);
+
+ Document document = parser.parse(getClass().getResourceAsStream(
+ "/recipt.xml"));
+
+ parseException = errorHandler.getFirstException();
+
+ goThroughDocument((Node) document, "");
+ assertTrue(textElements
+ .contains("BeefParmesan<title>withGarlicAngelHairPasta</title>"));
+ } catch (Exception ex) {
+ parseException = ex;
+ }
+ parser.setErrorHandler(null);
+
+ if (parseException != null) {
+ fail("Unexpected exception " + parseException.getMessage());
+ }
+
+ dbf.setCoalescing(false);
+ assertFalse(dbf.isCoalescing());
+
+ textElements.clear();
+ cdataElements.clear();
+
+ try {
+ parser = dbf.newDocumentBuilder();
+ ValidationErrorHandler errorHandler = new ValidationErrorHandler();
+ parser.setErrorHandler(errorHandler);
+
+ Document document = parser.parse(getClass().getResourceAsStream(
+ "/recipt.xml"));
+
+ parseException = errorHandler.getFirstException();
+
+ goThroughDocument((Node) document, "");
+
+ assertFalse(textElements
+ .contains("BeefParmesan<title>withGarlicAngelHairPasta</title>"));
+
+ } catch (Exception ex) {
+ parseException = ex;
+ }
+ parser.setErrorHandler(null);
+
+ if (parseException != null) {
+ fail("Unexpected exception " + parseException.getMessage());
+ }
+ }
+
+ /**
+ * @tests javax.xml.parsers.DocumentBuilderFactory#setExpandEntityReferences(boolean).
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "setExpandEntityReferences",
+ args = {boolean.class}
+ )
+ public void test_setExpandEntityReferencesZ() {
+ dbf.setExpandEntityReferences(true);
+ assertTrue(dbf.isExpandEntityReferences());
+
+ Exception parseException = null;
+ DocumentBuilder parser = null;
+
+ try {
+ parser = dbf.newDocumentBuilder();
+ ValidationErrorHandler errorHandler = new ValidationErrorHandler();
+ parser.setErrorHandler(errorHandler);
+
+ Document document = parser.parse(getClass().getResourceAsStream(
+ "/recipt.xml"));
+
+ parseException = errorHandler.getFirstException();
+
+ assertNotNull(document);
+
+ } catch (Exception ex) {
+ parseException = ex;
+ }
+ parser.setErrorHandler(null);
+
+ if (parseException != null) {
+ fail("Unexpected exception " + parseException.getMessage());
+ }
+
+ dbf.setExpandEntityReferences(false);
+ assertFalse(dbf.isExpandEntityReferences());
+ try {
+ parser = dbf.newDocumentBuilder();
+ ValidationErrorHandler errorHandler = new ValidationErrorHandler();
+ parser.setErrorHandler(errorHandler);
+
+ Document document = parser.parse(getClass().getResourceAsStream(
+ "/recipt.xml"));
+
+ parseException = errorHandler.getFirstException();
+
+ assertNotNull(document);
+
+ } catch (Exception ex) {
+ parseException = ex;
+ }
+ parser.setErrorHandler(null);
+
+ if (parseException != null) {
+ fail("Unexpected exception " + parseException.getMessage());
+ }
+ }
+
+ /**
+ * @tests javax.xml.parsers.DocumentBuilderFactory#setFeature(java.lang.String).
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getFeature",
+ args = {java.lang.String.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "setFeature",
+ args = {java.lang.String.class, boolean.class}
+ )
+ })
+ public void test_getSetFeatureLjava_lang_String() {
+ String[] features = { "http://xml.org/sax/features/namespaces",
+ "http://xml.org/sax/features/validation" };
+ try {
+ for (int i = 0; i < features.length; i++) {
+ dbf.setFeature(features[i], true);
+ assertTrue(dbf.getFeature(features[i]));
+ }
+ } catch (ParserConfigurationException e) {
+ fail("Unexpected ParserConfigurationException" + e.getMessage());
+ }
+
+ try {
+ for (int i = 0; i < features.length; i++) {
+ dbf.setFeature(features[i], false);
+ assertFalse(dbf.getFeature(features[i]));
+ }
+ } catch (ParserConfigurationException e) {
+ fail("Unexpected ParserConfigurationException" + e.getMessage());
+ }
+
+ try {
+ for (int i = 0; i < features.length; i++) {
+ dbf.setFeature(null, false);
+ fail("NullPointerException expected");
+ }
+ } catch (NullPointerException e) {
+ // expected
+ } catch (ParserConfigurationException e) {
+ fail("Unexpected ParserConfigurationException" + e.getMessage());
+ }
+
+ String[] badFeatures = { "bad1", "bad2", "" };
+ try {
+ for (int i = 0; i < badFeatures.length; i++) {
+ dbf.setFeature(badFeatures[i], false);
+ fail("ParserConfigurationException expected");
+ }
+ } catch (ParserConfigurationException e) {
+ // expected
+ }
+ }
+
+ /**
+ * @tests javax.xml.parsers.DocumentBuilderFactory#setIgnoringComments(boolean).
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "setIgnoringComments",
+ args = {boolean.class}
+ )
+ public void test_setIgnoringCommentsZ() {
+ commentElements.clear();
+
+ dbf.setIgnoringComments(true);
+ assertTrue(dbf.isIgnoringComments());
+
+ try {
+ DocumentBuilder parser = dbf.newDocumentBuilder();
+
+ Document document = parser.parse(getClass().getResourceAsStream(
+ "/recipt.xml"));
+
+ goThroughDocument((Node) document, "");
+ assertFalse(commentElements.contains("comment1"));
+ assertFalse(commentElements.contains("comment2"));
+
+ } catch (IOException e) {
+ fail("Unexpected IOException " + e.getMessage());
+ } catch (ParserConfigurationException e) {
+ fail("Unexpected ParserConfigurationException " + e.getMessage());
+ } catch (SAXException e) {
+ fail("Unexpected SAXException " + e.getMessage());
+ }
+
+ commentElements.clear();
+
+ dbf.setIgnoringComments(false);
+ assertFalse(dbf.isIgnoringComments());
+
+ try {
+ DocumentBuilder parser = dbf.newDocumentBuilder();
+
+ Document document = parser.parse(getClass().getResourceAsStream(
+ "/recipt.xml"));
+
+ goThroughDocument((Node) document, "");
+ assertTrue(commentElements.contains("comment1"));
+ assertTrue(commentElements.contains("comment2"));
+
+ } catch (IOException e) {
+ fail("Unexpected IOException " + e.getMessage());
+ } catch (ParserConfigurationException e) {
+ fail("Unexpected ParserConfigurationException " + e.getMessage());
+ } catch (SAXException e) {
+ fail("Unexpected SAXException " + e.getMessage());
+ }
+ }
+
+ /**
+ * @tests javax.xml.parsers.DocumentBuilderFactory#setIgnoringElementContentWhitespace(boolean).
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "setIgnoringElementContentWhitespace",
+ args = {boolean.class}
+ )
+ public void test_setIgnoringElementContentWhitespaceZ() {
+ dbf.setIgnoringElementContentWhitespace(true);
+ assertTrue(dbf.isIgnoringElementContentWhitespace());
+
+ try {
+ DocumentBuilder parser = dbf.newDocumentBuilder();
+
+ Document document = parser.parse(getClass().getResourceAsStream(
+ "/recipt.xml"));
+
+ assertNotNull(document);
+
+ } catch (IOException e) {
+ fail("Unexpected IOException " + e.getMessage());
+ } catch (ParserConfigurationException e) {
+ fail("Unexpected ParserConfigurationException " + e.getMessage());
+ } catch (SAXException e) {
+ fail("Unexpected SAXException " + e.getMessage());
+ }
+
+ dbf.setIgnoringElementContentWhitespace(false);
+ assertFalse(dbf.isIgnoringElementContentWhitespace());
+
+ try {
+ DocumentBuilder parser = dbf.newDocumentBuilder();
+
+ Document document = parser.parse(getClass().getResourceAsStream(
+ "/recipt.xml"));
+
+ assertNotNull(document);
+
+ } catch (IOException e) {
+ fail("Unexpected IOException " + e.getMessage());
+ } catch (ParserConfigurationException e) {
+ fail("Unexpected ParserConfigurationException " + e.getMessage());
+ } catch (SAXException e) {
+ fail("Unexpected SAXException " + e.getMessage());
+ }
+ }
+
+ /**
+ * @tests javax.xml.parsers.DocumentBuilderFactory#setNamespaceAware(boolean).
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "setNamespaceAware",
+ args = {boolean.class}
+ )
+ public void test_setNamespaceAwareZ() {
+ dbf.setNamespaceAware(true);
+ assertTrue(dbf.isNamespaceAware());
+
+ try {
+ DocumentBuilder parser = dbf.newDocumentBuilder();
+
+ Document document = parser.parse(getClass().getResourceAsStream(
+ "/recipt.xml"));
+
+ assertNotNull(document);
+
+ } catch (IOException e) {
+ fail("Unexpected IOException " + e.getMessage());
+ } catch (ParserConfigurationException e) {
+ fail("Unexpected ParserConfigurationException " + e.getMessage());
+ } catch (SAXException e) {
+ fail("Unexpected SAXException " + e.getMessage());
+ }
+
+ dbf.setNamespaceAware(false);
+ assertFalse(dbf.isNamespaceAware());
+
+ try {
+ DocumentBuilder parser = dbf.newDocumentBuilder();
+
+ Document document = parser.parse(getClass().getResourceAsStream(
+ "/recipt.xml"));
+
+ assertNotNull(document);
+
+ } catch (IOException e) {
+ fail("Unexpected IOException " + e.getMessage());
+ } catch (ParserConfigurationException e) {
+ fail("Unexpected ParserConfigurationException " + e.getMessage());
+ } catch (SAXException e) {
+ fail("Unexpected SAXException " + e.getMessage());
+ }
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getAttribute",
+ args = {java.lang.String.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "setAttribute",
+ args = {java.lang.String.class, Object.class}
+ )
+ })
+ public void test_getSetAttribute() {
+ // Android SAX implementation doesn't support attributes, so
+ // we can only make sure the expected exception is thrown.
+ try {
+ dbf.setAttribute("foo", new Object());
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ dbf.getAttribute("foo");
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ }
+
+ /**
+ * @tests javax.xml.parsers.DocumentBuilderFactory#setSchema(javax.xml.validation.Schema).
+ */
+ /* public void test_setSchemaLjavax_xml_validation_Schema() {
+ SchemaFactory sf =
+ SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
+ try {
+ Schema schema = sf.newSchema();
+ dbf.setSchema(schema);
+ assertNotNull(dbf.getSchema());
+ } catch (SAXException sax) {
+ fail("Unexpected exception " + sax.toString());
+ }
+ }
+*/
+ /**
+ * @tests javax.xml.parsers.DocumentBuilderFactory#setValidating(boolean).
+ */
+// public void test_setValidatingZ() {
+// Exception parseException = null;
+// DocumentBuilder parser = null;
+// Document document = null;
+//
+// ValidationErrorHandler errorHandler = new ValidationErrorHandler();
+//
+// dbf.setValidating(false);
+// assertFalse(dbf.isValidating());
+//
+// // case 1: Validation is not set. Correct xml-file
+// try {
+//
+// parser = dbf.newDocumentBuilder();
+// parser.setErrorHandler(errorHandler);
+//
+// document = parser.parse(getClass().getResourceAsStream(
+// "/recipt.xml"));
+//
+// parseException = errorHandler.getFirstException();
+//
+// assertNotNull(document);
+//
+// document = parser.parse(getClass().getResourceAsStream(
+// "/reciptWrong.xml"));
+//
+// parseException = errorHandler.getFirstException();
+//
+// assertNotNull(document);
+//
+// } catch (Exception ex) {
+// parseException = ex;
+// }
+// parser.setErrorHandler(null);
+//
+// if (parseException != null) {
+// fail("Unexpected exception " + parseException.getMessage());
+// }
+//
+// // case 2: Validation is not set. Wrong xml-file
+// try {
+//
+// parser = dbf.newDocumentBuilder();
+// parser.setErrorHandler(errorHandler);
+//
+// document = parser.parse(getClass().getResourceAsStream(
+// "/reciptWrong.xml"));
+// parseException = errorHandler.getFirstException();
+//
+// assertNotNull(document);
+//
+// } catch (Exception ex) {
+// parseException = ex;
+// }
+// parser.setErrorHandler(null);
+//
+// if (parseException != null) {
+// fail("Unexpected exception " + parseException.getMessage());
+// }
+//
+// // case 3: Validation is set. Correct xml-file
+// dbf.setValidating(true);
+// assertTrue(dbf.isValidating());
+//
+// try {
+//
+// parser = dbf.newDocumentBuilder();
+// parser.setErrorHandler(errorHandler);
+//
+// document = parser.parse(getClass().getResourceAsStream(
+// "/recipt.xml"));
+// parseException = errorHandler.getFirstException();
+//
+// assertNotNull(document);
+//
+// } catch (Exception ex) {
+// parseException = ex;
+// }
+// parser.setErrorHandler(null);
+//
+// if (parseException != null) {
+// fail("Unexpected exception " + parseException.getMessage());
+// }
+//
+// // case 4: Validation is set. Wrong xml-file
+// try {
+//
+// parser = dbf.newDocumentBuilder();
+// parser.setErrorHandler(errorHandler);
+//
+// document = parser.parse(getClass().getResourceAsStream(
+// "/reciptWrong.xml"));
+// parseException = errorHandler.getFirstException();
+//
+// assertNotNull(document);
+//
+// } catch (Exception ex) {
+// parseException = ex;
+// }
+// parser.setErrorHandler(null);
+//
+// if (parseException == null) {
+// fail("Unexpected exception " + parseException.getMessage());
+// } else {
+// assertTrue(parseException
+// .getMessage()
+// .contains(
+// "The content of element type \"collection\" must match \"(description,recipe+)\""));
+// }
+//
+// }
+
+ /**
+ * @tests javax.xml.parsers.DocumentBuilderFactory#setXIncludeAware().
+ */
+// public void test_setXIncludeAware() {
+// dbf.setXIncludeAware(true);
+// assertTrue(dbf.isXIncludeAware());
+//
+// try {
+// DocumentBuilder parser = dbf.newDocumentBuilder();
+//
+// Document document = parser.parse(getClass().getResourceAsStream(
+// "/recipt.xml"));
+//
+// assertNotNull(document);
+//
+// } catch (IOException e) {
+// fail("Unexpected IOException " + e.getMessage());
+// } catch (ParserConfigurationException e) {
+// fail("Unexpected ParserConfigurationException " + e.getMessage());
+// } catch (SAXException e) {
+// fail("Unexpected SAXException " + e.getMessage());
+// }
+//
+// dbf.setXIncludeAware(false);
+// assertFalse(dbf.isXIncludeAware());
+//
+// try {
+// DocumentBuilder parser = dbf.newDocumentBuilder();
+//
+// Document document = parser.parse(getClass().getResourceAsStream(
+// "/recipt.xml"));
+//
+// assertNotNull(document);
+//
+// } catch (IOException e) {
+// fail("Unexpected IOException " + e.getMessage());
+// } catch (ParserConfigurationException e) {
+// fail("Unexpected ParserConfigurationException " + e.getMessage());
+// } catch (SAXException e) {
+// fail("Unexpected SAXException " + e.getMessage());
+// }
+// }
+
+ private void goThroughDocument(Node node, String indent) {
+ String value = node.getNodeValue();
+
+ if (value != null) {
+ value = value.replaceAll(" ", "");
+ value = value.replaceAll("\n", "");
+ }
+
+ switch (node.getNodeType()) {
+ case Node.CDATA_SECTION_NODE:
+ cdataElements.add(value);
+ // System.out.println(indent + "CDATA_SECTION_NODE " + value);
+ break;
+ case Node.COMMENT_NODE:
+ commentElements.add(value);
+ // System.out.println(indent + "COMMENT_NODE " + value);
+ break;
+ case Node.DOCUMENT_FRAGMENT_NODE:
+ // System.out.println(indent + "DOCUMENT_FRAGMENT_NODE " + value);
+ break;
+ case Node.DOCUMENT_NODE:
+ // System.out.println(indent + "DOCUMENT_NODE " + value);
+ break;
+ case Node.DOCUMENT_TYPE_NODE:
+ // System.out.println(indent + "DOCUMENT_TYPE_NODE " + value);
+ break;
+ case Node.ELEMENT_NODE:
+ // System.out.println(indent + "ELEMENT_NODE " + value);
+ break;
+ case Node.ENTITY_NODE:
+ // System.out.println(indent + "ENTITY_NODE " + value);
+ break;
+ case Node.ENTITY_REFERENCE_NODE:
+ // System.out.println(indent + "ENTITY_REFERENCE_NODE " + value);
+ break;
+ case Node.NOTATION_NODE:
+ // System.out.println(indent + "NOTATION_NODE " + value);
+ break;
+ case Node.PROCESSING_INSTRUCTION_NODE:
+ // System.out.println(indent + "PROCESSING_INSTRUCTION_NODE " +
+ // value);
+ break;
+ case Node.TEXT_NODE:
+ textElements.add(value);
+ // System.out.println(indent + "TEXT_NODE " + value);
+ break;
+ default:
+ // System.out.println(indent + "Unknown node " + value);
+ break;
+ }
+ NodeList list = node.getChildNodes();
+ for (int i = 0; i < list.getLength(); i++)
+ goThroughDocument(list.item(i), indent + " ");
+ }
+
+ private class ValidationErrorHandler implements ErrorHandler {
+ private SAXException parseException;
+
+ private int errorCount;
+
+ private int warningCount;
+
+ public ValidationErrorHandler() {
+ parseException = null;
+ errorCount = 0;
+ warningCount = 0;
+ }
+
+ public void error(SAXParseException ex) {
+ errorCount++;
+ if (parseException == null) {
+ parseException = ex;
+ }
+ }
+
+ public void warning(SAXParseException ex) {
+ warningCount++;
+ }
+
+ public void fatalError(SAXParseException ex) {
+ if (parseException == null) {
+ parseException = ex;
+ }
+ }
+
+ public SAXException getFirstException() {
+ return parseException;
+ }
+ }
+
+ private class DocumentBuilderFactoryChild extends DocumentBuilderFactory {
+ public DocumentBuilderFactoryChild() {
+ super();
+ }
+
+ public Object getAttribute(String name) {
+ return null;
+ }
+
+ public boolean getFeature(String name) {
+ return false;
+ }
+
+ public DocumentBuilder newDocumentBuilder() {
+ return null;
+ }
+
+ public void setAttribute(String name, Object value) {
+ }
+
+ public void setFeature(String name, boolean value) {
+ }
+
+ }
+}
diff --git a/xml/src/test/java/tests/api/javax/xml/parsers/DocumentBuilderTest.java b/xml/src/test/java/tests/api/javax/xml/parsers/DocumentBuilderTest.java
new file mode 100644
index 0000000..181e8f5
--- /dev/null
+++ b/xml/src/test/java/tests/api/javax/xml/parsers/DocumentBuilderTest.java
@@ -0,0 +1,733 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.api.javax.xml.parsers;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import junit.framework.TestCase;
+
+import org.w3c.dom.DOMImplementation;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.EntityReference;
+import org.w3c.dom.Text;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+
+import tests.api.org.xml.sax.support.MethodLogger;
+import tests.api.org.xml.sax.support.MockHandler;
+import tests.api.org.xml.sax.support.MockResolver;
+import dalvik.annotation.BrokenTest;
+import dalvik.annotation.KnownFailure;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+
+@TestTargetClass(DocumentBuilder.class)
+public class DocumentBuilderTest extends TestCase {
+
+ private class MockDocumentBuilder extends DocumentBuilder {
+
+ public MockDocumentBuilder() {
+ super();
+ }
+
+ /*
+ * @see javax.xml.parsers.DocumentBuilder#getDOMImplementation()
+ */
+ @Override
+ public DOMImplementation getDOMImplementation() {
+ // it is a fake
+ return null;
+ }
+
+ /*
+ * @see javax.xml.parsers.DocumentBuilder#isNamespaceAware()
+ */
+ @Override
+ public boolean isNamespaceAware() {
+ // it is a fake
+ return false;
+ }
+
+ /*
+ * @see javax.xml.parsers.DocumentBuilder#isValidating()
+ */
+ @Override
+ public boolean isValidating() {
+ // it is a fake
+ return false;
+ }
+
+ /*
+ * @see javax.xml.parsers.DocumentBuilder#newDocument()
+ */
+ @Override
+ public Document newDocument() {
+ // it is a fake
+ return null;
+ }
+
+ /*
+ * @see javax.xml.parsers.DocumentBuilder#parse(org.xml.sax.InputSource)
+ */
+ @Override
+ public Document parse(InputSource is) throws SAXException, IOException {
+ // it is a fake
+ return null;
+ }
+
+ /*
+ * @see javax.xml.parsers.DocumentBuilder#setEntityResolver(
+ * org.xml.sax.EntityResolver)
+ */
+ @Override
+ public void setEntityResolver(EntityResolver er) {
+ // it is a fake
+ }
+
+ /*
+ * @see javax.xml.parsers.DocumentBuilder#setErrorHandler(
+ * org.xml.sax.ErrorHandler)
+ */
+ @Override
+ public void setErrorHandler(ErrorHandler eh) {
+ // it is a fake
+ }
+
+ public Object clone() throws CloneNotSupportedException {
+ return super.clone();
+ }
+ }
+
+ DocumentBuilderFactory dbf;
+
+ DocumentBuilder db;
+
+ protected void setUp() throws Exception {
+ dbf = DocumentBuilderFactory.newInstance();
+
+ dbf.setIgnoringElementContentWhitespace(true);
+
+ db = dbf.newDocumentBuilder();
+ super.setUp();
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "DocumentBuilder",
+ args = {}
+ )
+ public void testDocumentBuilder() {
+ try {
+ new MockDocumentBuilder();
+ } catch (Exception e) {
+ fail("unexpected exception " + e.toString());
+ }
+ }
+
+ /**
+ * @tests javax.xml.parsers.DocumentBuilder#getSchema()
+ * TBD getSchema() is not supported
+ */
+ /* public void test_getSchema() {
+ assertNull(db.getSchema());
+ SchemaFactory sf =
+ SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
+ try {
+ Schema schema = sf.newSchema();
+ dbf.setSchema(schema);
+ assertNotNull(dbf.newDocumentBuilder().getSchema());
+ } catch (ParserConfigurationException pce) {
+ fail("Unexpected ParserConfigurationException " + pce.toString());
+ } catch (SAXException sax) {
+ fail("Unexpected SAXException " + sax.toString());
+ }
+ }
+*/
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "newDocument",
+ args = { }
+ )
+ public void testNewDocument() {
+ Document d;
+
+ try {
+ d = dbf.newDocumentBuilder().newDocument();
+ } catch (Exception e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ assertNotNull(d);
+ assertNull(d.getDoctype());
+ assertNull(d.getDocumentElement());
+ assertNull(d.getNamespaceURI());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getDOMImplementation",
+ args = { }
+ )
+ public void testGetImplementation() {
+ DOMImplementation d;
+
+ try {
+ d = dbf.newDocumentBuilder().getDOMImplementation();
+ } catch (Exception e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ assertNotNull(d);
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "isNamespaceAware",
+ args = {}
+ )
+ public void testIsNamespaceAware() {
+ try {
+ dbf.setNamespaceAware(true);
+ assertTrue(dbf.newDocumentBuilder().isNamespaceAware());
+ dbf.setNamespaceAware(false);
+ assertFalse(dbf.newDocumentBuilder().isNamespaceAware());
+ } catch (Exception e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.SUFFICIENT,
+ notes = "No validating parser in Android, hence not tested",
+ method = "isValidating",
+ args = {}
+ )
+ public void testIsValidating() {
+ try {
+ dbf.setValidating(false);
+ assertFalse(dbf.newDocumentBuilder().isValidating());
+ } catch (Exception e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.SUFFICIENT,
+ notes = "No XInclude-aware parser in Android, hence not tested",
+ method = "isXIncludeAware",
+ args = {}
+ )
+ @KnownFailure("Should handle XIncludeAware flag more gracefully")
+ public void testIsXIncludeAware() {
+ try {
+ dbf.setXIncludeAware(false);
+ assertFalse(dbf.newDocumentBuilder().isXIncludeAware());
+ } catch (Exception e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+ }
+
+ /**
+ * @tests javax.xml.parsers.DocumentBuilder#parse(java.io.File)
+ * Case 1: Try to parse correct xml document.
+ * Case 2: Try to call parse() with null argument.
+ * Case 3: Try to parse a non-existent file.
+ * Case 4: Try to parse incorrect xml file.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "parse",
+ args = {java.io.File.class}
+ )
+ @BrokenTest("Need to use XML file from correct location")
+ public void test_parseLjava_io_File() {
+ File f = new File("/tmp/xml_source/simple.xml");
+ // case 1: Trivial use.
+ try {
+ Document d = db.parse(f);
+ assertNotNull(d);
+ // TBD getXmlEncoding() IS NOT SUPPORTED
+ // assertEquals("ISO-8859-1", d.getXmlEncoding());
+ assertEquals(2, d.getChildNodes().getLength());
+ assertEquals("#comment",
+ d.getChildNodes().item(0).getNodeName());
+ assertEquals("breakfast_menu",
+ d.getChildNodes().item(1).getNodeName());
+ } catch (IOException ioe) {
+ fail("Unexpected IOException " + ioe.toString());
+ } catch (SAXException sax) {
+ fail("Unexpected SAXException " + sax.toString());
+ }
+
+ // case 2: Try to call parse with null argument
+ try {
+ db.parse((File)null);
+ fail("Expected IllegalArgumentException was not thrown");
+ } catch (IllegalArgumentException iae) {
+ // expected
+ } catch (IOException ioe) {
+ fail("Unexpected IOException " + ioe.toString());
+ } catch (SAXException sax) {
+ fail("Unexpected SAXException " + sax.toString());
+ }
+
+ // case 3: Try to parse a non-existent file
+ try {
+ db.parse(new File("_"));
+ fail("Expected IOException was not thrown");
+ } catch (IOException ioe) {
+ // expected
+ } catch (SAXException sax) {
+ fail("Unexpected SAXException " + sax.toString());
+ }
+
+ // case 4: Try to parse incorrect xml file
+ try {
+ f = new File("/tmp/xml_source/wrong.xml");
+ db.parse(f);
+ fail("Expected SAXException was not thrown");
+ } catch (IOException ioe) {
+ fail("Unexpected IOException " + ioe.toString());
+ } catch (SAXException sax) {
+ // expected
+ }
+ }
+
+ /**
+ * @tests javax.xml.parsers.DocumentBuilder#parse(java.io.InputStream)
+ * Case 1: Try to parse correct xml document.
+ * Case 2: Try to call parse() with null argument.
+ * Case 3: Try to parse a non-existent file.
+ * Case 4: Try to parse incorrect xml file.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "parse",
+ args = {java.io.InputStream.class}
+ )
+ public void test_parseLjava_io_InputStream() {
+ InputStream is = getClass().getResourceAsStream("/simple.xml");
+ // case 1: Trivial use.
+ try {
+ Document d = db.parse(is);
+ assertNotNull(d);
+ // TBD getXmlEncoding() IS NOT SUPPORTED
+ // assertEquals("ISO-8859-1", d.getXmlEncoding());
+ assertEquals(2, d.getChildNodes().getLength());
+ assertEquals("#comment",
+ d.getChildNodes().item(0).getNodeName());
+ assertEquals("breakfast_menu",
+ d.getChildNodes().item(1).getNodeName());
+ } catch (IOException ioe) {
+ fail("Unexpected IOException " + ioe.toString());
+ } catch (SAXException sax) {
+ fail("Unexpected SAXException " + sax.toString());
+ }
+
+ // case 2: Try to call parse with null argument
+ try {
+ db.parse((InputStream)null);
+ fail("Expected IllegalArgumentException was not thrown");
+ } catch (IllegalArgumentException iae) {
+ // expected
+ } catch (IOException ioe) {
+ fail("Unexpected IOException " + ioe.toString());
+ } catch (SAXException sax) {
+ fail("Unexpected SAXException " + sax.toString());
+ }
+
+ // case 3: Try to parse a non-existent file
+ try {
+ db.parse(new FileInputStream("_"));
+ fail("Expected IOException was not thrown");
+ } catch (IOException ioe) {
+ // expected
+ } catch (SAXException sax) {
+ fail("Unexpected SAXException " + sax.toString());
+ }
+
+ // case 4: Try to parse incorrect xml file
+ try {
+ is = getClass().getResourceAsStream("/wrong.xml");
+ db.parse(is);
+ fail("Expected SAXException was not thrown");
+ } catch (IOException ioe) {
+ fail("Unexpected IOException " + ioe.toString());
+ } catch (SAXException sax) {
+ // expected
+ }
+ }
+
+ /**
+ * @tests javax.xml.parsers.DocumentBuilder#parse(java.io.InputStream)
+ * Case 1: Try to parse correct xml document.
+ * Case 2: Try to call parse() with null argument.
+ * Case 3: Try to parse a non-existent file.
+ * Case 4: Try to parse incorrect xml file.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "parse",
+ args = { InputSource.class }
+ )
+ public void testParseInputSource() {
+ InputStream stream = getClass().getResourceAsStream("/simple.xml");
+ InputSource is = new InputSource(stream);
+
+ // case 1: Trivial use.
+ try {
+ Document d = db.parse(is);
+ assertNotNull(d);
+ // TBD getXmlEncoding() IS NOT SUPPORTED
+ // assertEquals("ISO-8859-1", d.getXmlEncoding());
+ assertEquals(2, d.getChildNodes().getLength());
+ assertEquals("#comment",
+ d.getChildNodes().item(0).getNodeName());
+ assertEquals("breakfast_menu",
+ d.getChildNodes().item(1).getNodeName());
+ } catch (IOException ioe) {
+ fail("Unexpected IOException " + ioe.toString());
+ } catch (SAXException sax) {
+ fail("Unexpected SAXException " + sax.toString());
+ }
+
+ // case 2: Try to call parse with null argument
+ try {
+ db.parse((InputSource)null);
+ fail("Expected IllegalArgumentException was not thrown");
+ } catch (IllegalArgumentException iae) {
+ // expected
+ } catch (IOException ioe) {
+ fail("Unexpected IOException " + ioe.toString());
+ } catch (SAXException sax) {
+ fail("Unexpected SAXException " + sax.toString());
+ }
+
+ // case 3: Try to parse a non-existent file
+ try {
+ db.parse(new InputSource(new FileInputStream("_")));
+ fail("Expected IOException was not thrown");
+ } catch (IOException ioe) {
+ // expected
+ } catch (SAXException sax) {
+ fail("Unexpected SAXException " + sax.toString());
+ }
+
+ // case 4: Try to parse incorrect xml file
+ try {
+ is = new InputSource(getClass().getResourceAsStream("/wrong.xml"));
+ db.parse(is);
+ fail("Expected SAXException was not thrown");
+ } catch (IOException ioe) {
+ fail("Unexpected IOException " + ioe.toString());
+ } catch (SAXException sax) {
+ // expected
+ }
+ }
+
+ /**
+ * @tests javax.xml.parsers.DocumentBuilder#parse(java.io.InputStream,
+ * java.lang.String)
+ * Case 1: Try to parse correct xml document.
+ * Case 2: Try to call parse() with null argument.
+ * Case 3: Try to parse a non-existent file.
+ * Case 4: Try to parse incorrect xml file.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "parse",
+ args = {java.io.InputStream.class, java.lang.String.class}
+ )
+ public void test_parseLjava_io_InputStreamLjava_lang_String() {
+ InputStream is = getClass().getResourceAsStream("/systemid.xml");
+ // case 1: Trivial use.
+ try {
+ Document d = db.parse(is, SAXParserTestSupport.XML_SYSTEM_ID);
+ assertNotNull(d);
+// TBD getXmlEncoding() is not supported
+// assertEquals("UTF-8", d.getXmlEncoding());
+ assertEquals(4, d.getChildNodes().getLength());
+ assertEquals("collection",
+ d.getChildNodes().item(0).getNodeName());
+ assertEquals("#comment",
+ d.getChildNodes().item(1).getNodeName());
+ assertEquals("collection",
+ d.getChildNodes().item(2).getNodeName());
+ assertEquals("#comment",
+ d.getChildNodes().item(3).getNodeName());
+ } catch (IOException ioe) {
+ fail("Unexpected IOException " + ioe.toString());
+ } catch (SAXException sax) {
+ fail("Unexpected SAXException " + sax.toString());
+ }
+
+ // case 2: Try to call parse with null argument
+ try {
+ db.parse((InputStream)null, SAXParserTestSupport.XML_SYSTEM_ID);
+ fail("Expected IllegalArgumentException was not thrown");
+ } catch (IllegalArgumentException iae) {
+ // expected
+ } catch (IOException ioe) {
+ fail("Unexpected IOException " + ioe.toString());
+ } catch (SAXException sax) {
+ fail("Unexpected SAXException " + sax.toString());
+ }
+
+ // case 3: Try to parse a non-existent file
+// Doesn't make sense this way...
+// try {
+// db.parse(is, "/");
+// fail("Expected IOException was not thrown");
+// } catch (IOException ioe) {
+// // expected
+// } catch (SAXException sax) {
+// fail("Unexpected SAXException " + sax.toString());
+// }
+
+ // case 4: Try to parse incorrect xml file
+ try {
+ is = getClass().getResourceAsStream("/wrong.xml");
+ db.parse(is, SAXParserTestSupport.XML_SYSTEM_ID);
+ fail("Expected SAXException was not thrown");
+ } catch (IOException ioe) {
+ fail("Unexpected IOException " + ioe.toString());
+ } catch (SAXException sax) {
+ // expected
+ }
+ }
+
+ /**
+ * @tests javax.xml.parsers.DocumentBuilder#parse(java.lang.String)
+ * Case 1: Try to parse correct xml document.
+ * Case 2: Try to call parse() with null argument.
+ * Case 3: Try to parse a non-existent uri.
+ * Case 4: Try to parse incorrect xml file.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "parse",
+ args = {java.lang.String.class}
+ )
+ @KnownFailure("Android DocumentBuilder should support File sources")
+ public void test_parseLjava_lang_String() {
+ // case 1: Trivial use.
+ File f = new File(getClass().getResource("/simple.xml").getFile());
+ try {
+ Document d = db.parse(f.getAbsolutePath());
+ assertNotNull(d);
+// TBD getXmlEncoding() is not supported
+// assertEquals("ISO-8859-1", d.getXmlEncoding());
+ assertEquals(2, d.getChildNodes().getLength());
+ assertEquals("#comment",
+ d.getChildNodes().item(0).getNodeName());
+ assertEquals("breakfast_menu",
+ d.getChildNodes().item(1).getNodeName());
+ } catch (IOException ioe) {
+ fail("Unexpected IOException " + ioe.toString());
+ } catch (SAXException sax) {
+ fail("Unexpected SAXException " + sax.toString());
+ }
+
+ // case 2: Try to call parse with null argument
+ try {
+ db.parse((String)null);
+ fail("Expected IllegalArgumentException was not thrown");
+ } catch (IllegalArgumentException iae) {
+ // expected
+ } catch (IOException ioe) {
+ fail("Unexpected IOException " + ioe.toString());
+ } catch (SAXException sax) {
+ fail("Unexpected SAXException " + sax.toString());
+ }
+
+ // case 3: Try to parse a non-existent uri
+ try {
+ db.parse("_");
+ fail("Expected IOException was not thrown");
+ } catch (IOException ioe) {
+ // expected
+ } catch (SAXException sax) {
+ fail("Unexpected SAXException " + sax.toString());
+ }
+
+ // case 4: Try to parse incorrect xml file
+ try {
+ f = new File(getClass().getResource("/wrong.xml").getFile());
+ db.parse(f.getAbsolutePath());
+ fail("Expected SAXException was not thrown");
+ } catch (IOException ioe) {
+ fail("Unexpected IOException " + ioe.toString());
+ } catch (SAXException sax) {
+ // expected
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "reset",
+ args = { }
+ )
+ @KnownFailure("Android DocumentBuilder should implement reset() properly")
+ public void testReset() {
+ // Make sure EntityResolver gets reset
+ InputStream source = new ByteArrayInputStream("<a>&foo;</a>".getBytes());
+ InputStream entity = new ByteArrayInputStream("bar".getBytes());
+
+ MockResolver resolver = new MockResolver();
+ resolver.addEntity("foo", "foo", new InputSource(entity));
+
+ Document d;
+
+ try {
+ db = dbf.newDocumentBuilder();
+ db.setEntityResolver(resolver);
+ db.reset();
+ d = db.parse(source);
+ } catch (Exception e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ Element root = (Element)d.getElementsByTagName("a").item(0);
+ assertEquals("foo", ((EntityReference)root.getFirstChild()).getNodeName());
+
+ // Make sure ErrorHandler gets reset
+ source = new ByteArrayInputStream("</a>".getBytes());
+
+ MethodLogger logger = new MethodLogger();
+ ErrorHandler handler = new MockHandler(logger);
+
+ try {
+ db = dbf.newDocumentBuilder();
+ db.setErrorHandler(handler);
+ db.reset();
+ d = db.parse(source);
+ } catch (SAXParseException e) {
+ // Expected
+ } catch (Exception e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ assertEquals(0, logger.size());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setErrorHandler",
+ args = { ErrorHandler.class }
+ )
+ public void testSetErrorHandler() {
+ // Ordinary case
+ InputStream source = new ByteArrayInputStream("</a>".getBytes());
+
+ MethodLogger logger = new MethodLogger();
+ ErrorHandler handler = new MockHandler(logger);
+
+ try {
+ db = dbf.newDocumentBuilder();
+ db.setErrorHandler(handler);
+ db.parse(source);
+ } catch (SAXParseException e) {
+ // Expected, ErrorHandler does not mask exception
+ } catch (Exception e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ assertEquals("error", logger.getMethod());
+ assertTrue(logger.getArgs()[0] instanceof SAXParseException);
+
+ // null case
+ source = new ByteArrayInputStream("</a>".getBytes());
+
+ try {
+ db = dbf.newDocumentBuilder();
+ db.setErrorHandler(null);
+ db.parse(source);
+ } catch (SAXParseException e) {
+ // Expected
+ } catch (Exception e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setEntityResolver",
+ args = { EntityResolver.class }
+ )
+ @KnownFailure("Android DocumentBuilder should support entity resolving")
+ public void testSetEntityResolver() {
+ // Ordinary case
+ InputStream source = new ByteArrayInputStream("<a>&foo;</a>".getBytes());
+ InputStream entity = new ByteArrayInputStream("bar".getBytes());
+
+ MockResolver resolver = new MockResolver();
+ resolver.addEntity("foo", "foo", new InputSource(entity));
+
+ Document d;
+
+ try {
+ db = dbf.newDocumentBuilder();
+ db.setEntityResolver(resolver);
+ d = db.parse(source);
+ } catch (Exception e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ Element root = (Element)d.getElementsByTagName("a").item(0);
+ assertEquals("bar", ((Text)root.getFirstChild()).getData());
+
+ // null case
+ source = new ByteArrayInputStream("<a>&foo;</a>".getBytes());
+
+ try {
+ db = dbf.newDocumentBuilder();
+ db.setEntityResolver(null);
+ d = db.parse(source);
+ } catch (Exception e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ root = (Element)d.getElementsByTagName("a").item(0);
+ assertEquals("foo", ((EntityReference)root.getFirstChild()).getNodeName());
+ }
+
+}
diff --git a/xml/src/test/java/tests/api/javax/xml/parsers/FactoryConfigurationErrorTest.java b/xml/src/test/java/tests/api/javax/xml/parsers/FactoryConfigurationErrorTest.java
new file mode 100644
index 0000000..0b5f230
--- /dev/null
+++ b/xml/src/test/java/tests/api/javax/xml/parsers/FactoryConfigurationErrorTest.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package tests.api.javax.xml.parsers;
+
+import javax.xml.parsers.FactoryConfigurationError;
+
+import junit.framework.TestCase;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+
+@TestTargetClass(FactoryConfigurationError.class)
+public class FactoryConfigurationErrorTest extends TestCase {
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "FactoryConfigurationError",
+ args = {}
+ )
+ public void test_Constructor() {
+ FactoryConfigurationError fce = new FactoryConfigurationError();
+ assertNull(fce.getMessage());
+ assertNull(fce.getLocalizedMessage());
+ assertNull(fce.getCause());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "FactoryConfigurationError",
+ args = {java.lang.Exception.class}
+ )
+ public void test_ConstructorLjava_lang_Exception() {
+ Exception e = new Exception();
+ // case 1: Try to create FactoryConfigurationError
+ // which is based on Exception without parameters.
+ FactoryConfigurationError fce = new FactoryConfigurationError(e);
+ assertNotNull(fce.getMessage());
+ assertNotNull(fce.getLocalizedMessage());
+ assertEquals(e.getCause(), fce.getCause());
+
+ // case 2: Try to create FactoryConfigurationError
+ // which is based on Exception with String parameter.
+ e = new Exception("test message");
+ fce = new FactoryConfigurationError(e);
+ assertEquals(e.toString(), fce.getMessage());
+ assertEquals(e.toString(), fce.getLocalizedMessage());
+ assertEquals(e.getCause(), fce.getCause());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "FactoryConfigurationError",
+ args = {java.lang.Exception.class, java.lang.String.class}
+ )
+ public void test_ConstructorLjava_lang_ExceptionLjava_lang_String() {
+ Exception e = new Exception();
+ // case 1: Try to create FactoryConfigurationError
+ // which is based on Exception without parameters.
+ FactoryConfigurationError fce = new FactoryConfigurationError(e, "msg");
+ assertNotNull(fce.getMessage());
+ assertNotNull(fce.getLocalizedMessage());
+ assertEquals(e.getCause(), fce.getCause());
+
+ // case 2: Try to create FactoryConfigurationError
+ // which is based on Exception with String parameter.
+ e = new Exception("test message");
+ fce = new FactoryConfigurationError(e, "msg");
+ assertEquals("msg", fce.getMessage());
+ assertEquals("msg", fce.getLocalizedMessage());
+ assertEquals(e.getCause(), fce.getCause());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "FactoryConfigurationError",
+ args = {java.lang.String.class}
+ )
+ public void test_ConstructorLjava_lang_String() {
+ FactoryConfigurationError fce = new FactoryConfigurationError("Oops!");
+ assertEquals("Oops!", fce.getMessage());
+ assertEquals("Oops!", fce.getLocalizedMessage());
+ assertNull(fce.getCause());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getException",
+ args = {}
+ )
+ public void test_getException() {
+ FactoryConfigurationError fce = new FactoryConfigurationError();
+ assertNull(fce.getException());
+ fce = new FactoryConfigurationError("test");
+ assertNull(fce.getException());
+ Exception e = new Exception("msg");
+ fce = new FactoryConfigurationError(e);
+ assertEquals(e, fce.getException());
+ NullPointerException npe = new NullPointerException();
+ fce = new FactoryConfigurationError(npe);
+ assertEquals(npe, fce.getException());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getMessage",
+ args = {}
+ )
+ public void test_getMessage() {
+ assertNull(new FactoryConfigurationError().getMessage());
+ assertEquals("msg1",
+ new FactoryConfigurationError("msg1").getMessage());
+ assertEquals(new Exception("msg2").toString(),
+ new FactoryConfigurationError(
+ new Exception("msg2")).getMessage());
+ assertEquals(new NullPointerException().toString(),
+ new FactoryConfigurationError(
+ new NullPointerException()).getMessage());
+ }
+
+}
diff --git a/xml/src/test/java/tests/api/javax/xml/parsers/ParserConfigurationExceptionTest.java b/xml/src/test/java/tests/api/javax/xml/parsers/ParserConfigurationExceptionTest.java
new file mode 100644
index 0000000..63b87a7
--- /dev/null
+++ b/xml/src/test/java/tests/api/javax/xml/parsers/ParserConfigurationExceptionTest.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package tests.api.javax.xml.parsers;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import junit.framework.TestCase;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+
+@TestTargetClass(ParserConfigurationException.class)
+public class ParserConfigurationExceptionTest extends TestCase{
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "ParserConfigurationException",
+ args = {}
+ )
+ public void test_Constructor() {
+ ParserConfigurationException pce = new ParserConfigurationException();
+ assertNull(pce.getMessage());
+ assertNull(pce.getLocalizedMessage());
+ assertNull(pce.getCause());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "ParserConfigurationException",
+ args = {java.lang.String.class}
+ )
+ public void test_ConstructorLjava_lang_String() {
+ ParserConfigurationException pce =
+ new ParserConfigurationException("Oops!");
+ assertEquals("Oops!", pce.getMessage());
+ assertEquals("Oops!", pce.getLocalizedMessage());
+ assertNull(pce.getCause());
+ }
+
+}
diff --git a/xml/src/test/java/tests/api/javax/xml/parsers/SAXParserFactoryTest.java b/xml/src/test/java/tests/api/javax/xml/parsers/SAXParserFactoryTest.java
new file mode 100644
index 0000000..5d41356
--- /dev/null
+++ b/xml/src/test/java/tests/api/javax/xml/parsers/SAXParserFactoryTest.java
@@ -0,0 +1,547 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package tests.api.javax.xml.parsers;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Properties;
+import java.util.Vector;
+
+import javax.xml.parsers.FactoryConfigurationError;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import junit.framework.TestCase;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXNotRecognizedException;
+import org.xml.sax.SAXNotSupportedException;
+import org.xml.sax.helpers.DefaultHandler;
+
+import dalvik.annotation.AndroidOnly;
+import dalvik.annotation.KnownFailure;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargets;
+
+@TestTargetClass(SAXParserFactory.class)
+public class SAXParserFactoryTest extends TestCase {
+
+ SAXParserFactory spf;
+
+ InputStream is1;
+
+ static HashMap<String, String> ns;
+
+ static Vector<String> el;
+
+ static HashMap<String, String> attr;
+
+ public void setUp() throws Exception {
+ spf = SAXParserFactory.newInstance();
+
+ is1 = getClass().getResourceAsStream("/simple.xml");
+
+ ns = new HashMap<String, String>();
+ attr = new HashMap<String, String>();
+ el = new Vector<String>();
+ }
+
+ public void tearDown() throws Exception {
+ is1.close();
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "SAXParserFactory",
+ args = {}
+ )
+ @AndroidOnly("Android SAX implementation is non-validating")
+ public void test_Constructor() {
+ MySAXParserFactory mpf = new MySAXParserFactory();
+ assertTrue(mpf instanceof SAXParserFactory);
+ assertFalse(mpf.isValidating());
+ }
+
+ /**
+ * @tests javax.xml.parsers.SAXParserFactory#getSchema().
+ * TBD getSchema() IS NOT SUPPORTED
+ */
+ /* public void test_getSchema() {
+ assertNull(spf.getSchema());
+ SchemaFactory sf =
+ SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
+ try {
+ Schema schema = sf.newSchema();
+ spf.setSchema(schema);
+ assertNotNull(spf.getSchema());
+ } catch (SAXException sax) {
+ fail("Unexpected exception " + sax.toString());
+ }
+ }
+ */
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "isNamespaceAware",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "setNamespaceAware",
+ args = {boolean.class}
+ )
+ })
+ public void test_setIsNamespaceAware() {
+ spf.setNamespaceAware(true);
+ assertTrue(spf.isNamespaceAware());
+ spf.setNamespaceAware(false);
+ assertFalse(spf.isNamespaceAware());
+ spf.setNamespaceAware(true);
+ assertTrue(spf.isNamespaceAware());
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "isValidating",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.SUFFICIENT,
+ notes = "",
+ method = "setValidating",
+ args = {boolean.class}
+ )
+ })
+ public void test_setIsValidating() {
+ spf.setValidating(true);
+ assertTrue(spf.isValidating());
+ spf.setValidating(false);
+ assertFalse(spf.isValidating());
+ spf.setValidating(true);
+ assertTrue(spf.isValidating());
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "isXIncludeAware",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.SUFFICIENT,
+ notes = "",
+ method = "setXIncludeAware",
+ args = {boolean.class}
+ )
+ })
+ @KnownFailure("Should handle XIncludeAware flag more gracefully")
+ public void test_setIsXIncludeAware() {
+ spf.setXIncludeAware(true);
+ assertTrue(spf.isXIncludeAware());
+ spf.setXIncludeAware(false);
+ assertFalse(spf.isXIncludeAware());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "newInstance",
+ args = {}
+ )
+ public void test_newInstance() {
+ String className = null;
+ try {
+ SAXParserFactory dtf = SAXParserFactory.newInstance();
+ assertNotNull("New Instance of DatatypeFactory is null", dtf);
+
+ className = System.getProperty("javax.xml.parsers.SAXParserFactory");
+
+ System.setProperty("javax.xml.parsers.SAXParserFactory",
+ "org.apache.harmony.xml.parsers.SAXParserFactoryImpl");
+
+ SAXParserFactory spf1 = SAXParserFactory.newInstance();
+ assertTrue(spf1 instanceof org.apache.harmony.xml.parsers.SAXParserFactoryImpl);
+
+ String key = "javax.xml.parsers.SAXParserFactory = org.apache.harmony.xml.parsers.SAXParserFactoryImpl";
+
+ ByteArrayInputStream bis = new ByteArrayInputStream(key.getBytes());
+ Properties prop = System.getProperties();
+ prop.load(bis);
+ SAXParserFactory spf2 = SAXParserFactory.newInstance();
+ assertTrue(spf2 instanceof org.apache.harmony.xml.parsers.SAXParserFactoryImpl);
+
+ System.setProperty("javax.xml.parsers.SAXParserFactory", "");
+ try {
+ SAXParserFactory.newInstance();
+ fail("Expected FactoryConfigurationError was not thrown");
+ } catch (FactoryConfigurationError e) {
+ // expected
+ }
+ } catch (IOException ioe) {
+ fail("Unexpected exception " + ioe.toString());
+ } finally {
+ if (className == null) {
+ System.clearProperty("javax.xml.parsers.SAXParserFactory");
+ } else {
+ System.setProperty("javax.xml.parsers.SAXParserFactory",
+ className);
+ }
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.SUFFICIENT,
+ notes = "SAXException untested; unused on Android",
+ method = "newSAXParser",
+ args = {}
+ )
+ public void test_newSAXParser() {
+ // Ordinary case
+ try {
+ SAXParser sp = spf.newSAXParser();
+ assertTrue(sp instanceof SAXParser);
+ sp.parse(is1, new MyHandler());
+ } catch(Exception e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ // Exception case
+ spf.setValidating(true);
+ try {
+ SAXParser sp = spf.newSAXParser();
+ } catch(ParserConfigurationException e) {
+ // Expected, since Android doesn't have a validating parser.
+ } catch (SAXException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.SUFFICIENT,
+ method = "setFeature",
+ notes = "ParserConfigurationException untested; unused on Android",
+ args = {java.lang.String.class, boolean.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.SUFFICIENT,
+ method = "getFeature",
+ notes = "ParserConfigurationException untested; unused on Android",
+ args = {java.lang.String.class}
+ )
+ })
+ public void test_setFeatureLjava_lang_StringZ() {
+ // We can't verify ParserConfigurationException and
+ // SAXNotSupportedException since these are never
+ // thrown by Android.
+
+ String[] features = {
+ "http://xml.org/sax/features/namespaces",
+ "http://xml.org/sax/features/validation" };
+ for (int i = 0; i < features.length; i++) {
+ try {
+ spf.setFeature(features[i], true);
+ assertTrue(spf.getFeature(features[i]));
+ spf.setFeature(features[i], false);
+ assertFalse(spf.getFeature(features[i]));
+ } catch (ParserConfigurationException pce) {
+ fail("ParserConfigurationException is thrown");
+ } catch (SAXNotRecognizedException snre) {
+ fail("SAXNotRecognizedException is thrown");
+ } catch (SAXNotSupportedException snse) {
+ fail("SAXNotSupportedException is thrown");
+ }
+ }
+
+ try {
+ spf.setFeature("", true);
+ fail("SAXNotRecognizedException is not thrown");
+ } catch (ParserConfigurationException pce) {
+ fail("ParserConfigurationException is thrown");
+ } catch (SAXNotRecognizedException snre) {
+ //expected
+ } catch (SAXNotSupportedException snse) {
+ fail("SAXNotSupportedException is thrown");
+ } catch (NullPointerException npe) {
+ fail("NullPointerException is thrown");
+ }
+
+ try {
+ spf.setFeature("http://xml.org/sax/features/unknown-feature", true);
+ } catch (ParserConfigurationException pce) {
+ fail("ParserConfigurationException is thrown");
+ } catch (SAXNotRecognizedException snre) {
+ fail("SAXNotRecognizedException is thrown");
+ } catch (SAXNotSupportedException snse) {
+ // Acceptable, although this doesn't happen an Android.
+ } catch (NullPointerException npe) {
+ fail("NullPointerException is thrown");
+ }
+
+ try {
+ spf.setFeature(null, true);
+ fail("NullPointerException is not thrown");
+ } catch (ParserConfigurationException pce) {
+ fail("ParserConfigurationException is thrown");
+ } catch (SAXNotRecognizedException snre) {
+ fail("SAXNotRecognizedException is thrown");
+ } catch (SAXNotSupportedException snse) {
+ fail("SAXNotSupportedException is thrown");
+ } catch (NullPointerException npe) {
+ // expected
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setNamespaceAware",
+ args = {boolean.class}
+ )
+ @KnownFailure("Error in namespace feature handling (for ExpatParser)")
+ public void test_setNamespaceAwareZ() {
+
+ spf.setNamespaceAware(true);
+ MyHandler mh = new MyHandler();
+ InputStream is = getClass().getResourceAsStream("/simple_ns.xml");
+ try {
+ spf.newSAXParser().parse(is, mh);
+ } catch(javax.xml.parsers.ParserConfigurationException pce) {
+ fail("ParserConfigurationException was thrown during parsing");
+ } catch(org.xml.sax.SAXException se) {
+ fail("SAXException was thrown during parsing");
+ } catch(IOException ioe) {
+ fail("IOException was thrown during parsing");
+ } finally {
+ try {
+ is.close();
+ } catch(Exception e) {}
+ }
+ spf.setNamespaceAware(false);
+ is = getClass().getResourceAsStream("/simple_ns.xml");
+ try {
+ is = getClass().getResourceAsStream("/simple_ns.xml");
+ spf.newSAXParser().parse(is, mh);
+ } catch(javax.xml.parsers.ParserConfigurationException pce) {
+ fail("ParserConfigurationException was thrown during parsing");
+ } catch(org.xml.sax.SAXException se) {
+ se.printStackTrace();
+ fail("SAXException was thrown during parsing");
+ } catch(IOException ioe) {
+ fail("IOException was thrown during parsing");
+ } finally {
+ try {
+ is.close();
+ } catch(Exception ioee) {}
+ }
+ is = getClass().getResourceAsStream("/simple_ns.xml");
+ try {
+ spf.setNamespaceAware(true);
+ spf.newSAXParser().parse(is, mh);
+ } catch(javax.xml.parsers.ParserConfigurationException pce) {
+ fail("ParserConfigurationException was thrown during parsing");
+ } catch(org.xml.sax.SAXException se) {
+ fail("SAXException was thrown during parsing");
+ } catch(IOException ioe) {
+ fail("IOException was thrown during parsing");
+ } finally {
+ try {
+ is.close();
+ } catch(Exception ioee) {}
+ }
+ }
+
+ /* public void test_setSchemaLjavax_xml_validation_Schema() {
+ SchemaFactory sf =
+ SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
+ try {
+ Schema schema = sf.newSchema();
+ spf.setSchema(schema);
+ assertNotNull(spf.getSchema());
+ } catch (SAXException sax) {
+ fail("Unexpected exception " + sax.toString());
+ }
+ }
+ */
+
+// public void test_setValidatingZ() {
+// MyHandler mh = new MyHandler();
+// InputStream is2 = getClass().getResourceAsStream("/recipe.xml");
+// try {
+// spf.setValidating(true);
+// assertTrue(spf.isValidating());
+// spf.newSAXParser().parse(is2, mh);
+// } catch (org.xml.sax.SAXException se) {
+// fail("SAXException was thrown during parsing");
+// } catch (javax.xml.parsers.ParserConfigurationException pce) {
+// fail("ParserConfigurationException was thrown during parsing");
+// } catch (IOException ioe) {
+// fail("IOException was thrown during parsing");
+// } finally {
+// try {
+// is2.close();
+// } catch(Exception ioee) {}
+// }
+// InputStream is3 = getClass().getResourceAsStream("/recipe1.xml");
+// try {
+// assertTrue(spf.isValidating());
+// spf.newSAXParser().parse(is3, mh);
+// } catch (org.xml.sax.SAXException se) {
+// fail("SAXException was thrown during parsing");
+// } catch (javax.xml.parsers.ParserConfigurationException pce) {
+// fail("ParserConfigurationException was thrown during parsing");
+// } catch (IOException ioe) {
+// fail("IOEXception was thrown during parsing: " + ioe.getMessage());
+// } finally {
+// try {
+// is3.close();
+// } catch(Exception ioee) {}
+// }
+// is2 = getClass().getResourceAsStream("/recipe.xml");
+// try {
+// spf.setValidating(false);
+// assertFalse(spf.isValidating());
+// spf.newSAXParser().parse(is2, mh);
+// } catch (org.xml.sax.SAXException se) {
+// fail("SAXException was thrown during parsing");
+// } catch (javax.xml.parsers.ParserConfigurationException pce) {
+// fail("ParserConfigurationException was thrown during parsing");
+// } catch (IOException ioe) {
+// fail("IOException was thrown during parsing");
+// } finally {
+// try {
+// is2.close();
+// } catch(Exception ioee) {}
+// }
+// is3 = getClass().getResourceAsStream("/recipe1.xml");
+// try {
+// assertFalse(spf.isValidating());
+// spf.newSAXParser().parse(is3, mh);
+// } catch (org.xml.sax.SAXException se) {
+// fail("SAXException was thrown during parsing");
+// } catch (javax.xml.parsers.ParserConfigurationException pce) {
+// fail("ParserConfigurationException was thrown during parsing");
+// } catch (IOException ioe) {
+// fail("IOEXception was thrown during parsing: " + ioe.getMessage());
+// } finally {
+// try {
+// is3.close();
+// } catch(Exception ioee) {}
+// }
+// }
+
+// public void test_setXIncludeAwareZ() {
+// spf.setXIncludeAware(true);
+// MyHandler mh = new MyHandler();
+// InputStream is = getClass().getResourceAsStream("/simple_ns.xml");
+// try {
+// spf.newSAXParser().parse(is, mh);
+// } catch(javax.xml.parsers.ParserConfigurationException pce) {
+// fail("ParserConfigurationException was thrown during parsing");
+// } catch(org.xml.sax.SAXException se) {
+// fail("SAXException was thrown during parsing");
+// } catch(IOException ioe) {
+// fail("IOException was thrown during parsing");
+// } finally {
+// try {
+// is.close();
+// } catch(Exception ioee) {}
+// }
+// spf.setXIncludeAware(false);
+// is = getClass().getResourceAsStream("/simple_ns.xml");
+// try {
+// is = getClass().getResourceAsStream("/simple_ns.xml");
+// spf.newSAXParser().parse(is, mh);
+// } catch(javax.xml.parsers.ParserConfigurationException pce) {
+// fail("ParserConfigurationException was thrown during parsing");
+// } catch(org.xml.sax.SAXException se) {
+// fail("SAXException was thrown during parsing");
+// } catch(IOException ioe) {
+// fail("IOException was thrown during parsing");
+// } finally {
+// try {
+// is.close();
+// } catch(Exception ioee) {}
+// }
+// is = getClass().getResourceAsStream("/simple_ns.xml");
+// try {
+// spf.setXIncludeAware(true);
+// spf.newSAXParser().parse(is, mh);
+// } catch(javax.xml.parsers.ParserConfigurationException pce) {
+// fail("ParserConfigurationException was thrown during parsing");
+// } catch(org.xml.sax.SAXException se) {
+// fail("SAXException was thrown during parsing");
+// } catch(IOException ioe) {
+// fail("IOException was thrown during parsing");
+// } finally {
+// try {
+// is.close();
+// } catch(Exception ioee) {}
+// }
+// }
+
+ static class MyHandler extends DefaultHandler {
+
+ public void startElement(String uri, String localName, String qName,
+ Attributes atts) {
+
+ el.add(qName);
+ if (!uri.equals(""))
+ ns.put(qName, uri);
+ for (int i = 0; i < atts.getLength(); i++) {
+ attr.put(atts.getQName(i), atts.getValue(i));
+ }
+
+ }
+ }
+
+ class MySAXParserFactory extends SAXParserFactory {
+
+ public MySAXParserFactory() {
+ super();
+ }
+
+ public SAXParser newSAXParser() {
+ return null;
+ }
+
+ public void setFeature(String name, boolean value) throws
+ ParserConfigurationException, SAXNotRecognizedException,
+ SAXNotSupportedException {
+
+ }
+
+ public boolean getFeature(String name) throws
+ ParserConfigurationException, SAXNotRecognizedException,
+ SAXNotSupportedException {
+ return true;
+ }
+
+ }
+
+}
diff --git a/xml/src/test/java/tests/api/javax/xml/parsers/SAXParserTest.java b/xml/src/test/java/tests/api/javax/xml/parsers/SAXParserTest.java
new file mode 100644
index 0000000..4ca0f1f
--- /dev/null
+++ b/xml/src/test/java/tests/api/javax/xml/parsers/SAXParserTest.java
@@ -0,0 +1,1171 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package tests.api.javax.xml.parsers;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.util.HashMap;
+import java.util.Vector;
+
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import junit.framework.TestCase;
+
+import org.xml.sax.HandlerBase;
+import org.xml.sax.InputSource;
+import org.xml.sax.Parser;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXNotRecognizedException;
+import org.xml.sax.SAXNotSupportedException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.ext.LexicalHandler;
+import org.xml.sax.helpers.DefaultHandler;
+
+import tests.api.javax.xml.parsers.SAXParserTestSupport.MyDefaultHandler;
+import tests.api.javax.xml.parsers.SAXParserTestSupport.MyHandler;
+import tests.api.org.xml.sax.support.BrokenInputStream;
+import tests.api.org.xml.sax.support.MethodLogger;
+import tests.api.org.xml.sax.support.MockHandler;
+import dalvik.annotation.KnownFailure;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargets;
+
+@SuppressWarnings("deprecation")
+@TestTargetClass(SAXParser.class)
+public class SAXParserTest extends TestCase {
+
+ private class MockSAXParser extends SAXParser {
+ public MockSAXParser() {
+ super();
+ }
+
+ /*
+ * @see javax.xml.parsers.SAXParser#getParser()
+ */
+ @Override
+ public Parser getParser() throws SAXException {
+ // it is a fake
+ return null;
+ }
+
+ /*
+ * @see javax.xml.parsers.SAXParser#getProperty(java.lang.String)
+ */
+ @Override
+ public Object getProperty(String name) throws SAXNotRecognizedException,
+ SAXNotSupportedException {
+ // it is a fake
+ return null;
+ }
+
+ /*
+ * @see javax.xml.parsers.SAXParser#getXMLReader()
+ */
+ @Override
+ public XMLReader getXMLReader() throws SAXException {
+ // it is a fake
+ return null;
+ }
+
+ /*
+ * @see javax.xml.parsers.SAXParser#isNamespaceAware()
+ */
+ @Override
+ public boolean isNamespaceAware() {
+ // it is a fake
+ return false;
+ }
+
+ /*
+ * @see javax.xml.parsers.SAXParser#isValidating()
+ */
+ @Override
+ public boolean isValidating() {
+ // it is a fake
+ return false;
+ }
+
+ /*
+ * @see javax.xml.parsers.SAXParser#setProperty(java.lang.String,
+ * java.lang.Object)
+ */
+ @Override
+ public void setProperty(String name, Object value) throws
+ SAXNotRecognizedException, SAXNotSupportedException {
+ // it is a fake
+ }
+ }
+
+ private static final String LEXICAL_HANDLER_PROPERTY
+ = "http://xml.org/sax/properties/lexical-handler";
+
+ SAXParserFactory spf;
+
+ SAXParser parser;
+
+ static HashMap<String, String> ns;
+
+ static Vector<String> el;
+
+ static HashMap<String, String> attr;
+
+ SAXParserTestSupport sp = new SAXParserTestSupport();
+
+ File [] list_wf;
+ File [] list_nwf;
+ File [] list_out_dh;
+ File [] list_out_hb;
+
+ boolean validating = false;
+
+ private InputStream getResource(String name) {
+ return this.getClass().getResourceAsStream(name);
+ }
+
+ public SAXParserTest() throws Exception{
+ // we differntiate between a validating and a non validating parser
+ try {
+ SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
+ validating = parser.isValidating();
+ } catch (Exception e) {
+ fail("could not obtain a SAXParser");
+ }
+
+ // nwf = non well formed, wf = well formed
+ list_wf = new File[] {File.createTempFile(
+ SAXParserTestSupport.XML_WF + "staff","xml")};
+ list_nwf = new File[] {File.createTempFile(
+ SAXParserTestSupport.XML_NWF + "staff","xml")};
+
+ copyFile(getResource(SAXParserTestSupport.XML_WF + "staff.xml"),
+ list_wf[0].getAbsolutePath());
+ copyFile(getResource(SAXParserTestSupport.XML_WF + "staff.dtd"),
+ File.createTempFile(SAXParserTestSupport.XML_WF + "staff",
+ "dtd").getAbsolutePath());
+ copyFile(getResource(SAXParserTestSupport.XML_NWF + "staff.xml"),
+ list_nwf[0].getAbsolutePath());
+ copyFile(getResource(SAXParserTestSupport.XML_NWF + "staff.dtd"),
+ File.createTempFile(SAXParserTestSupport.XML_NWF + "staff",
+ "dtd").getAbsolutePath());
+
+ list_out_dh = new File[] {File.createTempFile(
+ SAXParserTestSupport.XML_WF_OUT_DH + "staff", "out")};
+ list_out_hb = new File[] {File.createTempFile(
+ SAXParserTestSupport.XML_WF_OUT_HB + "staff", "out")};
+ copyFile(getResource(SAXParserTestSupport.XML_WF_OUT_HB + "staff.out"),
+ list_out_hb[0].getAbsolutePath());
+ copyFile(getResource(SAXParserTestSupport.XML_WF_OUT_DH + "staff.out"),
+ list_out_dh[0].getAbsolutePath());
+ }
+
+ private void copyFile(InputStream toCopy, String target) throws Exception {
+ new File(target).getParentFile().mkdirs();
+ OutputStream writer = new FileOutputStream(target);
+ byte[] buffer = new byte[512];
+ int i = toCopy.read(buffer);
+ while (i >= 0) {
+ writer.write(buffer,0,i);
+ i = toCopy.read(buffer);
+ }
+ writer.flush();
+ writer.close();
+ toCopy.close();
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ spf = SAXParserFactory.newInstance();
+ parser = spf.newSAXParser();
+ assertNotNull(parser);
+
+ ns = new HashMap<String, String>();
+ attr = new HashMap<String, String>();
+ el = new Vector<String>();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ }
+
+// public static void main(String[] args) throws Exception {
+// SAXParserTest st = new SAXParserTest();
+// st.setUp();
+// st.generateDataFromReferenceImpl();
+//
+// }
+//
+// private void generateDataFromReferenceImpl() {
+// try {
+// for(int i = 0; i < list_wf.length; i++) {
+// MyDefaultHandler dh = new MyDefaultHandler();
+// InputStream is = new FileInputStream(list_wf[i]);
+// parser.parse(is, dh, ParsingSupport.XML_SYSTEM_ID);
+// HashMap refHm = dh.createData();
+//
+// StringBuilder sb = new StringBuilder();
+// for (int j = 0; j < ParsingSupport.KEYS.length; j++) {
+// String key = ParsingSupport.KEYS[j];
+// sb.append(refHm.get(key)).append(
+// ParsingSupport.SEPARATOR_DATA);
+// }
+// FileWriter fw = new FileWriter("/tmp/build_dh"+i+".out");
+// fw.append(sb.toString());
+// fw.close();
+// }
+//
+// for(int i = 0; i < list_nwf.length; i++) {
+// MyHandler hb = new MyHandler();
+// InputStream is = new FileInputStream(list_wf[i]);
+// parser.parse(is, hb, ParsingSupport.XML_SYSTEM_ID);
+// HashMap refHm = hb.createData();
+//
+// StringBuilder sb = new StringBuilder();
+// for (int j = 0; j < ParsingSupport.KEYS.length; j++) {
+// String key = ParsingSupport.KEYS[j];
+// sb.append(refHm.get(key)).append(
+// ParsingSupport.SEPARATOR_DATA);
+// }
+// FileWriter fw = new FileWriter("/tmp/build_hb"+i+".out");
+// fw.append(sb.toString());
+// fw.close();
+// }
+//
+//
+// } catch (Exception e) {
+// e.printStackTrace();
+// }
+// }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "SAXParser",
+ args = {}
+ )
+ public void testSAXParser() {
+ try {
+ new MockSAXParser();
+ } catch (Exception e) {
+ fail("unexpected exception " + e.toString());
+ }
+ }
+
+ /**
+ * @tests javax.xml.parser.SAXParser#getSchema().
+ * TODO getSchema() IS NOT SUPPORTED
+ */
+ /* public void test_getSchema() {
+ assertNull(parser.getSchema());
+ SchemaFactory sf =
+ SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
+ try {
+ Schema schema = sf.newSchema();
+ spf.setSchema(schema);
+ assertNotNull(spf.newSAXParser().getSchema());
+ } catch (ParserConfigurationException pce) {
+ fail("Unexpected ParserConfigurationException " + pce.toString());
+ } catch (SAXException sax) {
+ fail("Unexpected SAXException " + sax.toString());
+ }
+ }
+ */
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "isNamespaceAware",
+ args = {}
+ )
+ public void testIsNamespaceAware() {
+ try {
+ spf.setNamespaceAware(true);
+ assertTrue(spf.newSAXParser().isNamespaceAware());
+ spf.setNamespaceAware(false);
+ assertFalse(spf.newSAXParser().isNamespaceAware());
+ } catch (Exception e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.SUFFICIENT,
+ notes = "No validating parser in Android, hence not tested",
+ method = "isValidating",
+ args = {}
+ )
+ public void testIsValidating() {
+ try {
+ spf.setValidating(false);
+ assertFalse(spf.newSAXParser().isValidating());
+ } catch (Exception e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.SUFFICIENT,
+ notes = "No XInclude-aware parser in Android, hence not tested",
+ method = "isXIncludeAware",
+ args = {}
+ )
+ @KnownFailure("Should handle XIncludeAware flag more gracefully")
+ public void testIsXIncludeAware() {
+ try {
+ spf.setXIncludeAware(false);
+ assertFalse(spf.newSAXParser().isXIncludeAware());
+ } catch (Exception e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+ }
+
+ /**
+ * @test javax.xml.parsers.SAXParser#parse(java.io.File,
+ * org.xml.sax.helpers.DefaultHandler)
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Doesn't verify positive functionality properly; not all exceptions are verified.",
+ method = "parse",
+ args = {java.io.File.class, org.xml.sax.helpers.DefaultHandler.class}
+ )
+ public void _test_parseLjava_io_FileLorg_xml_sax_helpers_DefaultHandler()
+ throws Exception {
+
+ for(int i = 0; i < list_wf.length; i++) {
+ HashMap<String, String> hm =
+ new SAXParserTestSupport().readFile(list_out_dh[i].getPath());
+ MyDefaultHandler dh = new MyDefaultHandler();
+ parser.parse(list_wf[i], dh);
+ assertTrue(SAXParserTestSupport.equalsMaps(hm, dh.createData()));
+ }
+
+ for(int i = 0; i < list_nwf.length; i++) {
+ try {
+ MyDefaultHandler dh = new MyDefaultHandler();
+ parser.parse(list_nwf[i], dh);
+ fail("SAXException is not thrown");
+ } catch(org.xml.sax.SAXException se) {
+ //expected
+ }
+ }
+
+ try {
+ MyDefaultHandler dh = new MyDefaultHandler();
+ parser.parse((File) null, dh);
+ fail("java.lang.IllegalArgumentException is not thrown");
+ } catch(java.lang.IllegalArgumentException iae) {
+ //expected
+ }
+
+ try {
+ parser.parse(list_wf[0], (DefaultHandler) null);
+ } catch(java.lang.IllegalArgumentException iae) {
+ fail("java.lang.IllegalArgumentException is thrown");
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.SUFFICIENT,
+ notes = "Sufficient while XML parser situation is still unclear",
+ method = "parse",
+ args = {java.io.File.class, org.xml.sax.HandlerBase.class}
+ )
+ public void testParseFileHandlerBase() {
+ for(int i = 0; i < list_wf.length; i++) {
+ try {
+ HashMap<String, String> hm = sp.readFile(
+ list_out_hb[i].getPath());
+ MyHandler dh = new MyHandler();
+ parser.parse(list_wf[i], dh);
+ assertTrue(SAXParserTestSupport.equalsMaps(hm,
+ dh.createData()));
+ } catch (IOException ioe) {
+ fail("Unexpected IOException " + ioe.toString());
+ } catch (SAXException sax) {
+ fail("Unexpected SAXException " + sax.toString());
+ }
+ }
+
+ for(int i = 0; i < list_nwf.length; i++) {
+ try {
+ MyHandler dh = new MyHandler();
+ parser.parse(list_nwf[i], dh);
+ fail("SAXException is not thrown");
+ } catch(org.xml.sax.SAXException se) {
+ //expected
+ } catch (FileNotFoundException fne) {
+ fail("Unexpected FileNotFoundException " + fne.toString());
+ } catch (IOException ioe) {
+ fail("Unexpected IOException " + ioe.toString());
+ }
+ }
+
+ try {
+ MyHandler dh = new MyHandler();
+ parser.parse((File) null, dh);
+ fail("java.lang.IllegalArgumentException is not thrown");
+ } catch(java.lang.IllegalArgumentException iae) {
+ //expected
+ } catch (IOException ioe) {
+ fail("Unexpected IOException " + ioe.toString());
+ } catch(SAXException sax) {
+ fail("Unexpected SAXException " + sax.toString());
+ }
+
+ try {
+ parser.parse(list_wf[0], (HandlerBase) null);
+ } catch(java.lang.IllegalArgumentException iae) {
+ fail("java.lang.IllegalArgumentException is thrown");
+ } catch (FileNotFoundException fne) {
+ fail("Unexpected FileNotFoundException " + fne.toString());
+ } catch(IOException ioe) {
+ fail("Unexpected IOException " + ioe.toString());
+ } catch(SAXException sax) {
+ fail("Unexpected SAXException " + sax.toString());
+ }
+ }
+
+ /**
+ * @test javax.xml.parsers.SAXParser#parse(org.xml.sax.InputSource,
+ * org.xml.sax.helpers.DefaultHandler)
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Doesn't verify IOException.",
+ method = "parse",
+ args = {org.xml.sax.InputSource.class, org.xml.sax.helpers.DefaultHandler.class}
+ )
+
+ public void _test_parseLorg_xml_sax_InputSourceLorg_xml_sax_helpers_DefaultHandler()
+ throws Exception {
+
+ for(int i = 0; i < list_wf.length; i++) {
+
+ HashMap<String, String> hm = new SAXParserTestSupport().readFile(
+ list_out_dh[i].getPath());
+ MyDefaultHandler dh = new MyDefaultHandler();
+ InputSource is = new InputSource(new FileInputStream(list_wf[i]));
+ parser.parse(is, dh);
+ assertTrue(SAXParserTestSupport.equalsMaps(hm, dh.createData()));
+ }
+
+ for(int i = 0; i < list_nwf.length; i++) {
+ try {
+ MyDefaultHandler dh = new MyDefaultHandler();
+ InputSource is = new InputSource(
+ new FileInputStream(list_nwf[i]));
+ parser.parse(is, dh);
+ fail("SAXException is not thrown");
+ } catch(org.xml.sax.SAXException se) {
+ //expected
+ }
+ }
+
+ try {
+ MyDefaultHandler dh = new MyDefaultHandler();
+ parser.parse((InputSource) null, dh);
+ fail("java.lang.IllegalArgumentException is not thrown");
+ } catch(java.lang.IllegalArgumentException iae) {
+ //expected
+ }
+
+ try {
+ InputSource is = new InputSource(new FileInputStream(list_wf[0]));
+ parser.parse(is, (DefaultHandler) null);
+ } catch(java.lang.IllegalArgumentException iae) {
+ fail("java.lang.IllegalArgumentException is thrown");
+ }
+
+ try {
+ InputSource is = new InputSource(new BrokenInputStream(new FileInputStream(list_wf[0]), 10));
+ parser.parse(is, (DefaultHandler) null);
+ fail("IOException expected");
+ } catch(IOException e) {
+ // Expected
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.SUFFICIENT,
+ notes = "Sufficient while XML parser situation is still unclear",
+ method = "parse",
+ args = {org.xml.sax.InputSource.class, org.xml.sax.HandlerBase.class}
+ )
+ public void testParseInputSourceHandlerBase() {
+ for(int i = 0; i < list_wf.length; i++) {
+ try {
+ HashMap<String, String> hm = sp.readFile(
+ list_out_hb[i].getPath());
+ MyHandler dh = new MyHandler();
+ InputSource is = new InputSource(new FileInputStream(list_wf[i]));
+ parser.parse(is, dh);
+ assertTrue(SAXParserTestSupport.equalsMaps(hm,
+ dh.createData()));
+ } catch (IOException ioe) {
+ fail("Unexpected IOException " + ioe.toString());
+ } catch (SAXException sax) {
+ fail("Unexpected SAXException " + sax.toString());
+ }
+ }
+
+ for(int i = 0; i < list_nwf.length; i++) {
+ try {
+ MyHandler dh = new MyHandler();
+ InputSource is = new InputSource(new FileInputStream(list_nwf[i]));
+ parser.parse(is, dh);
+ fail("SAXException is not thrown");
+ } catch(org.xml.sax.SAXException se) {
+ //expected
+ } catch (FileNotFoundException fne) {
+ fail("Unexpected FileNotFoundException " + fne.toString());
+ } catch (IOException ioe) {
+ fail("Unexpected IOException " + ioe.toString());
+ }
+ }
+
+ try {
+ MyHandler dh = new MyHandler();
+ parser.parse((InputSource) null, dh);
+ fail("java.lang.IllegalArgumentException is not thrown");
+ } catch(java.lang.IllegalArgumentException iae) {
+ //expected
+ } catch (IOException ioe) {
+ fail("Unexpected IOException " + ioe.toString());
+ } catch(SAXException sax) {
+ fail("Unexpected SAXException " + sax.toString());
+ }
+
+ try {
+ InputSource is = new InputSource(new FileInputStream(list_wf[0]));
+ parser.parse(is, (HandlerBase) null);
+ } catch(java.lang.IllegalArgumentException iae) {
+ fail("java.lang.IllegalArgumentException is thrown");
+ } catch (FileNotFoundException fne) {
+ fail("Unexpected FileNotFoundException " + fne.toString());
+ } catch(IOException ioe) {
+ fail("Unexpected IOException " + ioe.toString());
+ } catch(SAXException sax) {
+ fail("Unexpected SAXException " + sax.toString());
+ }
+
+ // Reader case
+ try {
+ InputSource is = new InputSource(new InputStreamReader(
+ new FileInputStream(list_wf[0])));
+ parser.parse(is, (HandlerBase) null);
+ } catch(java.lang.IllegalArgumentException iae) {
+ fail("java.lang.IllegalArgumentException is thrown");
+ } catch (FileNotFoundException fne) {
+ fail("Unexpected FileNotFoundException " + fne.toString());
+ } catch(IOException ioe) {
+ fail("Unexpected IOException " + ioe.toString());
+ } catch(SAXException sax) {
+ fail("Unexpected SAXException " + sax.toString());
+ }
+
+ // SystemID case
+ try {
+ InputSource is = new InputSource(list_wf[0].toURI().toString());
+ parser.parse(is, (HandlerBase) null);
+ } catch(java.lang.IllegalArgumentException iae) {
+ fail("java.lang.IllegalArgumentException is thrown");
+ } catch (FileNotFoundException fne) {
+ fail("Unexpected FileNotFoundException " + fne.toString());
+ } catch(IOException ioe) {
+ fail("Unexpected IOException " + ioe.toString());
+ } catch(SAXException sax) {
+ fail("Unexpected SAXException " + sax.toString());
+ }
+
+ // Inject IOException
+ try {
+ InputStream is = new BrokenInputStream(
+ new FileInputStream(list_wf[0]), 10);
+ parser.parse(is, (HandlerBase) null,
+ SAXParserTestSupport.XML_SYSTEM_ID);
+ fail("IOException expected");
+ } catch(IOException e) {
+ // Expected
+ } catch (Exception e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+ }
+
+ /**
+ * @test javax.xml.parsers.SAXParser#parse(java.io.InputStream,
+ * org.xml.sax.helpers.DefaultHandler)
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Doesn't verify IOException.",
+ method = "parse",
+ args = {java.io.InputStream.class, org.xml.sax.helpers.DefaultHandler.class}
+ )
+ public void _test_parseLjava_io_InputStreamLorg_xml_sax_helpers_DefaultHandler()
+ throws Exception {
+
+ for(int i = 0; i < list_wf.length; i++) {
+
+ HashMap<String, String> hm = new SAXParserTestSupport().readFile(
+ list_out_dh[i].getPath());
+ MyDefaultHandler dh = new MyDefaultHandler();
+ InputStream is = new FileInputStream(list_wf[i]);
+ parser.parse(is, dh);
+ assertTrue(SAXParserTestSupport.equalsMaps(hm, dh.createData()));
+ }
+
+ for(int i = 0; i < list_nwf.length; i++) {
+ try {
+ MyDefaultHandler dh = new MyDefaultHandler();
+ InputStream is = new FileInputStream(list_nwf[i]);
+ parser.parse(is, dh);
+ fail("SAXException is not thrown");
+ } catch(org.xml.sax.SAXException se) {
+ //expected
+ }
+ }
+
+ try {
+ MyDefaultHandler dh = new MyDefaultHandler();
+ parser.parse((InputStream) null, dh);
+ fail("java.lang.IllegalArgumentException is not thrown");
+ } catch(java.lang.IllegalArgumentException iae) {
+ //expected
+ }
+
+ try {
+ InputStream is = new FileInputStream(list_wf[0]);
+ parser.parse(is, (DefaultHandler) null);
+ } catch(java.lang.IllegalArgumentException iae) {
+ fail("java.lang.IllegalArgumentException is thrown");
+ }
+ }
+
+ /**
+ * @test javax.xml.parsers.SAXParser#parse(java.io.InputStream,
+ * org.xml.sax.helpers.DefaultHandler, java.lang.String)
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Doesn't verify IOException.",
+ method = "parse",
+ args = {java.io.InputStream.class, org.xml.sax.helpers.DefaultHandler.class, java.lang.String.class}
+ )
+ public void _test_parseLjava_io_InputStreamLorg_xml_sax_helpers_DefaultHandlerLjava_lang_String() {
+ for(int i = 0; i < list_wf.length; i++) {
+ try {
+ HashMap<String, String> hm = sp.readFile(
+ list_out_hb[i].getPath());
+ MyDefaultHandler dh = new MyDefaultHandler();
+ InputStream is = new FileInputStream(list_wf[i]);
+ parser.parse(is, dh, SAXParserTestSupport.XML_SYSTEM_ID);
+ assertTrue(SAXParserTestSupport.equalsMaps(hm,
+ dh.createData()));
+ } catch (IOException ioe) {
+ fail("Unexpected IOException " + ioe.toString());
+ } catch (SAXException sax) {
+ fail("Unexpected SAXException " + sax.toString());
+ }
+ }
+
+ for(int i = 0; i < list_nwf.length; i++) {
+ try {
+ MyDefaultHandler dh = new MyDefaultHandler();
+ InputStream is = new FileInputStream(list_nwf[i]);
+ parser.parse(is, dh, SAXParserTestSupport.XML_SYSTEM_ID);
+ fail("SAXException is not thrown");
+ } catch(org.xml.sax.SAXException se) {
+ //expected
+ } catch (FileNotFoundException fne) {
+ fail("Unexpected FileNotFoundException " + fne.toString());
+ } catch (IOException ioe) {
+ fail("Unexpected IOException " + ioe.toString());
+ }
+ }
+
+ try {
+ MyDefaultHandler dh = new MyDefaultHandler();
+ parser.parse((InputStream) null, dh,
+ SAXParserTestSupport.XML_SYSTEM_ID);
+ fail("java.lang.IllegalArgumentException is not thrown");
+ } catch(java.lang.IllegalArgumentException iae) {
+ //expected
+ } catch (IOException ioe) {
+ fail("Unexpected IOException " + ioe.toString());
+ } catch(SAXException sax) {
+ fail("Unexpected SAXException " + sax.toString());
+ }
+
+ try {
+ InputStream is = new FileInputStream(list_wf[0]);
+ parser.parse(is, (DefaultHandler) null,
+ SAXParserTestSupport.XML_SYSTEM_ID);
+ } catch(java.lang.IllegalArgumentException iae) {
+ fail("java.lang.IllegalArgumentException is thrown");
+ } catch (FileNotFoundException fne) {
+ fail("Unexpected FileNotFoundException " + fne.toString());
+ } catch(IOException ioe) {
+ fail("Unexpected IOException " + ioe.toString());
+ } catch(SAXException sax) {
+ fail("Unexpected SAXException " + sax.toString());
+ }
+//
+// for(int i = 0; i < list_wf.length; i++) {
+//
+// HashMap<String, String> hm = new SAXParserTestSupport().readFile(
+// list_out_dh[i].getPath());
+// MyDefaultHandler dh = new MyDefaultHandler();
+// InputStream is = new FileInputStream(list_wf[i]);
+// parser.parse(is, dh, SAXParserTestSupport.XML_SYSTEM_ID);
+// assertTrue(SAXParserTestSupport.equalsMaps(hm, dh.createData()));
+// }
+//
+// for(int i = 0; i < list_nwf.length; i++) {
+// try {
+// MyDefaultHandler dh = new MyDefaultHandler();
+// InputStream is = new FileInputStream(list_nwf[i]);
+// parser.parse(is, dh, SAXParserTestSupport.XML_SYSTEM_ID);
+// fail("SAXException is not thrown");
+// } catch(org.xml.sax.SAXException se) {
+// //expected
+// }
+// }
+//
+// try {
+// MyDefaultHandler dh = new MyDefaultHandler();
+// parser.parse((InputStream) null, dh,
+// SAXParserTestSupport.XML_SYSTEM_ID);
+// fail("java.lang.IllegalArgumentException is not thrown");
+// } catch(java.lang.IllegalArgumentException iae) {
+// //expected
+// }
+//
+// try {
+// InputStream is = new FileInputStream(list_wf[0]);
+// parser.parse(is, (DefaultHandler) null,
+// SAXParserTestSupport.XML_SYSTEM_ID);
+// } catch(java.lang.IllegalArgumentException iae) {
+// fail("java.lang.IllegalArgumentException is thrown");
+// }
+//
+// // TODO commented out since our parser is nonvalidating and thus never
+// // tries to load staff.dtd in "/" ... and therefore never can fail with
+// // an IOException
+// /*try {
+// MyDefaultHandler dh = new MyDefaultHandler();
+// InputStream is = new FileInputStream(list_wf[0]);
+// parser.parse(is, dh, "/");
+// fail("Expected IOException was not thrown");
+// } catch(IOException ioe) {
+// // expected
+// }*/
+ }
+
+ @TestTargetNew(
+ level = TestLevel.SUFFICIENT,
+ notes = "Sufficient while XML parser situation is still unclear",
+ method = "parse",
+ args = {java.io.InputStream.class, org.xml.sax.HandlerBase.class}
+ )
+ public void testParseInputStreamHandlerBase() {
+ for(int i = 0; i < list_wf.length; i++) {
+ try {
+ HashMap<String, String> hm = sp.readFile(
+ list_out_hb[i].getPath());
+ MyHandler dh = new MyHandler();
+ InputStream is = new FileInputStream(list_wf[i]);
+ parser.parse(is, dh);
+ assertTrue(SAXParserTestSupport.equalsMaps(hm,
+ dh.createData()));
+ } catch (IOException ioe) {
+ fail("Unexpected IOException " + ioe.toString());
+ } catch (SAXException sax) {
+ fail("Unexpected SAXException " + sax.toString());
+ }
+ }
+
+ for(int i = 0; i < list_nwf.length; i++) {
+ try {
+ MyHandler dh = new MyHandler();
+ InputStream is = new FileInputStream(list_nwf[i]);
+ parser.parse(is, dh);
+ fail("SAXException is not thrown");
+ } catch(org.xml.sax.SAXException se) {
+ //expected
+ } catch (FileNotFoundException fne) {
+ fail("Unexpected FileNotFoundException " + fne.toString());
+ } catch (IOException ioe) {
+ fail("Unexpected IOException " + ioe.toString());
+ }
+ }
+
+ try {
+ MyHandler dh = new MyHandler();
+ parser.parse((InputStream) null, dh);
+ fail("java.lang.IllegalArgumentException is not thrown");
+ } catch(java.lang.IllegalArgumentException iae) {
+ //expected
+ } catch (IOException ioe) {
+ fail("Unexpected IOException " + ioe.toString());
+ } catch(SAXException sax) {
+ fail("Unexpected SAXException " + sax.toString());
+ }
+
+ try {
+ InputStream is = new FileInputStream(list_wf[0]);
+ parser.parse(is, (HandlerBase) null);
+ } catch(java.lang.IllegalArgumentException iae) {
+ fail("java.lang.IllegalArgumentException is thrown");
+ } catch (FileNotFoundException fne) {
+ fail("Unexpected FileNotFoundException " + fne.toString());
+ } catch(IOException ioe) {
+ fail("Unexpected IOException " + ioe.toString());
+ } catch(SAXException sax) {
+ fail("Unexpected SAXException " + sax.toString());
+ }
+
+ // Inject IOException
+ try {
+ InputStream is = new BrokenInputStream(
+ new FileInputStream(list_wf[0]), 10);
+ parser.parse(is, (HandlerBase) null);
+ fail("IOException expected");
+ } catch(IOException e) {
+ // Expected
+ } catch (Exception e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.SUFFICIENT,
+ notes = "Sufficient while XML parser situation is still unclear",
+ method = "parse",
+ args = {java.io.InputStream.class, org.xml.sax.HandlerBase.class, java.lang.String.class}
+ )
+ public void testParseInputStreamHandlerBaseString() {
+ for(int i = 0; i < list_wf.length; i++) {
+ try {
+ HashMap<String, String> hm = sp.readFile(
+ list_out_hb[i].getPath());
+ MyHandler dh = new MyHandler();
+ InputStream is = new FileInputStream(list_wf[i]);
+ parser.parse(is, dh, SAXParserTestSupport.XML_SYSTEM_ID);
+ assertTrue(SAXParserTestSupport.equalsMaps(hm,
+ dh.createData()));
+ } catch (IOException ioe) {
+ fail("Unexpected IOException " + ioe.toString());
+ } catch (SAXException sax) {
+ fail("Unexpected SAXException " + sax.toString());
+ }
+ }
+
+ for(int i = 0; i < list_nwf.length; i++) {
+ try {
+ MyHandler dh = new MyHandler();
+ InputStream is = new FileInputStream(list_nwf[i]);
+ parser.parse(is, dh, SAXParserTestSupport.XML_SYSTEM_ID);
+ fail("SAXException is not thrown");
+ } catch(org.xml.sax.SAXException se) {
+ //expected
+ } catch (FileNotFoundException fne) {
+ fail("Unexpected FileNotFoundException " + fne.toString());
+ } catch (IOException ioe) {
+ fail("Unexpected IOException " + ioe.toString());
+ }
+ }
+
+ try {
+ MyHandler dh = new MyHandler();
+ parser.parse((InputStream) null, dh,
+ SAXParserTestSupport.XML_SYSTEM_ID);
+ fail("java.lang.IllegalArgumentException is not thrown");
+ } catch(java.lang.IllegalArgumentException iae) {
+ //expected
+ } catch (IOException ioe) {
+ fail("Unexpected IOException " + ioe.toString());
+ } catch(SAXException sax) {
+ fail("Unexpected SAXException " + sax.toString());
+ }
+
+ try {
+ InputStream is = new FileInputStream(list_wf[0]);
+ parser.parse(is, (HandlerBase) null,
+ SAXParserTestSupport.XML_SYSTEM_ID);
+ } catch(java.lang.IllegalArgumentException iae) {
+ fail("java.lang.IllegalArgumentException is thrown");
+ } catch (FileNotFoundException fne) {
+ fail("Unexpected FileNotFoundException " + fne.toString());
+ } catch(IOException ioe) {
+ fail("Unexpected IOException " + ioe.toString());
+ } catch(SAXException sax) {
+ fail("Unexpected SAXException " + sax.toString());
+ }
+
+ // Inject IOException
+ try {
+ InputStream is = new BrokenInputStream(
+ new FileInputStream(list_wf[0]), 10);
+ parser.parse(is, (HandlerBase) null,
+ SAXParserTestSupport.XML_SYSTEM_ID);
+ fail("IOException expected");
+ } catch(IOException e) {
+ // Expected
+ } catch (Exception e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+ }
+
+ /**
+ * @test javax.xml.parsers.SAXParser#parse(java.lang.String,
+ * org.xml.sax.helpers.DefaultHandler)
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Doesn't verify IOException.",
+ method = "parse",
+ args = {java.lang.String.class, org.xml.sax.helpers.DefaultHandler.class}
+ )
+ public void _test_parseLjava_lang_StringLorg_xml_sax_helpers_DefaultHandler()
+ throws Exception {
+
+ for(int i = 0; i < list_wf.length; i++) {
+
+ HashMap<String, String> hm = new SAXParserTestSupport().readFile(
+ list_out_dh[i].getPath());
+ MyDefaultHandler dh = new MyDefaultHandler();
+ parser.parse(list_wf[i].getPath(), dh);
+ assertTrue(SAXParserTestSupport.equalsMaps(hm, dh.createData()));
+ }
+
+ for(int i = 0; i < list_nwf.length; i++) {
+ try {
+ MyDefaultHandler dh = new MyDefaultHandler();
+ parser.parse(list_nwf[i].getPath(), dh);
+ fail("SAXException is not thrown");
+ } catch(org.xml.sax.SAXException se) {
+ //expected
+ }
+ }
+
+ try {
+ MyDefaultHandler dh = new MyDefaultHandler();
+ parser.parse((String) null, dh);
+ fail("java.lang.IllegalArgumentException is not thrown");
+ } catch(java.lang.IllegalArgumentException iae) {
+ //expected
+ }
+
+ try {
+ parser.parse(list_wf[0].getPath(), (DefaultHandler) null);
+ } catch(java.lang.IllegalArgumentException iae) {
+ fail("java.lang.IllegalArgumentException is thrown");
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.SUFFICIENT,
+ notes = "Sufficient while XML parser situation is still unclear",
+ method = "parse",
+ args = {java.lang.String.class, org.xml.sax.HandlerBase.class}
+ )
+ public void testParseStringHandlerBase() {
+ for(int i = 0; i < list_wf.length; i++) {
+ try {
+ HashMap<String, String> hm = sp.readFile(
+ list_out_hb[i].getPath());
+ MyHandler dh = new MyHandler();
+ parser.parse(list_wf[i].toURI().toString(), dh);
+ assertTrue(SAXParserTestSupport.equalsMaps(hm,
+ dh.createData()));
+ } catch (IOException ioe) {
+ fail("Unexpected IOException " + ioe.toString());
+ } catch (SAXException sax) {
+ fail("Unexpected SAXException " + sax.toString());
+ }
+ }
+
+ for(int i = 0; i < list_nwf.length; i++) {
+ try {
+ MyHandler dh = new MyHandler();
+ parser.parse(list_nwf[i].toURI().toString(), dh);
+ fail("SAXException is not thrown");
+ } catch(org.xml.sax.SAXException se) {
+ //expected
+ } catch (FileNotFoundException fne) {
+ fail("Unexpected FileNotFoundException " + fne.toString());
+ } catch (IOException ioe) {
+ fail("Unexpected IOException " + ioe.toString());
+ }
+ }
+
+ try {
+ MyHandler dh = new MyHandler();
+ parser.parse((String) null, dh);
+ fail("java.lang.IllegalArgumentException is not thrown");
+ } catch(java.lang.IllegalArgumentException iae) {
+ //expected
+ } catch (IOException ioe) {
+ fail("Unexpected IOException " + ioe.toString());
+ } catch(SAXException sax) {
+ fail("Unexpected SAXException " + sax.toString());
+ }
+
+ try {
+ parser.parse(list_wf[0].toURI().toString(), (HandlerBase) null);
+ } catch(java.lang.IllegalArgumentException iae) {
+ fail("java.lang.IllegalArgumentException is thrown");
+ } catch (FileNotFoundException fne) {
+ fail("Unexpected FileNotFoundException " + fne.toString());
+ } catch(IOException ioe) {
+ fail("Unexpected IOException " + ioe.toString());
+ } catch(SAXException sax) {
+ fail("Unexpected SAXException " + sax.toString());
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "reset",
+ args = { }
+ )
+ @KnownFailure("Android DocumentBuilder should implement reset() properly")
+ public void testReset() {
+ try {
+ spf = SAXParserFactory.newInstance();
+ parser = spf.newSAXParser();
+
+ parser.setProperty(LEXICAL_HANDLER_PROPERTY, new MockHandler(new MethodLogger()));
+ parser.reset();
+ assertEquals(null, parser.getProperty(LEXICAL_HANDLER_PROPERTY));
+ } catch (Exception e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getParser",
+ args = { }
+ )
+ public void testGetParser() {
+ spf = SAXParserFactory.newInstance();
+ try {
+ Parser parser = spf.newSAXParser().getParser();
+ assertNotNull(parser);
+ } catch (Exception e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getXMLReader",
+ args = { }
+ )
+ public void testGetReader() {
+ spf = SAXParserFactory.newInstance();
+ try {
+ XMLReader reader = spf.newSAXParser().getXMLReader();
+ assertNotNull(reader);
+ } catch (Exception e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getProperty",
+ args = { String.class }
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setProperty",
+ args = { String.class, Object.class }
+ )
+ })
+ @KnownFailure("ExpatParser should allow to clear properties")
+ public void testSetGetProperty() {
+ // Ordinary case
+ String validName = "http://xml.org/sax/properties/lexical-handler";
+ LexicalHandler validValue = new MockHandler(new MethodLogger());
+
+ try {
+ SAXParser parser = spf.newSAXParser();
+ parser.setProperty(validName, validValue);
+ assertEquals(validValue, parser.getProperty(validName));
+
+ parser.setProperty(validName, null);
+ assertEquals(null, parser.getProperty(validName));
+ } catch (Exception e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ // Unsupported property
+ try {
+ SAXParser parser = spf.newSAXParser();
+ parser.setProperty("foo", "bar");
+ fail("SAXNotRecognizedException expected");
+ } catch (SAXNotRecognizedException e) {
+ // Expected
+ } catch (Exception e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ try {
+ SAXParser parser = spf.newSAXParser();
+ parser.getProperty("foo");
+ fail("SAXNotRecognizedException expected");
+ } catch (SAXNotRecognizedException e) {
+ // Expected
+ } catch (Exception e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ // No name case
+ try {
+ SAXParser parser = spf.newSAXParser();
+ parser.setProperty(null, "bar");
+ fail("NullPointerException expected");
+ } catch (NullPointerException e) {
+ // Expected
+ } catch (Exception e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ try {
+ SAXParser parser = spf.newSAXParser();
+ parser.getProperty(null);
+ fail("NullPointerException expected");
+ } catch (NullPointerException e) {
+ // Expected
+ } catch (Exception e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+ }
+
+}
+
diff --git a/xml/src/test/java/tests/api/javax/xml/parsers/SAXParserTestSupport.java b/xml/src/test/java/tests/api/javax/xml/parsers/SAXParserTestSupport.java
new file mode 100644
index 0000000..bc5e6a1
--- /dev/null
+++ b/xml/src/test/java/tests/api/javax/xml/parsers/SAXParserTestSupport.java
@@ -0,0 +1,492 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.api.javax.xml.parsers;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.HandlerBase;
+import org.xml.sax.InputSource;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.helpers.DefaultHandler;
+
+/**
+ * Support for SAXParserTest. Shares the element keys used in the golden files.
+ * Compares the result of the parser with golden data.
+ * Contains the handler classes used to track the output of the parser.
+ */
+class SAXParserTestSupport {
+
+ public static final char SEPARATOR_ELEMENT = '^';
+ public static final char SEPARATOR_STRING = '$';
+ public static final char SEPARATOR_DATA = '#';
+
+ public static final String XML_WF = "/wf/";
+ public static final String XML_NWF = "/nwf/";
+
+ public static final String XML_WF_OUT_DH = "/out_dh/";
+ public static final String XML_WF_OUT_HB = "/out_hb/";
+
+ public static final String XML_SYSTEM_ID = "." + "/systemid/";
+
+ public static final String KEY_IS_START_DOC = "isEndDocument";
+ public static final String KEY_IS_END_DOC = "isStartDocument";
+ public static final String KEY_TEXT = "text";
+ public static final String KEY_ERROR = "error";
+ public static final String KEY_FATAL_ERROR = "fatalError";
+ public static final String KEY_WARNING = "warning";
+ public static final String KEY_END_ELEMENT = "endEement";
+ public static final String KEY_END_PREFIX_MAPPING = "endPrefixMapping";
+ public static final String KEY_IGNORABLE_WHITE_SPACE =
+ "ignorableWhitespace";
+ public static final String KEY_NOTATION_DECL = "notationDecl";
+ public static final String KEY_PROCESSING_INSTRUCTION =
+ "processingInstruction";
+ public static final String KEY_RESOLVE_ENTITY = "resolveEntity";
+ public static final String KEY_DOCUMENT_LOCATORS = "documentLocators";
+ public static final String KEY_SKIPPED_ENTITY = "skippedEntity";
+ public static final String KEY_START_ELEMENT = "startElement";
+ public static final String KEY_START_PREFIX_MAPPING = "startPrefixMapping";
+ public static final String KEY_UNPARSED_ENTITY_DECL = "unparsedEntityDecl";
+
+ static String [] KEYS = {KEY_IS_START_DOC, KEY_IS_END_DOC, KEY_TEXT,
+ KEY_ERROR, KEY_FATAL_ERROR, KEY_WARNING, KEY_END_ELEMENT,
+ KEY_END_PREFIX_MAPPING, KEY_PROCESSING_INSTRUCTION,
+ KEY_SKIPPED_ENTITY, KEY_START_ELEMENT,
+ KEY_START_PREFIX_MAPPING};
+
+ static {
+ String tmp = System.getProperty("java.io.tmpdir", ".");
+
+ new File(tmp).mkdirs();
+ new File(tmp, XML_WF).mkdirs();
+ new File(tmp, XML_NWF).mkdirs();
+ new File(tmp, XML_WF_OUT_DH).mkdirs();
+ new File(tmp, XML_WF_OUT_HB).mkdirs();
+ }
+
+ /**
+ * Initialize the SAXParserTest reference by filling in the data from the
+ * file passed to the method. This will be the reference to compare
+ * against with the output of the parser.
+ */
+ public HashMap<String, String> readFile(String fileName) {
+ HashMap<String, String> storage = new HashMap<String, String>();
+ try {
+
+ InputStream is = new FileInputStream(fileName);
+
+ int c = is.read();
+
+ StringBuffer str = new StringBuffer();
+ int i = 0;
+ while(c != -1) {
+ if((char)c == SEPARATOR_DATA) {
+ // if(str.length() > 0) {
+ if(i < KEYS.length) {
+ storage.put(KEYS[i], str.toString());
+ // System.out.println(str.toString());
+ str.setLength(0);
+ i++;
+ }
+ // }
+ } else {
+ str.append((char)c);
+ }
+ try {
+ c = is.read();
+ } catch (Exception e) {
+ c = -1;
+ }
+ }
+ try {
+ is.close();
+ } catch (IOException e) {
+ }
+
+ } catch(IOException ioe) {
+ System.out.println("IOException during processing the file: "
+ + fileName);
+ }
+ return storage;
+ }
+
+ /**
+ * Compares the content of two HashMaps. One map should be the reference
+ * containing the correct string for each xml document element and the other
+ * should contain the elements filled with output from the parser.
+ *
+ * @param original the reference
+ * @param result the result of the parser
+ * @return true if they're equal.
+ */
+ public static boolean equalsMaps(HashMap<String, String> original,
+ HashMap<String, String> result) {
+
+ if(original == null && result == null) {
+ return true;
+ } else {
+ if(original.size() != result.size()) return false;
+
+ for(int i = 0; i < KEYS.length; i++) {
+ if(!original.get(KEYS[i]).equals(result.get(KEYS[i]))) {
+ System.out.println("for "+KEYS[i]+": original:" +
+ original.get(KEYS[i]));
+ System.out.println();
+ System.out.println(" result:" + result.get(KEYS[i]));
+ System.out.println();
+ return false;
+ }
+ }
+ return true;
+ }
+ }
+
+ static class MyDefaultHandler extends DefaultHandler {
+
+ public StringBuffer data_isEndDocument = new StringBuffer();
+ public StringBuffer data_isStartDocument = new StringBuffer();
+ public StringBuffer data_text = new StringBuffer();
+ public StringBuffer data_error = new StringBuffer();
+ public StringBuffer data_fatalError = new StringBuffer();
+ public StringBuffer data_warning = new StringBuffer();
+ public StringBuffer data_endElement = new StringBuffer();
+ public StringBuffer data_endPrefixMapping = new StringBuffer();
+ public StringBuffer data_processingInstruction = new StringBuffer();
+ public StringBuffer data_skippedEntity = new StringBuffer();
+ public StringBuffer data_startElement = new StringBuffer();
+ public StringBuffer data_startPrefixMapping = new StringBuffer();
+
+ public HashMap<String, String> createData() {
+ HashMap<String, String> hm = new HashMap<String, String>();
+ hm.put(KEY_IS_END_DOC, data_isEndDocument.toString());
+ hm.put(KEY_IS_START_DOC, data_isStartDocument.toString());
+ hm.put(KEY_TEXT, data_text.toString());
+ hm.put(KEY_ERROR, data_error.toString());
+ hm.put(KEY_FATAL_ERROR, data_fatalError.toString());
+ hm.put(KEY_WARNING, data_warning.toString());
+ hm.put(KEY_END_ELEMENT, data_endElement.toString());
+ hm.put(KEY_END_PREFIX_MAPPING, data_endPrefixMapping.toString());
+
+ hm.put(KEY_PROCESSING_INSTRUCTION,
+ data_processingInstruction.toString());
+ hm.put(KEY_SKIPPED_ENTITY, data_skippedEntity.toString());
+ hm.put(KEY_START_ELEMENT, data_startElement.toString());
+ hm.put(KEY_START_PREFIX_MAPPING,
+ data_startPrefixMapping.toString());
+ return hm;
+ }
+
+ public void printMap() {
+ System.out.print(data_isStartDocument.toString() + SEPARATOR_DATA +
+ data_isEndDocument.toString() + SEPARATOR_DATA +
+ data_text.toString() + SEPARATOR_DATA +
+ data_error.toString()+ SEPARATOR_DATA +
+ data_fatalError.toString()+ SEPARATOR_DATA +
+ data_warning.toString()+ SEPARATOR_DATA +
+ data_endElement.toString() + SEPARATOR_DATA+
+ data_endPrefixMapping.toString()+ SEPARATOR_DATA +
+ data_processingInstruction.toString() + SEPARATOR_DATA +
+ data_skippedEntity.toString() + SEPARATOR_DATA +
+ data_startElement.toString() + SEPARATOR_DATA +
+ data_startPrefixMapping.toString()+ SEPARATOR_DATA);
+ }
+
+ @Override
+ public void characters(char[] ch, int start, int length) {
+ String str = new String(ch, start, length);
+ data_text.append(str);
+ // different sax parsers are allowed to handle chunking differently,
+ // therefore we cannot rely on identical chunks being delivered.
+ //data_text.append(ParsingSupport.SEPARATOR_ELEMENT);
+ }
+
+ @Override
+ public void endDocument() {
+ data_isEndDocument.append(true);
+ data_isEndDocument.append(SEPARATOR_ELEMENT);
+ }
+
+ @Override
+ public void endElement(String uri, String localName, String qName) {
+ StringBuffer sb = new StringBuffer();
+ sb.append(uri);
+ sb.append(SEPARATOR_STRING);
+ sb.append(localName);
+ sb.append(SEPARATOR_STRING);
+ sb.append(qName);
+ data_endElement.append(sb);
+ data_endElement.append(SEPARATOR_ELEMENT);
+ }
+
+ @Override
+ public void endPrefixMapping(String prefix) {
+ data_endPrefixMapping.append(prefix);
+ data_endPrefixMapping.append(SEPARATOR_ELEMENT);
+ }
+
+ @Override
+ public void error(SAXParseException e) {
+ data_error.append(e);
+ data_error.append(SEPARATOR_ELEMENT);
+ }
+
+ @Override
+ public void fatalError(SAXParseException e) {
+ data_fatalError.append(e);
+ data_fatalError.append(SEPARATOR_ELEMENT);
+ }
+
+ @Override
+ public void ignorableWhitespace(char[] ch, int start, int length) {
+ /* String s = new String(ch, start, length);
+ ignorableWhitespace.append(s);
+ ignorableWhitespace.append(ParsingSupport.SEPARATOR_ELEMENT);*/
+ }
+
+ @Override
+ public void notationDecl(String name, String publicId,
+ String systemId) {
+ /* data_notationDecl.append(name + ParsingSupport.SEPARATOR_STRING +
+ publicId + ParsingSupport.SEPARATOR_STRING +
+ systemId + ParsingSupport.SEPARATOR_STRING);
+ data_notationDecl.append(ParsingSupport.SEPARATOR_ELEMENT);*/
+ }
+
+ @Override
+ public void processingInstruction(String target, String data) {
+ data_processingInstruction.append(target + SEPARATOR_STRING + data);
+ data_processingInstruction.append(SEPARATOR_ELEMENT);
+ }
+
+ @Override
+ public InputSource resolveEntity(String publicId, String systemId) {
+ // data_resolveEntity.append(publicId +
+ // ParsingSupport.SEPARATOR_STRING + systemId);
+ // data_resolveEntity.append(ParsingSupport.SEPARATOR_ELEMENT);
+ return null;
+ }
+
+ @Override
+ public void setDocumentLocator(Locator locator) {
+ // data_documentLocators.append(locator);
+ // data_documentLocators.append(ParsingSupport.SEPARATOR_ELEMENT);
+ }
+
+ @Override
+ public void skippedEntity(String name) {
+ data_skippedEntity.append(name);
+ data_skippedEntity.append(SEPARATOR_ELEMENT);
+ }
+
+ @Override
+ public void startDocument() {
+ data_isStartDocument.append(true);
+ data_isStartDocument.append(SEPARATOR_ELEMENT);
+ }
+
+ @Override
+ public void startElement(String uri, String localName, String qName,
+ Attributes attributes) {
+ data_startElement.append(uri);
+ data_startElement.append(SEPARATOR_STRING);
+ data_startElement.append(localName);
+ data_startElement.append(SEPARATOR_STRING);
+ data_startElement.append(qName);
+
+ for(int i = 0; i < attributes.getLength(); i ++)
+ data_startElement.append(
+ SEPARATOR_STRING +attributes.getQName(i) +
+ SEPARATOR_STRING + attributes.getValue(i));
+
+ data_isStartDocument.append(SEPARATOR_ELEMENT);
+ }
+
+ @Override
+ public void startPrefixMapping(String prefix, String uri) {
+ data_startPrefixMapping.append(prefix + SEPARATOR_STRING + uri);
+ }
+
+ @Override
+ public void unparsedEntityDecl(String name, String publicId,
+ String systemId, String notationName) {
+ // data_unparsedEntityDecl.append(name
+ // + ParsingSupport.SEPARATOR_STRING + publicId
+ // + ParsingSupport.SEPARATOR_STRING
+ // + systemId + ParsingSupport.SEPARATOR_STRING + notationName);
+ }
+
+ @Override
+ public void warning(SAXParseException e) {
+ data_warning.append(e);
+ }
+ }
+
+ @SuppressWarnings("deprecation")
+ static class MyHandler extends HandlerBase {
+
+ public StringBuffer data_isEndDocument = new StringBuffer();
+ public StringBuffer data_isStartDocument = new StringBuffer();
+ public StringBuffer data_text = new StringBuffer();
+ public StringBuffer data_error = new StringBuffer();
+ public StringBuffer data_fatalError = new StringBuffer();
+ public StringBuffer data_warning = new StringBuffer();
+ public StringBuffer data_endElement = new StringBuffer();
+ public StringBuffer data_endPrefixMapping = new StringBuffer();
+ public StringBuffer data_processingInstruction = new StringBuffer();
+ public StringBuffer data_skippedEntity = new StringBuffer();
+ public StringBuffer data_startElement = new StringBuffer();
+ public StringBuffer data_startPrefixMapping = new StringBuffer();
+
+ public void printMap() {
+ System.out.print(data_isStartDocument.toString() + SEPARATOR_DATA +
+ data_isEndDocument.toString() + SEPARATOR_DATA +
+ data_text.toString() + SEPARATOR_DATA +
+ data_error.toString()+ SEPARATOR_DATA +
+ data_fatalError.toString()+ SEPARATOR_DATA +
+ data_warning.toString()+ SEPARATOR_DATA +
+ data_endElement.toString() + SEPARATOR_DATA+
+ data_endPrefixMapping.toString()+ SEPARATOR_DATA +
+ data_processingInstruction.toString() + SEPARATOR_DATA +
+ data_skippedEntity.toString() + SEPARATOR_DATA +
+ data_startElement.toString() + SEPARATOR_DATA +
+ data_startPrefixMapping.toString()+ SEPARATOR_DATA);
+ }
+
+ public HashMap<String, String> createData() {
+ HashMap<String, String> hm = new HashMap<String, String>();
+ hm.put(KEY_IS_END_DOC, data_isEndDocument.toString());
+ hm.put(KEY_IS_START_DOC, data_isStartDocument.toString());
+ hm.put(KEY_TEXT, data_text.toString());
+ hm.put(KEY_ERROR, data_error.toString());
+ hm.put(KEY_FATAL_ERROR, data_fatalError.toString());
+ hm.put(KEY_WARNING, data_warning.toString());
+ hm.put(KEY_END_ELEMENT, data_endElement.toString());
+ hm.put(KEY_END_PREFIX_MAPPING, data_endPrefixMapping.toString());
+ hm.put(KEY_PROCESSING_INSTRUCTION,
+ data_processingInstruction.toString());
+ hm.put(KEY_SKIPPED_ENTITY, data_skippedEntity.toString());
+ hm.put(KEY_START_ELEMENT, data_startElement.toString());
+ hm.put(KEY_START_PREFIX_MAPPING,
+ data_startPrefixMapping.toString());
+ return hm;
+ }
+
+ @Override
+ public void characters(char[] ch, int start, int length) {
+ String str = new String(ch, start, length);
+ data_text.append(str);
+ // different sax parsers are allowed to handle chunking differently,
+ // therefore we cannot rely on identical chunks being delivered.
+ //data_text.append(ParsingSupport.SEPARATOR_ELEMENT);
+ }
+
+ @Override
+ public void endDocument() {
+ data_isEndDocument.append(true);
+ data_isEndDocument.append(SEPARATOR_ELEMENT);
+ }
+
+ public void endElement(String uri, String localName, String qName) {
+ StringBuffer sb = new StringBuffer();
+ sb.append(uri);
+ sb.append(SEPARATOR_STRING);
+ sb.append(localName);
+ sb.append(SEPARATOR_STRING);
+ sb.append(qName);
+ data_endElement.append(sb);
+ data_endElement.append(SEPARATOR_ELEMENT);
+ }
+
+ @Override
+ public void error(SAXParseException e) {
+ data_error.append(e);
+ data_error.append(SEPARATOR_ELEMENT);
+ }
+
+ @Override
+ public void fatalError(SAXParseException e) {
+ data_fatalError.append(e);
+ data_fatalError.append(SEPARATOR_ELEMENT);
+ }
+
+ @Override
+ public void ignorableWhitespace(char[] ch, int start, int length) {
+
+ }
+
+ @Override
+ public void notationDecl(String name, String publicId,
+ String systemId) {
+
+ }
+
+ @Override
+ public void processingInstruction(String target, String data) {
+ data_processingInstruction.append(target + SEPARATOR_STRING + data);
+ data_processingInstruction.append(SEPARATOR_ELEMENT);
+ }
+
+ @Override
+ public InputSource resolveEntity(String publicId, String systemId) {
+ return null;
+ }
+
+ @Override
+ public void setDocumentLocator(Locator locator) {
+
+ }
+
+ @Override
+ public void startDocument() {
+ data_isStartDocument.append(true);
+ data_isStartDocument.append(SEPARATOR_ELEMENT);
+ }
+
+ public void startElement(String uri, String localName, String qName,
+ Attributes attributes) {
+ data_startElement.append(uri);
+ data_startElement.append(SEPARATOR_STRING);
+ data_startElement.append(localName);
+ data_startElement.append(SEPARATOR_STRING);
+ data_startElement.append(qName);
+
+ for(int i = 0; i < attributes.getLength(); i ++)
+ data_startElement.append(SEPARATOR_STRING
+ + attributes.getQName(i) +
+ SEPARATOR_STRING + attributes.getValue(i));
+
+ data_isStartDocument.append(SEPARATOR_ELEMENT);
+ }
+
+ @Override
+ public void unparsedEntityDecl(String name, String publicId,
+ String systemId, String notationName) {
+
+ }
+
+ @Override
+ public void warning(SAXParseException e) {
+ data_warning.append(e);
+ }
+ }
+}
diff --git a/xml/src/test/java/tests/api/org/xml/sax/AllTests.java b/xml/src/test/java/tests/api/org/xml/sax/AllTests.java
new file mode 100644
index 0000000..9c29178
--- /dev/null
+++ b/xml/src/test/java/tests/api/org/xml/sax/AllTests.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.api.org.xml.sax;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class AllTests {
+
+ public static void main(String[] args) {
+ junit.textui.TestRunner.run(AllTests.suite());
+ }
+
+ public static Test suite() {
+ TestSuite suite = tests.TestSuiteFactory.createTestSuite("Tests for org.xml.sax package");
+ // $JUnit-BEGIN$
+
+ suite.addTestSuite(HandlerBaseTest.class);
+ suite.addTestSuite(InputSourceTest.class);
+ suite.addTestSuite(SAXExceptionTest.class);
+ suite.addTestSuite(SAXNotRecognizedExceptionTest.class);
+ suite.addTestSuite(SAXNotSupportedExceptionTest.class);
+ suite.addTestSuite(SAXParseExceptionTest.class);
+
+ suite.addTest(tests.api.org.xml.sax.ext.AllTests.suite());
+ suite.addTest(tests.api.org.xml.sax.helpers.AllTests.suite());
+
+ // $JUnit-END$
+ return suite;
+ }
+}
diff --git a/xml/src/test/java/tests/api/org/xml/sax/HandlerBaseTest.java b/xml/src/test/java/tests/api/org/xml/sax/HandlerBaseTest.java
new file mode 100644
index 0000000..7c7f591
--- /dev/null
+++ b/xml/src/test/java/tests/api/org/xml/sax/HandlerBaseTest.java
@@ -0,0 +1,226 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.api.org.xml.sax;
+
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+
+import junit.framework.TestCase;
+
+import org.xml.sax.AttributeList;
+import org.xml.sax.HandlerBase;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.helpers.AttributeListImpl;
+import org.xml.sax.helpers.LocatorImpl;
+
+@SuppressWarnings("deprecation")
+@TestTargetClass(HandlerBase.class)
+public class HandlerBaseTest extends TestCase {
+
+ /*
+ * Note: most of the tests have to check for an empty implementation of the
+ * respective methods and, as a result, are somewhat trivial.
+ */
+
+ private HandlerBase h = new HandlerBase();
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "resolveEntity",
+ args = { String.class, String.class }
+ )
+ public void testResolveEntity() {
+ try {
+ h.resolveEntity("publicID", "systemID");
+ } catch (SAXException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "notationDecl",
+ args = { String.class, String.class, String.class }
+ )
+ public void testNotationDecl() {
+ h.notationDecl("name", "publicID", "systemID");
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "unparsedEntityDecl",
+ args = { String.class, String.class, String.class, String.class }
+ )
+ public void testUnparsedEntityDecl() {
+ h.unparsedEntityDecl("name", "publicID", "systemID", "notationName");
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setDocumentLocator",
+ args = { org.xml.sax.Locator.class }
+ )
+ public void testSetDocumentLocator() {
+ h.setDocumentLocator(new LocatorImpl());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "startDocument",
+ args = { }
+ )
+ public void testStartDocument() {
+ try {
+ h.startDocument();
+ } catch (SAXException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "endDocument",
+ args = { }
+ )
+ public void testEndDocument() {
+ try {
+ h.endDocument();
+ } catch (SAXException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "startElement",
+ args = { String.class, AttributeList.class }
+ )
+ public void testStartElement() {
+ try {
+ h.startElement("name", new AttributeListImpl());
+ } catch (SAXException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "endElement",
+ args = { String.class }
+ )
+ public void testEndElement() {
+ try {
+ h.endElement("name");
+ } catch (SAXException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "characters",
+ args = { char[].class, int.class, int.class }
+ )
+ public void testCharacters() {
+ try {
+ h.characters("The quick brown fox".toCharArray(), 4, 11);
+ } catch (SAXException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "ignorableWhitespace",
+ args = { char[].class, int.class, int.class }
+ )
+ public void testIgnorableWhitespace() {
+ try {
+ h.ignorableWhitespace(" ".toCharArray(), 4, 11);
+ } catch (SAXException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "processingInstruction",
+ args = { String.class, String.class }
+ )
+ public void testProcessingInstruction() {
+ try {
+ h.processingInstruction("target", "data");
+ } catch (SAXException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "warning",
+ args = { org.xml.sax.SAXParseException.class }
+ )
+ public void testWarning() {
+ try {
+ h.warning(new SAXParseException("Foo", new LocatorImpl()));
+ } catch (SAXException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "error",
+ args = { org.xml.sax.SAXParseException.class }
+ )
+ public void testError() {
+ try {
+ h.error(new SAXParseException("Foo", new LocatorImpl()));
+ } catch (SAXException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "fatalError",
+ args = { org.xml.sax.SAXParseException.class }
+ )
+ public void testFatalError() {
+ // Ordinary case
+ try {
+ h.fatalError(new SAXParseException("Foo", new LocatorImpl()));
+ fail("SAXException expected");
+ } catch (SAXException e) {
+ // Expected
+ }
+
+ // No exception
+ try {
+ h.fatalError(null);
+ fail("NullPointerException expected");
+ } catch (SAXException e) {
+ fail("NullPointerException expected");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ }
+
+}
diff --git a/xml/src/test/java/tests/api/org/xml/sax/InputSourceTest.java b/xml/src/test/java/tests/api/org/xml/sax/InputSourceTest.java
new file mode 100644
index 0000000..7c73b52
--- /dev/null
+++ b/xml/src/test/java/tests/api/org/xml/sax/InputSourceTest.java
@@ -0,0 +1,254 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.api.org.xml.sax;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.Reader;
+import java.io.StringReader;
+
+import junit.framework.TestCase;
+
+import org.xml.sax.InputSource;
+
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargets;
+
+@TestTargetClass(InputSource.class)
+public class InputSourceTest extends TestCase {
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "InputSource",
+ args = { }
+ )
+ public void testInputSource() {
+ InputSource i = new InputSource();
+
+ assertNull(i.getByteStream());
+ assertNull(i.getCharacterStream());
+ assertNull(i.getEncoding());
+ assertNull(i.getPublicId());
+ assertNull(i.getSystemId());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "InputSource",
+ args = { String.class }
+ )
+ public void testInputSourceString() {
+ InputSource i = new InputSource("Foo");
+
+ assertNull(i.getByteStream());
+ assertNull(i.getCharacterStream());
+ assertNull(i.getEncoding());
+ assertNull(i.getPublicId());
+ assertEquals("Foo", i.getSystemId());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "InputSource",
+ args = { InputStream.class }
+ )
+ public void testInputSourceInputStream() {
+ ByteArrayInputStream bais = new ByteArrayInputStream(new byte[0]);
+
+ // Ordinary case
+ InputSource i = new InputSource(bais);
+
+ assertEquals(bais, i.getByteStream());
+ assertNull(i.getCharacterStream());
+ assertNull(i.getEncoding());
+ assertNull(i.getPublicId());
+ assertNull(i.getSystemId());
+
+ // No input stream
+ i = new InputSource((InputStream)null);
+
+ assertNull(i.getByteStream());
+ assertNull(i.getCharacterStream());
+ assertNull(i.getEncoding());
+ assertNull(i.getPublicId());
+ assertNull(i.getSystemId());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "InputSource",
+ args = { Reader.class }
+ )
+ public void testInputSourceReader() {
+ StringReader sr = new StringReader("Hello, world.");
+
+ // Ordinary case
+ InputSource i = new InputSource(sr);
+
+ assertNull(i.getByteStream());
+ assertEquals(sr, i.getCharacterStream());
+ assertNull(i.getEncoding());
+ assertNull(i.getPublicId());
+ assertNull(i.getSystemId());
+
+ // No reader
+ i = new InputSource((Reader)null);
+
+ assertNull(i.getByteStream());
+ assertNull(i.getCharacterStream());
+ assertNull(i.getEncoding());
+ assertNull(i.getPublicId());
+ assertNull(i.getSystemId());
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setPublicId",
+ args = { String.class }
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getPublicId",
+ args = { }
+ )
+ })
+ public void testSetPublicIdGetPublicId() {
+ InputSource i = new InputSource();
+
+ i.setPublicId("Foo");
+ assertEquals("Foo", i.getPublicId());
+
+ i.setPublicId(null);
+ assertNull(i.getPublicId());
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setSystemId",
+ args = { String.class }
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getSystemId",
+ args = { }
+ )
+ })
+ public void testSetSystemIdGetSystemId() {
+ InputSource i = new InputSource();
+
+ i.setSystemId("Foo");
+ assertEquals("Foo", i.getSystemId());
+
+ i.setSystemId(null);
+ assertNull(i.getSystemId());
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setByteStream",
+ args = { InputStream.class }
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getByteStream",
+ args = { }
+ )
+ })
+ public void testSetByteStreamGetByteStream() {
+ ByteArrayInputStream bais = new ByteArrayInputStream(new byte[0]);
+
+ InputSource i = new InputSource();
+
+ // Ordinary case
+ i.setByteStream(bais);
+
+ assertEquals(bais, i.getByteStream());
+
+ // No input stream
+ i.setByteStream(null);
+
+ assertNull(i.getByteStream());
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setEncoding",
+ args = { String.class }
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getEncoding",
+ args = { }
+ )
+ })
+ public void testSetEncodingGetEncoding() {
+ InputSource i = new InputSource();
+
+ // Ordinary case
+ i.setEncoding("Klingon");
+
+ assertEquals("Klingon", i.getEncoding());
+
+ // No encoding
+ i.setEncoding(null);
+
+ assertNull(i.getEncoding());
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setCharacterStream",
+ args = { Reader.class }
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getCharacterStream",
+ args = { }
+ )
+ })
+ public void testSetCharacterStreamGetCharacterStream() {
+ StringReader sr = new StringReader("Hello, world.");
+
+ InputSource i = new InputSource();
+
+ // Ordinary case
+ i.setCharacterStream(sr);
+
+ assertNull(i.getByteStream());
+ assertEquals(sr, i.getCharacterStream());
+ assertNull(i.getEncoding());
+ assertNull(i.getPublicId());
+ assertNull(i.getSystemId());
+
+ // No reader
+ i.setCharacterStream(null);
+
+ assertNull(i.getByteStream());
+ assertNull(i.getCharacterStream());
+ assertNull(i.getEncoding());
+ assertNull(i.getPublicId());
+ assertNull(i.getSystemId());
+ }
+
+}
diff --git a/xml/src/test/java/tests/api/org/xml/sax/SAXExceptionTest.java b/xml/src/test/java/tests/api/org/xml/sax/SAXExceptionTest.java
new file mode 100644
index 0000000..afc1f8d
--- /dev/null
+++ b/xml/src/test/java/tests/api/org/xml/sax/SAXExceptionTest.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.api.org.xml.sax;
+
+import junit.framework.TestCase;
+
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+
+@TestTargetClass(SAXException.class)
+public class SAXExceptionTest extends TestCase {
+
+ public static final String ERR = "Houston, we have a problem";
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "SAXException",
+ args = { }
+ )
+ public void testSAXParseException() {
+ SAXException e = new SAXException();
+
+ assertNull(e.getMessage());
+ assertNull(e.getException());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "SAXException",
+ args = { String.class, Exception.class }
+ )
+ public void testSAXException_String_Exception() {
+ Exception c = new Exception();
+
+ // Ordinary case
+ SAXException e = new SAXException(ERR, c);
+
+ assertEquals(ERR, e.getMessage());
+ assertEquals(c, e.getException());
+
+ // No message
+ e = new SAXException(null, c);
+
+ assertNull(e.getMessage());
+ assertEquals(c, e.getException());
+
+ // No cause
+ e = new SAXParseException(ERR, null);
+
+ assertEquals(ERR, e.getMessage());
+ assertNull(e.getException());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "SAXException",
+ args = { String.class }
+ )
+ public void testSAXException_String() {
+ // Ordinary case
+ SAXException e = new SAXException(ERR);
+
+ assertEquals(ERR, e.getMessage());
+ assertNull(e.getException());
+
+ // No message
+ e = new SAXException((String)null);
+
+ assertNull(e.getMessage());
+ assertNull(e.getException());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "SAXException",
+ args = { Exception.class }
+ )
+ public void testSAXException_Exception() {
+ Exception c = new Exception();
+
+ // Ordinary case
+ SAXException e = new SAXException(c);
+
+ assertNull(e.getMessage());
+ assertEquals(c, e.getException());
+
+ // No cause
+ e = new SAXException((Exception)null);
+
+ assertNull(e.getMessage());
+ assertNull(e.getException());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "toString",
+ args = { }
+ )
+ public void testToString() {
+ // Ordinary case
+ SAXException e = new SAXException(ERR);
+ String s = e.toString();
+
+ assertTrue(s.contains(ERR));
+
+ // No message
+ e = new SAXException();
+ s = e.toString();
+
+ assertFalse(s.contains(ERR));
+ }
+
+} \ No newline at end of file
diff --git a/xml/src/test/java/tests/api/org/xml/sax/SAXNotRecognizedExceptionTest.java b/xml/src/test/java/tests/api/org/xml/sax/SAXNotRecognizedExceptionTest.java
new file mode 100644
index 0000000..1fab7bf
--- /dev/null
+++ b/xml/src/test/java/tests/api/org/xml/sax/SAXNotRecognizedExceptionTest.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.api.org.xml.sax;
+
+import junit.framework.TestCase;
+
+import org.xml.sax.SAXNotRecognizedException;
+
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+
+@TestTargetClass(SAXNotRecognizedException.class)
+public class SAXNotRecognizedExceptionTest extends TestCase {
+
+ public static final String ERR = "Houston, we have a problem";
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "SAXNotRecognizedException",
+ args = { }
+ )
+ public void testSAXNotRecognizedException() {
+ SAXNotRecognizedException e = new SAXNotRecognizedException();
+ assertNull(e.getMessage());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "SAXNotRecognizedException",
+ args = { String.class }
+ )
+ public void testSAXNotRecognizedException_String() {
+ SAXNotRecognizedException e = new SAXNotRecognizedException(ERR);
+ assertEquals(ERR, e.getMessage());
+
+ e = new SAXNotRecognizedException(null);
+ assertNull(e.getMessage());
+ }
+
+}
diff --git a/xml/src/test/java/tests/api/org/xml/sax/SAXNotSupportedExceptionTest.java b/xml/src/test/java/tests/api/org/xml/sax/SAXNotSupportedExceptionTest.java
new file mode 100644
index 0000000..9060a14
--- /dev/null
+++ b/xml/src/test/java/tests/api/org/xml/sax/SAXNotSupportedExceptionTest.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.api.org.xml.sax;
+
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+
+import junit.framework.TestCase;
+
+import org.xml.sax.SAXNotSupportedException;
+
+@TestTargetClass(SAXNotSupportedException.class)
+public class SAXNotSupportedExceptionTest extends TestCase {
+
+ public static final String ERR = "Houston, we have a problem";
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "SAXNotSupportedException",
+ args = { }
+ )
+ public void testSAXNotSupportedException() {
+ SAXNotSupportedException e = new SAXNotSupportedException();
+ assertNull(e.getMessage());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "SAXNotSupportedException",
+ args = { String.class }
+ )
+ public void testSAXNotSupportedException_String() {
+ SAXNotSupportedException e = new SAXNotSupportedException(ERR);
+ assertEquals(ERR, e.getMessage());
+
+ e = new SAXNotSupportedException(null);
+ assertNull(e.getMessage());
+ }
+
+}
diff --git a/xml/src/test/java/tests/api/org/xml/sax/SAXParseExceptionTest.java b/xml/src/test/java/tests/api/org/xml/sax/SAXParseExceptionTest.java
new file mode 100644
index 0000000..aff0c7f
--- /dev/null
+++ b/xml/src/test/java/tests/api/org/xml/sax/SAXParseExceptionTest.java
@@ -0,0 +1,276 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.api.org.xml.sax;
+
+import junit.framework.TestCase;
+
+import org.xml.sax.Locator;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.helpers.LocatorImpl;
+
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargets;
+
+@TestTargetClass(SAXParseException.class)
+public class SAXParseExceptionTest extends TestCase {
+
+ public static final String ERR = "Houston, we have a problem";
+
+ public static final String SYS = "mySystemID";
+
+ public static final String PUB = "myPublicID";
+
+ public static final int ROW = 1;
+
+ public static final int COL = 2;
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "SAXParseException",
+ args = { String.class, Locator.class, Exception.class }
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getMessage",
+ args = { }
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getException",
+ args = { }
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getPublicId",
+ args = { }
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getSystemId",
+ args = { }
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getLineNumber",
+ args = { }
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getColumnNumber",
+ args = { }
+ )
+ })
+ public void testSAXParseException_String_Locator_Exception() {
+ LocatorImpl l = new LocatorImpl();
+ l.setPublicId(PUB);
+ l.setSystemId(SYS);
+ l.setLineNumber(ROW);
+ l.setColumnNumber(COL);
+
+ Exception c = new Exception();
+
+ // Ordinary case
+ SAXParseException e = new SAXParseException(ERR, l, c);
+
+ assertEquals(ERR, e.getMessage());
+ assertEquals(c, e.getException());
+
+ assertEquals(PUB, e.getPublicId());
+ assertEquals(SYS, e.getSystemId());
+ assertEquals(ROW, e.getLineNumber());
+ assertEquals(COL, e.getColumnNumber());
+
+ // No message
+ e = new SAXParseException(null, l, c);
+
+ assertNull(e.getMessage());
+ assertEquals(c, e.getException());
+
+ assertEquals(PUB, e.getPublicId());
+ assertEquals(SYS, e.getSystemId());
+ assertEquals(ROW, e.getLineNumber());
+ assertEquals(COL, e.getColumnNumber());
+
+ // No locator
+ e = new SAXParseException(ERR, null, c);
+
+ assertEquals(ERR, e.getMessage());
+ assertEquals(c, e.getException());
+
+ assertNull(e.getPublicId());
+ assertNull(e.getSystemId());
+ assertEquals(-1, e.getLineNumber());
+ assertEquals(-1, e.getColumnNumber());
+
+ // No cause
+ e = new SAXParseException(ERR, l, null);
+
+ assertEquals(ERR, e.getMessage());
+ assertNull(e.getException());
+
+ assertEquals(PUB, e.getPublicId());
+ assertEquals(SYS, e.getSystemId());
+ assertEquals(ROW, e.getLineNumber());
+ assertEquals(COL, e.getColumnNumber());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "SAXParseException",
+ args = { String.class, Locator.class }
+ )
+ public void testSAXParseException_String_Locator() {
+ LocatorImpl l = new LocatorImpl();
+ l.setPublicId(PUB);
+ l.setSystemId(SYS);
+ l.setLineNumber(ROW);
+ l.setColumnNumber(COL);
+
+ // Ordinary case
+ SAXParseException e = new SAXParseException(ERR, l);
+
+ assertEquals(ERR, e.getMessage());
+ assertNull(e.getException());
+
+ assertEquals(PUB, e.getPublicId());
+ assertEquals(SYS, e.getSystemId());
+ assertEquals(ROW, e.getLineNumber());
+ assertEquals(COL, e.getColumnNumber());
+
+ // No message
+ e = new SAXParseException(null, l);
+
+ assertNull(e.getMessage());
+ assertNull(e.getException());
+
+ assertEquals(PUB, e.getPublicId());
+ assertEquals(SYS, e.getSystemId());
+ assertEquals(ROW, e.getLineNumber());
+ assertEquals(COL, e.getColumnNumber());
+
+ // No locator
+ e = new SAXParseException(ERR, null);
+
+ assertEquals(ERR, e.getMessage());
+ assertNull(e.getException());
+
+ assertNull(e.getPublicId());
+ assertNull(e.getSystemId());
+ assertEquals(-1, e.getLineNumber());
+ assertEquals(-1, e.getColumnNumber());
+
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "SAXParseException",
+ args = { String.class, String.class, String.class, int.class, int.class,
+ Exception.class }
+ )
+ public void testSAXParseException_String_String_String_int_int_Exception() {
+ Exception c = new Exception();
+
+ // Ordinary case
+ SAXParseException e = new SAXParseException(ERR, PUB, SYS, ROW, COL, c);
+
+ assertEquals(ERR, e.getMessage());
+ assertEquals(c, e.getException());
+
+ assertEquals(PUB, e.getPublicId());
+ assertEquals(SYS, e.getSystemId());
+ assertEquals(ROW, e.getLineNumber());
+ assertEquals(COL, e.getColumnNumber());
+
+ // No message
+ e = new SAXParseException(null, PUB, SYS, ROW, COL, c);
+
+ assertNull(e.getMessage());
+ assertEquals(c, e.getException());
+
+ assertEquals(PUB, e.getPublicId());
+ assertEquals(SYS, e.getSystemId());
+ assertEquals(ROW, e.getLineNumber());
+ assertEquals(COL, e.getColumnNumber());
+
+ // No locator
+ e = new SAXParseException(ERR, null, null, -1, -1, c);
+
+ assertEquals(ERR, e.getMessage());
+ assertEquals(c, e.getException());
+
+ assertNull(e.getPublicId());
+ assertNull(e.getSystemId());
+ assertEquals(-1, e.getLineNumber());
+ assertEquals(-1, e.getColumnNumber());
+
+ // No cause
+ e = new SAXParseException(ERR, PUB, SYS, ROW, COL, null);
+
+ assertEquals(ERR, e.getMessage());
+ assertNull(e.getException());
+
+ assertEquals(PUB, e.getPublicId());
+ assertEquals(SYS, e.getSystemId());
+ assertEquals(ROW, e.getLineNumber());
+ assertEquals(COL, e.getColumnNumber());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "SAXParseException",
+ args = { String.class, String.class, String.class, int.class,
+ int.class }
+ )
+ public void testSAXParseException_String_String_String_int_int() {
+ // Ordinary case
+ SAXParseException e = new SAXParseException(ERR, PUB, SYS, ROW, COL);
+
+ assertEquals(ERR, e.getMessage());
+ assertNull(e.getException());
+
+ assertEquals(PUB, e.getPublicId());
+ assertEquals(SYS, e.getSystemId());
+ assertEquals(ROW, e.getLineNumber());
+ assertEquals(COL, e.getColumnNumber());
+
+ // No message
+ e = new SAXParseException(null, PUB, SYS, ROW, COL);
+
+ assertNull(e.getMessage());
+ assertNull(e.getException());
+
+ assertEquals(PUB, e.getPublicId());
+ assertEquals(SYS, e.getSystemId());
+ assertEquals(ROW, e.getLineNumber());
+ assertEquals(COL, e.getColumnNumber());
+
+ // No locator
+ e = new SAXParseException(ERR, null, null, -1, -1);
+
+ assertEquals(ERR, e.getMessage());
+ assertNull(e.getException());
+
+ assertNull(e.getPublicId());
+ assertNull(e.getSystemId());
+ assertEquals(-1, e.getLineNumber());
+ assertEquals(-1, e.getColumnNumber());
+ }
+
+} \ No newline at end of file
diff --git a/xml/src/test/java/tests/api/org/xml/sax/ext/AllTests.java b/xml/src/test/java/tests/api/org/xml/sax/ext/AllTests.java
new file mode 100644
index 0000000..f4b34b8
--- /dev/null
+++ b/xml/src/test/java/tests/api/org/xml/sax/ext/AllTests.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.api.org.xml.sax.ext;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class AllTests {
+
+ public static void main(String[] args) {
+ junit.textui.TestRunner.run(AllTests.suite());
+ }
+
+ public static Test suite() {
+ TestSuite suite = tests.TestSuiteFactory.createTestSuite("Tests for org.xml.sax.ext package");
+ // $JUnit-BEGIN$
+
+ suite.addTestSuite(Attributes2ImplTest.class);
+ suite.addTestSuite(DefaultHandler2Test.class);
+ suite.addTestSuite(Locator2ImplTest.class);
+
+ // $JUnit-END$
+ return suite;
+ }
+}
diff --git a/xml/src/test/java/tests/api/org/xml/sax/ext/Attributes2ImplTest.java b/xml/src/test/java/tests/api/org/xml/sax/ext/Attributes2ImplTest.java
new file mode 100644
index 0000000..9ccdc8a
--- /dev/null
+++ b/xml/src/test/java/tests/api/org/xml/sax/ext/Attributes2ImplTest.java
@@ -0,0 +1,464 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.api.org.xml.sax.ext;
+
+import junit.framework.TestCase;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.ext.Attributes2Impl;
+import org.xml.sax.helpers.AttributesImpl;
+
+import dalvik.annotation.KnownFailure;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+
+@TestTargetClass(Attributes2Impl.class)
+public class Attributes2ImplTest extends TestCase {
+
+ // Note: The original SAX2 implementation of Attributes2Impl is
+ // severely broken. Thus all of these tests will probably fail
+ // unless the Android implementation of the class gets fixed.
+
+ private Attributes2Impl empty = new Attributes2Impl();
+
+ private Attributes2Impl multi = new Attributes2Impl();
+
+ private Attributes2Impl cdata = new Attributes2Impl();
+
+ @Override
+ public void setUp() {
+ multi.addAttribute("http://some.uri", "foo", "ns1:foo",
+ "string", "abc");
+ multi.addAttribute("http://some.uri", "bar", "ns1:bar",
+ "string", "xyz");
+ multi.addAttribute("http://some.other.uri", "answer", "ns2:answer",
+ "int", "42");
+ multi.addAttribute("http://yet.another.uri", "gabba", "ns3:gabba",
+ "string", "gabba");
+
+ multi.setDeclared(0, false);
+ multi.setSpecified(0, false);
+
+ multi.setDeclared(1, true);
+ multi.setSpecified(1, false);
+
+ multi.setDeclared(2, false);
+ multi.setSpecified(2, true);
+
+ multi.setDeclared(3, true);
+ multi.setSpecified(3, true);
+
+ cdata.addAttribute("http://yet.another.uri", "hey", "ns3:hey",
+ "CDATA", "hey");
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setAttributes",
+ args = { Attributes.class }
+ )
+ public void testSetAttributes() {
+ // Ordinary case with Attributes2Impl
+ Attributes2Impl attrs = new Attributes2Impl();
+ attrs.addAttribute("", "", "john", "string", "doe");
+
+ attrs.setAttributes(empty);
+ assertEquals(0, attrs.getLength());
+
+ attrs.setAttributes(multi);
+ for (int i = 0; i < multi.getLength(); i++) {
+ assertEquals(multi.getURI(i), attrs.getURI(i));
+ assertEquals(multi.getLocalName(i), attrs.getLocalName(i));
+ assertEquals(multi.getQName(i), attrs.getQName(i));
+ assertEquals(multi.getType(i), attrs.getType(i));
+ assertEquals(multi.getValue(i), attrs.getValue(i));
+ assertEquals(multi.isDeclared(i), attrs.isDeclared(i));
+ assertEquals(multi.isSpecified(i), attrs.isSpecified(i));
+ }
+
+ attrs.setAttributes(empty);
+ assertEquals(0, attrs.getLength());
+
+ // Ordinary case with AttributesImpl
+ attrs.setAttributes(new AttributesImpl(multi));
+ assertEquals(multi.getLength(), attrs.getLength());
+
+ for (int i = 0; i < multi.getLength(); i++) {
+ assertEquals(multi.getURI(i), attrs.getURI(i));
+ assertEquals(multi.getLocalName(i), attrs.getLocalName(i));
+ assertEquals(multi.getQName(i), attrs.getQName(i));
+ assertEquals(multi.getType(i), attrs.getType(i));
+ assertEquals(multi.getValue(i), attrs.getValue(i));
+ assertEquals(true, attrs.isDeclared(i));
+ assertEquals(true, attrs.isSpecified(i));
+ }
+
+ // Special case with CDATA
+ attrs.setAttributes(new AttributesImpl(cdata));
+ assertEquals(1, attrs.getLength());
+ assertEquals(false, attrs.isDeclared(0));
+ assertEquals(true, attrs.isSpecified(0));
+
+ // null case
+ try {
+ attrs.setAttributes(null);
+ fail("NullPointerException expected");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "addAttribute",
+ args = { String.class, String.class, String.class, String.class,
+ String.class }
+ )
+ public void testAddAttribute() {
+ Attributes2Impl attrs = new Attributes2Impl();
+
+ // Ordinary case
+ attrs.addAttribute("http://yet.another.uri", "doe", "john:doe",
+ "string", "abc");
+
+ assertEquals(1, attrs.getLength());
+
+ assertEquals("http://yet.another.uri", attrs.getURI(0));
+ assertEquals("doe", attrs.getLocalName(0));
+ assertEquals("john:doe", attrs.getQName(0));
+ assertEquals("string", attrs.getType(0));
+ assertEquals("abc", attrs.getValue(0));
+
+ assertEquals(true, attrs.isDeclared(0));
+ assertEquals(true, attrs.isSpecified(0));
+
+ // CDATA case
+ attrs.addAttribute("http://yet.another.uri", "doe", "jane:doe",
+ "CDATA", "abc");
+
+ assertEquals(2, attrs.getLength());
+
+ assertEquals("http://yet.another.uri", attrs.getURI(1));
+ assertEquals("doe", attrs.getLocalName(1));
+ assertEquals("jane:doe", attrs.getQName(1));
+ assertEquals("CDATA", attrs.getType(1));
+ assertEquals("abc", attrs.getValue(1));
+
+ assertEquals(false, attrs.isDeclared(1));
+ assertEquals(true, attrs.isSpecified(1));
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "removeAttribute",
+ args = { int.class }
+ )
+ public void testRemoveAttribute() {
+ Attributes2Impl attrs = new Attributes2Impl(multi);
+
+ // Ordinary case
+ attrs.removeAttribute(1);
+
+ assertEquals(3, attrs.getLength());
+
+ assertEquals(multi.getURI(0), attrs.getURI(0));
+ assertEquals(multi.getLocalName(0), attrs.getLocalName(0));
+ assertEquals(multi.getQName(0), attrs.getQName(0));
+ assertEquals(multi.getType(0), attrs.getType(0));
+ assertEquals(multi.getValue(0), attrs.getValue(0));
+ assertEquals(multi.isDeclared(0), attrs.isDeclared(0));
+ assertEquals(multi.isSpecified(0), attrs.isSpecified(0));
+
+ assertEquals(multi.getURI(2), attrs.getURI(1));
+ assertEquals(multi.getLocalName(2), attrs.getLocalName(1));
+ assertEquals(multi.getQName(2), attrs.getQName(1));
+ assertEquals(multi.getType(2), attrs.getType(1));
+ assertEquals(multi.getValue(2), attrs.getValue(1));
+ assertEquals(multi.isDeclared(2), attrs.isDeclared(1));
+ assertEquals(multi.isSpecified(2), attrs.isSpecified(1));
+
+ // Out of range
+ try {
+ attrs.removeAttribute(-1);
+ fail("ArrayIndexOutOfBoundsException expected");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ try {
+ attrs.removeAttribute(3);
+ fail("ArrayIndexOutOfBoundsException expected");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // Expected
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "Attributes2Impl",
+ args = { }
+ )
+ public void testAttributes2Impl() {
+ assertEquals(0, empty.getLength());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "Attributes2Impl",
+ args = { Attributes.class }
+ )
+ public void testAttributes2ImplAttributes() {
+ // Ordinary case with Attributes2Impl
+ Attributes2Impl attrs = new Attributes2Impl(multi);
+ assertEquals(multi.getLength(), attrs.getLength());
+
+ for (int i = 0; i < multi.getLength(); i++) {
+ assertEquals(multi.getURI(i), attrs.getURI(i));
+ assertEquals(multi.getLocalName(i), attrs.getLocalName(i));
+ assertEquals(multi.getQName(i), attrs.getQName(i));
+ assertEquals(multi.getType(i), attrs.getType(i));
+ assertEquals(multi.getValue(i), attrs.getValue(i));
+ assertEquals(multi.isDeclared(i), attrs.isDeclared(i));
+ assertEquals(multi.isSpecified(i), attrs.isSpecified(i));
+ }
+
+ attrs = new Attributes2Impl(empty);
+ assertEquals(0, attrs.getLength());
+
+ // Ordinary case with AttributesImpl
+ attrs = new Attributes2Impl(new AttributesImpl(multi));
+ assertEquals(multi.getLength(), attrs.getLength());
+
+ for (int i = 0; i < multi.getLength(); i++) {
+ assertEquals(multi.getURI(i), attrs.getURI(i));
+ assertEquals(multi.getLocalName(i), attrs.getLocalName(i));
+ assertEquals(multi.getQName(i), attrs.getQName(i));
+ assertEquals(multi.getType(i), attrs.getType(i));
+ assertEquals(multi.getValue(i), attrs.getValue(i));
+ assertEquals(true, attrs.isDeclared(i));
+ assertEquals(true, attrs.isSpecified(i));
+ }
+
+ // Special case with CDATA
+ attrs = new Attributes2Impl(new AttributesImpl(cdata));
+ assertEquals(1, attrs.getLength());
+ assertEquals(false, attrs.isDeclared(0));
+ assertEquals(true, attrs.isSpecified(0));
+
+ // null case
+ try {
+ attrs = new Attributes2Impl(null);
+ fail("NullPointerException expected");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "isDeclared",
+ args = { int.class }
+ )
+ public void testIsDeclaredInt() {
+ // Ordinary cases
+ assertEquals(false, multi.isDeclared(0));
+ assertEquals(true, multi.isDeclared(1));
+
+ // Out of range
+ try {
+ multi.isDeclared(-1);
+ fail("ArrayIndexOutOfBoundsException expected");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ try {
+ multi.isDeclared(4);
+ fail("ArrayIndexOutOfBoundsException expected");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // Expected
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "isDeclared",
+ args = { String.class, String.class }
+ )
+ public void testIsDeclaredStringString() {
+ // Ordinary cases
+ assertEquals(false, multi.isDeclared("http://some.uri", "foo"));
+ assertEquals(true, multi.isDeclared("http://some.uri", "bar"));
+
+ // Not found
+ try {
+ assertFalse(multi.isDeclared("not", "found"));
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "isDeclared",
+ args = { String.class }
+ )
+ public void testIsDeclaredString() {
+ // Ordinary cases
+ assertEquals(false, multi.isDeclared("ns1:foo"));
+ assertEquals(true, multi.isDeclared("ns1:bar"));
+
+ // Not found
+ try {
+ assertFalse(multi.isDeclared("notfound"));
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "isSpecified",
+ args = { int.class }
+ )
+ public void testIsSpecifiedInt() {
+ // Ordinary cases
+ assertEquals(false, multi.isSpecified(1));
+ assertEquals(true, multi.isSpecified(2));
+
+ // Out of range
+ try {
+ multi.isSpecified(-1);
+ fail("ArrayIndexOutOfBoundsException expected");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ try {
+ multi.isSpecified(4);
+ fail("ArrayIndexOutOfBoundsException expected");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // Expected
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "isSpecified",
+ args = { String.class, String.class }
+ )
+ public void testIsSpecifiedStringString() {
+ // Ordinary cases
+ assertEquals(false, multi.isSpecified("http://some.uri", "bar"));
+ assertEquals(true, multi.isSpecified("http://some.other.uri", "answer"));
+
+ // Not found
+ try {
+ assertFalse(multi.isSpecified("not", "found"));
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "isSpecified",
+ args = { String.class }
+ )
+ public void testIsSpecifiedString() {
+ // Ordinary cases
+ assertEquals(false, multi.isSpecified("ns1:bar"));
+ assertEquals(true, multi.isSpecified("ns2:answer"));
+
+ // Not found
+ try {
+ assertFalse(multi.isSpecified("notfound"));
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setDeclared",
+ args = { int.class, boolean.class }
+ )
+ public void testSetDeclared() {
+ // Ordinary cases
+ multi.setSpecified(0, false);
+ assertEquals(false, multi.isSpecified(0));
+
+ multi.setSpecified(0, true);
+ assertEquals(true, multi.isSpecified(0));
+
+ multi.setSpecified(0, false);
+ assertEquals(false, multi.isSpecified(0));
+
+ // Out of range
+ try {
+ multi.setSpecified(-1, true);
+ fail("ArrayIndexOutOfBoundsException expected");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ try {
+ multi.setSpecified(5, true);
+ fail("ArrayIndexOutOfBoundsException expected");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // Expected
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setSpecified",
+ args = { int.class, boolean.class }
+ )
+ public void testSetSpecified() {
+ // Ordinary cases
+ multi.setSpecified(0, false);
+ assertEquals(false, multi.isSpecified(0));
+
+ multi.setSpecified(0, true);
+ assertEquals(true, multi.isSpecified(0));
+
+ multi.setSpecified(0, false);
+ assertEquals(false, multi.isSpecified(0));
+
+ // Out of range
+ try {
+ multi.setSpecified(-1, true);
+ fail("ArrayIndexOutOfBoundsException expected");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ try {
+ multi.setSpecified(5, true);
+ fail("ArrayIndexOutOfBoundsException expected");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // Expected
+ }
+ }
+
+}
diff --git a/xml/src/test/java/tests/api/org/xml/sax/ext/DefaultHandler2Test.java b/xml/src/test/java/tests/api/org/xml/sax/ext/DefaultHandler2Test.java
new file mode 100644
index 0000000..52a5972
--- /dev/null
+++ b/xml/src/test/java/tests/api/org/xml/sax/ext/DefaultHandler2Test.java
@@ -0,0 +1,234 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.api.org.xml.sax.ext;
+
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+
+import junit.framework.TestCase;
+
+import org.xml.sax.SAXException;
+import org.xml.sax.ext.DefaultHandler2;
+
+import java.io.IOException;
+
+@TestTargetClass(DefaultHandler2.class)
+public class DefaultHandler2Test extends TestCase {
+
+ private DefaultHandler2 h = new DefaultHandler2();
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "DefaultHandler2",
+ args = { }
+ )
+ public void testDefaultHandler2() {
+ new DefaultHandler2();
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "startCDATA",
+ args = { }
+ )
+ public void testStartCDATA() {
+ try {
+ h.startCDATA();
+ } catch (SAXException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "endCDATA",
+ args = { }
+ )
+ public void testEndCDATA() {
+ try {
+ h.endCDATA();
+ } catch (SAXException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "startDTD",
+ args = { String.class, String.class, String.class }
+ )
+ public void testStartDTD() {
+ try {
+ h.startDTD("name", "publicId", "systemId");
+ } catch (SAXException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "endDTD",
+ args = { }
+ )
+ public void testEndDTD() {
+ try {
+ h.endDTD();
+ } catch (SAXException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "startEntity",
+ args = { String.class }
+ )
+ public void testStartEntity() {
+ try {
+ h.startEntity("name");
+ } catch (SAXException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "endEntity",
+ args = { String.class }
+ )
+ public void testEndEntity() {
+ try {
+ h.endEntity("name");
+ } catch (SAXException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "comment",
+ args = { char[].class, int.class, int.class }
+ )
+ public void testComment() {
+ try {
+ h.comment("<!-- Comment -->".toCharArray(), 0, 15);
+ } catch (SAXException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "attributeDecl",
+ args = { String.class, String.class, String.class, String.class,
+ String.class }
+ )
+ public void testAttributeDecl() {
+ try {
+ h.attributeDecl("eName", "aName", "type", "mode", "value");
+ } catch (SAXException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "elementDecl",
+ args = { String.class, String.class }
+ )
+ public void testElementDecl() {
+ try {
+ h.elementDecl("name", "model");
+ } catch (SAXException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "externalEntityDecl",
+ args = { String.class, String.class, String.class }
+ )
+ public void testExternalEntityDecl() {
+ try {
+ h.externalEntityDecl("name", "publicId", "systemId");
+ } catch (SAXException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "internalEntityDecl",
+ args = { String.class, String.class }
+ )
+ public void testInternalEntityDecl() {
+ try {
+ h.internalEntityDecl("name", "value");
+ } catch (SAXException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getExternalSubset",
+ args = { String.class, String.class }
+ )
+ public void testGetExternalSubset() {
+ try {
+ assertNull(h.getExternalSubset("name", "http://some.uri"));
+ } catch (SAXException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ } catch (IOException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "resolveEntity",
+ args = { String.class, String.class }
+ )
+ public void testResolveEntityStringString() {
+ try {
+ assertNull(h.resolveEntity("publicId", "systemId"));
+ } catch (SAXException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ } catch (IOException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "resolveEntity",
+ args = { String.class, String.class, String.class, String.class }
+ )
+ public void testResolveEntityStringStringStringString() {
+ try {
+ assertNull(h.resolveEntity("name", "publicId", "http://some.uri",
+ "systemId"));
+ } catch (SAXException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ } catch (IOException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+ }
+
+}
diff --git a/xml/src/test/java/tests/api/org/xml/sax/ext/Locator2ImplTest.java b/xml/src/test/java/tests/api/org/xml/sax/ext/Locator2ImplTest.java
new file mode 100644
index 0000000..b018f59
--- /dev/null
+++ b/xml/src/test/java/tests/api/org/xml/sax/ext/Locator2ImplTest.java
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.api.org.xml.sax.ext;
+
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargets;
+
+import junit.framework.TestCase;
+
+import org.xml.sax.Locator;
+import org.xml.sax.ext.Locator2Impl;
+import org.xml.sax.helpers.LocatorImpl;
+
+@TestTargetClass(Locator2Impl.class)
+public class Locator2ImplTest extends TestCase {
+
+ public static final String SYS = "mySystemID";
+
+ public static final String PUB = "myPublicID";
+
+ public static final int ROW = 1;
+
+ public static final int COL = 2;
+
+ public static final String ENC = "Klingon";
+
+ public static final String XML = "1.0";
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "Locator2Impl",
+ args = { }
+ )
+ public void testLocatorImpl() {
+ Locator2Impl l = new Locator2Impl();
+
+ assertEquals(null, l.getPublicId());
+ assertEquals(null, l.getSystemId());
+ assertEquals(0, l.getLineNumber());
+ assertEquals(0, l.getColumnNumber());
+
+ assertEquals(null, l.getEncoding());
+ assertEquals(null, l.getXMLVersion());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "Locator2Impl",
+ args = { Locator.class }
+ )
+ public void testLocatorImplLocator() {
+ Locator2Impl inner = new Locator2Impl();
+
+ inner.setPublicId(PUB);
+ inner.setSystemId(SYS);
+ inner.setLineNumber(ROW);
+ inner.setColumnNumber(COL);
+
+ inner.setEncoding(ENC);
+ inner.setXMLVersion(XML);
+
+ // Ordinary case
+ Locator2Impl outer = new Locator2Impl(inner);
+
+ assertEquals(PUB, outer.getPublicId());
+ assertEquals(SYS, outer.getSystemId());
+ assertEquals(ROW, outer.getLineNumber());
+ assertEquals(COL, outer.getColumnNumber());
+
+ assertEquals(ENC, outer.getEncoding());
+ assertEquals(XML, outer.getXMLVersion());
+
+ // Instance of old locator
+ outer = new Locator2Impl(new LocatorImpl(inner));
+
+ assertEquals(PUB, outer.getPublicId());
+ assertEquals(SYS, outer.getSystemId());
+ assertEquals(ROW, outer.getLineNumber());
+ assertEquals(COL, outer.getColumnNumber());
+
+ assertEquals(null, outer.getEncoding());
+ assertEquals(null, outer.getXMLVersion());
+
+ // No locator
+ try {
+ outer = new Locator2Impl(null);
+ fail("NullPointerException expected");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setXMLVersion",
+ args = { String.class }
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getXMLVersion",
+ args = { }
+ )
+ })
+ public void testSetXMLVersionGetXMLVersion() {
+ Locator2Impl l = new Locator2Impl();
+
+ l.setXMLVersion(XML);
+ assertEquals(XML, l.getXMLVersion());
+
+ l.setXMLVersion(null);
+ assertEquals(null, l.getXMLVersion());
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setEncoding",
+ args = { String.class }
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getEncoding",
+ args = { }
+ )
+ })
+ public void testSetEncodingGetEncoding() {
+ Locator2Impl l = new Locator2Impl();
+
+ l.setEncoding(ENC);
+ assertEquals(ENC, l.getEncoding());
+
+ l.setEncoding(null);
+ assertEquals(null, l.getEncoding());
+ }
+
+}
diff --git a/xml/src/test/java/tests/api/org/xml/sax/helpers/AllTests.java b/xml/src/test/java/tests/api/org/xml/sax/helpers/AllTests.java
new file mode 100644
index 0000000..5bf63bf
--- /dev/null
+++ b/xml/src/test/java/tests/api/org/xml/sax/helpers/AllTests.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.api.org.xml.sax.helpers;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class AllTests {
+
+ public static void main(String[] args) {
+ junit.textui.TestRunner.run(AllTests.suite());
+ }
+
+ public static Test suite() {
+ TestSuite suite = tests.TestSuiteFactory.createTestSuite("Tests for org.xml.sax.helpers package");
+ // $JUnit-BEGIN$
+
+ suite.addTestSuite(AttributeListImplTest.class);
+ suite.addTestSuite(AttributesImplTest.class);
+ suite.addTestSuite(ParserFactoryTest.class);
+ suite.addTestSuite(DefaultHandlerTest.class);
+ suite.addTestSuite(LocatorImplTest.class);
+ suite.addTestSuite(NamespaceSupportTest.class);
+ suite.addTestSuite(XMLFilterImplTest.class);
+ suite.addTestSuite(XMLReaderAdapterTest.class);
+ suite.addTestSuite(XMLReaderFactoryTest.class);
+
+ // $JUnit-END$
+ return suite;
+ }
+}
diff --git a/xml/src/test/java/tests/api/org/xml/sax/helpers/AttributeListImplTest.java b/xml/src/test/java/tests/api/org/xml/sax/helpers/AttributeListImplTest.java
new file mode 100644
index 0000000..00658cb
--- /dev/null
+++ b/xml/src/test/java/tests/api/org/xml/sax/helpers/AttributeListImplTest.java
@@ -0,0 +1,270 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.api.org.xml.sax.helpers;
+
+import junit.framework.TestCase;
+
+import org.xml.sax.AttributeList;
+import org.xml.sax.helpers.AttributeListImpl;
+
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+
+@SuppressWarnings("deprecation")
+@TestTargetClass(AttributeListImpl.class)
+public class AttributeListImplTest extends TestCase {
+
+ private AttributeListImpl empty = new AttributeListImpl();
+
+ private AttributeListImpl multi = new AttributeListImpl();
+
+ @Override
+ public void setUp() {
+ multi.addAttribute("foo", "string", "abc");
+ multi.addAttribute("bar", "string", "xyz");
+ multi.addAttribute("answer", "int", "42");
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "AttributeListImpl",
+ args = { }
+ )
+ public void testAttributeListImpl() {
+ assertEquals(0, empty.getLength());
+ assertEquals(3, multi.getLength());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "AttributeListImpl",
+ args = { AttributeList.class }
+ )
+ public void testAttributeListImplAttributeList() {
+ // Ordinary case
+ AttributeListImpl ai = new AttributeListImpl(empty);
+ assertEquals(0, ai.getLength());
+
+ // Another ordinary case
+ ai = new AttributeListImpl(multi);
+ assertEquals(3, ai.getLength());
+
+ // No Attributes
+ try {
+ ai = new AttributeListImpl(null);
+ assertEquals(0, ai.getLength());
+ fail("NullPointerException expected");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setAttributeList",
+ args = { AttributeList.class }
+ )
+ public void testSetAttributeList() {
+ // Ordinary cases
+ AttributeListImpl attrs = new AttributeListImpl();
+ attrs.addAttribute("doe", "boolean", "false");
+
+ attrs.setAttributeList(empty);
+ assertEquals(0, attrs.getLength());
+
+ attrs.setAttributeList(multi);
+ assertEquals(multi.getLength(), attrs.getLength());
+
+ for (int i = 0; i < multi.getLength(); i++) {
+ assertEquals(multi.getName(i), attrs.getName(i));
+ assertEquals(multi.getType(i), attrs.getType(i));
+ assertEquals(multi.getValue(i), attrs.getValue(i));
+ }
+
+ // null case
+ try {
+ attrs.setAttributeList(null);
+ fail("NullPointerException expected");
+ } catch (NullPointerException e) {
+ // Expected, must still have old elements
+ assertEquals(3, attrs.getLength());
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "addAttribute",
+ args = { String.class, String.class, String.class }
+ )
+ public void testAddAttribute() {
+ // Ordinary case
+ multi.addAttribute("doe", "boolean", "false");
+
+ assertEquals("doe", multi.getName(3));
+ assertEquals("boolean", multi.getType(3));
+ assertEquals("false", multi.getValue(3));
+
+ // Duplicate case
+ multi.addAttribute("doe", "boolean", "false");
+
+ assertEquals("doe", multi.getName(4));
+ assertEquals("boolean", multi.getType(4));
+ assertEquals("false", multi.getValue(4));
+
+ // null case
+ multi.addAttribute(null, null, null);
+ assertEquals(null, multi.getName(5));
+ assertEquals(null, multi.getType(5));
+ assertEquals(null, multi.getValue(5));
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "removeAttribute",
+ args = { String.class }
+ )
+ public void testRemoveAttribute() {
+ // Ordinary case
+ multi.removeAttribute("foo");
+ assertEquals("bar", multi.getName(0));
+ assertEquals("string", multi.getType(0));
+ assertEquals("xyz", multi.getValue(0));
+
+ // Unknown attribute
+ multi.removeAttribute("john");
+ assertEquals(2, multi.getLength());
+
+ // null case
+ multi.removeAttribute(null);
+ assertEquals(2, multi.getLength());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "clear",
+ args = { }
+ )
+ public void testClear() {
+ assertEquals(3, multi.getLength());
+ multi.clear();
+ assertEquals(0, multi.getLength());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getLength",
+ args = { }
+ )
+ public void testGetLength() {
+ AttributeListImpl ai = new AttributeListImpl(empty);
+ assertEquals(0, ai.getLength());
+
+ ai = new AttributeListImpl(multi);
+ assertEquals(3, ai.getLength());
+
+ for (int i = 2; i >= 0; i--) {
+ ai.removeAttribute(ai.getName(i));
+ assertEquals(i, ai.getLength());
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getName",
+ args = { int.class }
+ )
+ public void testGetName() {
+ // Ordinary cases
+ assertEquals("foo", multi.getName(0));
+ assertEquals("bar", multi.getName(1));
+ assertEquals("answer", multi.getName(2));
+
+ // Out of range
+ assertEquals(null, multi.getName(-1));
+ assertEquals(null, multi.getName(3));
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getType",
+ args = { int.class }
+ )
+ public void testGetTypeInt() {
+ // Ordinary cases
+ assertEquals("string", multi.getType(0));
+ assertEquals("string", multi.getType(1));
+ assertEquals("int", multi.getType(2));
+
+ // Out of range
+ assertEquals(null, multi.getType(-1));
+ assertEquals(null, multi.getType(3));
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getValue",
+ args = { int.class }
+ )
+ public void testGetValueInt() {
+ // Ordinary cases
+ assertEquals("abc", multi.getValue(0));
+ assertEquals("xyz", multi.getValue(1));
+ assertEquals("42", multi.getValue(2));
+
+ // Out of range
+ assertEquals(null, multi.getValue(-1));
+ assertEquals(null, multi.getValue(5));
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getType",
+ args = { String.class }
+ )
+ public void testGetTypeString() {
+ // Ordinary cases
+ assertEquals("string", multi.getType("foo"));
+ assertEquals("string", multi.getType("bar"));
+ assertEquals("int", multi.getType("answer"));
+
+ // Not found
+ assertEquals(null, multi.getType("john"));
+
+ // null case
+ assertEquals(null, multi.getType(null));
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getValue",
+ args = { String.class }
+ )
+ public void testGetValueString() {
+ // Ordinary cases
+ assertEquals("abc", multi.getValue("foo"));
+ assertEquals("xyz", multi.getValue("bar"));
+ assertEquals("42", multi.getValue("answer"));
+
+ // Not found
+ assertEquals(null, multi.getValue("john"));
+
+ // null case
+ assertEquals(null, multi.getValue(null));
+ }
+
+}
diff --git a/xml/src/test/java/tests/api/org/xml/sax/helpers/AttributesImplTest.java b/xml/src/test/java/tests/api/org/xml/sax/helpers/AttributesImplTest.java
new file mode 100644
index 0000000..0efe25f
--- /dev/null
+++ b/xml/src/test/java/tests/api/org/xml/sax/helpers/AttributesImplTest.java
@@ -0,0 +1,608 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.api.org.xml.sax.helpers;
+
+import junit.framework.TestCase;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.helpers.AttributesImpl;
+
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+
+@TestTargetClass(AttributesImpl.class)
+public class AttributesImplTest extends TestCase {
+
+ private AttributesImpl empty = new AttributesImpl();
+
+ private AttributesImpl multi = new AttributesImpl();
+
+ @Override
+ public void setUp() {
+ multi.addAttribute("http://some.uri", "foo", "ns1:foo",
+ "string", "abc");
+ multi.addAttribute("http://some.uri", "bar", "ns1:bar",
+ "string", "xyz");
+ multi.addAttribute("http://some.other.uri", "answer", "ns2:answer",
+ "int", "42");
+
+ multi.addAttribute("", "gabbaHey", "", "string", "1-2-3-4");
+ multi.addAttribute("", "", "gabba:hey", "string", "1-2-3-4");
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "AttributesImpl",
+ args = { }
+ )
+ public void testAttributesImpl() {
+ assertEquals(0, empty.getLength());
+ assertEquals(5, multi.getLength());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "AttributesImpl",
+ args = { Attributes.class }
+ )
+ public void testAttributesImplAttributes() {
+ // Ordinary case
+ AttributesImpl ai = new AttributesImpl(empty);
+ assertEquals(0, ai.getLength());
+
+ // Another ordinary case
+ ai = new AttributesImpl(multi);
+ assertEquals(5, ai.getLength());
+
+ // No Attributes
+ try {
+ ai = new AttributesImpl(null);
+ assertEquals(0, ai.getLength());
+ fail("NullPointerException expected");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getLength",
+ args = { }
+ )
+ public void testGetLength() {
+ AttributesImpl ai = new AttributesImpl(empty);
+ assertEquals(0, ai.getLength());
+
+ ai = new AttributesImpl(multi);
+ assertEquals(5, ai.getLength());
+
+ for (int i = 4; i >= 0; i--) {
+ ai.removeAttribute(i);
+ assertEquals(i, ai.getLength());
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getURI",
+ args = { int.class }
+ )
+ public void testGetURI() {
+ // Ordinary cases
+ assertEquals("http://some.uri", multi.getURI(0));
+ assertEquals("http://some.uri", multi.getURI(1));
+ assertEquals("http://some.other.uri", multi.getURI(2));
+ assertEquals("", multi.getURI(3));
+ assertEquals("", multi.getURI(4));
+
+ // Out of range
+ assertEquals(null, multi.getURI(-1));
+ assertEquals(null, multi.getURI(5));
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getLocalName",
+ args = { int.class }
+ )
+ public void testGetLocalName() {
+ // Ordinary cases
+ assertEquals("foo", multi.getLocalName(0));
+ assertEquals("bar", multi.getLocalName(1));
+ assertEquals("answer", multi.getLocalName(2));
+ assertEquals("gabbaHey", multi.getLocalName(3));
+ assertEquals("", multi.getLocalName(4));
+
+ // Out of range
+ assertEquals(null, multi.getLocalName(-1));
+ assertEquals(null, multi.getLocalName(5));
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getQName",
+ args = { int.class }
+ )
+ public void testGetQName() {
+ // Ordinary cases
+ assertEquals("ns1:foo", multi.getQName(0));
+ assertEquals("ns1:bar", multi.getQName(1));
+ assertEquals("ns2:answer", multi.getQName(2));
+ assertEquals("", multi.getQName(3));
+ assertEquals("gabba:hey", multi.getQName(4));
+
+ // Out of range
+ assertEquals(null, multi.getQName(-1));
+ assertEquals(null, multi.getQName(5));
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getType",
+ args = { int.class }
+ )
+ public void testGetTypeInt() {
+ // Ordinary cases
+ assertEquals("string", multi.getType(0));
+ assertEquals("string", multi.getType(1));
+ assertEquals("int", multi.getType(2));
+ assertEquals("string", multi.getType(3));
+ assertEquals("string", multi.getType(4));
+
+ // Out of range
+ assertEquals(null, multi.getType(-1));
+ assertEquals(null, multi.getType(5));
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getValue",
+ args = { int.class }
+ )
+ public void testGetValueInt() {
+ // Ordinary cases
+ assertEquals("abc", multi.getValue(0));
+ assertEquals("xyz", multi.getValue(1));
+ assertEquals("42", multi.getValue(2));
+ assertEquals("1-2-3-4", multi.getValue(3));
+ assertEquals("1-2-3-4", multi.getValue(4));
+
+ // Out of range
+ assertEquals(null, multi.getValue(-1));
+ assertEquals(null, multi.getValue(5));
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getIndex",
+ args = { String.class, String.class }
+ )
+ public void testGetIndexStringString() {
+ // Ordinary cases
+ assertEquals(0, multi.getIndex("http://some.uri", "foo"));
+ assertEquals(1, multi.getIndex("http://some.uri", "bar"));
+ assertEquals(2, multi.getIndex("http://some.other.uri", "answer"));
+
+ // Not found
+ assertEquals(-1, multi.getIndex("john", "doe"));
+
+ // null cases
+ assertEquals(-1, multi.getIndex("http://some.uri", null));
+ assertEquals(-1, multi.getIndex(null, "foo"));
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getIndex",
+ args = { String.class }
+ )
+ public void testGetIndexString() {
+ // Ordinary cases
+ assertEquals(0, multi.getIndex("ns1:foo"));
+ assertEquals(1, multi.getIndex("ns1:bar"));
+ assertEquals(2, multi.getIndex("ns2:answer"));
+ assertEquals(4, multi.getIndex("gabba:hey"));
+
+ // Not found
+ assertEquals(-1, multi.getIndex("john:doe"));
+
+ // null case
+ assertEquals(-1, multi.getIndex(null));
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getType",
+ args = { String.class, String.class }
+ )
+ public void testGetTypeStringString() {
+ // Ordinary cases
+ assertEquals("string", multi.getType("http://some.uri", "foo"));
+ assertEquals("string", multi.getType("http://some.uri", "bar"));
+ assertEquals("int", multi.getType("http://some.other.uri", "answer"));
+
+ // Not found
+ assertEquals(null, multi.getType("john", "doe"));
+
+ // null cases
+ assertEquals(null, multi.getType("http://some.uri", null));
+ assertEquals(null, multi.getType(null, "foo"));
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getType",
+ args = { String.class }
+ )
+ public void testGetTypeString() {
+ // Ordinary cases
+ assertEquals("string", multi.getType("ns1:foo"));
+ assertEquals("string", multi.getType("ns1:bar"));
+ assertEquals("int", multi.getType("ns2:answer"));
+ assertEquals("string", multi.getType("gabba:hey"));
+
+ // Not found
+ assertEquals(null, multi.getType("john:doe"));
+
+ // null case
+ assertEquals(null, multi.getType(null));
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getValue",
+ args = { String.class, String.class }
+ )
+ public void testGetValueStringString() {
+ // Ordinary cases
+ assertEquals("abc", multi.getValue("http://some.uri", "foo"));
+ assertEquals("xyz", multi.getValue("http://some.uri", "bar"));
+ assertEquals("42", multi.getValue("http://some.other.uri", "answer"));
+
+ // Not found
+ assertEquals(null, multi.getValue("john", "doe"));
+
+ // null cases
+ assertEquals(null, multi.getValue("http://some.uri", null));
+ assertEquals(null, multi.getValue(null, "foo"));
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getValue",
+ args = { String.class }
+ )
+ public void testGetValueString() {
+ // Ordinary cases
+ assertEquals("abc", multi.getValue("ns1:foo"));
+ assertEquals("xyz", multi.getValue("ns1:bar"));
+ assertEquals("42", multi.getValue("ns2:answer"));
+ assertEquals("1-2-3-4", multi.getValue("gabba:hey"));
+
+ // Not found
+ assertEquals(null, multi.getValue("john:doe"));
+
+ // null case
+ assertEquals(null, multi.getValue(null));
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "clear",
+ args = { }
+ )
+ public void testClear() {
+ assertEquals(5, multi.getLength());
+ multi.clear();
+ assertEquals(0, multi.getLength());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setAttributes",
+ args = { Attributes.class }
+ )
+ public void testSetAttributes() {
+ // Ordinary cases
+ AttributesImpl attrs = new AttributesImpl();
+ attrs.addAttribute("http://yet.another.uri", "doe", "john:doe",
+ "boolean", "false");
+
+ attrs.setAttributes(empty);
+ assertEquals(0, attrs.getLength());
+
+ attrs.setAttributes(multi);
+ assertEquals(multi.getLength(), attrs.getLength());
+
+ for (int i = 0; i < multi.getLength(); i++) {
+ assertEquals(multi.getURI(i), attrs.getURI(i));
+ assertEquals(multi.getLocalName(i), attrs.getLocalName(i));
+ assertEquals(multi.getQName(i), attrs.getQName(i));
+ assertEquals(multi.getType(i), attrs.getType(i));
+ assertEquals(multi.getValue(i), attrs.getValue(i));
+ }
+
+ // null case
+ try {
+ attrs.setAttributes(null);
+ fail("NullPointerException expected");
+ } catch (NullPointerException e) {
+ // Expected, but must be empty now
+ assertEquals(0, attrs.getLength());
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "addAttribute",
+ args = { String.class, String.class, String.class, String.class,
+ String.class }
+ )
+ public void testAddAttribute() {
+ // Ordinary case
+ multi.addAttribute("http://yet.another.uri", "doe", "john:doe",
+ "boolean", "false");
+
+ assertEquals("http://yet.another.uri", multi.getURI(5));
+ assertEquals("doe", multi.getLocalName(5));
+ assertEquals("john:doe", multi.getQName(5));
+ assertEquals("boolean", multi.getType(5));
+ assertEquals("false", multi.getValue(5));
+
+ // Duplicate case
+ multi.addAttribute("http://yet.another.uri", "doe", "john:doe",
+ "boolean", "false");
+
+ assertEquals("http://yet.another.uri", multi.getURI(6));
+ assertEquals("doe", multi.getLocalName(6));
+ assertEquals("john:doe", multi.getQName(6));
+ assertEquals("boolean", multi.getType(6));
+ assertEquals("false", multi.getValue(6));
+
+ // null case
+ multi.addAttribute(null, null, null, null, null);
+ assertEquals(null, multi.getURI(7));
+ assertEquals(null, multi.getLocalName(7));
+ assertEquals(null, multi.getQName(7));
+ assertEquals(null, multi.getType(7));
+ assertEquals(null, multi.getValue(7));
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setAttribute",
+ args = { int.class, String.class, String.class, String.class,
+ String.class, String.class }
+ )
+ public void testSetAttribute() {
+ // Ordinary case
+ multi.setAttribute(0, "http://yet.another.uri", "doe", "john:doe",
+ "boolean", "false");
+ assertEquals("http://yet.another.uri", multi.getURI(0));
+ assertEquals("doe", multi.getLocalName(0));
+ assertEquals("john:doe", multi.getQName(0));
+ assertEquals("boolean", multi.getType(0));
+ assertEquals("false", multi.getValue(0));
+
+ // null case
+ multi.setAttribute(1, null, null, null, null, null);
+ assertEquals(null, multi.getURI(1));
+ assertEquals(null, multi.getLocalName(1));
+ assertEquals(null, multi.getQName(1));
+ assertEquals(null, multi.getType(1));
+ assertEquals(null, multi.getValue(1));
+
+ // Out of range
+ try {
+ multi.setAttribute(-1, "http://yet.another.uri", "doe", "john:doe",
+ "boolean", "false");
+ fail("ArrayIndexOutOfBoundsException expected");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ try {
+ multi.setAttribute(5, "http://yet.another.uri", "doe", "john:doe",
+ "boolean", "false");
+ fail("ArrayIndexOutOfBoundsException expected");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // Expected
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "removeAttribute",
+ args = { int.class }
+ )
+ public void testRemoveAttribute() {
+ // Ordinary case
+ multi.removeAttribute(0);
+ assertEquals("http://some.uri", multi.getURI(0));
+ assertEquals("bar", multi.getLocalName(0));
+ assertEquals("ns1:bar", multi.getQName(0));
+ assertEquals("string", multi.getType(0));
+ assertEquals("xyz", multi.getValue(0));
+
+ // Out of range
+ try {
+ multi.removeAttribute(-1);
+ fail("ArrayIndexOutOfBoundsException expected");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ try {
+ multi.removeAttribute(4);
+ fail("ArrayIndexOutOfBoundsException expected");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // Expected
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setURI",
+ args = { int.class, String.class }
+ )
+ public void testSetURI() {
+ // Ordinary case
+ multi.setURI(0, "http://yet.another.uri");
+ assertEquals("http://yet.another.uri", multi.getURI(0));
+
+ // null case
+ multi.setURI(1, null);
+ assertEquals(null, multi.getURI(1));
+
+ // Out of range
+ try {
+ multi.setURI(-1, "http://yet.another.uri");
+ fail("ArrayIndexOutOfBoundsException expected");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ try {
+ multi.setURI(5, "http://yet.another.uri");
+ fail("ArrayIndexOutOfBoundsException expected");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // Expected
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setLocalName",
+ args = { int.class, String.class }
+ )
+ public void testSetLocalName() {
+ // Ordinary case
+ multi.setLocalName(0, "john");
+ assertEquals("john", multi.getLocalName(0));
+
+ // null case
+ multi.setLocalName(1, null);
+ assertEquals(null, multi.getLocalName(1));
+
+ // Out of range
+ try {
+ multi.setLocalName(-1, "john");
+ fail("ArrayIndexOutOfBoundsException expected");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ try {
+ multi.setLocalName(5, "john");
+ fail("ArrayIndexOutOfBoundsException expected");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // Expected
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setQName",
+ args = { int.class, String.class }
+ )
+ public void testSetQName() {
+ // Ordinary case
+ multi.setQName(0, "john:doe");
+ assertEquals("john:doe", multi.getQName(0));
+
+ // null case
+ multi.setQName(1, null);
+ assertEquals(null, multi.getQName(1));
+
+ // Out of range
+ try {
+ multi.setQName(-1, "john:doe");
+ fail("ArrayIndexOutOfBoundsException expected");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ try {
+ multi.setQName(5, "john:doe");
+ fail("ArrayIndexOutOfBoundsException expected");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // Expected
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setType",
+ args = { int.class, String.class }
+ )
+ public void testSetType() {
+ // Ordinary case
+ multi.setType(0, "float");
+ assertEquals("float", multi.getType(0));
+
+ // null case
+ multi.setType(1, null);
+ assertEquals(null, multi.getType(1));
+
+ // Out of range
+ try {
+ multi.setType(-1, "float");
+ fail("ArrayIndexOutOfBoundsException expected");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ try {
+ multi.setType(5, "float");
+ fail("ArrayIndexOutOfBoundsException expected");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // Expected
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setValue",
+ args = { int.class, String.class }
+ )
+ public void testSetValue() {
+ // Ordinary case
+ multi.setValue(0, "too much");
+ assertEquals("too much", multi.getValue(0));
+
+ // null case
+ multi.setValue(1, null);
+ assertEquals(null, multi.getValue(1));
+
+ // Out of range
+ try {
+ multi.setValue(-1, "too much");
+ fail("ArrayIndexOutOfBoundsException expected");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ try {
+ multi.setValue(5, "too much");
+ fail("ArrayIndexOutOfBoundsException expected");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // Expected
+ }
+ }
+
+}
diff --git a/xml/src/test/java/tests/api/org/xml/sax/helpers/DefaultHandlerTest.java b/xml/src/test/java/tests/api/org/xml/sax/helpers/DefaultHandlerTest.java
new file mode 100644
index 0000000..527048f
--- /dev/null
+++ b/xml/src/test/java/tests/api/org/xml/sax/helpers/DefaultHandlerTest.java
@@ -0,0 +1,278 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.api.org.xml.sax.helpers;
+
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+
+import junit.framework.TestCase;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.helpers.AttributesImpl;
+import org.xml.sax.helpers.DefaultHandler;
+import org.xml.sax.helpers.LocatorImpl;
+
+import java.io.IOException;
+
+@TestTargetClass(DefaultHandler.class)
+public class DefaultHandlerTest extends TestCase {
+
+ /*
+ * Note: most of the tests have to check for an empty implementation of the
+ * respective methods and, as a result, are somewhat trivial.
+ */
+
+ private DefaultHandler h = new DefaultHandler();
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "resolveEntity",
+ args = { String.class, String.class }
+ )
+ public void testResolveEntity() {
+ try {
+ h.resolveEntity("publicID", "systemID");
+ } catch (SAXException e) {
+ throw new RuntimeException(e);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "notationDecl",
+ args = { String.class, String.class, String.class }
+ )
+ public void testNotationDecl() {
+ try {
+ h.notationDecl("name", "publicID", "systemID");
+ } catch (SAXException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "unparsedEntityDecl",
+ args = { String.class, String.class, String.class, String.class }
+ )
+ public void testUnparsedEntityDecl() {
+ try {
+ h.unparsedEntityDecl("name", "publicID", "systemID",
+ "notationName");
+ } catch (SAXException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setDocumentLocator",
+ args = { org.xml.sax.Locator.class }
+ )
+ public void testSetDocumentLocator() {
+ h.setDocumentLocator(new LocatorImpl());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "startDocument",
+ args = { }
+ )
+ public void testStartDocument() {
+ try {
+ h.startDocument();
+ } catch (SAXException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "endDocument",
+ args = { }
+ )
+ public void testEndDocument() {
+ try {
+ h.endDocument();
+ } catch (SAXException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "startPrefixMapping",
+ args = { String.class, String.class }
+ )
+ public void testStartPrefixMapping() {
+ try {
+ h.startPrefixMapping("prefix", "uri");
+ } catch (SAXException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "endPrefixMapping",
+ args = { String.class }
+ )
+ public void testEndPrefixMapping() {
+ try {
+ h.endPrefixMapping("prefix");
+ } catch (SAXException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "startElement",
+ args = { String.class, String.class, String.class,
+ Attributes.class }
+ )
+ public void testStartElement() {
+ try {
+ h.startElement("uri", "name", "qname", new AttributesImpl());
+ } catch (SAXException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "endElement",
+ args = { String.class, String.class, String.class }
+ )
+ public void testEndElement() {
+ try {
+ h.endElement("uri", "name", "qname");
+ } catch (SAXException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "characters",
+ args = { char[].class, int.class, int.class }
+ )
+ public void testCharacters() {
+ try {
+ h.characters("The quick brown fox".toCharArray(), 4, 11);
+ } catch (SAXException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "ignorableWhitespace",
+ args = { char[].class, int.class, int.class }
+ )
+ public void testIgnorableWhitespace() {
+ try {
+ h.ignorableWhitespace(" ".toCharArray(), 4, 11);
+ } catch (SAXException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "processingInstruction",
+ args = { String.class, String.class }
+ )
+ public void testProcessingInstruction() {
+ try {
+ h.processingInstruction("target", "data");
+ } catch (SAXException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "skippedEntity",
+ args = { String.class }
+ )
+ public void testSkippedEntity() {
+ try {
+ h.skippedEntity("name");
+ } catch (SAXException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "warning",
+ args = { org.xml.sax.SAXParseException.class }
+ )
+ public void testWarning() {
+ try {
+ h.warning(new SAXParseException("Foo", new LocatorImpl()));
+ } catch (SAXException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "error",
+ args = { org.xml.sax.SAXParseException.class }
+ )
+ public void testError() {
+ try {
+ h.error(new SAXParseException("Foo", new LocatorImpl()));
+ } catch (SAXException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "fatalError",
+ args = { org.xml.sax.SAXParseException.class }
+ )
+ public void testFatalError() {
+ // Ordinary case
+ try {
+ h.fatalError(new SAXParseException("Foo", new LocatorImpl()));
+ fail("SAXException expected");
+ } catch (SAXException e) {
+ // Expected
+ }
+
+ // No exception
+ try {
+ h.fatalError(null);
+ fail("NullPointerException expected");
+ } catch (SAXException e) {
+ fail("NullPointerException expected");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ }
+
+}
diff --git a/xml/src/test/java/tests/api/org/xml/sax/helpers/LocatorImplTest.java b/xml/src/test/java/tests/api/org/xml/sax/helpers/LocatorImplTest.java
new file mode 100644
index 0000000..e6b243c
--- /dev/null
+++ b/xml/src/test/java/tests/api/org/xml/sax/helpers/LocatorImplTest.java
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.api.org.xml.sax.helpers;
+
+import junit.framework.TestCase;
+
+import org.xml.sax.Locator;
+import org.xml.sax.helpers.LocatorImpl;
+
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargets;
+
+@TestTargetClass(LocatorImpl.class)
+public class LocatorImplTest extends TestCase {
+
+ public static final String SYS = "mySystemID";
+
+ public static final String PUB = "myPublicID";
+
+ public static final int ROW = 1;
+
+ public static final int COL = 2;
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "LocatorImpl",
+ args = { }
+ )
+ public void testLocatorImpl() {
+ LocatorImpl l = new LocatorImpl();
+
+ assertEquals(null, l.getPublicId());
+ assertEquals(null, l.getSystemId());
+ assertEquals(0, l.getLineNumber());
+ assertEquals(0, l.getColumnNumber());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "LocatorImpl",
+ args = { Locator.class }
+ )
+ public void testLocatorImplLocator() {
+ LocatorImpl inner = new LocatorImpl();
+
+ inner.setPublicId(PUB);
+ inner.setSystemId(SYS);
+ inner.setLineNumber(ROW);
+ inner.setColumnNumber(COL);
+
+ // Ordinary case
+ LocatorImpl outer = new LocatorImpl(inner);
+
+ assertEquals(PUB, outer.getPublicId());
+ assertEquals(SYS, outer.getSystemId());
+ assertEquals(ROW, outer.getLineNumber());
+ assertEquals(COL, outer.getColumnNumber());
+
+ // No locator
+ try {
+ outer = new LocatorImpl(null);
+ fail("NullPointerException expected");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setPublicId",
+ args = { String.class }
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getPublicId",
+ args = { }
+ )
+ })
+ public void testSetPublicIdGetPublicId() {
+ LocatorImpl l = new LocatorImpl();
+
+ l.setPublicId(PUB);
+ assertEquals(PUB, l.getPublicId());
+
+ l.setPublicId(null);
+ assertEquals(null, l.getPublicId());
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setSystemId",
+ args = { String.class }
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getSystemId",
+ args = { }
+ )
+ })
+ public void testSetSystemIdGetSystemId() {
+ LocatorImpl l = new LocatorImpl();
+
+ l.setSystemId(SYS);
+ assertEquals(SYS, l.getSystemId());
+
+ l.setSystemId(null);
+ assertEquals(null, l.getSystemId());
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setLineNumber",
+ args = { int.class }
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getLineNumber",
+ args = { }
+ )
+ })
+ public void testSetLineNumberGetLineNumber() {
+ LocatorImpl l = new LocatorImpl();
+
+ l.setLineNumber(ROW);
+ assertEquals(ROW, l.getLineNumber());
+
+ l.setLineNumber(0);
+ assertEquals(0, l.getLineNumber());
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setColumnNumber",
+ args = { int.class }
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getColumnNumber",
+ args = { }
+ )
+ })
+ public void testSetColumnNumberGetColumnNumber() {
+ LocatorImpl l = new LocatorImpl();
+
+ l.setColumnNumber(COL);
+ assertEquals(COL, l.getColumnNumber());
+
+ l.setColumnNumber(0);
+ assertEquals(0, l.getColumnNumber());
+ }
+
+}
diff --git a/xml/src/test/java/tests/api/org/xml/sax/helpers/NamespaceSupportTest.java b/xml/src/test/java/tests/api/org/xml/sax/helpers/NamespaceSupportTest.java
new file mode 100644
index 0000000..b163b54
--- /dev/null
+++ b/xml/src/test/java/tests/api/org/xml/sax/helpers/NamespaceSupportTest.java
@@ -0,0 +1,434 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.api.org.xml.sax.helpers;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.EmptyStackException;
+import java.util.Enumeration;
+
+import junit.framework.TestCase;
+
+import org.xml.sax.helpers.NamespaceSupport;
+
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargets;
+
+@TestTargetClass(
+ value = NamespaceSupport.class,
+ untestedMethods = {
+ }
+)
+public class NamespaceSupportTest extends TestCase {
+
+ final static String defaultUri = "http://www.android.com";
+ final static String marketUri = "http://www.android.com/market";
+
+ NamespaceSupport ns;
+ ArrayList<String> expected;
+
+ @Override
+ public void setUp() {
+ expected = new ArrayList<String>();
+ expected.add("ak");
+ expected.add("bk");
+
+ ns = new NamespaceSupport();
+ ns.pushContext();
+
+ ns.declarePrefix("ak", marketUri);
+ ns.declarePrefix("bk", marketUri);
+ ns.declarePrefix("", defaultUri);
+ }
+
+ @SuppressWarnings("unchecked")
+ @TestTargets ({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Checks that a new NamespaceSupport object contains a " +
+ "default context with two predefined prefixes.",
+ method = "NamespaceSupport",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ method = "popContext",
+ args = {}
+ )
+ })
+ public void testConstructor() {
+ String prefix;
+ boolean xmlPrefixExists = false;
+
+ ns = new NamespaceSupport();
+ Enumeration<String> prefixes = ns.getDeclaredPrefixes();
+
+ while (prefixes.hasMoreElements()) {
+ prefix = prefixes.nextElement();
+ if (prefix.equals("xml")) xmlPrefixExists = true;
+ }
+
+ assertTrue("Test 1: xml prefix does not exist.", xmlPrefixExists);
+
+ // Check that only one context has been created by the constructor.
+ try {
+ ns.popContext();
+ fail("Test 2: EmptyStackException expected.");
+ } catch (EmptyStackException e) {
+ // Expected.
+ }
+ }
+
+ @TestTargets ({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "pushContext",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ method = "popContext",
+ args = {}
+ )
+ })
+ public void testPush_PopContext() {
+ int count;
+
+ ns = new NamespaceSupport();
+ count = countPrefixes();
+
+ ns.pushContext();
+ ns.declarePrefix("dc", "http://www.purl.org/dc#");
+ assertEquals("Test 1: Incorrect prefix count;",
+ count + 1, countPrefixes());
+
+ ns.popContext();
+ assertEquals("Test 2: Incorrect prefix count;",
+ count, countPrefixes());
+
+ // Check that only one context has been created by pushContext().
+ try {
+ ns.popContext();
+ fail("Test 3: EmptyStackException expected.");
+ } catch (EmptyStackException e) {
+ // Expected.
+ }
+ }
+
+ @TestTargets ({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "reset",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ method = "popContext",
+ args = {}
+ )
+ })
+ public void testReset() {
+ int count;
+
+ ns = new NamespaceSupport();
+ count = countPrefixes();
+
+ ns.pushContext();
+ ns.declarePrefix("dc", "http://www.purl.org/dc#");
+
+ assertEquals("Test 1: Incorrect prefix count;",
+ count + 1, countPrefixes());
+
+ ns.reset();
+ assertEquals("Test 2: Incorrect prefix count;",
+ count, countPrefixes());
+
+ // Check that only one context has been created by reset().
+ try {
+ ns.popContext();
+ fail("Test 3: EmptyStackException expected.");
+ } catch (EmptyStackException e) {
+ // Expected.
+ }
+ }
+
+ @TestTargets ({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "declarePrefix",
+ args = {String.class, String.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getPrefix",
+ args = {String.class}
+ )
+ })
+ public void testDeclare_GetPrefix() {
+ ns.pushContext();
+
+ // Part 1: Check that xml and xmlns are not accepted as prefixes.
+ assertFalse("Test 1: Invalid prefix accepted.",
+ ns.declarePrefix("xml", marketUri));
+
+ assertFalse("Test 2: Invalid prefix accepted.",
+ ns.declarePrefix("xmlns", marketUri));
+
+ // Part 2: Check that declarePrefix and getPrefix work for valid
+ // prefixes.
+ assertTrue("Test 3: Valid prefix not accepted.",
+ ns.declarePrefix("ak", marketUri));
+
+ assertTrue("Test 4: Incorrect prefix returned.",
+ ns.getPrefix(marketUri).equals("ak"));
+
+ assertTrue("Test 5: Valid prefix not accepted.",
+ ns.declarePrefix("bk", marketUri));
+
+ assertTrue("Test 6: Incorrect prefix returned.",
+ expected.contains(ns.getPrefix(marketUri)));
+
+ assertTrue("Test 7: Valid prefix not accepted.",
+ ns.declarePrefix("", defaultUri));
+
+ // Part 3: Negative Tests for getPrefix.
+ assertNull("Test 8: Non-null value returned for the URI that is " +
+ "assigned to the default namespace.",
+ ns.getPrefix(defaultUri));
+
+ assertNull("Test 9: Non-null value returned for an unassigned URI.",
+ ns.getPrefix(defaultUri + "/42"));
+ }
+
+ @SuppressWarnings("unchecked")
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getPrefixes",
+ args = {String.class}
+ )
+ public void testGetPrefixesLjava_lang_String() {
+ ArrayList<String> prefixes;
+
+ prefixes = Collections.list(ns.getPrefixes(marketUri));
+ assertTrue("Test 1: Incorrect set of prefixes returned.",
+ expected.containsAll(prefixes) && prefixes.containsAll(expected));
+
+ prefixes = Collections.list(ns.getPrefixes(defaultUri));
+ assertTrue("Test 2: Default namespace prefix should not be returned.",
+ prefixes.size() == 0);
+
+ prefixes = Collections.list(ns.getPrefixes(NamespaceSupport.XMLNS));
+ assertTrue("Test 3: xml prefix is missing.",
+ prefixes.contains("xml") && prefixes.size() == 1);
+
+ prefixes = Collections.list(ns.getPrefixes(defaultUri + "/42"));
+ assertTrue("Test 4: Non-empty enumeration returned for an unassigned URI.",
+ prefixes.size() == 0);
+ }
+
+ @SuppressWarnings("unchecked")
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getPrefixes",
+ args = {}
+ )
+ public void testGetPrefixes() {
+ ArrayList<String> prefixes;
+
+ expected.add("xml");
+
+ prefixes = Collections.list(ns.getPrefixes());
+ assertTrue("Test 1: Incorrect set of prefixes returned.",
+ expected.containsAll(prefixes) && prefixes.containsAll(expected));
+ }
+
+ @SuppressWarnings("unchecked")
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getDeclaredPrefixes",
+ args = {}
+ )
+ public void testGetDeclaredPrefixes() {
+ ArrayList<String> prefixes;
+
+ expected.add("");
+
+ prefixes = Collections.list(ns.getDeclaredPrefixes());
+ assertTrue("Test 1: Incorrect set of prefixes returned.",
+ expected.containsAll(prefixes) && prefixes.containsAll(expected));
+ }
+
+ @TestTargets ({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getURI",
+ args = {String.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ method = "popContext",
+ args = {}
+ )
+ })
+ public void testGetUri() {
+ assertEquals("Test 1: Incorrect URI returned;",
+ marketUri, ns.getURI("bk"));
+ assertEquals("Test 2: Incorrect URI returned;",
+ defaultUri, ns.getURI(""));
+ assertNull("Test 3: Null expected for not-existing prefix.",
+ ns.getURI("ck"));
+
+ ns.popContext();
+ assertNull("Test 4: Null expected for not-existing prefix.",
+ ns.getURI("bk"));
+ assertEquals("Test 5: Incorrect URI returned;",
+ NamespaceSupport.XMLNS, ns.getURI("xml"));
+ }
+
+ @TestTargets ({
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ method = "setNamespaceDeclUris",
+ args = {boolean.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "isNamespaceDeclUris",
+ args = {}
+ )
+ })
+ public void testNamespaceDeclUris() {
+
+ assertFalse("Test 1: Incorrect default value returned by isNamespaceDeclUris().",
+ ns.isNamespaceDeclUris());
+
+ try {
+ ns.setNamespaceDeclUris(true);
+ fail("Test 2: IllegalStateException expected since a context has already been pushed in setUp().");
+ } catch (IllegalStateException e) {
+ // Expected.
+ }
+
+ ns = new NamespaceSupport();
+ ns.setNamespaceDeclUris(true);
+ assertTrue("Test 3: Incorrect value returned by isNamespaceDeclUris().",
+ ns.isNamespaceDeclUris());
+
+ ns.setNamespaceDeclUris(false);
+ assertFalse("Test 4: Incorrect value returned by isNamespaceDeclUris().",
+ ns.isNamespaceDeclUris());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ method = "processName",
+ args = {String.class, String[].class, boolean.class}
+ )
+ public void testProcessName_Element() {
+ String[] parts = new String[3];
+
+ assertNotNull("Test 1: Non-null value expected.",
+ ns.processName("ak:hello", parts, false));
+ assertEquals("Test 2: Incorrect namespace URI;", marketUri, parts[0]);
+ assertEquals("Test 3: Incorrect local name;", "hello", parts[1]);
+ assertEquals("Test 4: Incorrect raw name;", "ak:hello", parts[2]);
+
+ assertNotNull("Test 5: Non-null value expected.",
+ ns.processName("bk:", parts, false));
+ assertEquals("Test 6: Incorrect namespace URI;", marketUri, parts[0]);
+ assertEquals("Test 7: Incorrect local name;", "", parts[1]);
+ assertEquals("Test 8: Incorrect raw name;", "bk:", parts[2]);
+
+ assertNotNull("Test 9: Non-null value expected.",
+ ns.processName("world", parts, false));
+ assertEquals("Test 10: Incorrect namespace URI;", defaultUri, parts[0]);
+ assertEquals("Test 11: Incorrect local name;", "world", parts[1]);
+ assertEquals("Test 12: Incorrect raw name;", "world", parts[2]);
+
+ assertNull("Test 13: Null expected for undeclared prefix.",
+ ns.processName("ck:lorem", parts, false));
+
+ assertNull("Test 14: Null expected for xmlns prefix.",
+ ns.processName("xmlns:ipsum", parts, false));
+
+ ns = new NamespaceSupport();
+ ns.pushContext();
+ assertNotNull("Test 15: Non-null value expected.",
+ ns.processName("world", parts, false));
+ assertEquals("Test 16: Incorrect namespace URI;", "", parts[0]);
+ assertEquals("Test 17: Incorrect local name;", "world", parts[1]);
+ assertEquals("Test 18: Incorrect raw name;", "world", parts[2]);
+ }
+
+ @TestTargets ({
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ method = "setNamespaceDeclUris",
+ args = {boolean.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ method = "processName",
+ args = {String.class, String[].class, boolean.class}
+ )
+ })
+ public void testProcessName_Attribute() {
+ String[] parts = new String[3];
+
+ assertNotNull("Test 1: Non-null value expected.",
+ ns.processName("ak:hello", parts, true));
+ assertEquals("Test 2: Incorrect namespace URI;", marketUri, parts[0]);
+ assertEquals("Test 3: Incorrect local name;", "hello", parts[1]);
+ assertEquals("Test 4: Incorrect raw name;", "ak:hello", parts[2]);
+
+ assertNotNull("Test 5: Non-null value expected.",
+ ns.processName("bk:", parts, true));
+ assertEquals("Test 6: Incorrect namespace URI;", marketUri, parts[0]);
+ assertEquals("Test 7: Incorrect local name;", "", parts[1]);
+ assertEquals("Test 8: Incorrect raw name;", "bk:", parts[2]);
+
+ assertNotNull("Test 9: Non-null value expected.",
+ ns.processName("world", parts, true));
+ assertEquals("Test 10: Incorrect namespace URI;", "", parts[0]);
+ assertEquals("Test 11: Incorrect local name;", "world", parts[1]);
+ assertEquals("Test 12: Incorrect raw name;", "world", parts[2]);
+
+ assertNull("Test 13: Null expected for undeclared prefix.",
+ ns.processName("ck:lorem", parts, true));
+
+ assertNull("Test 14: Null expected for xmlns prefix.",
+ ns.processName("xmlns:ipsum", parts, true));
+
+ ns = new NamespaceSupport();
+ ns.setNamespaceDeclUris(true);
+ ns.pushContext();
+ assertNotNull("Test 15: Non-null value expected.",
+ ns.processName("xmlns", parts, true));
+ assertEquals("Test 16: Incorrect namespace URI;", NamespaceSupport.NSDECL, parts[0]);
+ assertEquals("Test 17: Incorrect local name;", "xmlns", parts[1]);
+ assertEquals("Test 18: Incorrect raw name;", "xmlns", parts[2]);
+ }
+
+ @SuppressWarnings("unchecked")
+ private int countPrefixes()
+ {
+ ArrayList<String> prefixes = Collections.list(ns.getPrefixes());
+ return prefixes.size();
+ }
+}
diff --git a/xml/src/test/java/tests/api/org/xml/sax/helpers/ParserAdapterTest.java b/xml/src/test/java/tests/api/org/xml/sax/helpers/ParserAdapterTest.java
new file mode 100644
index 0000000..27a7e78
--- /dev/null
+++ b/xml/src/test/java/tests/api/org/xml/sax/helpers/ParserAdapterTest.java
@@ -0,0 +1,468 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.api.org.xml.sax.helpers;
+
+import java.io.IOException;
+
+import junit.framework.TestCase;
+
+import org.xml.sax.AttributeList;
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.DTDHandler;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.Locator;
+import org.xml.sax.Parser;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXNotRecognizedException;
+import org.xml.sax.SAXNotSupportedException;
+import org.xml.sax.helpers.AttributeListImpl;
+import org.xml.sax.helpers.LocatorImpl;
+import org.xml.sax.helpers.ParserAdapter;
+
+import tests.api.org.xml.sax.support.MethodLogger;
+import tests.api.org.xml.sax.support.MockHandler;
+import tests.api.org.xml.sax.support.MockParser;
+import tests.api.org.xml.sax.support.MockResolver;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargets;
+
+@SuppressWarnings("deprecation")
+@TestTargetClass(ParserAdapter.class)
+public class ParserAdapterTest extends TestCase {
+
+ // Note: In many cases we can only test that delegation works
+ // properly. The rest is outside the scope of the specification.
+
+ private final static String FEATURES = "http://xml.org/sax/features/";
+
+ private final static String NAMESPACES = FEATURES + "namespaces";
+
+ private final static String NAMESPACE_PREFIXES = FEATURES
+ + "namespace-prefixes";
+
+ private final static String XMLNS_URIs = FEATURES + "xmlns-uris";
+
+ private MethodLogger logger = new MethodLogger();
+
+ private MockHandler handler = new MockHandler(logger);
+
+ private Parser parser = new MockParser(logger);
+
+ private ParserAdapter adapter = new ParserAdapter(parser);
+
+ private void assertEquals(Object[] a, Object[] b) {
+ assertEquals(a.length, b.length);
+
+ for (int i = 0; i < a.length; i++) {
+ assertEquals("Element #" + i + " must be equal", a[i], b[i]);
+ }
+ }
+
+ @Override
+ public void setUp() {
+ adapter.setContentHandler(handler);
+ adapter.setDTDHandler(handler);
+ adapter.setErrorHandler(handler);
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "ParserAdapter",
+ args = { }
+ )
+ public void testParserAdapter() {
+ System.setProperty("org.xml.sax.parser",
+ "tests.api.org.xml.sax.support.DoNothingParser");
+
+ try {
+ new ParserAdapter();
+ } catch (SAXException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "ParserAdapter",
+ args = { Parser.class }
+ )
+ public void testParserAdapterParser() {
+ // Ordinary case
+ @SuppressWarnings("unused")
+ ParserAdapter adapter = new ParserAdapter(parser);
+
+ // Null case
+ try {
+ adapter = new ParserAdapter(null);
+ fail("NullPointerException expected");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getFeature",
+ args = { String.class }
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setFeature",
+ args = { String.class, boolean.class }
+ )
+ })
+ public void testGetSetFeature() {
+ String[] features = new String[] { NAMESPACES, NAMESPACE_PREFIXES,
+ XMLNS_URIs };
+
+ for (String s: features) {
+ try {
+ adapter.setFeature(s, true);
+ assertEquals(true, adapter.getFeature(s));
+
+ adapter.setFeature(s, false);
+ assertEquals(false, adapter.getFeature(s));
+ } catch (SAXException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+ }
+
+ try {
+ adapter.setFeature("http://argle.bargle", true);
+ fail("SAXNotRecognizedException expected");
+ } catch (SAXNotRecognizedException e) {
+ // Expected
+ } catch (SAXNotSupportedException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getProperty",
+ args = { String.class }
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setProperty",
+ args = { String.class, Object.class }
+ )
+ })
+ public void testGetSetProperty() {
+ try {
+ adapter.setProperty("http://argle.bargle", ":)");
+ fail("SAXNotRecognizedException expected");
+ } catch (SAXNotRecognizedException e) {
+ // Expected
+ } catch (SAXNotSupportedException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ try {
+ adapter.getProperty("http://argle.bargle");
+ fail("SAXNotRecognizedException expected");
+ } catch (SAXNotRecognizedException e) {
+ // Expected
+ } catch (SAXNotSupportedException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getEntityResolver",
+ args = { }
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setEntityResolver",
+ args = { EntityResolver.class }
+ )
+ })
+ public void testGetSetEntityResolver() {
+ EntityResolver resolver = new MockResolver();
+
+ adapter.setEntityResolver(resolver);
+ assertEquals(resolver, adapter.getEntityResolver());
+
+ adapter.setEntityResolver(null);
+ assertEquals(null, adapter.getEntityResolver());
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getDTDHandler",
+ args = { }
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setDTDHandler",
+ args = { DTDHandler.class }
+ )
+ })
+ public void testGetSetDTDHandler() {
+ adapter.setDTDHandler(null);
+ assertEquals(null, adapter.getDTDHandler());
+
+ adapter.setDTDHandler(handler);
+ assertEquals(handler, adapter.getDTDHandler());
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getContentHandler",
+ args = { }
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setContentHandler",
+ args = { ContentHandler.class }
+ )
+ })
+ public void testGetSetContentHandler() {
+ adapter.setContentHandler(null);
+ assertEquals(null, adapter.getContentHandler());
+
+ adapter.setContentHandler(handler);
+ assertEquals(handler, adapter.getContentHandler());
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getErrorHandler",
+ args = { }
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setErrorHandler",
+ args = { ErrorHandler.class }
+ )
+ })
+ public void testGetSetErrorHandler() {
+ adapter.setErrorHandler(null);
+ assertEquals(null, adapter.getErrorHandler());
+
+ adapter.setErrorHandler(handler);
+ assertEquals(handler, adapter.getErrorHandler());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "parse",
+ args = { String.class }
+ )
+ public void testParseString() {
+ try {
+ adapter.parse("foo");
+ } catch (SAXException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ } catch (IOException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ // The SAX RI creates an InputSource itself and then delegates to the
+ // "other" parse method.
+ assertEquals("parse", logger.getMethod());
+ assertEquals(InputSource.class, logger.getArgs()[0].getClass());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "parse",
+ args = { InputSource.class }
+ )
+ public void testParseInputSource() {
+ InputSource source = new InputSource("foo");
+
+ try {
+ adapter.parse(source);
+ } catch (SAXException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ } catch (IOException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ assertEquals("parse", logger.getMethod());
+ assertEquals(new Object[] { source }, logger.getArgs());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setDocumentLocator",
+ args = { Locator.class }
+ )
+ public void testSetDocumentLocator() {
+ Locator l = new LocatorImpl();
+
+ adapter.setDocumentLocator(l);
+
+ assertEquals(logger.size(), 1);
+ assertEquals("setDocumentLocator", logger.getMethod());
+ assertEquals(new Object[] { l }, logger.getArgs());
+
+ adapter.setDocumentLocator(null);
+
+ assertEquals(logger.size(), 2);
+ assertEquals("setDocumentLocator", logger.getMethod());
+ assertEquals(new Object[] { null }, logger.getArgs());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "startDocument",
+ args = { }
+ )
+ public void testStartDocument() {
+ try {
+ adapter.startDocument();
+ } catch (SAXException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ assertEquals(logger.size(), 1);
+ assertEquals("startDocument", logger.getMethod());
+ assertEquals(new Object[] {}, logger.getArgs());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "endDocument",
+ args = { }
+ )
+ public void testEndDocument() {
+ try {
+ adapter.endDocument();
+ } catch (SAXException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ assertEquals(logger.size(), 1);
+ assertEquals("endDocument", logger.getMethod());
+ assertEquals(new Object[] {}, logger.getArgs());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "startElement",
+ args = { String.class, AttributeList.class }
+ )
+ public void testStartElement() {
+ AttributeListImpl atts = new AttributeListImpl();
+ atts.addAttribute("john:doe", "int", "42");
+
+ try {
+ adapter.startDocument();
+ adapter.startElement("foo:bar", atts);
+ } catch (SAXException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ assertEquals("startElement", logger.getMethod());
+ assertEquals("", logger.getArgs()[0]);
+ assertEquals("", logger.getArgs()[1]);
+ assertEquals("foo:bar", logger.getArgs()[2]);
+ assertEquals("john:doe", ((Attributes)logger.getArgs()[3]).getQName(0));
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "endElement",
+ args = { String.class }
+ )
+ public void testEndElement() {
+ AttributeListImpl atts = new AttributeListImpl();
+ atts.addAttribute("john:doe", "int", "42");
+
+ try {
+ adapter.startDocument();
+ adapter.startElement("foo:bar", atts);
+ adapter.endElement("foo:bar");
+ } catch (SAXException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ assertEquals("endElement", logger.getMethod());
+ assertEquals(new String[] { "", "", "foo:bar" }, logger.getArgs());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "characters",
+ args = { char[].class, int.class, int.class }
+ )
+ public void testCharacters() {
+ char[] ch = "Android".toCharArray();
+
+ try {
+ adapter.characters(ch, 2, 5);
+ } catch (SAXException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ assertEquals(logger.size(), 1);
+ assertEquals("characters", logger.getMethod());
+ assertEquals(new Object[] { ch, 2, 5 }, logger.getArgs());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "ignorableWhitespace",
+ args = { char[].class, int.class, int.class }
+ )
+ public void testIgnorableWhitespace() {
+ char[] ch = " ".toCharArray();
+
+ try {
+ adapter.ignorableWhitespace(ch, 0, 5);
+ } catch (SAXException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ assertEquals(logger.size(), 1);
+ assertEquals("ignorableWhitespace", logger.getMethod());
+ assertEquals(new Object[] { ch, 0, 5 }, logger.getArgs());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "processingInstruction",
+ args = { String.class, String.class }
+ )
+ public void testProcessingInstruction() {
+ try {
+ adapter.processingInstruction("foo", "bar");
+ } catch (SAXException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ assertEquals(logger.size(), 1);
+ assertEquals("processingInstruction", logger.getMethod());
+ assertEquals(new Object[] { "foo" , "bar" }, logger.getArgs());
+ }
+
+}
diff --git a/xml/src/test/java/tests/api/org/xml/sax/helpers/ParserFactoryTest.java b/xml/src/test/java/tests/api/org/xml/sax/helpers/ParserFactoryTest.java
new file mode 100644
index 0000000..ebf2a04
--- /dev/null
+++ b/xml/src/test/java/tests/api/org/xml/sax/helpers/ParserFactoryTest.java
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.api.org.xml.sax.helpers;
+
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+
+import junit.framework.TestCase;
+
+import org.xml.sax.helpers.ParserFactory;
+
+@SuppressWarnings("deprecation")
+@TestTargetClass(ParserFactory.class)
+public class ParserFactoryTest extends TestCase {
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "makeParser",
+ args = { },
+ notes = "Checks everything except META-INF case"
+ )
+ public void testMakeParser() {
+ // Property not set at all
+ try {
+ ParserFactory.makeParser();
+ } catch (NullPointerException e) {
+ // Expected
+ } catch (Exception e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ // Unknown class
+ System.setProperty("org.xml.sax.parser", "foo.bar.SAXParser");
+
+ try {
+ ParserFactory.makeParser();
+ } catch (ClassNotFoundException e) {
+ // Expected
+ } catch (Exception e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ // Non-accessible class
+ System.setProperty("org.xml.sax.parser",
+ "tests.api.org.xml.sax.support.NoAccessParser");
+
+ try {
+ ParserFactory.makeParser();
+ } catch (IllegalAccessException e) {
+ // Expected
+ } catch (Exception e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ // Non-instantiable class
+ System.setProperty("org.xml.sax.parser",
+ "tests.api.org.xml.sax.support.NoInstanceParser");
+
+ try {
+ ParserFactory.makeParser();
+ } catch (InstantiationException e) {
+ // Expected
+ } catch (Exception e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ // Non-Parser class
+ System.setProperty("org.xml.sax.parser",
+ "tests.api.org.xml.sax.support.NoSubclassParser");
+
+ try {
+ ParserFactory.makeParser();
+ } catch (ClassCastException e) {
+ // Expected
+ } catch (Exception e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ // Good one, finally
+ System.setProperty("org.xml.sax.parser",
+ "tests.api.org.xml.sax.support.DoNothingParser");
+
+ try {
+ ParserFactory.makeParser();
+ } catch (Exception e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "makeParser",
+ args = { String.class }
+ )
+ public void testMakeParserString() {
+ // No class
+ try {
+ ParserFactory.makeParser(null);
+ } catch (NullPointerException e) {
+ // Expected
+ } catch (Exception e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ // Unknown class
+ try {
+ ParserFactory.makeParser("foo.bar.SAXParser");
+ } catch (ClassNotFoundException e) {
+ // Expected
+ } catch (Exception e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ // Non-accessible class
+ try {
+ ParserFactory.makeParser(
+ "tests.api.org.xml.sax.support.NoAccessParser");
+ } catch (IllegalAccessException e) {
+ // Expected
+ } catch (Exception e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ // Non-instantiable class
+ try {
+ ParserFactory.makeParser(
+ "tests.api.org.xml.sax.support.NoInstanceParser");
+ } catch (InstantiationException e) {
+ // Expected
+ } catch (Exception e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ // Non-Parser class
+ try {
+ ParserFactory.makeParser(
+ "tests.api.org.xml.sax.support.NoSubclassParser");
+ } catch (ClassCastException e) {
+ // Expected
+ } catch (Exception e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ // Good one, finally
+ try {
+ ParserFactory.makeParser(
+ "tests.api.org.xml.sax.support.DoNothingParser");
+ } catch (Exception e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ }
+
+}
diff --git a/xml/src/test/java/tests/api/org/xml/sax/helpers/XMLFilterImplTest.java b/xml/src/test/java/tests/api/org/xml/sax/helpers/XMLFilterImplTest.java
new file mode 100644
index 0000000..6586461
--- /dev/null
+++ b/xml/src/test/java/tests/api/org/xml/sax/helpers/XMLFilterImplTest.java
@@ -0,0 +1,678 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.api.org.xml.sax.helpers;
+
+import java.io.IOException;
+
+import junit.framework.TestCase;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.DTDHandler;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXNotRecognizedException;
+import org.xml.sax.SAXNotSupportedException;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.AttributesImpl;
+import org.xml.sax.helpers.LocatorImpl;
+import org.xml.sax.helpers.XMLFilterImpl;
+
+import tests.api.org.xml.sax.support.MethodLogger;
+import tests.api.org.xml.sax.support.MockFilter;
+import tests.api.org.xml.sax.support.MockHandler;
+import tests.api.org.xml.sax.support.MockResolver;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargets;
+
+@TestTargetClass(XMLFilterImpl.class)
+public class XMLFilterImplTest extends TestCase {
+
+ // Note: In many cases we can only test that delegation works
+ // properly. The rest is outside the scope of the specification.
+
+ private MethodLogger logger = new MethodLogger();
+
+ private MockHandler handler = new MockHandler(logger);
+
+ private XMLFilterImpl parent = new MockFilter(logger);
+
+ private XMLFilterImpl child = new XMLFilterImpl(parent);
+
+ private XMLFilterImpl orphan = new XMLFilterImpl();
+
+ private void assertEquals(Object[] a, Object[] b) {
+ assertEquals(a.length, b.length);
+
+ for (int i = 0; i < a.length; i++) {
+ assertEquals("Element #" + i + " must be equal", a[i], b[i]);
+ }
+ }
+
+ public void setUp() {
+ parent.setContentHandler(handler);
+ parent.setDTDHandler(handler);
+ parent.setErrorHandler(handler);
+
+ child.setContentHandler(handler);
+ child.setDTDHandler(handler);
+ child.setErrorHandler(handler);
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "XMLFilterImpl",
+ args = { }
+ )
+ public void testXMLFilterImpl() {
+ assertEquals(null, parent.getParent());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "XMLFilterImpl",
+ args = { XMLReader.class }
+ )
+ public void testXMLFilterImplXMLReader() {
+ // Ordinary case
+ assertEquals(null, parent.getParent());
+
+ // null case
+ XMLFilterImpl filter = new XMLFilterImpl(null);
+ assertEquals(null, filter.getParent());
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getParent",
+ args = { }
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setParent",
+ args = { XMLReader.class }
+ )
+ })
+ public void testGetSetParent() {
+ child.setParent(null);
+ assertEquals(null, child.getParent());
+
+ child.setParent(parent);
+ assertEquals(parent, child.getParent());
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getFeature",
+ args = { String.class }
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setFeature",
+ args = { String.class, boolean.class }
+ )
+ })
+ public void testGetSetFeature() {
+ // Ordinary case
+ try {
+ child.setFeature("foo", true);
+ assertEquals(true, child.getFeature("foo"));
+
+ child.setFeature("foo", false);
+ assertEquals(false, child.getFeature("foo"));
+ } catch (SAXNotRecognizedException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ } catch (SAXNotSupportedException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ // No parent case
+ try {
+ orphan.setFeature("foo", false);
+ fail("SAXNotRecognizedException expected");
+ } catch (SAXNotRecognizedException e) {
+ // Expected
+ } catch (SAXNotSupportedException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getProperty",
+ args = { String.class }
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setProperty",
+ args = { String.class, Object.class }
+ )
+ })
+ public void testGetSetProperty() {
+ // Ordinary case
+ try {
+ child.setProperty("foo", "bar");
+ assertEquals("bar", child.getProperty("foo"));
+
+ child.setProperty("foo", null);
+ assertEquals(null, child.getProperty("foo"));
+ } catch (SAXNotRecognizedException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ } catch (SAXNotSupportedException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ // No parent case
+ try {
+ orphan.setProperty("foo", "bar");
+ fail("SAXNotRecognizedException expected");
+ } catch (SAXNotRecognizedException e) {
+ // Expected
+ } catch (SAXNotSupportedException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getEntityResolver",
+ args = { }
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setEntityResolver",
+ args = { EntityResolver.class }
+ )
+ })
+ public void testGetSetEntityResolver() {
+ EntityResolver resolver = new MockResolver();
+
+ parent.setEntityResolver(resolver);
+ assertEquals(resolver, parent.getEntityResolver());
+
+ parent.setEntityResolver(null);
+ assertEquals(null, parent.getEntityResolver());
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getDTDHandler",
+ args = { }
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setDTDHandler",
+ args = { DTDHandler.class }
+ )
+ })
+ public void testGetSetDTDHandler() {
+ parent.setDTDHandler(null);
+ assertEquals(null, parent.getDTDHandler());
+
+ parent.setDTDHandler(handler);
+ assertEquals(handler, parent.getDTDHandler());
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getContentHandler",
+ args = { }
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setContentHandler",
+ args = { ContentHandler.class }
+ )
+ })
+ public void testGetSetContentHandler() {
+ parent.setContentHandler(null);
+ assertEquals(null, parent.getContentHandler());
+
+ parent.setContentHandler(handler);
+ assertEquals(handler, parent.getContentHandler());
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getErrorHandler",
+ args = { }
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setErrorHandler",
+ args = { ErrorHandler.class }
+ )
+ })
+ public void testGetSetErrorHandler() {
+ parent.setErrorHandler(null);
+ assertEquals(null, parent.getErrorHandler());
+
+ parent.setErrorHandler(handler);
+ assertEquals(handler, parent.getErrorHandler());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "parse",
+ args = { InputSource.class }
+ )
+ public void testParseInputSource() {
+ InputSource is = new InputSource();
+
+ // Ordinary case
+ try {
+ child.parse(is);
+ } catch (SAXException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ } catch (IOException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ assertEquals(1, logger.size());
+ assertEquals("parse", logger.getMethod());
+
+ // No parent case
+ try {
+ orphan.parse(is);
+ fail("NullPointerException expected");
+ } catch (NullPointerException e) {
+ // Expected
+ } catch (SAXException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ } catch (IOException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "parse",
+ args = { String.class }
+ )
+ public void testParseString() {
+ // Ordinary case
+ try {
+ child.parse("foo");
+ } catch (SAXException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ } catch (IOException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ assertEquals(1, logger.size());
+ assertEquals("parse", logger.getMethod());
+
+ // No parent case
+ try {
+ orphan.parse("foo");
+ fail("NullPointerException expected");
+ } catch (NullPointerException e) {
+ // Expected
+ } catch (SAXException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ } catch (IOException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "resolveEntity",
+ args = { String.class, String.class }
+ )
+ public void testResolveEntity() {
+ InputSource expected = new InputSource();
+
+ MockResolver resolver = new MockResolver();
+ resolver.addEntity("foo", "bar", expected);
+
+ InputSource result = null;
+
+ parent.setEntityResolver(resolver);
+
+ // Ordinary case
+ try {
+ result = parent.resolveEntity("foo", "bar");
+ } catch (SAXException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ } catch (IOException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ assertEquals(expected, result);
+
+ // No entity resolver case
+ parent.setEntityResolver(null);
+
+ try {
+ result = parent.resolveEntity("foo", "bar");
+ } catch (SAXException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ } catch (IOException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ assertEquals(null, result);
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "notationDecl",
+ args = { String.class, String.class, String.class }
+ )
+ public void testNotationDecl() {
+ try {
+ parent.notationDecl("foo", "bar", "foobar");
+ } catch (SAXException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ assertEquals(logger.size(), 1);
+ assertEquals("notationDecl", logger.getMethod());
+ assertEquals(new Object[] { "foo", "bar", "foobar" },
+ logger.getArgs());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "unparsedEntityDecl",
+ args = { String.class, String.class, String.class, String.class }
+ )
+ public void testUnparsedEntityDecl() {
+ try {
+ parent.unparsedEntityDecl("foo", "bar", "gabba", "hey");
+ } catch (SAXException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ assertEquals(logger.size(), 1);
+ assertEquals("unparsedEntityDecl", logger.getMethod());
+ assertEquals(new Object[] { "foo", "bar", "gabba", "hey" },
+ logger.getArgs());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setDocumentLocator",
+ args = { Locator.class }
+ )
+ public void testSetDocumentLocator() {
+ Locator l = new LocatorImpl();
+
+ child.setDocumentLocator(l);
+
+ assertEquals(logger.size(), 1);
+ assertEquals("setDocumentLocator", logger.getMethod());
+ assertEquals(new Object[] { l }, logger.getArgs());
+
+ child.setDocumentLocator(null);
+
+ assertEquals(logger.size(), 2);
+ assertEquals("setDocumentLocator", logger.getMethod());
+ assertEquals(new Object[] { null }, logger.getArgs());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "startDocument",
+ args = { }
+ )
+ public void testStartDocument() {
+ try {
+ parent.startDocument();
+ } catch (SAXException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ assertEquals(logger.size(), 1);
+ assertEquals("startDocument", logger.getMethod());
+ assertEquals(new Object[] {}, logger.getArgs());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "endDocument",
+ args = { }
+ )
+ public void testEndDocument() {
+ try {
+ parent.endDocument();
+ } catch (SAXException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ assertEquals(logger.size(), 1);
+ assertEquals("endDocument", logger.getMethod());
+ assertEquals(new Object[] {}, logger.getArgs());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "startPrefixMapping",
+ args = { String.class, String.class }
+ )
+ public void testStartPrefixMapping() {
+ try {
+ parent.startPrefixMapping("foo", "http://some.uri");
+ } catch (SAXException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ assertEquals(logger.size(), 1);
+ assertEquals("startPrefixMapping", logger.getMethod());
+ assertEquals(new Object[] { "foo", "http://some.uri" },
+ logger.getArgs());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "endPrefixMapping",
+ args = { String.class }
+ )
+ public void testEndPrefixMapping() {
+ try {
+ parent.endPrefixMapping("foo");
+ } catch (SAXException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ assertEquals(logger.size(), 1);
+ assertEquals("endPrefixMapping", logger.getMethod());
+ assertEquals(new Object[] { "foo" }, logger.getArgs());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "startElement",
+ args = { String.class, String.class, String.class, Attributes.class }
+ )
+ public void testStartElement() {
+ Attributes atts = new AttributesImpl();
+
+ try {
+ parent.startElement("http://some.uri", "bar", "foo:bar", atts);
+ } catch (SAXException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ assertEquals(logger.size(), 1);
+ assertEquals("startElement", logger.getMethod());
+ assertEquals(new Object[] { "http://some.uri", "bar", "foo:bar", atts },
+ logger.getArgs());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "endElement",
+ args = { String.class, String.class, String.class }
+ )
+ public void testEndElement() {
+ try {
+ parent.endElement("http://some.uri", "bar", "foo:bar");
+ } catch (SAXException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ assertEquals(logger.size(), 1);
+ assertEquals("endElement", logger.getMethod());
+ assertEquals(new Object[] { "http://some.uri", "bar", "foo:bar" },
+ logger.getArgs());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "characters",
+ args = { char[].class, int.class, int.class }
+ )
+ public void testCharacters() {
+ char[] ch = "Android".toCharArray();
+
+ try {
+ parent.characters(ch, 2, 5);
+ } catch (SAXException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ assertEquals(logger.size(), 1);
+ assertEquals("characters", logger.getMethod());
+ assertEquals(new Object[] { ch, 2, 5 }, logger.getArgs());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "ignorableWhitespace",
+ args = { char[].class, int.class, int.class }
+ )
+ public void testIgnorableWhitespace() {
+ char[] ch = " ".toCharArray();
+
+ try {
+ parent.ignorableWhitespace(ch, 0, 5);
+ } catch (SAXException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ assertEquals(logger.size(), 1);
+ assertEquals("ignorableWhitespace", logger.getMethod());
+ assertEquals(new Object[] { ch, 0, 5 }, logger.getArgs());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "processingInstruction",
+ args = { String.class, String.class }
+ )
+ public void testProcessingInstruction() {
+ try {
+ parent.processingInstruction("foo", "bar");
+ } catch (SAXException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ assertEquals(logger.size(), 1);
+ assertEquals("processingInstruction", logger.getMethod());
+ assertEquals(new Object[] { "foo", "bar" }, logger.getArgs());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "skippedEntity",
+ args = { String.class }
+ )
+ public void testSkippedEntity() {
+ try {
+ parent.skippedEntity("foo");
+ } catch (SAXException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ assertEquals(logger.size(), 1);
+ assertEquals("skippedEntity", logger.getMethod());
+ assertEquals(new Object[] { "foo" }, logger.getArgs());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "warning",
+ args = { SAXParseException.class }
+ )
+ public void testWarning() {
+ SAXParseException exception = new SAXParseException("Oops!", null);
+
+ try {
+ parent.warning(exception);
+ } catch (SAXException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ assertEquals(logger.size(), 1);
+ assertEquals("warning", logger.getMethod());
+ assertEquals(new Object[] { exception }, logger.getArgs());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "error",
+ args = { SAXParseException.class }
+ )
+ public void testError() {
+ SAXParseException exception = new SAXParseException("Oops!", null);
+
+ try {
+ parent.error(exception);
+ } catch (SAXException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ assertEquals(logger.size(), 1);
+ assertEquals("error", logger.getMethod());
+ assertEquals(new Object[] { exception }, logger.getArgs());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "fatalError",
+ args = { SAXParseException.class }
+ )
+ public void testFatalError() {
+ SAXParseException exception = new SAXParseException("Oops!", null);
+
+ try {
+ parent.fatalError(exception);
+ } catch (SAXException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ assertEquals(logger.size(), 1);
+ assertEquals("fatalError", logger.getMethod());
+ assertEquals(new Object[] { exception }, logger.getArgs());
+ }
+
+}
diff --git a/xml/src/test/java/tests/api/org/xml/sax/helpers/XMLReaderAdapterTest.java b/xml/src/test/java/tests/api/org/xml/sax/helpers/XMLReaderAdapterTest.java
new file mode 100644
index 0000000..20488c5
--- /dev/null
+++ b/xml/src/test/java/tests/api/org/xml/sax/helpers/XMLReaderAdapterTest.java
@@ -0,0 +1,414 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.api.org.xml.sax.helpers;
+
+import java.io.IOException;
+import java.util.Locale;
+
+import junit.framework.TestCase;
+
+import org.xml.sax.AttributeList;
+import org.xml.sax.Attributes;
+import org.xml.sax.DTDHandler;
+import org.xml.sax.DocumentHandler;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.AttributesImpl;
+import org.xml.sax.helpers.LocatorImpl;
+import org.xml.sax.helpers.XMLReaderAdapter;
+
+import tests.api.org.xml.sax.support.MethodLogger;
+import tests.api.org.xml.sax.support.MockHandler;
+import tests.api.org.xml.sax.support.MockReader;
+import tests.api.org.xml.sax.support.MockResolver;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+
+@SuppressWarnings("deprecation")
+@TestTargetClass(XMLReaderAdapter.class)
+public class XMLReaderAdapterTest extends TestCase {
+
+ // Note: In many cases we can only test that delegation works
+ // properly. The rest is outside the scope of the specification.
+
+ private MethodLogger logger = new MethodLogger();
+
+ private MockHandler handler = new MockHandler(logger);
+
+ private XMLReader reader = new MockReader(logger);
+
+ private XMLReaderAdapter adapter = new XMLReaderAdapter(reader);
+
+ private void assertEquals(Object[] a, Object[] b) {
+ assertEquals(a.length, b.length);
+
+ for (int i = 0; i < a.length; i++) {
+ assertEquals("Element #" + i + " must be equal", a[i], b[i]);
+ }
+ }
+
+ @Override
+ public void setUp() {
+ adapter.setDocumentHandler(handler);
+ adapter.setDTDHandler(handler);
+ adapter.setErrorHandler(handler);
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "XMLReaderAdapter",
+ args = { }
+ )
+ public void testXMLReaderAdapter() {
+ System.setProperty("org.xml.sax.driver",
+ "tests.api.org.xml.sax.support.DoNothingXMLReader");
+
+ try {
+ new XMLReaderAdapter();
+ } catch (SAXException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "XMLReaderAdapter",
+ args = { XMLReader.class }
+ )
+ public void testXMLReaderAdapterXMLReader() {
+ // Ordinary case
+ @SuppressWarnings("unused")
+ XMLReaderAdapter adapter = new XMLReaderAdapter(reader);
+
+ // Null case
+ try {
+ adapter = new XMLReaderAdapter(null);
+ fail("NullPointerException expected");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setLocale",
+ args = { Locale.class }
+ )
+ public void testSetLocale() {
+ // SAX RI does not support this, hence always expect exception
+ try {
+ adapter.setLocale(Locale.getDefault());
+ fail("SAXException expected");
+ } catch (SAXException e) {
+ // Expected
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setEntityResolver",
+ args = { EntityResolver.class }
+ )
+ public void testSetEntityResolver() {
+ EntityResolver resolver = new MockResolver();
+
+ // Ordinary case
+ adapter.setEntityResolver(resolver);
+ assertEquals(resolver, reader.getEntityResolver());
+
+ // null case
+ adapter.setEntityResolver(null);
+ assertEquals(null, reader.getEntityResolver());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setDTDHandler",
+ args = { DTDHandler.class }
+ )
+ public void testSetDTDHandler() {
+ // Ordinary case
+ assertEquals(handler, reader.getDTDHandler());
+
+ // null case
+ adapter.setDTDHandler(null);
+ assertEquals(null, reader.getDTDHandler());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setDocumentHandler",
+ args = { DocumentHandler.class }
+ )
+ public void testSetDocumentHandler() {
+ // There is no getter for the DocumentHandler, so we can only test
+ // indirectly whether is has been set correctly.
+ try {
+ adapter.startDocument();
+ } catch (SAXException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ assertEquals("startDocument", logger.getMethod());
+ assertEquals(new Object[] { }, logger.getArgs());
+
+ // null case
+ adapter.setDocumentHandler(null);
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setErrorHandler",
+ args = { ErrorHandler.class }
+ )
+ public void testSetErrorHandler() {
+ // Ordinary case
+ assertEquals(handler, reader.getErrorHandler());
+
+ // null case
+ adapter.setErrorHandler(null);
+ assertEquals(null, reader.getErrorHandler());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "parse",
+ args = { String.class }
+ )
+ public void testParseString() {
+ try {
+ adapter.parse("foo");
+ } catch (SAXException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ } catch (IOException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ // The SAX RI creates an InputSource itself and then delegates to the
+ // "other" parse method.
+ assertEquals("parse", logger.getMethod(0));
+ assertEquals(InputSource.class, logger.getArgs(0)[0].getClass());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "parse",
+ args = { InputSource.class }
+ )
+ public void testParseInputSource() {
+ InputSource source = new InputSource("foo");
+
+ try {
+ adapter.parse(source);
+ } catch (SAXException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ } catch (IOException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ assertEquals("parse", logger.getMethod());
+ assertEquals(new Object[] { source }, logger.getArgs());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setDocumentLocator",
+ args = { Locator.class }
+ )
+ public void testSetDocumentLocator() {
+ // Ordinary case
+ LocatorImpl locator = new LocatorImpl();
+ adapter.setDocumentLocator(locator);
+
+ assertEquals("setDocumentLocator", logger.getMethod());
+ assertEquals(new Object[] { locator }, logger.getArgs());
+
+ // null case (for the DocumentHandler itself!)
+ adapter.setDocumentHandler(null);
+ adapter.setDocumentLocator(locator);
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "startDocument",
+ args = { }
+ )
+ public void testStartDocument() {
+ try {
+ adapter.startDocument();
+ } catch (SAXException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ assertEquals(logger.size(), 1);
+ assertEquals("startDocument", logger.getMethod());
+ assertEquals(new Object[] {}, logger.getArgs());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "endDocument",
+ args = { }
+ )
+ public void testEndDocument() {
+ try {
+ adapter.endDocument();
+ } catch (SAXException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ assertEquals(logger.size(), 1);
+ assertEquals("endDocument", logger.getMethod());
+ assertEquals(new Object[] {}, logger.getArgs());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "startPrefixMapping",
+ args = { String.class, String.class }
+ )
+ public void testStartPrefixMapping() {
+ adapter.startPrefixMapping("foo", "http://some.uri");
+ assertEquals(logger.size(), 0);
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "endPrefixMapping",
+ args = { String.class }
+ )
+ public void testEndPrefixMapping() {
+ adapter.endPrefixMapping("foo");
+ assertEquals(logger.size(), 0);
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "startElement",
+ args = { String.class, String.class, String.class, Attributes.class }
+ )
+ public void testStartElement() {
+ AttributesImpl atts = new AttributesImpl();
+ atts.addAttribute("http://some.other.uri", "gabba", "gabba:hey",
+ "int", "42");
+
+ try {
+ adapter.startElement("http://some.uri", "bar", "foo:bar", atts);
+ } catch (SAXException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ assertEquals(logger.size(), 1);
+ assertEquals("startElement", logger.getMethod());
+ assertEquals("foo:bar", logger.getArgs()[0]);
+ assertEquals("gabba:hey",
+ ((AttributeList)logger.getArgs()[1]).getName(0));
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "endElement",
+ args = { String.class, String.class, String.class }
+ )
+ public void testEndElement() {
+ try {
+ adapter.endElement("http://some.uri", "bar", "foo:bar");
+ } catch (SAXException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ assertEquals(logger.size(), 1);
+ assertEquals("endElement", logger.getMethod());
+ assertEquals(new Object[] { "foo:bar" }, logger.getArgs());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "characters",
+ args = { char[].class, int.class, int.class }
+ )
+ public void testCharacters() {
+ char[] ch = "Android".toCharArray();
+
+ try {
+ adapter.characters(ch, 2, 5);
+ } catch (SAXException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ assertEquals(logger.size(), 1);
+ assertEquals("characters", logger.getMethod());
+ assertEquals(new Object[] { ch, 2, 5 }, logger.getArgs());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "ignorableWhitespace",
+ args = { char[].class, int.class, int.class }
+ )
+ public void testIgnorableWhitespace() {
+ char[] ch = " ".toCharArray();
+
+ try {
+ adapter.ignorableWhitespace(ch, 0, 5);
+ } catch (SAXException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ assertEquals(logger.size(), 1);
+ assertEquals("ignorableWhitespace", logger.getMethod());
+ assertEquals(new Object[] { ch, 0, 5 }, logger.getArgs());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "processingInstruction",
+ args = { String.class, String.class }
+ )
+ public void testProcessingInstruction() {
+ try {
+ adapter.processingInstruction("foo", "bar");
+ } catch (SAXException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ assertEquals(logger.size(), 1);
+ assertEquals("processingInstruction", logger.getMethod());
+ assertEquals(new Object[] { "foo" , "bar" }, logger.getArgs());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "skippedEntity",
+ args = { String.class }
+ )
+ public void testSkippedEntity() {
+ try {
+ adapter.skippedEntity("foo");
+ } catch (SAXException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ assertEquals(logger.size(), 0);
+ }
+
+}
diff --git a/xml/src/test/java/tests/api/org/xml/sax/helpers/XMLReaderFactoryTest.java b/xml/src/test/java/tests/api/org/xml/sax/helpers/XMLReaderFactoryTest.java
new file mode 100644
index 0000000..bfb1bd1
--- /dev/null
+++ b/xml/src/test/java/tests/api/org/xml/sax/helpers/XMLReaderFactoryTest.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.api.org.xml.sax.helpers;
+
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+
+import junit.framework.TestCase;
+
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.XMLReaderFactory;
+
+@TestTargetClass(XMLReaderFactory.class)
+public class XMLReaderFactoryTest extends TestCase {
+
+ @TestTargetNew(
+ level = TestLevel.SUFFICIENT,
+ method = "createXMLReader",
+ args = { },
+ notes = "Checks everything except META-INF case"
+ )
+ public void testCreateXMLReader() {
+ // Property not set at all
+ try {
+ XMLReaderFactory.createXMLReader();
+ } catch (SAXException e) {
+ // Expected
+ }
+
+ // Unknown class
+ System.setProperty("org.xml.sax.driver", "foo.bar.XMLReader");
+
+ try {
+ XMLReaderFactory.createXMLReader();
+ } catch (SAXException e) {
+ // Expected
+ }
+
+ // Non-accessible class
+ System.setProperty("org.xml.sax.driver",
+ "tests.api.org.xml.sax.support.NoAccessXMLReader");
+
+ try {
+ XMLReaderFactory.createXMLReader();
+ } catch (SAXException e) {
+ // Expected
+ }
+
+ // Non-instantiable class
+ System.setProperty("org.xml.sax.driver",
+ "tests.api.org.xml.sax.support.NoInstanceXMLReader");
+
+ try {
+ XMLReaderFactory.createXMLReader();
+ } catch (SAXException e) {
+ // Expected
+ }
+
+ // Non-XMLReader class
+ System.setProperty("org.xml.sax.driver",
+ "tests.api.org.xml.sax.support.NoSubclassXMLReader");
+
+ try {
+ XMLReaderFactory.createXMLReader();
+ } catch (ClassCastException e) {
+ // Expected
+ } catch (SAXException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ // Good one, finally
+ System.setProperty("org.xml.sax.driver",
+ "tests.api.org.xml.sax.support.DoNothingXMLReader");
+
+ try {
+ XMLReaderFactory.createXMLReader();
+ } catch (SAXException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "createXMLReader",
+ args = { String.class }
+ )
+ public void testMakeParserString() {
+ // No class
+ try {
+ XMLReaderFactory.createXMLReader(null);
+ } catch (NullPointerException e) {
+ // Expected
+ } catch (SAXException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ // Unknown class
+ try {
+ XMLReaderFactory.createXMLReader("foo.bar.XMLReader");
+ } catch (SAXException e) {
+ // Expected
+ }
+
+ // Non-accessible class
+ try {
+ XMLReaderFactory.createXMLReader(
+ "tests.api.org.xml.sax.support.NoAccessXMLReader");
+ } catch (SAXException e) {
+ // Expected
+ }
+
+ // Non-instantiable class
+ try {
+ XMLReaderFactory.createXMLReader(
+ "tests.api.org.xml.sax.support.NoInstanceXMLReader");
+ } catch (SAXException e) {
+ // Expected
+ }
+
+ // Non-Parser class
+ try {
+ XMLReaderFactory.createXMLReader(
+ "tests.api.org.xml.sax.support.NoSubclassXMLReader");
+ } catch (SAXException e) {
+ // Expected
+ }
+
+ // Good one, finally
+ try {
+ XMLReaderFactory.createXMLReader(
+ "tests.api.org.xml.sax.support.DoNothingXMLReader");
+ } catch (SAXException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+
+ }
+
+}
diff --git a/xml/src/test/java/tests/api/org/xml/sax/support/BrokenInputStream.java b/xml/src/test/java/tests/api/org/xml/sax/support/BrokenInputStream.java
new file mode 100644
index 0000000..daa36f9
--- /dev/null
+++ b/xml/src/test/java/tests/api/org/xml/sax/support/BrokenInputStream.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.api.org.xml.sax.support;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Implements an InputStream what wraps another InputStream and throws an
+ * IOException after having read a specified number of bytes. Used for
+ * injecting IOExceptions on lower levels.
+ */
+public class BrokenInputStream extends InputStream {
+
+ private InputStream stream;
+
+ private int offset;
+
+ public BrokenInputStream(InputStream stream, int offset) {
+ super();
+
+ this.stream = stream;
+ this.offset = offset;
+ }
+
+ @Override
+ public int read() throws IOException {
+ if (offset == 0) {
+ throw new IOException("Injected exception");
+ }
+
+ offset--;
+ return stream.read();
+ }
+
+} \ No newline at end of file
diff --git a/xml/src/test/java/tests/api/org/xml/sax/support/DoNothingParser.java b/xml/src/test/java/tests/api/org/xml/sax/support/DoNothingParser.java
new file mode 100644
index 0000000..6049cc6
--- /dev/null
+++ b/xml/src/test/java/tests/api/org/xml/sax/support/DoNothingParser.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.api.org.xml.sax.support;
+
+import org.xml.sax.DTDHandler;
+import org.xml.sax.DocumentHandler;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.Parser;
+
+import java.util.Locale;
+
+/**
+ * A SAX Parser that does nothing, but can be instantiated properly.
+ */
+@SuppressWarnings("deprecation")
+public class DoNothingParser implements Parser {
+
+ public void parse(InputSource source) {
+ }
+
+ public void parse(String systemId) {
+ }
+
+ public void setDocumentHandler(DocumentHandler handler) {
+ }
+
+ public void setDTDHandler(DTDHandler handler) {
+ }
+
+ public void setEntityResolver(EntityResolver resolver) {
+ }
+
+ public void setErrorHandler(ErrorHandler handler) {
+ }
+
+ public void setLocale(Locale locale) {
+ }
+
+}
diff --git a/xml/src/test/java/tests/api/org/xml/sax/support/DoNothingXMLReader.java b/xml/src/test/java/tests/api/org/xml/sax/support/DoNothingXMLReader.java
new file mode 100644
index 0000000..8687bff
--- /dev/null
+++ b/xml/src/test/java/tests/api/org/xml/sax/support/DoNothingXMLReader.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.api.org.xml.sax.support;
+
+import org.xml.sax.ContentHandler;
+import org.xml.sax.DTDHandler;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.XMLReader;
+
+/**
+ * An XMLReader that does nothing, but can be instantiated properly.
+ */
+public class DoNothingXMLReader implements XMLReader {
+
+ public ContentHandler getContentHandler() {
+ return null;
+ }
+
+ public DTDHandler getDTDHandler() {
+ return null;
+ }
+
+ public EntityResolver getEntityResolver() {
+ return null;
+ }
+
+ public ErrorHandler getErrorHandler() {
+ return null;
+ }
+
+ public boolean getFeature(String name) {
+ return false;
+ }
+
+ public Object getProperty(String name) {
+ return null;
+ }
+
+ public void parse(InputSource input) {
+ }
+
+ public void parse(String systemId) {
+ }
+
+ public void setContentHandler(ContentHandler handler) {
+ }
+
+ public void setDTDHandler(DTDHandler handler) {
+ }
+
+ public void setEntityResolver(EntityResolver resolver) {
+ }
+
+ public void setErrorHandler(ErrorHandler handler) {
+ }
+
+ public void setFeature(String name, boolean value) {
+ }
+
+ public void setProperty(String name, Object value) {
+ }
+
+}
diff --git a/xml/src/test/java/tests/api/org/xml/sax/support/MethodLogger.java b/xml/src/test/java/tests/api/org/xml/sax/support/MethodLogger.java
new file mode 100644
index 0000000..198172b
--- /dev/null
+++ b/xml/src/test/java/tests/api/org/xml/sax/support/MethodLogger.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.api.org.xml.sax.support;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A simple helper class that logs method calls by storing method names and
+ * parameter lists. Used as a foundation for various simple SAX handlers.
+ */
+public class MethodLogger {
+
+ /**
+ * The names of the invoked methods, in order.
+ */
+ private List<String> methods = new ArrayList<String>();
+
+ /**
+ * The parameter lists of the invoked methods, in order.
+ */
+ private List<Object[]> argLists = new ArrayList<Object[]>();
+
+ /**
+ * Adds a method call with a variable list of arguments.
+ */
+ public void add(String method, Object ... args) {
+ Object[] argsCopy = new Object[args.length];
+ System.arraycopy(args, 0, argsCopy, 0, args.length);
+
+ methods.add(method);
+ argLists.add(argsCopy);
+ }
+
+ /**
+ * Returns the number of method invoked so far.
+ */
+ public int size() {
+ return methods.size();
+ }
+
+ /**
+ * Returns the method name stored at the given index.
+ */
+ public String getMethod(int index) {
+ return methods.get(index);
+ }
+
+ /**
+ * Returns the name of the last method that was invoked. Returns null if no
+ * method calls have been logged so far.
+ */
+ public String getMethod() {
+ return (size() == 0 ? null : getMethod(size() - 1));
+ }
+
+ /**
+ * Returns the argument array stored at the given index. May be empty, but
+ * not null.
+ */
+ public Object[] getArgs(int index) {
+ return argLists.get(index);
+ }
+
+ /**
+ * Returns the argument array of the last method that was invoked. Returns
+ * null if no method has been invoked so far.
+ */
+ public Object[] getArgs() {
+ return (size() == 0 ? null : getArgs(size() - 1));
+ }
+
+ /**
+ * Clears the log.
+ */
+ public void clear() {
+ methods.clear();
+ argLists.clear();
+ }
+
+}
diff --git a/xml/src/test/java/tests/api/org/xml/sax/support/MockFilter.java b/xml/src/test/java/tests/api/org/xml/sax/support/MockFilter.java
new file mode 100644
index 0000000..0b54bf8
--- /dev/null
+++ b/xml/src/test/java/tests/api/org/xml/sax/support/MockFilter.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.api.org.xml.sax.support;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXNotRecognizedException;
+import org.xml.sax.SAXNotSupportedException;
+import org.xml.sax.helpers.XMLFilterImpl;
+
+/**
+ * A helper class that extends XMLFilterImpl, provides dummy feature/property
+ * management, and logs some method calls.
+ */
+public class MockFilter extends XMLFilterImpl {
+
+ private MethodLogger logger;
+
+ private Set<String> features = new HashSet<String>();
+
+ private Map<String, Object> properties = new HashMap<String, Object>();
+
+ public MockFilter(MethodLogger logger) {
+ super();
+ this.logger = logger;
+ }
+
+ @Override
+ public boolean getFeature(String name) throws SAXNotRecognizedException,
+ SAXNotSupportedException {
+ return features.contains(name);
+ }
+
+ @Override
+ public Object getProperty(String name) throws SAXNotRecognizedException,
+ SAXNotSupportedException {
+ return properties.get(name);
+ }
+
+ @Override
+ public void setFeature(String name, boolean value) {
+ if (value) {
+ features.add(name);
+ } else {
+ features.remove(name);
+ }
+ }
+
+ @Override
+ public void setProperty(String name, Object value) throws SAXNotRecognizedException,
+ SAXNotSupportedException {
+ if (value == null) {
+ properties.remove(name);
+ } else {
+ properties.put(name, value);
+ }
+ }
+
+ @Override
+ public void parse(InputSource input) throws SAXException, IOException {
+ logger.add("parse", input);
+ }
+
+ @Override
+ public void parse(String systemId) throws SAXException, IOException {
+ logger.add("parse", systemId);
+ }
+
+}
diff --git a/xml/src/test/java/tests/api/org/xml/sax/support/MockHandler.java b/xml/src/test/java/tests/api/org/xml/sax/support/MockHandler.java
new file mode 100644
index 0000000..98b024a
--- /dev/null
+++ b/xml/src/test/java/tests/api/org/xml/sax/support/MockHandler.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.api.org.xml.sax.support;
+
+import org.xml.sax.AttributeList;
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.DTDHandler;
+import org.xml.sax.DocumentHandler;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.ext.LexicalHandler;
+
+/**
+ * A helper class that implements the various SAX callback interfaces and logs
+ * method calls.
+ */
+@SuppressWarnings("deprecation")
+public class MockHandler implements ContentHandler, DTDHandler, DocumentHandler,
+ ErrorHandler, LexicalHandler {
+
+ private MethodLogger logger;
+
+ public MockHandler(MethodLogger logger) {
+ super();
+ this.logger = logger;
+ }
+
+ public void characters(char[] ch, int start, int length) throws SAXException {
+ logger.add("characters", ch, start, length);
+ }
+
+ public void endDocument() throws SAXException {
+ logger.add("endDocument");
+ }
+
+ public void endElement(String name) throws SAXException {
+ logger.add("endElement", name);
+ }
+
+ public void endElement(String uri, String localName, String name) throws SAXException {
+ logger.add("endElement", uri, localName, name);
+ }
+
+ public void endPrefixMapping(String prefix) throws SAXException {
+ logger.add("endPrefixMapping", prefix);
+ }
+
+ public void error(SAXParseException exception) throws SAXException {
+ logger.add("error", exception);
+ }
+
+ public void fatalError(SAXParseException exception) throws SAXException {
+ logger.add("fatalError", exception);
+ }
+
+ public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
+ logger.add("ignorableWhitespace", ch, start, length);
+ }
+
+ public void notationDecl(String name, String publicId, String systemId) throws SAXException {
+ logger.add("notationDecl", name, publicId, systemId);
+ }
+
+ public void processingInstruction(String target, String data) throws SAXException {
+ logger.add("processingInstruction", target, data);
+ }
+
+ public void setDocumentLocator(Locator locator) {
+ logger.add("setDocumentLocator", locator);
+ }
+
+ public void skippedEntity(String name) throws SAXException {
+ logger.add("skippedEntity", name);
+ }
+
+ public void startDocument() throws SAXException {
+ logger.add("startDocument");
+ }
+
+ public void startElement(String name, AttributeList atts) throws SAXException {
+ logger.add("startElement", name, atts);
+ }
+
+ public void startElement(String uri, String localName, String name, Attributes atts)
+ throws SAXException {
+ logger.add("startElement", uri, localName, name, atts);
+ }
+
+ public void startPrefixMapping(String prefix, String uri) throws SAXException {
+ logger.add("startPrefixMapping", prefix, uri);
+ }
+
+ public void unparsedEntityDecl(String name, String publicId, String systemId,
+ String notationName) throws SAXException {
+ logger.add("unparsedEntityDecl", name, publicId, systemId, notationName);
+ }
+
+ public void warning(SAXParseException exception) throws SAXException {
+ logger.add("warning", exception);
+ }
+
+ public void comment(char[] ch, int start, int length) throws SAXException {
+ logger.add("comment", ch, start, length);
+ }
+
+ public void endCDATA() throws SAXException {
+ logger.add("endCDATA");
+ }
+
+ public void endDTD() throws SAXException {
+ logger.add("endDTD");
+ }
+
+ public void endEntity(String name) throws SAXException {
+ logger.add("endEntity", name);
+ }
+
+ public void startCDATA() throws SAXException {
+ logger.add("startCDATA");
+ }
+
+ public void startDTD(String name, String publicId, String systemId) throws SAXException {
+ logger.add("startDTD", name, publicId, systemId);
+ }
+
+ public void startEntity(String name) throws SAXException {
+ logger.add("startEntity", name);
+ }
+
+}
diff --git a/xml/src/test/java/tests/api/org/xml/sax/support/MockParser.java b/xml/src/test/java/tests/api/org/xml/sax/support/MockParser.java
new file mode 100644
index 0000000..01520f8
--- /dev/null
+++ b/xml/src/test/java/tests/api/org/xml/sax/support/MockParser.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.api.org.xml.sax.support;
+
+import java.io.IOException;
+import java.util.Locale;
+
+import org.xml.sax.DTDHandler;
+import org.xml.sax.DocumentHandler;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.Parser;
+import org.xml.sax.SAXException;
+
+@SuppressWarnings("deprecation")
+public class MockParser implements Parser {
+
+ private MethodLogger logger;
+
+ public MockParser(MethodLogger logger) {
+ super();
+ this.logger = logger;
+ }
+
+ public void parse(InputSource source) throws SAXException, IOException {
+ logger.add("parse", source);
+ }
+
+ public void parse(String systemId) throws SAXException, IOException {
+ logger.add("parse", systemId);
+ }
+
+ public void setDTDHandler(DTDHandler handler) {
+ logger.add("setDTDHandler", handler);
+ }
+
+ public void setDocumentHandler(DocumentHandler handler) {
+ logger.add("setDocumentHandler", handler);
+ }
+
+ public void setEntityResolver(EntityResolver resolver) {
+ logger.add("setEntityResolver", resolver);
+ }
+
+ public void setErrorHandler(ErrorHandler handler) {
+ logger.add("setErrorHandler", handler);
+ }
+
+ public void setLocale(Locale locale) throws SAXException {
+ logger.add("setLocale", locale);
+ }
+
+}
diff --git a/xml/src/test/java/tests/api/org/xml/sax/support/MockReader.java b/xml/src/test/java/tests/api/org/xml/sax/support/MockReader.java
new file mode 100644
index 0000000..22a6a57
--- /dev/null
+++ b/xml/src/test/java/tests/api/org/xml/sax/support/MockReader.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.api.org.xml.sax.support;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.xml.sax.ContentHandler;
+import org.xml.sax.DTDHandler;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXNotRecognizedException;
+import org.xml.sax.SAXNotSupportedException;
+import org.xml.sax.XMLReader;
+
+/**
+ * A helper class that implements the SAX XMLReader interface and logs method
+ * calls.
+ */
+public class MockReader implements XMLReader {
+
+ private MethodLogger logger;
+
+ private ContentHandler contentHandler;
+
+ private DTDHandler dtdHandler;
+
+ private EntityResolver resolver;
+
+ private ErrorHandler errorHandler;
+
+ private Set<String> features = new HashSet<String>();
+
+ private Map<String, Object> properties = new HashMap<String, Object>();
+
+ public MockReader(MethodLogger logger) {
+ super();
+ this.logger = logger;
+ }
+
+
+ public ContentHandler getContentHandler() {
+ return contentHandler;
+ }
+
+ public DTDHandler getDTDHandler() {
+ return dtdHandler;
+ }
+
+ public EntityResolver getEntityResolver() {
+ return resolver;
+ }
+
+ public ErrorHandler getErrorHandler() {
+ return errorHandler;
+ }
+
+ public boolean getFeature(String name) throws SAXNotRecognizedException,
+ SAXNotSupportedException {
+ return features.contains(name);
+ }
+
+ public Object getProperty(String name) throws SAXNotRecognizedException,
+ SAXNotSupportedException {
+ return properties.get(name);
+ }
+
+ public void parse(InputSource input) throws IOException, SAXException {
+ logger.add("parse", input);
+ }
+
+ public void parse(String systemId) throws IOException, SAXException {
+ logger.add("parse", systemId);
+ }
+
+ public void setContentHandler(ContentHandler handler) {
+ this.contentHandler = handler;
+ }
+
+ public void setDTDHandler(DTDHandler handler) {
+ this.dtdHandler = handler;
+ }
+
+ public void setEntityResolver(EntityResolver resolver) {
+ this.resolver = resolver;
+ }
+
+ public void setErrorHandler(ErrorHandler handler) {
+ this.errorHandler = handler;
+ }
+
+ public void setFeature(String name, boolean value) {
+ if (value) {
+ features.add(name);
+ } else {
+ features.remove(name);
+ }
+ }
+
+ public void setProperty(String name, Object value) throws SAXNotRecognizedException,
+ SAXNotSupportedException {
+ if (value == null) {
+ properties.remove(name);
+ } else {
+ properties.put(name, value);
+ }
+ }
+
+}
diff --git a/xml/src/test/java/tests/api/org/xml/sax/support/MockResolver.java b/xml/src/test/java/tests/api/org/xml/sax/support/MockResolver.java
new file mode 100644
index 0000000..ae0066e
--- /dev/null
+++ b/xml/src/test/java/tests/api/org/xml/sax/support/MockResolver.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.api.org.xml.sax.support;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.xml.sax.EntityResolver;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+/**
+ * A helper class for resolving entities.
+ */
+public class MockResolver implements EntityResolver {
+
+ private Map<String, InputSource> entities = new HashMap<String, InputSource>();
+
+ public void addEntity(String publicId, String systemId, InputSource source) {
+ entities.put("[" + publicId + ":" + systemId + "]", source);
+ }
+
+ public void removeEntity(String publicId, String systemId) {
+ entities.remove("[" + publicId + ":" + systemId + "]");
+ }
+
+ public InputSource resolveEntity(String publicId, String systemId)
+ throws SAXException, IOException {
+ return entities.get("[" + publicId + ":" + systemId + "]");
+ }
+
+}
diff --git a/xml/src/test/java/tests/api/org/xml/sax/support/NoAccessParser.java b/xml/src/test/java/tests/api/org/xml/sax/support/NoAccessParser.java
new file mode 100644
index 0000000..5aac9af
--- /dev/null
+++ b/xml/src/test/java/tests/api/org/xml/sax/support/NoAccessParser.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.api.org.xml.sax.support;
+
+import org.xml.sax.DTDHandler;
+import org.xml.sax.DocumentHandler;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.Parser;
+
+import java.util.Locale;
+
+/**
+ * A SAX Parser that can't be accessed.
+ */
+@SuppressWarnings("deprecation")
+class NoAccessParser implements Parser {
+
+ public void parse(InputSource source) {
+ }
+
+ public void parse(String systemId) {
+ }
+
+ public void setDocumentHandler(DocumentHandler handler) {
+ }
+
+ public void setDTDHandler(DTDHandler handler) {
+ }
+
+ public void setEntityResolver(EntityResolver resolver) {
+ }
+
+ public void setErrorHandler(ErrorHandler handler) {
+ }
+
+ public void setLocale(Locale locale) {
+ }
+
+}
diff --git a/xml/src/test/java/tests/api/org/xml/sax/support/NoAccessXMLReader.java b/xml/src/test/java/tests/api/org/xml/sax/support/NoAccessXMLReader.java
new file mode 100644
index 0000000..b6a0a68
--- /dev/null
+++ b/xml/src/test/java/tests/api/org/xml/sax/support/NoAccessXMLReader.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.api.org.xml.sax.support;
+
+import org.xml.sax.ContentHandler;
+import org.xml.sax.DTDHandler;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.XMLReader;
+
+/**
+ * An XMLReader that is not accessible.
+ */
+class NoAccessXMLReader implements XMLReader {
+
+ public ContentHandler getContentHandler() {
+ return null;
+ }
+
+ public DTDHandler getDTDHandler() {
+ return null;
+ }
+
+ public EntityResolver getEntityResolver() {
+ return null;
+ }
+
+ public ErrorHandler getErrorHandler() {
+ return null;
+ }
+
+ public boolean getFeature(String name) {
+ return false;
+ }
+
+ public Object getProperty(String name) {
+ return null;
+ }
+
+ public void parse(InputSource input) {
+ }
+
+ public void parse(String systemId) {
+ }
+
+ public void setContentHandler(ContentHandler handler) {
+ }
+
+ public void setDTDHandler(DTDHandler handler) {
+ }
+
+ public void setEntityResolver(EntityResolver resolver) {
+ }
+
+ public void setErrorHandler(ErrorHandler handler) {
+ }
+
+ public void setFeature(String name, boolean value) {
+ }
+
+ public void setProperty(String name, Object value) {
+ }
+
+}
diff --git a/xml/src/test/java/tests/api/org/xml/sax/support/NoInstanceParser.java b/xml/src/test/java/tests/api/org/xml/sax/support/NoInstanceParser.java
new file mode 100644
index 0000000..8f1692f
--- /dev/null
+++ b/xml/src/test/java/tests/api/org/xml/sax/support/NoInstanceParser.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.api.org.xml.sax.support;
+
+import org.xml.sax.DTDHandler;
+import org.xml.sax.DocumentHandler;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.Parser;
+
+import java.util.Locale;
+
+/**
+ * A SAX Parser that can be accessed, but not instantiated.
+ */
+@SuppressWarnings("deprecation")
+public class NoInstanceParser implements Parser {
+
+ public NoInstanceParser(int i) {
+ }
+
+ public void parse(InputSource source) {
+ }
+
+ public void parse(String systemId) {
+ }
+
+ public void setDocumentHandler(DocumentHandler handler) {
+ }
+
+ public void setDTDHandler(DTDHandler handler) {
+ }
+
+ public void setEntityResolver(EntityResolver resolver) {
+ }
+
+ public void setErrorHandler(ErrorHandler handler) {
+ }
+
+ public void setLocale(Locale locale) {
+ }
+
+}
diff --git a/xml/src/test/java/tests/api/org/xml/sax/support/NoInstanceXMLReader.java b/xml/src/test/java/tests/api/org/xml/sax/support/NoInstanceXMLReader.java
new file mode 100644
index 0000000..764c451
--- /dev/null
+++ b/xml/src/test/java/tests/api/org/xml/sax/support/NoInstanceXMLReader.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.api.org.xml.sax.support;
+
+import org.xml.sax.ContentHandler;
+import org.xml.sax.DTDHandler;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.XMLReader;
+
+/**
+ * An XMLReader that is accessible, but can't be instantiated.
+ */
+public class NoInstanceXMLReader implements XMLReader {
+
+ public NoInstanceXMLReader(int i) {
+ }
+
+ public ContentHandler getContentHandler() {
+ return null;
+ }
+
+ public DTDHandler getDTDHandler() {
+ return null;
+ }
+
+ public EntityResolver getEntityResolver() {
+ return null;
+ }
+
+ public ErrorHandler getErrorHandler() {
+ return null;
+ }
+
+ public boolean getFeature(String name) {
+ return false;
+ }
+
+ public Object getProperty(String name) {
+ return null;
+ }
+
+ public void parse(InputSource input) {
+ }
+
+ public void parse(String systemId) {
+ }
+
+ public void setContentHandler(ContentHandler handler) {
+ }
+
+ public void setDTDHandler(DTDHandler handler) {
+ }
+
+ public void setEntityResolver(EntityResolver resolver) {
+ }
+
+ public void setErrorHandler(ErrorHandler handler) {
+ }
+
+ public void setFeature(String name, boolean value) {
+ }
+
+ public void setProperty(String name, Object value) {
+ }
+
+}
diff --git a/xml/src/test/java/tests/api/org/xml/sax/support/NoSubclassParser.java b/xml/src/test/java/tests/api/org/xml/sax/support/NoSubclassParser.java
new file mode 100644
index 0000000..f178998
--- /dev/null
+++ b/xml/src/test/java/tests/api/org/xml/sax/support/NoSubclassParser.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.api.org.xml.sax.support;
+
+import org.xml.sax.DTDHandler;
+import org.xml.sax.DocumentHandler;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.InputSource;
+
+import java.util.Locale;
+
+/**
+ * A SAX Parser that does not implement the Parser interface.
+ */
+@SuppressWarnings("deprecation")
+public class NoSubclassParser {
+
+ public void parse(InputSource source) {
+ }
+
+ public void parse(String systemId) {
+ }
+
+ public void setDocumentHandler(DocumentHandler handler) {
+ }
+
+ public void setDTDHandler(DTDHandler handler) {
+ }
+
+ public void setEntityResolver(EntityResolver resolver) {
+ }
+
+ public void setErrorHandler(ErrorHandler handler) {
+ }
+
+ public void setLocale(Locale locale) {
+ }
+
+}
diff --git a/xml/src/test/java/tests/api/org/xml/sax/support/NoSubclassXMLReader.java b/xml/src/test/java/tests/api/org/xml/sax/support/NoSubclassXMLReader.java
new file mode 100644
index 0000000..acdbd88
--- /dev/null
+++ b/xml/src/test/java/tests/api/org/xml/sax/support/NoSubclassXMLReader.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.api.org.xml.sax.support;
+
+import org.xml.sax.ContentHandler;
+import org.xml.sax.DTDHandler;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.XMLReader;
+
+/**
+ * An XMLReader that does not implement the XMLReader interface.
+ */
+public class NoSubclassXMLReader implements XMLReader {
+
+ public ContentHandler getContentHandler() {
+ return null;
+ }
+
+ public DTDHandler getDTDHandler() {
+ return null;
+ }
+
+ public EntityResolver getEntityResolver() {
+ return null;
+ }
+
+ public ErrorHandler getErrorHandler() {
+ return null;
+ }
+
+ public boolean getFeature(String name) {
+ return false;
+ }
+
+ public Object getProperty(String name) {
+ return null;
+ }
+
+ public void parse(InputSource input) {
+ }
+
+ public void parse(String systemId) {
+ }
+
+ public void setContentHandler(ContentHandler handler) {
+ }
+
+ public void setDTDHandler(DTDHandler handler) {
+ }
+
+ public void setEntityResolver(EntityResolver resolver) {
+ }
+
+ public void setErrorHandler(ErrorHandler handler) {
+ }
+
+ public void setFeature(String name, boolean value) {
+ }
+
+ public void setProperty(String name, Object value) {
+ }
+
+}
diff --git a/xml/src/test/java/tests/org/w3c/dom/AllTests.java b/xml/src/test/java/tests/org/w3c/dom/AllTests.java
new file mode 100644
index 0000000..a4299a7
--- /dev/null
+++ b/xml/src/test/java/tests/org/w3c/dom/AllTests.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.org.w3c.dom;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+/**
+ * This is autogenerated source file. Includes tests for package org.w3c.dom;
+ */
+
+public class AllTests {
+
+ public static void main(String[] args) {
+ junit.textui.TestRunner.run(AllTests.suite());
+ }
+
+ public static Test suite() {
+ TestSuite suite = tests.TestSuiteFactory.createTestSuite("All tests for package org.w3c.dom;");
+ // $JUnit-BEGIN$
+
+ suite.addTestSuite(AttrGetOwnerElement.class);
+ suite.addTestSuite(CreateAttributeNS.class);
+ suite.addTestSuite(CreateDocument.class);
+ suite.addTestSuite(CreateDocumentType.class);
+ suite.addTestSuite(CreateElementNS.class);
+ suite.addTestSuite(DOMImplementationCreateDocument.class);
+ suite.addTestSuite(DOMImplementationCreateDocumentType.class);
+ suite.addTestSuite(DOMImplementationHasFeature.class);
+ suite.addTestSuite(DocumentCreateAttributeNS.class);
+ suite.addTestSuite(DocumentCreateElementNS.class);
+ suite.addTestSuite(DocumentGetElementsByTagnameNS.class);
+ suite.addTestSuite(DocumentGeteEementById.class);
+ suite.addTestSuite(DocumentImportNode.class);
+ suite.addTestSuite(DocumentTypeInternalSubset.class);
+ suite.addTestSuite(DocumentTypePublicId.class);
+ suite.addTestSuite(DocumentTypeSystemId.class);
+// Is empty. Only test assumes validation. Leave disabled.
+// suite.addTestSuite(ElementGetAttributeNS.class);
+ suite.addTestSuite(ElementGetAttributeNodeNS.class);
+ suite.addTestSuite(ElementGetElementsByTagNameNS.class);
+ suite.addTestSuite(ElementHasAttribute.class);
+ suite.addTestSuite(ElementHasAttributeNS.class);
+ suite.addTestSuite(ElementRemoveAttributeNS.class);
+ suite.addTestSuite(ElementSetAttributeNS.class);
+ suite.addTestSuite(ElementSetAttributeNodeNS.class);
+ suite.addTestSuite(GetAttributeNS.class);
+ suite.addTestSuite(GetAttributeNodeNS.class);
+ suite.addTestSuite(GetElementById.class);
+ suite.addTestSuite(GetElementsByTagNameNS.class);
+ suite.addTestSuite(GetNamedItemNS.class);
+// Is empty. Only test assumes validation. Leave disabled.
+// suite.addTestSuite(HCEntitiesRemoveNamedItemNS.class);
+// Is empty. Only test assumes validation. Leave disabled.
+// suite.addTestSuite(HCEntitiesSetNamedItemNS.class);
+ suite.addTestSuite(HCNamedNodeMapInvalidType.class);
+ suite.addTestSuite(HCNodeDocumentFragmentNormalize.class);
+// Is empty. Only test assumes validation. Leave disabled.
+// suite.addTestSuite(HCNotationsRemoveNamedItemNS.class);
+// Is empty. Only test assumes validation. Leave disabled.
+// suite.addTestSuite(HCNotationsSetNamedItemNS.class);
+ suite.addTestSuite(HasAttribute.class);
+ suite.addTestSuite(HasAttributeNS.class);
+ suite.addTestSuite(HasAttributes.class);
+ suite.addTestSuite(ImportNode.class);
+ suite.addTestSuite(InternalSubset.class);
+ suite.addTestSuite(IsSupported.class);
+ suite.addTestSuite(LocalName.class);
+ suite.addTestSuite(NamedNodeMapGetNamedItemNS.class);
+ suite.addTestSuite(NamedNodeMapRemoveNamedItemNS.class);
+ suite.addTestSuite(NamedNodeMapSetNamedItemNS.class);
+ suite.addTestSuite(NamespaceURI.class);
+ suite.addTestSuite(NodeGetLocalName.class);
+ suite.addTestSuite(NodeGetNamespaceURI.class);
+ suite.addTestSuite(NodeGetOwnerDocument.class);
+ suite.addTestSuite(NodeGetPrefix.class);
+ suite.addTestSuite(NodeHasAttributes.class);
+ suite.addTestSuite(NodeIsSupported.class);
+ suite.addTestSuite(NodeNormalize.class);
+ suite.addTestSuite(NodeSetPrefix.class);
+ suite.addTestSuite(Normalize.class);
+ suite.addTestSuite(OwnerDocument.class);
+ suite.addTestSuite(OwnerElement.class);
+ suite.addTestSuite(Prefix.class);
+ suite.addTestSuite(PublicId.class);
+// Is empty. Only test assumes validation. Leave disabled.
+// suite.addTestSuite(RemoveAttributeNS.class);
+ suite.addTestSuite(RemoveNamedItemNS.class);
+ suite.addTestSuite(SetAttributeNS.class);
+ suite.addTestSuite(SetAttributeNodeNS.class);
+ suite.addTestSuite(SetNamedItemNS.class);
+ suite.addTestSuite(SystemId.class);
+ // $JUnit-END$
+ return suite;
+ }
+}
diff --git a/xml/src/test/java/tests/org/w3c/dom/AttrGetOwnerElement.java b/xml/src/test/java/tests/org/w3c/dom/AttrGetOwnerElement.java
new file mode 100644
index 0000000..bb42121
--- /dev/null
+++ b/xml/src/test/java/tests/org/w3c/dom/AttrGetOwnerElement.java
@@ -0,0 +1,156 @@
+package tests.org.w3c.dom;
+
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.NamedNodeMap;
+
+import javax.xml.parsers.DocumentBuilder;
+
+@TestTargetClass(Attr.class)
+public final class AttrGetOwnerElement extends DOMTestCase {
+
+ DOMDocumentBuilderFactory factory;
+
+ DocumentBuilder builder;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ try {
+ factory = new DOMDocumentBuilderFactory(DOMDocumentBuilderFactory
+ .getConfiguration2());
+ builder = factory.getBuilder();
+ } catch (Exception e) {
+ fail("Unexpected exception " + e.getMessage());
+ }
+ }
+
+ protected void tearDown() throws Exception {
+ factory = null;
+ builder = null;
+ super.tearDown();
+ }
+
+// Assumes validation.
+// public void testGetOwnerElement1() throws Throwable {
+// Document doc;
+// Attr attr;
+// Element element;
+// Element ownerElement;
+// String ownerElementName;
+// NodeList elementList;
+// NamedNodeMap attributes;
+// String nullNS = null;
+//
+// doc = (Document) load("staffNS", builder);
+//
+// elementList = doc.getElementsByTagNameNS("http://www.nist.gov",
+// "employee");
+// element = (Element) elementList.item(1);
+// attributes = element.getAttributes();
+// attr = (Attr) attributes.getNamedItemNS(nullNS, "defaultAttr");
+// ownerElement = attr.getOwnerElement();
+// ownerElementName = ownerElement.getNodeName();
+// assertEquals("attrgetownerelement01", "emp:employee", ownerElementName);
+//
+// }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Doesn't verify that getOwnerElement returns null if an attribute is not in use.",
+ method = "getOwnerElement",
+ args = {}
+ )
+ public void testGetOwnerElement2() throws Throwable {
+ Document doc;
+ Element element;
+ Element ownerElement;
+ String ownerElementName;
+ Attr attr;
+
+ doc = (Document) load("staffNS", builder);
+ element = doc.createElement("root");
+ attr = doc.createAttributeNS("http://www.w3.org/DOM/L1", "L1:att");
+ element.setAttributeNodeNS(attr);
+ ownerElement = attr.getOwnerElement();
+ ownerElementName = ownerElement.getNodeName();
+ assertEquals("attrgetownerelement02", "root", ownerElementName);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Verifies that getOwnerElement returns null if an attribute is not in use.",
+ method = "getOwnerElement",
+ args = {}
+ )
+ public void testGetOwnerElement3() throws Throwable {
+ Document doc;
+ Node ownerElement;
+ Attr attr;
+ doc = (Document) load("staffNS", builder);
+ attr = doc.createAttributeNS("http://www.w3.org/DOM", "dom:attr");
+ ownerElement = attr.getOwnerElement();
+ assertNull("attrgetownerelement03", ownerElement);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Verifies that getOwnerElement returns null if an attribute is not in use.",
+ method = "getOwnerElement",
+ args = {}
+ )
+ public void testGetOwnerElement4() throws Throwable {
+ Document doc;
+ Document docImp;
+ Node ownerElement;
+ Element element;
+ Attr attr;
+ Attr attrImp;
+ NodeList addresses;
+
+ doc = (Document) load("staffNS", builder);
+ docImp = (Document) load("staff", builder);
+
+ addresses = doc
+ .getElementsByTagNameNS("http://www.nist.gov", "address");
+ element = (Element) addresses.item(1);
+ assertNotNull("empAddressNotNull", element);
+ attr = element.getAttributeNodeNS("http://www.nist.gov", "zone");
+ attrImp = (Attr) docImp.importNode(attr, true);
+ ownerElement = attrImp.getOwnerElement();
+ assertNull("attrgetownerelement04", ownerElement);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Doesn't verify that getOwnerElement returns null if an attribute is not in use.",
+ method = "getOwnerElement",
+ args = {}
+ )
+ public void testGetOwnerElement5() throws Throwable {
+ Document doc;
+ Node element;
+ Element ownerElement;
+ Element parentElement;
+ NodeList elementList;
+ String ownerElementName;
+ Attr attr;
+
+ NamedNodeMap nodeMap;
+ String nullNS = null;
+
+ doc = (Document) load("staffNS", builder);
+ elementList = doc.getElementsByTagNameNS("*", "address");
+ element = elementList.item(1);
+ parentElement = (Element) element.getParentNode();
+ nodeMap = element.getAttributes();
+ parentElement.removeChild(element);
+ attr = (Attr) nodeMap.getNamedItemNS(nullNS, "street");
+ ownerElement = attr.getOwnerElement();
+ ownerElementName = ownerElement.getNodeName();
+ assertEquals("attrgetownerelement05", "address", ownerElementName);
+ }
+}
diff --git a/xml/src/test/java/tests/org/w3c/dom/CreateAttributeNS.java b/xml/src/test/java/tests/org/w3c/dom/CreateAttributeNS.java
new file mode 100644
index 0000000..c7e0d34
--- /dev/null
+++ b/xml/src/test/java/tests/org/w3c/dom/CreateAttributeNS.java
@@ -0,0 +1,229 @@
+/*
+ This Java source file was generated by test-to-java.xsl
+ and is a derived work from the source document.
+ The source document contained the following notice:
+
+
+
+ Copyright (c) 2001 World Wide Web Consortium,
+ (Massachusetts Institute of Technology, Institut National de
+ Recherche en Informatique et en Automatique, Keio University). All
+ Rights Reserved. This program is distributed under the W3C's Software
+ Intellectual Property License. This program is distributed in the
+ hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+ See W3C License http://www.w3.org/Consortium/Legal/ for more details.
+
+
+ */
+
+package tests.org.w3c.dom;
+
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.DOMException;
+import org.w3c.dom.Attr;
+
+import javax.xml.parsers.DocumentBuilder;
+
+@TestTargetClass(Document.class)
+public final class CreateAttributeNS extends DOMTestCase {
+
+ DOMDocumentBuilderFactory factory;
+
+ DocumentBuilder builder;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ try {
+ factory = new DOMDocumentBuilderFactory(DOMDocumentBuilderFactory
+ .getConfiguration2());
+ builder = factory.getBuilder();
+ } catch (Exception e) {
+ fail("Unexpected exception" + e.getMessage());
+ }
+ }
+
+ protected void tearDown() throws Exception {
+ factory = null;
+ builder = null;
+ super.tearDown();
+ }
+
+ /**
+ * Runs the test case.
+ *
+ * @throws Throwable
+ * Any uncaught exception causes test to fail
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies NAMESPACE_ERR exception code.",
+ method = "createAttributeNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testCreateAttributeNS1() throws Throwable {
+ String namespaceURI = "http://www.ecommerce.org/";
+ String malformedName = "prefix::local";
+ Document doc;
+
+ doc = (Document) load("staffNS", builder);
+
+ {
+ boolean success = false;
+ try {
+ doc.createAttributeNS(namespaceURI, malformedName);
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.NAMESPACE_ERR);
+ }
+ assertTrue("throw_NAMESPACE_ERR", success);
+ }
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies createAttributeNS method with null as the fisrt parameter.",
+ method = "createAttributeNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testCreateAttributeNS2() throws Throwable {
+ String namespaceURI = null;
+
+ String qualifiedName = "prefix:local";
+ Document doc;
+
+ doc = (Document) load("staffNS", builder);
+
+ {
+ boolean success = false;
+ try {
+ doc.createAttributeNS(namespaceURI, qualifiedName);
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.NAMESPACE_ERR);
+ }
+ assertTrue("throw_NAMESPACE_ERR", success);
+ }
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies that createAttributeNS throws DOMException.",
+ method = "createAttributeNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testCreateAttributeNS3() throws Throwable {
+ String namespaceURI = "http://www.wedding.com/";
+ String qualifiedName;
+ Document doc;
+
+ List<String> illegalQNames = new ArrayList<String>();
+ illegalQNames.add("person:{");
+ illegalQNames.add("person:}");
+ illegalQNames.add("person:~");
+ illegalQNames.add("person:'");
+ illegalQNames.add("person:!");
+ illegalQNames.add("person:@");
+ illegalQNames.add("person:#");
+ illegalQNames.add("person:$");
+ illegalQNames.add("person:%");
+ illegalQNames.add("person:^");
+ illegalQNames.add("person:&");
+ illegalQNames.add("person:*");
+ illegalQNames.add("person:(");
+ illegalQNames.add("person:)");
+ illegalQNames.add("person:+");
+ illegalQNames.add("person:=");
+ illegalQNames.add("person:[");
+ illegalQNames.add("person:]");
+ illegalQNames.add("person:\\");
+ illegalQNames.add("person:/");
+ illegalQNames.add("person:;");
+ illegalQNames.add("person:`");
+ illegalQNames.add("person:<");
+ illegalQNames.add("person:>");
+ illegalQNames.add("person:,");
+ illegalQNames.add("person:a ");
+ illegalQNames.add("person:\"");
+
+ doc = (Document) load("staffNS", builder);
+ for (int indexN10090 = 0; indexN10090 < illegalQNames.size(); indexN10090++) {
+ qualifiedName = (String) illegalQNames.get(indexN10090);
+ {
+ boolean success = false;
+ try {
+ doc.createAttributeNS(namespaceURI, qualifiedName);
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.INVALID_CHARACTER_ERR);
+ }
+ assertTrue("throw_INVALID_CHARACTER_ERR", success);
+ }
+ }
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Doesn't verify exceptions.",
+ method = "createAttributeNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testCreateAttributeNS4() throws Throwable {
+ String namespaceURI = "http://www.w3.org/XML/1998/namespaces";
+ String qualifiedName = "xml:attr1";
+ Document doc;
+
+ doc = (Document) load("staffNS", builder);
+
+ {
+ boolean success = false;
+ try {
+ doc.createAttributeNS(namespaceURI, qualifiedName);
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.NAMESPACE_ERR);
+ }
+ assertTrue("throw_NAMESPACE_ERR", success);
+ }
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Doesn't verify exceptions.",
+ method = "createAttributeNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testCreateAttributeNS5() throws Throwable {
+ String namespaceURI = "http://www.ecommerce.org/";
+ String qualifiedName = "econm:local";
+ Document doc;
+ Attr newAttr;
+ String attrName;
+ doc = (Document) load("staffNS", builder);
+ newAttr = doc.createAttributeNS(namespaceURI, qualifiedName);
+ attrName = newAttr.getName();
+ assertEquals("throw_Equals", qualifiedName, attrName);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "createAttributeNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testCreateAttributeNS6() throws Throwable {
+ String namespaceURI = "http://www.example.com/";
+ Document doc;
+
+ doc = (Document) load("hc_staff", builder);
+
+ boolean success = false;
+ try {
+ doc.createAttributeNS(namespaceURI, "");
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.NAMESPACE_ERR);
+ }
+ assertTrue("throw_INVALID_CHARACTER_ERR", success);
+ }
+}
diff --git a/xml/src/test/java/tests/org/w3c/dom/CreateDocument.java b/xml/src/test/java/tests/org/w3c/dom/CreateDocument.java
new file mode 100644
index 0000000..157b394
--- /dev/null
+++ b/xml/src/test/java/tests/org/w3c/dom/CreateDocument.java
@@ -0,0 +1,317 @@
+/*
+ This Java source file was generated by test-to-java.xsl
+ and is a derived work from the source document.
+ The source document contained the following notice:
+
+
+
+ Copyright (c) 2001 World Wide Web Consortium,
+ (Massachusetts Institute of Technology, Institut National de
+ Recherche en Informatique et en Automatique, Keio University). All
+ Rights Reserved. This program is distributed under the W3C's Software
+ Intellectual Property License. This program is distributed in the
+ hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+ See W3C License http://www.w3.org/Consortium/Legal/ for more details.
+
+
+ */
+
+package tests.org.w3c.dom;
+
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.w3c.dom.DOMImplementation;
+import org.w3c.dom.Document;
+import org.w3c.dom.DocumentType;
+import org.w3c.dom.DOMException;
+
+import javax.xml.parsers.DocumentBuilder;
+
+/**
+ * The "createDocument(namespaceURI,qualifiedName,doctype)" method for a
+ * DOMImplementation should raise NAMESPACE_ERR DOMException if parameter
+ * qualifiedName is malformed.
+ *
+ * Retrieve the DOMImplementation on the XMLNS Document. Invoke method
+ * createDocument(namespaceURI,qualifiedName,doctype) on the retrieved
+ * DOMImplementation with namespaceURI being the literal string
+ * "http://www.ecommerce.org/", qualifiedName as "prefix::local", and doctype as
+ * null. Method should raise NAMESPACE_ERR DOMException.
+ *
+ * @author NIST
+ * @author Mary Brady
+ * @see <a
+ * href="http://www.w3.org/TR/DOM-Level-2-Core/core#xpointer(id('ID-258A00AF')/constant[@name='NAMESPACE_ERR'])">http://www.w3.org/TR/DOM-Level-2-Core/core#xpointer(id('ID-258A00AF')/constant[@name='NAMESPACE_ERR'])</a>
+ * @see <a
+ * href="http://www.w3.org/TR/DOM-Level-2-Core/core#Level-2-Core-DOM-createDocument">http://www.w3.org/TR/DOM-Level-2-Core/core#Level-2-Core-DOM-createDocument</a>
+ * @see <a
+ * href="http://www.w3.org/TR/DOM-Level-2-Core/core#xpointer(id('Level-2-Core-DOM-createDocument')/raises/exception[@name='DOMException']/descr/p[substring-before(.,':')='NAMESPACE_ERR'])">http://www.w3.org/TR/DOM-Level-2-Core/core#xpointer(id('Level-2-Core-DOM-createDocument')/raises/exception[@name='DOMException']/descr/p[substring-before(.,':')='NAMESPACE_ERR'])</a>
+ */
+@TestTargetClass(DOMImplementation.class)
+public final class CreateDocument extends DOMTestCase {
+
+ DOMDocumentBuilderFactory factory;
+
+ DocumentBuilder builder;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ try {
+ factory = new DOMDocumentBuilderFactory(DOMDocumentBuilderFactory
+ .getConfiguration1());
+ builder = factory.getBuilder();
+ } catch (Exception e) {
+ fail("Unexpected exception" + e.getMessage());
+ }
+ }
+
+ protected void tearDown() throws Exception {
+ factory = null;
+ builder = null;
+ super.tearDown();
+ }
+
+ /**
+ * Runs the test case.
+ *
+ * @throws Throwable
+ * Any uncaught exception causes test to fail
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Doesn't verify null as parameters.",
+ method = "createDocument",
+ args = {java.lang.String.class, java.lang.String.class, org.w3c.dom.DocumentType.class}
+ )
+ public void testCreateDocument1() throws Throwable {
+ String namespaceURI = "http://www.ecommerce.org/";
+ String malformedName = "prefix::local";
+ Document doc;
+ DocumentType docType = null;
+
+ DOMImplementation domImpl;
+
+ doc = (Document) load("staffNS", builder);
+ domImpl = doc.getImplementation();
+
+ boolean success = false;
+ try {
+ domImpl.createDocument(namespaceURI, malformedName, docType);
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.NAMESPACE_ERR);
+ }
+ assertTrue("throw_NAMESPACE_ERR", success);
+
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Doesn't verify null as parameters.",
+ method = "createDocument",
+ args = {java.lang.String.class, java.lang.String.class, org.w3c.dom.DocumentType.class}
+ )
+ public void testCreateDocument2() throws Throwable {
+ String namespaceURI = null;
+
+ String qualifiedName = "k:local";
+ Document doc;
+ DocumentType docType = null;
+
+ DOMImplementation domImpl;
+
+ doc = (Document) load("staffNS", builder);
+ domImpl = doc.getImplementation();
+
+ boolean success = false;
+ try {
+ domImpl.createDocument(namespaceURI, qualifiedName, docType);
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.NAMESPACE_ERR);
+ }
+ assertTrue("throw_NAMESPACE_ERR", success);
+
+ }
+
+// public void testCreateDocument3() throws Throwable {
+// String namespaceURI = "http://www.ecommerce.org/schema";
+// String qualifiedName = "namespaceURI:x";
+// Document doc;
+// DocumentType docType;
+// DOMImplementation domImpl;
+//
+// doc = (Document) load("staffNS", builder);
+// docType = doc.getDoctype();
+// domImpl = doc.getImplementation();
+//
+// boolean success = false;
+// try {
+// domImpl.createDocument(namespaceURI, qualifiedName, docType);
+// } catch (DOMException ex) {
+// success = (ex.code == DOMException.WRONG_DOCUMENT_ERR);
+// }
+// assertTrue("throw_WRONG_DOCUMENT_ERR", success);
+//
+// }
+
+// public void testCreateDocument4() throws Throwable {
+// String namespaceURI = "http://www.ecommerce.org/schema";
+// String qualifiedName = "namespaceURI:x";
+// Document doc;
+// DocumentType docType;
+// DOMImplementation domImpl;
+// Document aNewDoc;
+// doc = (Document) load("staffNS", builder);
+// aNewDoc = (Document) load("staffNS", builder);
+// docType = doc.getDoctype();
+// domImpl = aNewDoc.getImplementation();
+//
+// boolean success = false;
+// try {
+// aNewDoc = domImpl.createDocument(namespaceURI, qualifiedName,
+// docType);
+// } catch (DOMException ex) {
+// success = (ex.code == DOMException.WRONG_DOCUMENT_ERR);
+// }
+// assertTrue("throw_WRONG_DOCUMENT_ERR", success);
+//
+// }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Doesn't verify null as parameters.",
+ method = "createDocument",
+ args = {java.lang.String.class, java.lang.String.class, org.w3c.dom.DocumentType.class}
+ )
+ public void testCreateDocument5() throws Throwable {
+ String namespaceURI = "http://www.ecommerce.org/schema";
+ String qualifiedName;
+ Document doc;
+ DocumentType docType = null;
+
+ DOMImplementation domImpl;
+
+ List<String> illegalQNames = new ArrayList<String>();
+ illegalQNames.add("namespaceURI:{");
+ illegalQNames.add("namespaceURI:}");
+ illegalQNames.add("namespaceURI:~");
+ illegalQNames.add("namespaceURI:'");
+ illegalQNames.add("namespaceURI:!");
+ illegalQNames.add("namespaceURI:@");
+ illegalQNames.add("namespaceURI:#");
+ illegalQNames.add("namespaceURI:$");
+ illegalQNames.add("namespaceURI:%");
+ illegalQNames.add("namespaceURI:^");
+ illegalQNames.add("namespaceURI:&");
+ illegalQNames.add("namespaceURI:*");
+ illegalQNames.add("namespaceURI:(");
+ illegalQNames.add("namespaceURI:)");
+ illegalQNames.add("namespaceURI:+");
+ illegalQNames.add("namespaceURI:=");
+ illegalQNames.add("namespaceURI:[");
+ illegalQNames.add("namespaceURI:]");
+ illegalQNames.add("namespaceURI:\\");
+ illegalQNames.add("namespaceURI:/");
+ illegalQNames.add("namespaceURI:;");
+ illegalQNames.add("namespaceURI:`");
+ illegalQNames.add("namespaceURI:<");
+ illegalQNames.add("namespaceURI:>");
+ illegalQNames.add("namespaceURI:,");
+ illegalQNames.add("namespaceURI:a ");
+ illegalQNames.add("namespaceURI:\"");
+
+ doc = (Document) load("staffNS", builder);
+ for (int indexN1009A = 0; indexN1009A < illegalQNames.size(); indexN1009A++) {
+ qualifiedName = (String) illegalQNames.get(indexN1009A);
+ domImpl = doc.getImplementation();
+
+ boolean success = false;
+ try {
+ domImpl.createDocument(namespaceURI, qualifiedName, docType);
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.INVALID_CHARACTER_ERR);
+ }
+ assertTrue("throw_INVALID_CHARACTER_ERR", success);
+
+ }
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Doesn't verify null as parameters.",
+ method = "createDocument",
+ args = {java.lang.String.class, java.lang.String.class, org.w3c.dom.DocumentType.class}
+ )
+ public void testCreateDocument6() throws Throwable {
+ String namespaceURI = "http://ecommerce.org/schema";
+ String qualifiedName = "xml:local";
+ Document doc;
+ DocumentType docType = null;
+
+ DOMImplementation domImpl;
+
+ doc = (Document) load("staffNS", builder);
+ domImpl = doc.getImplementation();
+
+ boolean success = false;
+ try {
+ domImpl.createDocument(namespaceURI, qualifiedName, docType);
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.NAMESPACE_ERR);
+ }
+ assertTrue("throw_NAMESPACE_ERR", success);
+
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Doesn't verify null as parameters.",
+ method = "createDocument",
+ args = {java.lang.String.class, java.lang.String.class, org.w3c.dom.DocumentType.class}
+ )
+ public void testCreateDocument7() throws Throwable {
+ String namespaceURI = "http://www.ecommerce.org/schema";
+ String qualifiedName = "y:x";
+ Document doc;
+ DocumentType docType = null;
+
+ DOMImplementation domImpl;
+ Document aNewDoc;
+ String nodeName;
+ String nodeValue;
+ doc = (Document) load("staffNS", builder);
+ domImpl = doc.getImplementation();
+ aNewDoc = domImpl.createDocument(namespaceURI, qualifiedName, docType);
+ nodeName = aNewDoc.getNodeName();
+ nodeValue = aNewDoc.getNodeValue();
+ assertEquals("nodeName", "#document", nodeName);
+ assertNull("nodeValue", nodeValue);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Doesn't verify null as parameters.",
+ method = "createDocument",
+ args = {java.lang.String.class, java.lang.String.class, org.w3c.dom.DocumentType.class}
+ )
+ public void testCreateDocument8() throws Throwable {
+ String namespaceURI = "http://www.example.org/schema";
+ DocumentType docType = null;
+
+ DOMImplementation domImpl;
+
+ domImpl = builder.getDOMImplementation();
+
+ boolean success = false;
+ try {
+ domImpl.createDocument(namespaceURI, "", docType);
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.NAMESPACE_ERR);
+ }
+ assertTrue("throw_NAMESPACE_ERR", success);
+
+ }
+}
diff --git a/xml/src/test/java/tests/org/w3c/dom/CreateDocumentType.java b/xml/src/test/java/tests/org/w3c/dom/CreateDocumentType.java
new file mode 100644
index 0000000..c5061b8
--- /dev/null
+++ b/xml/src/test/java/tests/org/w3c/dom/CreateDocumentType.java
@@ -0,0 +1,222 @@
+/*
+ This Java source file was generated by test-to-java.xsl
+ and is a derived work from the source document.
+ The source document contained the following notice:
+
+
+
+ Copyright (c) 2001 World Wide Web Consortium,
+ (Massachusetts Institute of Technology, Institut National de
+ Recherche en Informatique et en Automatique, Keio University). All
+ Rights Reserved. This program is distributed under the W3C's Software
+ Intellectual Property License. This program is distributed in the
+ hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+ See W3C License http://www.w3.org/Consortium/Legal/ for more details.
+
+
+ */
+
+package tests.org.w3c.dom;
+
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.w3c.dom.DOMImplementation;
+import org.w3c.dom.Document;
+import org.w3c.dom.DOMException;
+import org.w3c.dom.DocumentType;
+
+import javax.xml.parsers.DocumentBuilder;
+
+/**
+ * The "createDocumentType(qualifiedName,publicId,systemId)" method for a
+ * DOMImplementation should raise NAMESPACE_ERR DOMException if qualifiedName is
+ * malformed.
+ *
+ * Retrieve the DOMImplementation on the XMLNS Document. Invoke method
+ * createDocumentType(qualifiedName,publicId,systemId) on the retrieved
+ * DOMImplementation with qualifiedName being the literal string
+ * "prefix::local", publicId as "STAFF", and systemId as "staff". Method should
+ * raise NAMESPACE_ERR DOMException.
+ *
+ * @author NIST
+ * @author Mary Brady
+ * @see <a
+ * href="http://www.w3.org/TR/DOM-Level-2-Core/core#xpointer(id('ID-258A00AF')/constant[@name='NAMESPACE_ERR'])">http://www.w3.org/TR/DOM-Level-2-Core/core#xpointer(id('ID-258A00AF')/constant[@name='NAMESPACE_ERR'])</a>
+ * @see <a
+ * href="http://www.w3.org/TR/DOM-Level-2-Core/core#Level-2-Core-DOM-createDocType">http://www.w3.org/TR/DOM-Level-2-Core/core#Level-2-Core-DOM-createDocType</a>
+ * @see <a
+ * href="http://www.w3.org/TR/DOM-Level-2-Core/core#xpointer(id('Level-2-Core-DOM-createDocType')/raises/exception[@name='DOMException']/descr/p[substring-before(.,':')='NAMESPACE_ERR'])">http://www.w3.org/TR/DOM-Level-2-Core/core#xpointer(id('Level-2-Core-DOM-createDocType')/raises/exception[@name='DOMException']/descr/p[substring-before(.,':')='NAMESPACE_ERR'])</a>
+ */
+@TestTargetClass(DOMImplementation.class)
+public final class CreateDocumentType extends DOMTestCase {
+
+ DOMDocumentBuilderFactory factory;
+
+ DocumentBuilder builder;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ try {
+ factory = new DOMDocumentBuilderFactory(DOMDocumentBuilderFactory
+ .getConfiguration1());
+ builder = factory.getBuilder();
+ } catch (Exception e) {
+ fail("Unexpected exception" + e.getMessage());
+ }
+ }
+
+ protected void tearDown() throws Exception {
+ factory = null;
+ builder = null;
+ super.tearDown();
+ }
+
+ /**
+ * Runs the test case.
+ *
+ * @throws Throwable
+ * Any uncaught exception causes test to fail
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Doesn't verify null as parameters.",
+ method = "createDocumentType",
+ args = {java.lang.String.class, java.lang.String.class, java.lang.String.class}
+ )
+ public void testCreateDocumentType1() throws Throwable {
+ String publicId = "STAFF";
+ String systemId = "staff.xml";
+ String malformedName = "prefix::local";
+ Document doc;
+ DOMImplementation domImpl;
+
+ doc = (Document) load("staffNS", builder);
+ domImpl = doc.getImplementation();
+
+ {
+ boolean success = false;
+ try {
+ domImpl.createDocumentType(malformedName, publicId, systemId);
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.NAMESPACE_ERR);
+ }
+ assertTrue("throw_NAMESPACE_ERR", success);
+ }
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Doesn't verify null as parameters.",
+ method = "createDocumentType",
+ args = {java.lang.String.class, java.lang.String.class, java.lang.String.class}
+ )
+ public void testCreateDocumentType2() throws Throwable {
+ String publicId = "http://www.localhost.com/";
+ String systemId = "myDoc.dtd";
+ String qualifiedName;
+ Document doc;
+
+ DOMImplementation domImpl;
+ List<String> illegalQNames = new ArrayList<String>();
+ illegalQNames.add("edi:{");
+ illegalQNames.add("edi:}");
+ illegalQNames.add("edi:~");
+ illegalQNames.add("edi:'");
+ illegalQNames.add("edi:!");
+ illegalQNames.add("edi:@");
+ illegalQNames.add("edi:#");
+ illegalQNames.add("edi:$");
+ illegalQNames.add("edi:%");
+ illegalQNames.add("edi:^");
+ illegalQNames.add("edi:&");
+ illegalQNames.add("edi:*");
+ illegalQNames.add("edi:(");
+ illegalQNames.add("edi:)");
+ illegalQNames.add("edi:+");
+ illegalQNames.add("edi:=");
+ illegalQNames.add("edi:[");
+ illegalQNames.add("edi:]");
+ illegalQNames.add("edi:\\");
+ illegalQNames.add("edi:/");
+ illegalQNames.add("edi:;");
+ illegalQNames.add("edi:`");
+ illegalQNames.add("edi:<");
+ illegalQNames.add("edi:>");
+ illegalQNames.add("edi:,");
+ illegalQNames.add("edi:a ");
+ illegalQNames.add("edi:\"");
+
+ doc = (Document) load("staffNS", builder);
+ for (int indexN1009A = 0; indexN1009A < illegalQNames.size(); indexN1009A++) {
+ qualifiedName = (String) illegalQNames.get(indexN1009A);
+ domImpl = doc.getImplementation();
+
+ {
+ boolean success = false;
+ try {
+ domImpl.createDocumentType(qualifiedName, publicId,
+ systemId);
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.INVALID_CHARACTER_ERR);
+ }
+ assertTrue("throw_INVALID_CHARACTER_ERR", success);
+ }
+ }
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Doesn't verify null as parameters.",
+ method = "createDocumentType",
+ args = {java.lang.String.class, java.lang.String.class, java.lang.String.class}
+ )
+ public void testCreateDocumentType3() throws Throwable {
+
+ String qualifiedName = "prefix:myDoc";
+ String publicId = "http://www.localhost.com";
+ String systemId = "myDoc.dtd";
+ Document doc;
+ DOMImplementation domImpl;
+ DocumentType newType = null;
+
+ String nodeName;
+ String nodeValue;
+ doc = (Document) load("staffNS", builder);
+ domImpl = doc.getImplementation();
+ newType = domImpl.createDocumentType(qualifiedName, publicId, systemId);
+ nodeName = newType.getNodeName();
+ assertEquals("nodeName", "prefix:myDoc", nodeName);
+ nodeValue = newType.getNodeValue();
+ assertNull("nodeValue", nodeValue);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Doesn't verify null as parameters.",
+ method = "createDocumentType",
+ args = {java.lang.String.class, java.lang.String.class, java.lang.String.class}
+ )
+ public void testCreateDocumentType4() throws Throwable {
+ String publicId = "http://www.example.com/";
+ String systemId = "myDoc.dtd";
+
+ DOMImplementation domImpl;
+ domImpl = builder.getDOMImplementation();
+
+ {
+ boolean success = false;
+ try {
+ domImpl.createDocumentType("", publicId, systemId);
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.NAMESPACE_ERR);
+ }
+ assertTrue("throw_NAMESPACE_ERR", success);
+ }
+ }
+}
diff --git a/xml/src/test/java/tests/org/w3c/dom/CreateElementNS.java b/xml/src/test/java/tests/org/w3c/dom/CreateElementNS.java
new file mode 100644
index 0000000..8d8bb4d
--- /dev/null
+++ b/xml/src/test/java/tests/org/w3c/dom/CreateElementNS.java
@@ -0,0 +1,251 @@
+/*
+ This Java source file was generated by test-to-java.xsl
+ and is a derived work from the source document.
+ The source document contained the following notice:
+
+
+
+ Copyright (c) 2001 World Wide Web Consortium,
+ (Massachusetts Institute of Technology, Institut National de
+ Recherche en Informatique et en Automatique, Keio University). All
+ Rights Reserved. This program is distributed under the W3C's Software
+ Intellectual Property License. This program is distributed in the
+ hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+ See W3C License http://www.w3.org/Consortium/Legal/ for more details.
+
+
+ */
+
+package tests.org.w3c.dom;
+
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.DOMException;
+import org.w3c.dom.Element;
+
+import javax.xml.parsers.DocumentBuilder;
+
+/**
+ * The "createElementNS(namespaceURI,qualifiedName)" method for a Document
+ * should raise NAMESPACE_ERR DOMException if qualifiedName is malformed.
+ *
+ * Invoke method createElementNS(namespaceURI,qualifiedName) on the XMLNS
+ * Document with namespaceURI being the literal string
+ * "http://www.ecommerce.org/", and qualifiedName as "prefix::local". Method
+ * should raise NAMESPACE_ERR DOMException.
+ *
+ * @author NIST
+ * @author Mary Brady
+ * @see <a
+ * href="http://www.w3.org/TR/DOM-Level-2-Core/core#xpointer(id('ID-258A00AF')/constant[@name='NAMESPACE_ERR'])">http://www.w3.org/TR/DOM-Level-2-Core/core#xpointer(id('ID-258A00AF')/constant[@name='NAMESPACE_ERR'])</a>
+ * @see <a
+ * href="http://www.w3.org/TR/DOM-Level-2-Core/core#ID-DocCrElNS">http://www.w3.org/TR/DOM-Level-2-Core/core#ID-DocCrElNS</a>
+ * @see <a
+ * href="http://www.w3.org/TR/DOM-Level-2-Core/core#xpointer(id('ID-DocCrElNS')/raises/exception[@name='DOMException']/descr/p[substring-before(.,':')='NAMESPACE_ERR'])">http://www.w3.org/TR/DOM-Level-2-Core/core#xpointer(id('ID-DocCrElNS')/raises/exception[@name='DOMException']/descr/p[substring-before(.,':')='NAMESPACE_ERR'])</a>
+ */
+@TestTargetClass(Document.class)
+public final class CreateElementNS extends DOMTestCase {
+
+ DOMDocumentBuilderFactory factory;
+
+ DocumentBuilder builder;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ try {
+ factory = new DOMDocumentBuilderFactory(DOMDocumentBuilderFactory
+ .getConfiguration1());
+ builder = factory.getBuilder();
+ } catch (Exception e) {
+ fail("Unexpected exception" + e.getMessage());
+ }
+ }
+
+ protected void tearDown() throws Exception {
+ factory = null;
+ builder = null;
+ super.tearDown();
+ }
+
+ /**
+ * Runs the test case.
+ *
+ * @throws Throwable
+ * Any uncaught exception causes test to fail
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Doesn't verify null as a parameters, and other types of DOMException.",
+ method = "createElementNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testCreateElementNS1() throws Throwable {
+ String namespaceURI = "http://www.ecommerce.org/";
+ String malformedName = "prefix::local";
+ Document doc;
+
+ doc = (Document) load("staffNS", builder);
+
+ {
+ boolean success = false;
+ try {
+ doc.createElementNS(namespaceURI, malformedName);
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.NAMESPACE_ERR);
+ }
+ assertTrue("throw_NAMESPACE_ERR", success);
+ }
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Doesn't verify null as a parameters, and other types of DOMException.",
+ method = "createElementNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testCreateElementNS2() throws Throwable {
+ String namespaceURI = null;
+
+ String qualifiedName = "prefix:local";
+ Document doc;
+
+ doc = (Document) load("staffNS", builder);
+
+ {
+ boolean success = false;
+ try {
+ doc.createElementNS(namespaceURI, qualifiedName);
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.NAMESPACE_ERR);
+ }
+ assertTrue("throw_NAMESPACE_ERR", success);
+ }
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Doesn't verify null as a parameters, and other types of DOMException.",
+ method = "createElementNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testCreateElementNS3() throws Throwable {
+ String namespaceURI = "http://www.wedding.com/";
+ String qualifiedName;
+ Document doc;
+
+ List<String> illegalQNames = new ArrayList<String>();
+ illegalQNames.add("person:{");
+ illegalQNames.add("person:}");
+ illegalQNames.add("person:~");
+ illegalQNames.add("person:'");
+ illegalQNames.add("person:!");
+ illegalQNames.add("person:@");
+ illegalQNames.add("person:#");
+ illegalQNames.add("person:$");
+ illegalQNames.add("person:%");
+ illegalQNames.add("person:^");
+ illegalQNames.add("person:&");
+ illegalQNames.add("person:*");
+ illegalQNames.add("person:(");
+ illegalQNames.add("person:)");
+ illegalQNames.add("person:+");
+ illegalQNames.add("person:=");
+ illegalQNames.add("person:[");
+ illegalQNames.add("person:]");
+ illegalQNames.add("person:\\");
+ illegalQNames.add("person:/");
+ illegalQNames.add("person:;");
+ illegalQNames.add("person:`");
+ illegalQNames.add("person:<");
+ illegalQNames.add("person:>");
+ illegalQNames.add("person:,");
+ illegalQNames.add("person:a ");
+ illegalQNames.add("person:\"");
+
+ doc = (Document) load("staffNS", builder);
+ for (int indexN10098 = 0; indexN10098 < illegalQNames.size(); indexN10098++) {
+ qualifiedName = (String) illegalQNames.get(indexN10098);
+
+ {
+ boolean success = false;
+ try {
+ doc.createElementNS(namespaceURI, qualifiedName);
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.INVALID_CHARACTER_ERR);
+ }
+ assertTrue("throw_INVALID_CHARACTER_ERR", success);
+ }
+ }
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Doesn't verify null as a parameters, and other types of DOMException.",
+ method = "createElementNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testCreateElementNS4() throws Throwable {
+ String namespaceURI = "http://www.w3.org/XML/1998/namespaces";
+ String qualifiedName = "xml:element1";
+ Document doc;
+
+ doc = (Document) load("staffNS", builder);
+
+ {
+ boolean success = false;
+ try {
+ doc.createElementNS(namespaceURI, qualifiedName);
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.NAMESPACE_ERR);
+ }
+ assertTrue("throw_NAMESPACE_ERR", success);
+ }
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Doesn't verify null as a parameters, and other types of DOMException.",
+ method = "createElementNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testCreateElementNS5() throws Throwable {
+ String namespaceURI = "http://www.nist.gov";
+ String qualifiedName = "gov:faculty";
+ Document doc;
+ Element newElement;
+ String elementName;
+ doc = (Document) load("staffNS", builder);
+ newElement = doc.createElementNS(namespaceURI, qualifiedName);
+ elementName = newElement.getTagName();
+ assertEquals("throw_Equals", qualifiedName, elementName);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Doesn't verify null as a parameters, and other types of DOMException.",
+ method = "createElementNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testCreateElementNS6() throws Throwable {
+ String namespaceURI = "http://www.example.com/";
+
+ Document doc;
+
+ doc = (Document) load("hc_staff", builder);
+
+ {
+ boolean success = false;
+ try {
+ doc.createElementNS(namespaceURI, "");
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.NAMESPACE_ERR);
+ }
+ assertTrue("throw_NAMESPACE_ERR", success);
+ }
+ }
+}
diff --git a/xml/src/test/java/tests/org/w3c/dom/DOMDocumentBuilderFactory.java b/xml/src/test/java/tests/org/w3c/dom/DOMDocumentBuilderFactory.java
new file mode 100644
index 0000000..d28b2d7
--- /dev/null
+++ b/xml/src/test/java/tests/org/w3c/dom/DOMDocumentBuilderFactory.java
@@ -0,0 +1,94 @@
+package tests.org.w3c.dom;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+public class DOMDocumentBuilderFactory {
+ /**
+ * Parser configuration
+ */
+ private DocumentBuilderSetting[] settings = null;
+
+ private DocumentBuilder builder = null;
+
+ private DocumentBuilderFactory factory = null;
+
+ public DOMDocumentBuilderFactory(DocumentBuilderSetting[] settings) {
+ if (settings == null) {
+ settings = new DocumentBuilderSetting[0];
+ } else {
+ settings = (DocumentBuilderSetting[]) settings.clone();
+ }
+
+ factory = DocumentBuilderFactory.newInstance();
+
+ if (factory == null) {
+ throw new RuntimeException("DocumentBuilderFactory must not be null");
+ }
+
+ if (settings != null) {
+ for (int i = 0; i < settings.length; i++) {
+ settings[i].applySetting(factory);
+ }
+ }
+ try {
+ builder = factory.newDocumentBuilder();
+ } catch (ParserConfigurationException e) {
+ e.printStackTrace();
+ }
+
+ if (builder == null) {
+ throw new RuntimeException("DocumentBuilder must not be null");
+ }
+
+ }
+
+ public DocumentBuilder getBuilder() {
+ return builder;
+ }
+
+ public boolean hasFeature(String feature, String version) {
+ return builder.getDOMImplementation().hasFeature(feature, version);
+ }
+
+ public boolean isCoalescing() {
+ return factory.isCoalescing();
+ }
+
+ public boolean isExpandEntityReferences() {
+ return factory.isExpandEntityReferences();
+ }
+
+ public boolean isIgnoringElementContentWhitespace() {
+ return factory.isIgnoringElementContentWhitespace();
+ }
+
+ public boolean isNamespaceAware() {
+ return factory.isNamespaceAware();
+ }
+
+ public boolean isValidating() {
+ return factory.isValidating();
+ }
+
+ public static DocumentBuilderSetting[] getConfiguration1() {
+ return new DocumentBuilderSetting[] {
+ DocumentBuilderSetting.notCoalescing,
+ DocumentBuilderSetting.notExpandEntityReferences,
+ DocumentBuilderSetting.notIgnoringElementContentWhitespace,
+ DocumentBuilderSetting.notNamespaceAware,
+ DocumentBuilderSetting.notValidating };
+ }
+
+ public static DocumentBuilderSetting[] getConfiguration2() {
+ return new DocumentBuilderSetting[] {
+ DocumentBuilderSetting.notCoalescing,
+ DocumentBuilderSetting.notExpandEntityReferences,
+ DocumentBuilderSetting.notIgnoringElementContentWhitespace,
+ DocumentBuilderSetting.namespaceAware,
+ DocumentBuilderSetting.notValidating };
+
+ }
+
+}
diff --git a/xml/src/test/java/tests/org/w3c/dom/DOMImplementationCreateDocument.java b/xml/src/test/java/tests/org/w3c/dom/DOMImplementationCreateDocument.java
new file mode 100644
index 0000000..d2650a4
--- /dev/null
+++ b/xml/src/test/java/tests/org/w3c/dom/DOMImplementationCreateDocument.java
@@ -0,0 +1,177 @@
+package tests.org.w3c.dom;
+
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.w3c.dom.DOMImplementation;
+import org.w3c.dom.Document;
+import org.w3c.dom.DocumentType;
+import org.w3c.dom.DOMException;
+
+import javax.xml.parsers.DocumentBuilder;
+
+/**
+ * The createDocument method with valid arguments, should create a DOM Document
+ * of the specified type.
+ *
+ * Call the createDocument on this DOMImplementation with createDocument
+ * ("http://www.w3.org/DOMTest/L2",see the array below for valid QNames,null).
+ * Check if the returned Document object is is empty with no Document Element.
+ *
+ * @author IBM
+ * @author Neil Delima
+ * @see <a
+ * href="http://www.w3.org/TR/DOM-Level-2-Core/core#Level-2-Core-DOM-createDocument">http://www.w3.org/TR/DOM-Level-2-Core/core#Level-2-Core-DOM-createDocument</a>
+ */
+@TestTargetClass(DOMImplementation.class)
+public final class DOMImplementationCreateDocument extends DOMTestCase {
+
+ DOMDocumentBuilderFactory factory;
+
+ DocumentBuilder builder;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ try {
+ factory = new DOMDocumentBuilderFactory(DOMDocumentBuilderFactory
+ .getConfiguration1());
+ builder = factory.getBuilder();
+ } catch (Exception e) {
+ fail("Unexpected exception" + e.getMessage());
+ }
+ }
+
+ protected void tearDown() throws Exception {
+ factory = null;
+ builder = null;
+ super.tearDown();
+ }
+
+ /**
+ * Runs the test case.
+ *
+ * @throws Throwable
+ * Any uncaught exception causes test to fail
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Doesn't verify DOMException.",
+ method = "createDocument",
+ args = {java.lang.String.class, java.lang.String.class, org.w3c.dom.DocumentType.class}
+ )
+ public void testCreateDocument3() throws Throwable {
+ Document doc;
+ DOMImplementation domImpl;
+ Document newDoc;
+ DocumentType docType = null;
+
+ String namespaceURI = "http://www.w3.org/DOMTest/L2";
+ String qualifiedName;
+ List<String> qualifiedNames = new ArrayList<String>();
+ qualifiedNames.add("_:_");
+ qualifiedNames.add("_:h0");
+ qualifiedNames.add("_:test");
+ qualifiedNames.add("l_:_");
+ qualifiedNames.add("ns:_0");
+ qualifiedNames.add("ns:a0");
+ qualifiedNames.add("ns0:test");
+ qualifiedNames.add("a.b:c");
+ qualifiedNames.add("a-b:c");
+ qualifiedNames.add("a-b:c");
+
+ doc = (Document) load("staffNS", builder);
+ domImpl = doc.getImplementation();
+ for (int indexN1006B = 0; indexN1006B < qualifiedNames.size(); indexN1006B++) {
+ qualifiedName = (String) qualifiedNames.get(indexN1006B);
+ newDoc = domImpl.createDocument(namespaceURI, qualifiedName,
+ docType);
+ assertNotNull("domimplementationcreatedocument03", newDoc);
+ }
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Verifies DOMException with NAMESPACE_ERR code.",
+ method = "createDocument",
+ args = {java.lang.String.class, java.lang.String.class, org.w3c.dom.DocumentType.class}
+ )
+ public void testCreateDocument4() throws Throwable {
+ Document doc;
+ DOMImplementation domImpl;
+
+ String namespaceURI = null;
+
+ String qualifiedName = "dom:root";
+ DocumentType docType = null;
+
+ doc = (Document) load("staffNS", builder);
+ domImpl = doc.getImplementation();
+
+ {
+ boolean success = false;
+ try {
+ domImpl.createDocument(namespaceURI, qualifiedName, docType);
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.NAMESPACE_ERR);
+ }
+ assertTrue("domimplementationcreatedocument04", success);
+ }
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Verifies DOMException with NAMESPACE_ERR code.",
+ method = "createDocument",
+ args = {java.lang.String.class, java.lang.String.class, org.w3c.dom.DocumentType.class}
+ )
+ public void testCreateDocument5() throws Throwable {
+ Document doc;
+ DOMImplementation domImpl;
+
+ String namespaceURI = "http://www.w3.org/xml/1998/namespace";
+ String qualifiedName = "xml:root";
+ DocumentType docType = null;
+
+ doc = (Document) load("staffNS", builder);
+ domImpl = doc.getImplementation();
+
+ {
+ boolean success = false;
+ try {
+ domImpl.createDocument(namespaceURI, qualifiedName, docType);
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.NAMESPACE_ERR);
+ }
+ assertTrue("domimplementationcreatedocument05", success);
+ }
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Verifies DOMException with NAMESPACE_ERR code.",
+ method = "createDocument",
+ args = {java.lang.String.class, java.lang.String.class, org.w3c.dom.DocumentType.class}
+ )
+ public void testCreateDocument7() throws Throwable {
+ Document doc;
+ DOMImplementation domImpl;
+
+ String namespaceURI = "http://www.w3.org/DOMTest/level2";
+ DocumentType docType = null;
+
+ doc = (Document) load("staffNS", builder);
+ domImpl = doc.getImplementation();
+
+ {
+ boolean success = false;
+ try {
+ domImpl.createDocument(namespaceURI, ":", docType);
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.NAMESPACE_ERR);
+ }
+ assertTrue("domimplementationcreatedocument07", success);
+ }
+ }
+}
diff --git a/xml/src/test/java/tests/org/w3c/dom/DOMImplementationCreateDocumentType.java b/xml/src/test/java/tests/org/w3c/dom/DOMImplementationCreateDocumentType.java
new file mode 100644
index 0000000..286e75d
--- /dev/null
+++ b/xml/src/test/java/tests/org/w3c/dom/DOMImplementationCreateDocumentType.java
@@ -0,0 +1,208 @@
+/*
+ This Java source file was generated by test-to-java.xsl
+ and is a derived work from the source document.
+ The source document contained the following notice:
+
+
+
+ Copyright (c) 2001 World Wide Web Consortium,
+ (Massachusetts Institute of Technology, Institut National de
+ Recherche en Informatique et en Automatique, Keio University). All
+ Rights Reserved. This program is distributed under the W3C's Software
+ Intellectual Property License. This program is distributed in the
+ hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+ See W3C License http://www.w3.org/Consortium/Legal/ for more details.
+
+
+ */
+
+package tests.org.w3c.dom;
+
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.w3c.dom.DOMImplementation;
+import org.w3c.dom.Document;
+import org.w3c.dom.DocumentType;
+
+import javax.xml.parsers.DocumentBuilder;
+
+/**
+ * The method createDocumentType with valid values for qualifiedName, publicId
+ * and systemId should create an empty DocumentType node.
+ *
+ * Invoke createDocument on this DOMImplementation with a valid qualifiedName
+ * and different publicIds and systemIds. Check if the the DocumentType node was
+ * created with its ownerDocument attribute set to null.
+ *
+ * @author IBM
+ * @author Neil Delima
+ * @see <a
+ * href="http://www.w3.org/TR/DOM-Level-2-Core/core#Level-2-Core-DOM-createDocument">http://www.w3.org/TR/DOM-Level-2-Core/core#Level-2-Core-DOM-createDocument</a>
+ */
+@TestTargetClass(DOMImplementation.class)
+public final class DOMImplementationCreateDocumentType extends DOMTestCase {
+
+ DOMDocumentBuilderFactory factory;
+
+ DocumentBuilder builder;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ try {
+ factory = new DOMDocumentBuilderFactory(DOMDocumentBuilderFactory
+ .getConfiguration1());
+ builder = factory.getBuilder();
+ } catch (Exception e) {
+ fail("Unexpected exception" + e.getMessage());
+ }
+ }
+
+ protected void tearDown() throws Exception {
+ factory = null;
+ builder = null;
+ super.tearDown();
+ }
+
+ /**
+ * Runs the test case.
+ *
+ * @throws Throwable
+ * Any uncaught exception causes test to fail
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Doesn't verify DOMException.",
+ method = "createDocumentType",
+ args = {java.lang.String.class, java.lang.String.class, java.lang.String.class}
+ )
+ public void testCreateDocumentType1() throws Throwable {
+ Document doc;
+ DOMImplementation domImpl;
+ DocumentType newDocType;
+ Document ownerDocument;
+ String qualifiedName = "test:root";
+ String publicId;
+ String systemId;
+ List<String> publicIds = new ArrayList<String>();
+ publicIds.add("1234");
+ publicIds.add("test");
+
+ List<String> systemIds = new ArrayList<String>();
+ systemIds.add("");
+ systemIds.add("test");
+
+ doc = (Document) load("staffNS", builder);
+ domImpl = doc.getImplementation();
+ for (int indexN1005D = 0; indexN1005D < publicIds.size(); indexN1005D++) {
+ publicId = (String) publicIds.get(indexN1005D);
+ for (int indexN10061 = 0; indexN10061 < systemIds.size(); indexN10061++) {
+ systemId = (String) systemIds.get(indexN10061);
+ newDocType = domImpl.createDocumentType(qualifiedName,
+ publicId, systemId);
+ assertNotNull(
+ "domimplementationcreatedocumenttype01_newDocType",
+ newDocType);
+ ownerDocument = newDocType.getOwnerDocument();
+ assertNull(
+ "domimplementationcreatedocumenttype01_ownerDocument",
+ ownerDocument);
+ }
+ }
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Doesn't verify DOMException.",
+ method = "createDocumentType",
+ args = {java.lang.String.class, java.lang.String.class, java.lang.String.class}
+ )
+ public void testCreateDocumentType2() throws Throwable {
+ Document doc;
+ DOMImplementation domImpl;
+ DocumentType newDocType;
+ Document ownerDocument;
+ String publicId = "http://www.w3.org/DOM/Test/dom2.dtd";
+ String systemId = "dom2.dtd";
+ String qualifiedName;
+ List<String> qualifiedNames = new ArrayList<String>();
+ qualifiedNames.add("_:_");
+ qualifiedNames.add("_:h0");
+ qualifiedNames.add("_:test");
+ qualifiedNames.add("_:_.");
+ qualifiedNames.add("_:a-");
+ qualifiedNames.add("l_:_");
+ qualifiedNames.add("ns:_0");
+ qualifiedNames.add("ns:a0");
+ qualifiedNames.add("ns0:test");
+ qualifiedNames.add("ns:EEE.");
+ qualifiedNames.add("ns:_-");
+ qualifiedNames.add("a.b:c");
+ qualifiedNames.add("a-b:c.j");
+ qualifiedNames.add("a-b:c");
+
+ doc = (Document) load("staffNS", builder);
+ domImpl = doc.getImplementation();
+ for (int indexN10077 = 0; indexN10077 < qualifiedNames.size(); indexN10077++) {
+ qualifiedName = (String) qualifiedNames.get(indexN10077);
+ newDocType = domImpl.createDocumentType(qualifiedName, publicId,
+ systemId);
+ assertNotNull("domimplementationcreatedocumenttype02_newDocType",
+ newDocType);
+ ownerDocument = newDocType.getOwnerDocument();
+ assertNull("domimplementationcreatedocumenttype02_ownerDocument",
+ ownerDocument);
+ }
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Doesn't verify DOMException.",
+ method = "createDocumentType",
+ args = {java.lang.String.class, java.lang.String.class, java.lang.String.class}
+ )
+ public void testCreateDocumentType4() throws Throwable {
+ Document doc;
+ DOMImplementation domImpl;
+ DocumentType newDocType;
+ Document ownerDocument;
+ String publicId = "http://www.w3.org/DOM/Test/dom2.dtd";
+ String systemId = "dom2.dtd";
+ String qualifiedName;
+ List<String> qualifiedNames = new ArrayList<String>();
+ qualifiedNames.add("_:_");
+ qualifiedNames.add("_:h0");
+ qualifiedNames.add("_:test");
+ qualifiedNames.add("_:_.");
+ qualifiedNames.add("_:a-");
+ qualifiedNames.add("l_:_");
+ qualifiedNames.add("ns:_0");
+ qualifiedNames.add("ns:a0");
+ qualifiedNames.add("ns0:test");
+ qualifiedNames.add("ns:EEE.");
+ qualifiedNames.add("ns:_-");
+ qualifiedNames.add("a.b:c");
+ qualifiedNames.add("a-b:c.j");
+ qualifiedNames.add("a-b:c");
+
+ doc = (Document) load("staffNS", builder);
+ domImpl = doc.getImplementation();
+ for (int indexN10077 = 0; indexN10077 < qualifiedNames.size(); indexN10077++) {
+ qualifiedName = (String) qualifiedNames.get(indexN10077);
+ newDocType = domImpl.createDocumentType(qualifiedName, publicId,
+ systemId);
+ assertNotNull("domimplementationcreatedocumenttype02_newDocType",
+ newDocType);
+ ownerDocument = newDocType.getOwnerDocument();
+ assertNull("domimplementationcreatedocumenttype02_ownerDocument",
+ ownerDocument);
+ }
+ }
+
+}
diff --git a/xml/src/test/java/tests/org/w3c/dom/DOMImplementationHasFeature.java b/xml/src/test/java/tests/org/w3c/dom/DOMImplementationHasFeature.java
new file mode 100644
index 0000000..257555b
--- /dev/null
+++ b/xml/src/test/java/tests/org/w3c/dom/DOMImplementationHasFeature.java
@@ -0,0 +1,147 @@
+package tests.org.w3c.dom;
+
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.w3c.dom.DOMImplementation;
+import org.w3c.dom.Document;
+
+import javax.xml.parsers.DocumentBuilder;
+
+/**
+ * The "feature" parameter in the "hasFeature(feature,version)" method is the
+ * package name of the feature. Legal values are XML and HTML and CORE. (Test
+ * for feature core, lower case)
+ *
+ * Retrieve the entire DOM document and invoke its "getImplementation()" method.
+ * This should create a DOMImplementation object whose "hasFeature(feature,
+ * version)" method is invoked with feature equal to "core". The method should
+ * return a boolean "true".
+ *
+ * @author NIST
+ * @author Mary Brady
+ * @see <a
+ * href="http://www.w3.org/TR/DOM-Level-2-Core/core#ID-5CED94D7">http://www.w3.org/TR/DOM-Level-2-Core/core#ID-5CED94D7</a>
+ */
+@TestTargetClass(DOMImplementation.class)
+public final class DOMImplementationHasFeature extends DOMTestCase {
+
+ DOMDocumentBuilderFactory factory;
+
+ DocumentBuilder builder;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ try {
+ factory = new DOMDocumentBuilderFactory(DOMDocumentBuilderFactory
+ .getConfiguration1());
+ builder = factory.getBuilder();
+ } catch (Exception e) {
+ fail("Unexpected exception" + e.getMessage());
+ }
+ }
+
+ protected void tearDown() throws Exception {
+ factory = null;
+ builder = null;
+ super.tearDown();
+ }
+
+ /**
+ * Runs the test case.
+ *
+ * @throws Throwable
+ * Any uncaught exception causes test to fail
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Verifies that hasFeature returns true value.",
+ method = "hasFeature",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testHasFeatureCore() throws Throwable {
+ Document doc;
+ DOMImplementation domImpl;
+ boolean state;
+ doc = (Document) load("staff", builder);
+ domImpl = doc.getImplementation();
+ state = domImpl.hasFeature("core", "2.0");
+ assertTrue("domimplementationFeaturecoreAssert", state);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Verifies that hasFeature returns true value.",
+ method = "hasFeature",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testHasFeatureXml() throws Throwable {
+ Document doc;
+ DOMImplementation domImpl;
+ boolean state;
+ doc = (Document) load("staff", builder);
+ domImpl = doc.getImplementation();
+ state = domImpl.hasFeature("xml", "2.0");
+ assertTrue("domimplementationFeaturexmlVersion2Assert", state);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Doesn't verify that hasFeature method returns false.",
+ method = "hasFeature",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testHasFeature1() throws Throwable {
+ Document doc;
+ DOMImplementation domImpl;
+ String version = "";
+ String version1 = "1.0";
+ String version2 = "2.0";
+ String featureCore;
+ String featureXML;
+ boolean success;
+ List<String> featuresXML = new ArrayList<String>();
+ featuresXML.add("XML");
+ featuresXML.add("xmL");
+
+ List<String> featuresCore = new ArrayList<String>();
+ featuresCore.add("Core");
+ featuresCore.add("CORE");
+
+ doc = (Document) load("staffNS", builder);
+ domImpl = doc.getImplementation();
+ for (int indexN10063 = 0; indexN10063 < featuresXML.size(); indexN10063++) {
+ featureXML = (String) featuresXML.get(indexN10063);
+ success = domImpl.hasFeature(featureXML, version);
+ assertTrue("domimplementationhasfeature01_XML_1", success);
+ success = domImpl.hasFeature(featureXML, version1);
+ assertTrue("domimplementationhasfeature01_XML_2", success);
+ }
+ for (int indexN1007C = 0; indexN1007C < featuresCore.size(); indexN1007C++) {
+ featureCore = (String) featuresCore.get(indexN1007C);
+ success = domImpl.hasFeature(featureCore, version);
+ assertTrue("domimplementationhasfeature01_Core_1", success);
+ success = domImpl.hasFeature(featureCore, version1);
+ success = domImpl.hasFeature(featureCore, version2);
+ assertTrue("domimplementationhasfeature01_Core_3", success);
+ }
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Verifies that hasFeature method returns false.",
+ method = "hasFeature",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testHasFeature2() throws Throwable {
+ Document doc;
+ DOMImplementation domImpl;
+ boolean success;
+ doc = (Document) load("staffNS", builder);
+ domImpl = doc.getImplementation();
+ success = domImpl.hasFeature("Blah Blah", "");
+ assertFalse("domimplementationhasfeature02", success);
+ }
+}
diff --git a/xml/src/test/java/tests/org/w3c/dom/DOMTestCase.java b/xml/src/test/java/tests/org/w3c/dom/DOMTestCase.java
new file mode 100644
index 0000000..041b67b
--- /dev/null
+++ b/xml/src/test/java/tests/org/w3c/dom/DOMTestCase.java
@@ -0,0 +1,230 @@
+package tests.org.w3c.dom;
+
+import dalvik.annotation.TestTargetClass;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import javax.xml.parsers.DocumentBuilder;
+
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+
+import junit.framework.TestCase;
+
+@TestTargetClass(Document.class)
+public class DOMTestCase extends TestCase {
+
+ public Document load(String docURI, DocumentBuilder builder) {
+ Document doc = load(resolveURI(docURI), builder);
+ return doc;
+ }
+
+ public Document load(URL url, DocumentBuilder builder) {
+ Document doc = null;
+ Exception parseException = null;
+ try {
+ LoadErrorHandler errorHandler = new LoadErrorHandler();
+ builder.setErrorHandler(errorHandler);
+ doc = builder.parse(url.openStream());
+ parseException = errorHandler.getFirstException();
+ } catch (Exception ex) {
+ parseException = ex;
+ }
+ builder.setErrorHandler(null);
+ if (parseException != null) {
+ // fail("Unexpected exception " + parseException.getMessage());
+ throw new RuntimeException("Unexpected exception " + parseException.getMessage(), parseException);
+ }
+ return doc;
+ }
+
+ public void preload(String contentType, String docURI,
+ boolean willBeModified) {
+ if ("text/html".equals(contentType)
+ || "application/xhtml+xml".equals(contentType)) {
+ if (docURI.startsWith("staff")
+ || docURI.equals("datatype_normalization")) {
+
+ }
+ }
+ }
+
+ private URL resolveURI(String baseURI) {
+ String docURI = baseURI + ".xml";
+
+ URL resolvedURI = null;
+ try {
+ resolvedURI = new URL(docURI);
+ if (resolvedURI.getProtocol() != null) {
+ return resolvedURI;
+ }
+ } catch (MalformedURLException ex) {
+ // fail("Unexpected exception " + ex.getMessage());
+ }
+ //
+ // build a URL for a test file in the JAR
+ //
+ resolvedURI = getClass().getResource("/" + docURI);
+ if (resolvedURI == null) {
+ //
+ // see if it is an absolute URI
+ //
+ int firstSlash = docURI.indexOf('/');
+ try {
+ if (firstSlash == 0
+ || (firstSlash >= 1 && docURI.charAt(firstSlash - 1) == ':')) {
+ resolvedURI = new URL(docURI);
+ } else {
+ //
+ // try the files/level?/spec directory
+ //
+ String filename = getClass().getPackage().getName();
+ filename = "tests/"
+ + filename.substring(14).replace('.', '/')
+ + "/files/" + docURI;
+ resolvedURI = new java.io.File(filename).toURL();
+ }
+ } catch (MalformedURLException ex) {
+ fail("Unexpected exception " + ex.getMessage());
+ }
+ }
+
+ if (resolvedURI == null) {
+ fail("resolvedURI is null ");
+ }
+ return resolvedURI;
+ }
+
+
+ public String getContentType() {
+ return "xml";
+ }
+
+ public void assertURIEquals(String assertID, String scheme, String path,
+ String host, String file, String name, String query,
+ String fragment, Boolean isAbsolute, String actual) {
+ //
+ // URI must be non-null
+ assertNotNull(assertID, actual);
+
+ String uri = actual;
+
+ int lastPound = actual.lastIndexOf("#");
+ String actualFragment = "";
+ if (lastPound != -1) {
+ //
+ // substring before pound
+ //
+ uri = actual.substring(0, lastPound);
+ actualFragment = actual.substring(lastPound + 1);
+ }
+ if (fragment != null) {
+ assertEquals(assertID, fragment, actualFragment);
+
+ }
+ int lastQuestion = uri.lastIndexOf("?");
+ String actualQuery = "";
+ if (lastQuestion != -1) {
+ //
+ // substring before pound
+ //
+ uri = actual.substring(0, lastQuestion);
+ actualQuery = actual.substring(lastQuestion + 1);
+ }
+ if (query != null) {
+ assertEquals(assertID, query, actualQuery);
+
+ }
+ int firstColon = uri.indexOf(":");
+ int firstSlash = uri.indexOf("/");
+ String actualPath = uri;
+ String actualScheme = "";
+ if (firstColon != -1 && firstColon < firstSlash) {
+ actualScheme = uri.substring(0, firstColon);
+ actualPath = uri.substring(firstColon + 1);
+ }
+
+ if (scheme != null) {
+ assertEquals(assertID, scheme, actualScheme);
+ }
+
+ if (path != null) {
+ assertEquals(assertID, path, actualPath);
+ }
+
+ if (host != null) {
+ String actualHost = "";
+ if (actualPath.startsWith("//")) {
+ int termSlash = actualPath.indexOf("/", 2);
+ actualHost = actualPath.substring(0, termSlash);
+ }
+ assertEquals(assertID, host, actualHost);
+ }
+
+ String actualFile = actualPath;
+ if (file != null || name != null) {
+ int finalSlash = actualPath.lastIndexOf("/");
+ if (finalSlash != -1) {
+ actualFile = actualPath.substring(finalSlash + 1);
+ }
+ if (file != null) {
+ assertEquals(assertID, file, actualFile);
+ }
+ }
+
+ if (name != null) {
+ String actualName = actualFile;
+ int finalPeriod = actualFile.lastIndexOf(".");
+ if (finalPeriod != -1) {
+ actualName = actualFile.substring(0, finalPeriod);
+ }
+ assertEquals(assertID, name, actualName);
+ }
+
+ if (isAbsolute != null) {
+ //
+ // Jar URL's will have any actual path like file:/c:/somedrive...
+ assertEquals(assertID, isAbsolute.booleanValue(), actualPath
+ .startsWith("/")
+ || actualPath.startsWith("file:/"));
+ }
+ }
+
+
+ private class LoadErrorHandler implements org.xml.sax.ErrorHandler {
+ private SAXException parseException;
+
+ private int errorCount;
+
+ private int warningCount;
+
+ public LoadErrorHandler() {
+ parseException = null;
+ errorCount = 0;
+ warningCount = 0;
+ }
+
+ public void error(SAXParseException ex) {
+ errorCount++;
+ if (parseException == null) {
+ parseException = ex;
+ }
+ }
+
+ public void warning(SAXParseException ex) {
+ warningCount++;
+ }
+
+ public void fatalError(SAXParseException ex) {
+ if (parseException == null) {
+ parseException = ex;
+ }
+ }
+
+ public SAXException getFirstException() {
+ return parseException;
+ }
+ }
+}
diff --git a/xml/src/test/java/tests/org/w3c/dom/DocumentBuilderSetting.java b/xml/src/test/java/tests/org/w3c/dom/DocumentBuilderSetting.java
new file mode 100644
index 0000000..bbb7190
--- /dev/null
+++ b/xml/src/test/java/tests/org/w3c/dom/DocumentBuilderSetting.java
@@ -0,0 +1,281 @@
+/*
+ * Copyright (c) 2001-2004 World Wide Web Consortium, (Massachusetts Institute
+ * of Technology, Institut National de Recherche en Informatique et en
+ * Automatique, Keio University). All Rights Reserved. This program is
+ * distributed under the W3C's Software Intellectual Property License. This
+ * program is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See W3C License
+ * http://www.w3.org/Consortium/Legal/ for more details.
+ */
+
+package tests.org.w3c.dom;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+
+/**
+ * This class is an parser setting, such as non-validating or entity-expanding.
+ *
+ * @author Curt Arnold @date 2 Feb 2002
+ */
+public final class DocumentBuilderSetting {
+ /**
+ * property name.
+ */
+ private final String property;
+
+ /**
+ * property value.
+ */
+ private final boolean value;
+
+ /**
+ * strategy used to set or get property value.
+ */
+ private final DocumentBuilderSettingStrategy strategy;
+
+ /**
+ * coalescing = true.
+ */
+ public static final DocumentBuilderSetting coalescing =
+ new DocumentBuilderSetting(
+ "coalescing",
+ true,
+ DocumentBuilderSettingStrategy.coalescing);
+
+ /**
+ * coalescing = false.
+ */
+ public static final DocumentBuilderSetting notCoalescing =
+ new DocumentBuilderSetting(
+ "coalescing",
+ false,
+ DocumentBuilderSettingStrategy.coalescing);
+
+ /**
+ * expandEntityReferences = false.
+ */
+ public static final DocumentBuilderSetting expandEntityReferences =
+ new DocumentBuilderSetting(
+ "expandEntityReferences",
+ true,
+ DocumentBuilderSettingStrategy.expandEntityReferences);
+
+ /**
+ * expandEntityReferences = true.
+ */
+ public static final DocumentBuilderSetting notExpandEntityReferences =
+ new DocumentBuilderSetting(
+ "expandEntityReferences",
+ false,
+ DocumentBuilderSettingStrategy.expandEntityReferences);
+
+ /**
+ * ignoringElementContentWhitespace = true.
+ */
+ public static final DocumentBuilderSetting ignoringElementContentWhitespace =
+ new DocumentBuilderSetting(
+ "ignoringElementContentWhitespace",
+ true,
+ DocumentBuilderSettingStrategy.ignoringElementContentWhitespace);
+
+ /**
+ * ignoringElementContentWhitespace = false.
+ */
+ public static final DocumentBuilderSetting
+ notIgnoringElementContentWhitespace =
+ new DocumentBuilderSetting(
+ "ignoringElementContentWhitespace",
+ false,
+ DocumentBuilderSettingStrategy.ignoringElementContentWhitespace);
+
+ /**
+ * namespaceAware = true.
+ */
+ public static final DocumentBuilderSetting namespaceAware =
+ new DocumentBuilderSetting(
+ "namespaceAware",
+ true,
+ DocumentBuilderSettingStrategy.namespaceAware);
+
+ /**
+ * namespaceAware = false.
+ */
+ public static final DocumentBuilderSetting notNamespaceAware =
+ new DocumentBuilderSetting(
+ "namespaceAware",
+ false,
+ DocumentBuilderSettingStrategy.namespaceAware);
+
+ /**
+ * validating = true.
+ */
+ public static final DocumentBuilderSetting validating =
+ new DocumentBuilderSetting(
+ "validating",
+ true,
+ DocumentBuilderSettingStrategy.validating);
+
+ /**
+ * validating = false.
+ */
+ public static final DocumentBuilderSetting notValidating =
+ new DocumentBuilderSetting(
+ "validating",
+ false,
+ DocumentBuilderSettingStrategy.validating);
+
+ /**
+ * signed = true.
+ */
+ public static final DocumentBuilderSetting signed =
+ new DocumentBuilderSetting(
+ "signed",
+ true,
+ DocumentBuilderSettingStrategy.signed);
+
+ /**
+ * signed = false.
+ */
+ public static final DocumentBuilderSetting notSigned =
+ new DocumentBuilderSetting(
+ "signed",
+ false,
+ DocumentBuilderSettingStrategy.signed);
+
+ /**
+ * hasNullString = true.
+ */
+ public static final DocumentBuilderSetting hasNullString =
+ new DocumentBuilderSetting(
+ "hasNullString",
+ true,
+ DocumentBuilderSettingStrategy.hasNullString);
+
+ /**
+ * hasNullString = false.
+ */
+ public static final DocumentBuilderSetting notHasNullString =
+ new DocumentBuilderSetting(
+ "hasNullString",
+ false,
+ DocumentBuilderSettingStrategy.hasNullString);
+
+ /**
+ * Schema validating enabled.
+ */
+ public static final DocumentBuilderSetting schemaValidating =
+ new DocumentBuilderSetting(
+ "schemaValidating",
+ true,
+ DocumentBuilderSettingStrategy.schemaValidating);
+
+ /**
+ * Schema validating disabled.
+ */
+ public static final DocumentBuilderSetting notSchemaValidating =
+ new DocumentBuilderSetting(
+ "schemaValidating",
+ false,
+ DocumentBuilderSettingStrategy.schemaValidating);
+
+ /**
+ * Comments ignored.
+ */
+ public static final DocumentBuilderSetting ignoringComments =
+ new DocumentBuilderSetting(
+ "ignoringComments",
+ true,
+ DocumentBuilderSettingStrategy.ignoringComments);
+
+ /**
+ * Comments preserved.
+ */
+ public static final DocumentBuilderSetting notIgnoringComments =
+ new DocumentBuilderSetting(
+ "ignoringComments",
+ false,
+ DocumentBuilderSettingStrategy.ignoringComments);
+
+ /**
+ * Protected constructor, use static members for supported settings.
+ * @param property property name, follows JAXP.
+ * @param value property value
+ * @param strategy strategy, may not be null
+ */
+ protected DocumentBuilderSetting(
+ String property,
+ boolean value,
+ DocumentBuilderSettingStrategy strategy) {
+ if (property == null) {
+ throw new NullPointerException("property");
+ }
+ this.property = property;
+ this.value = value;
+ this.strategy = strategy;
+ }
+
+ /**
+ * Returns true if the settings have a conflict or are identical.
+ *
+ * @param other
+ * other setting, may not be null.
+ * @return true if this setting and the specified setting conflict
+ */
+ public final boolean hasConflict(DocumentBuilderSetting other) {
+ if (other == null) {
+ throw new NullPointerException("other");
+ }
+ if (other == this) {
+ return true;
+ }
+ return strategy.hasConflict(other.strategy);
+ }
+
+ /**
+ * Determines current value of setting.
+ * @param factory DOMTestDocumentBuilderFactory factory
+ * @return boolean true if property enabled.
+ */
+ public final boolean hasSetting(DOMDocumentBuilderFactory factory) {
+ return strategy.hasSetting(factory) == value;
+ }
+
+ /**
+ * Attempts to change builder to have this setting.
+ * @param factory DocumentBuilderFactory Factory for DOM builders
+ * @throws DOMTestIncompatibleException
+ * if factory does not support the setting
+ */
+ public final void applySetting(DocumentBuilderFactory factory) {
+ strategy.applySetting(factory, value);
+ }
+
+ /**
+ * Gets the property name.
+ * @return property name
+ */
+ public final String getProperty() {
+ return property;
+ }
+
+ /**
+ * Gets the property value.
+ * @return property value
+ */
+ public final boolean getValue() {
+ return value;
+ }
+
+ /**
+ * Gets a string representation of the setting.
+ * @return string representation
+ */
+ public final String toString() {
+ StringBuffer builder = new StringBuffer(property);
+ builder.append('=');
+ builder.append(String.valueOf(value));
+ return builder.toString();
+ }
+
+}
diff --git a/xml/src/test/java/tests/org/w3c/dom/DocumentBuilderSettingStrategy.java b/xml/src/test/java/tests/org/w3c/dom/DocumentBuilderSettingStrategy.java
new file mode 100644
index 0000000..77bbce8
--- /dev/null
+++ b/xml/src/test/java/tests/org/w3c/dom/DocumentBuilderSettingStrategy.java
@@ -0,0 +1,158 @@
+package tests.org.w3c.dom;
+
+import java.lang.reflect.Method;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+
+public abstract class DocumentBuilderSettingStrategy {
+ protected DocumentBuilderSettingStrategy() {
+ }
+
+ private static final String JAXP_SCHEMA_LANGUAGE = "http://java.sun.com/xml/jaxp/properties/schemaLanguage";
+
+ private static final String W3C_XML_SCHEMA = "http://www.w3.org/2001/XMLSchema";
+
+ public boolean hasConflict(DocumentBuilderSettingStrategy other) {
+ return (other == this);
+ }
+
+ public abstract void applySetting(DocumentBuilderFactory factory,
+ boolean value);
+
+ public abstract boolean hasSetting(DOMDocumentBuilderFactory factory);
+
+ public static final DocumentBuilderSettingStrategy coalescing = new DocumentBuilderSettingStrategy() {
+ public void applySetting(DocumentBuilderFactory factory,
+ boolean value) {
+ factory.setCoalescing(value);
+ }
+
+ public boolean hasSetting(DOMDocumentBuilderFactory factory) {
+ return factory.isCoalescing();
+ }
+
+ };
+
+ public static final DocumentBuilderSettingStrategy expandEntityReferences = new DocumentBuilderSettingStrategy() {
+ public void applySetting(DocumentBuilderFactory factory, boolean value) {
+ factory.setExpandEntityReferences(value);
+ }
+
+ public boolean hasSetting(DOMDocumentBuilderFactory factory) {
+ return factory.isExpandEntityReferences();
+ }
+ };
+
+ public static final DocumentBuilderSettingStrategy ignoringElementContentWhitespace = new DocumentBuilderSettingStrategy() {
+ public void applySetting(DocumentBuilderFactory factory, boolean value) {
+ factory.setIgnoringElementContentWhitespace(value);
+ }
+
+ public boolean hasSetting(DOMDocumentBuilderFactory factory) {
+ return factory.isIgnoringElementContentWhitespace();
+ }
+ };
+
+ public static final DocumentBuilderSettingStrategy ignoringComments = new DocumentBuilderSettingStrategy() {
+ public void applySetting(DocumentBuilderFactory factory, boolean value) {
+ if (value) {
+ System.out.println("ignoreComments=true not supported");
+ }
+ }
+
+ public boolean hasSetting(DOMDocumentBuilderFactory factory) {
+ return false;
+ }
+ };
+
+ public static final DocumentBuilderSettingStrategy namespaceAware = new DocumentBuilderSettingStrategy() {
+ public void applySetting(DocumentBuilderFactory factory, boolean value)
+ {
+ factory.setNamespaceAware(value);
+ }
+
+ public boolean hasSetting(DOMDocumentBuilderFactory factory) {
+ return factory.isNamespaceAware();
+ }
+ };
+
+ public static final DocumentBuilderSettingStrategy validating = new DocumentBuilderSettingStrategy() {
+ public void applySetting(DocumentBuilderFactory factory, boolean value)
+ {
+ factory.setValidating(value);
+ }
+
+ public boolean hasSetting(DOMDocumentBuilderFactory factory) {
+ return factory.isValidating();
+ }
+ };
+
+ public static final DocumentBuilderSettingStrategy signed = new DocumentBuilderSettingStrategy() {
+ public void applySetting(DocumentBuilderFactory factory, boolean value)
+ {
+ if (!value) {
+ System.out.println("DocumentBuilderSetting.notSigned");
+ }
+ }
+
+ public boolean hasSetting(DOMDocumentBuilderFactory factory) {
+ return true;
+ }
+ };
+
+ public static final DocumentBuilderSettingStrategy hasNullString = new DocumentBuilderSettingStrategy() {
+ public void applySetting(DocumentBuilderFactory factory, boolean value)
+ {
+ if (!value) {
+ System.out.println("DocumentBuilderSetting.notHasNullString");
+ }
+ }
+
+ public boolean hasSetting(DOMDocumentBuilderFactory factory) {
+ return true;
+ }
+ };
+
+ public static final DocumentBuilderSettingStrategy schemaValidating = new DocumentBuilderSettingStrategy() {
+ public void applySetting(DocumentBuilderFactory factory, boolean value)
+ {
+ if (value) {
+ factory.setNamespaceAware(true);
+ factory.setValidating(true);
+ factory.setAttribute(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA);
+ } else {
+ factory.setAttribute(JAXP_SCHEMA_LANGUAGE,
+ "http://www.w3.org/TR/REC-xml");
+ }
+ }
+
+ public boolean hasSetting(DOMDocumentBuilderFactory factory) {
+ try {
+ if (factory.isValidating()) {
+ Method getAttrMethod = factory.getClass().getMethod(
+ "getAttribute", new Class[] { String.class });
+ String val = (String) getAttrMethod.invoke(factory,
+ new Object[] { JAXP_SCHEMA_LANGUAGE });
+ return W3C_XML_SCHEMA.equals(val);
+ }
+ } catch (Exception ex) {
+ }
+ return false;
+ }
+
+ //
+ // schema validating conflicts with namespaceAware
+ // and validating
+ //
+ public boolean hasConflict(DocumentBuilderSettingStrategy other) {
+ if (other == this
+ || other == DocumentBuilderSettingStrategy.namespaceAware
+ || other == DocumentBuilderSettingStrategy.validating) {
+ return true;
+ }
+ return false;
+ }
+
+ };
+
+}
diff --git a/xml/src/test/java/tests/org/w3c/dom/DocumentCreateAttributeNS.java b/xml/src/test/java/tests/org/w3c/dom/DocumentCreateAttributeNS.java
new file mode 100644
index 0000000..e46f3b3
--- /dev/null
+++ b/xml/src/test/java/tests/org/w3c/dom/DocumentCreateAttributeNS.java
@@ -0,0 +1,313 @@
+/*
+ This Java source file was generated by test-to-java.xsl
+ and is a derived work from the source document.
+ The source document contained the following notice:
+
+
+
+ Copyright (c) 2001 World Wide Web Consortium,
+ (Massachusetts Institute of Technology, Institut National de
+ Recherche en Informatique et en Automatique, Keio University). All
+ Rights Reserved. This program is distributed under the W3C's Software
+ Intellectual Property License. This program is distributed in the
+ hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+ See W3C License http://www.w3.org/Consortium/Legal/ for more details.
+
+
+ */
+
+package tests.org.w3c.dom;
+
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Attr;
+import org.w3c.dom.DOMException;
+import org.w3c.dom.DocumentType;
+import org.w3c.dom.DOMImplementation;
+
+import javax.xml.parsers.DocumentBuilder;
+
+/**
+ * The method createAttributeNS creates an attribute of the given qualified name
+ * and namespace URI
+ *
+ * Invoke the createAttributeNS method on this Document object with a null
+ * namespaceURI, and a qualifiedName without a prefix. This should return a
+ * valid Attr node object.
+ *
+ * @author IBM
+ * @author Neil Delima
+ * @see <a
+ * href="http://www.w3.org/TR/DOM-Level-2-Core/core">http://www.w3.org/TR/DOM-Level-2-Core/core</a>
+ * @see <a
+ * href="http://www.w3.org/TR/DOM-Level-2-Core/core#ID-DocCrAttrNS">http://www.w3.org/TR/DOM-Level-2-Core/core#ID-DocCrAttrNS</a>
+ */
+@TestTargetClass(Document.class)
+public final class DocumentCreateAttributeNS extends DOMTestCase {
+
+ DOMDocumentBuilderFactory factory;
+
+ DocumentBuilder builder;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ try {
+ factory = new DOMDocumentBuilderFactory(DOMDocumentBuilderFactory
+ .getConfiguration1());
+ builder = factory.getBuilder();
+ } catch (Exception e) {
+ fail("Unexpected exception" + e.getMessage());
+ }
+ }
+
+ protected void tearDown() throws Exception {
+ factory = null;
+ builder = null;
+ super.tearDown();
+ }
+
+ /**
+ * Runs the test case.
+ *
+ * @throws Throwable
+ * Any uncaught exception causes test to fail
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies positive functionality.",
+ method = "createAttributeNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testCreateAttributeNS1() throws Throwable {
+ Document doc;
+ Attr attribute;
+ String namespaceURI = null;
+
+ String qualifiedName = "test";
+
+ String nodeName;
+
+ doc = (Document) load("staffNS", builder);
+ attribute = doc.createAttributeNS(namespaceURI, qualifiedName);
+ nodeName = attribute.getNodeName();
+
+ assertEquals("documentcreateattributeNS01", "test", nodeName);
+ }
+
+ /**
+ * Runs the test case.
+ *
+ * @throws Throwable
+ * Any uncaught exception causes test to fail
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies positive functionality.",
+ method = "createAttributeNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testCreateAttributeNS2() throws Throwable {
+ Document doc;
+ Attr attribute1;
+ Attr attribute2;
+ String name;
+ String nodeName;
+ String nodeValue;
+ String prefix;
+ String namespaceURI;
+ doc = (Document) load("staffNS", builder);
+ attribute1 = doc.createAttributeNS(
+ "http://www.w3.org/XML/1998/namespace", "xml:xml");
+ name = attribute1.getName();
+ nodeName = attribute1.getNodeName();
+ nodeValue = attribute1.getNodeValue();
+ prefix = attribute1.getPrefix();
+ namespaceURI = attribute1.getNamespaceURI();
+ assertEquals("documentcreateattributeNS02_att1_name", "xml:xml", name);
+ assertEquals("documentcreateattributeNS02_att1_nodeName", "xml:xml",
+ nodeName);
+ assertEquals("documentcreateattributeNS02_att1_nodeValue", "",
+ nodeValue);
+ assertEquals("documentcreateattributeNS02_att1_prefix", "xml", prefix);
+ assertEquals("documentcreateattributeNS02_att1_namespaceURI",
+ "http://www.w3.org/XML/1998/namespace", namespaceURI);
+ attribute2 = doc.createAttributeNS("http://www.w3.org/2000/xmlns/",
+ "xmlns");
+ name = attribute2.getName();
+ nodeName = attribute2.getNodeName();
+ nodeValue = attribute2.getNodeValue();
+ prefix = attribute2.getPrefix();
+ namespaceURI = attribute2.getNamespaceURI();
+ assertEquals("documentcreateattributeNS02_att2_name", "xmlns", name);
+ assertEquals("documentcreateattributeNS02_att2_nodeName", "xmlns",
+ nodeName);
+ assertEquals("documentcreateattributeNS02_att2_nodeValue", "",
+ nodeValue);
+ assertEquals("documentcreateattributeNS02_att2_namespaceURI",
+ "http://www.w3.org/2000/xmlns/", namespaceURI);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies that createAttributeNS throws DOMException with INVALID_CHARACTER_ERR code.",
+ method = "createAttributeNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testCreateAttributeNS3() throws Throwable {
+ Document doc;
+
+ String namespaceURI = "http://www.w3.org/DOM/Test/Level2";
+ String qualifiedName;
+ List<String> qualifiedNames = new ArrayList<String>();
+ qualifiedNames.add("/");
+ qualifiedNames.add("//");
+ qualifiedNames.add("\\");
+ qualifiedNames.add(";");
+ qualifiedNames.add("&");
+ qualifiedNames.add("*");
+ qualifiedNames.add("]]");
+ qualifiedNames.add(">");
+ qualifiedNames.add("<");
+
+ doc = (Document) load("staffNS", builder);
+ for (int indexN1005A = 0; indexN1005A < qualifiedNames.size(); indexN1005A++) {
+ qualifiedName = (String) qualifiedNames.get(indexN1005A);
+
+ {
+ boolean success = false;
+ try {
+ doc.createAttributeNS(namespaceURI, qualifiedName);
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.INVALID_CHARACTER_ERR);
+ }
+ assertTrue("documentcreateattributeNS03", success);
+ }
+ }
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies that createAttributeNS throws DOMException with NAMESPACE_ERR code.",
+ method = "createAttributeNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testCreateAttributeNS4() throws Throwable {
+ Document doc;
+
+ String namespaceURI = "http://www.w3.org/DOM/Test/Level2";
+ String qualifiedName;
+ List<String> qualifiedNames = new ArrayList<String>();
+ qualifiedNames.add("_:");
+ qualifiedNames.add(":0a");
+ qualifiedNames.add(":");
+ qualifiedNames.add("a:b:c");
+ qualifiedNames.add("_::a");
+
+ doc = (Document) load("staffNS", builder);
+ for (int indexN1004E = 0; indexN1004E < qualifiedNames.size(); indexN1004E++) {
+ qualifiedName = (String) qualifiedNames.get(indexN1004E);
+
+ {
+ boolean success = false;
+ try {
+ doc.createAttributeNS(namespaceURI, qualifiedName);
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.NAMESPACE_ERR);
+ }
+ assertTrue("documentcreateattributeNS04", success);
+ }
+ }
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies that createAttributeNS throws DOMException with NAMESPACE_ERR code.",
+ method = "createAttributeNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testCreateAttributeNS5() throws Throwable {
+ Document doc;
+ Document newDoc;
+ DocumentType docType = null;
+
+ DOMImplementation domImpl;
+
+ String namespaceURI = null;
+
+ String qualifiedName = "abc:def";
+ doc = (Document) load("staffNS", builder);
+ domImpl = doc.getImplementation();
+ newDoc = domImpl.createDocument("http://www.w3.org/DOM/Test",
+ "dom:doc", docType);
+
+ {
+ boolean success = false;
+ try {
+ newDoc.createAttributeNS(namespaceURI, qualifiedName);
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.NAMESPACE_ERR);
+ }
+ assertTrue("documentcreateattributeNS05", success);
+ }
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies that createAttributeNS throws DOMException with NAMESPACE_ERR code.",
+ method = "createElementNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testCreateAttributeNS6() throws Throwable {
+ Document doc;
+ Document newDoc;
+ DocumentType docType = null;
+
+ DOMImplementation domImpl;
+
+ String namespaceURI = "http://www.w3.org/XML/1998 /namespace";
+ String qualifiedName = "xml:root";
+ doc = (Document) load("staffNS", builder);
+ domImpl = doc.getImplementation();
+ newDoc = domImpl.createDocument("http://www.w3.org/DOM/Test",
+ "dom:doc", docType);
+
+ {
+ boolean success = false;
+ try {
+ newDoc.createAttributeNS(namespaceURI, qualifiedName);
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.NAMESPACE_ERR);
+ }
+ assertTrue("documentcreateattributeNS06", success);
+ }
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies that createAttributeNS throws DOMException with NAMESPACE_ERR code.",
+ method = "createAttributeNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testCreateAttributeNS7() throws Throwable {
+ Document doc;
+
+ String namespaceURI = "http://www.W3.org/2000/xmlns";
+ String qualifiedName = "xmlns";
+ doc = (Document) load("staffNS", builder);
+
+ {
+ boolean success = false;
+ try {
+ doc.createAttributeNS(namespaceURI, qualifiedName);
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.NAMESPACE_ERR);
+ }
+ assertTrue("documentcreateattributeNS07", success);
+ }
+ }
+}
diff --git a/xml/src/test/java/tests/org/w3c/dom/DocumentCreateElementNS.java b/xml/src/test/java/tests/org/w3c/dom/DocumentCreateElementNS.java
new file mode 100644
index 0000000..85f2fff
--- /dev/null
+++ b/xml/src/test/java/tests/org/w3c/dom/DocumentCreateElementNS.java
@@ -0,0 +1,169 @@
+package tests.org.w3c.dom;
+
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.DOMException;
+import org.w3c.dom.DocumentType;
+import org.w3c.dom.DOMImplementation;
+
+import javax.xml.parsers.DocumentBuilder;
+
+/**
+ * The method createElementNS creates an element of the given valid
+ * qualifiedName and NamespaceURI.
+ *
+ * Invoke the createElementNS method on this Document object with a valid
+ * namespaceURI and qualifiedName. Check if a valid Element object is returned
+ * with the same node attributes.
+ *
+ * @author IBM
+ * @author Neil Delima
+ * @see <a
+ * href="http://www.w3.org/TR/DOM-Level-2-Core/core">http://www.w3.org/TR/DOM-Level-2-Core/core</a>
+ * @see <a
+ * href="http://www.w3.org/TR/DOM-Level-2-Core/core#ID-DocCrElNS">http://www.w3.org/TR/DOM-Level-2-Core/core#ID-DocCrElNS</a>
+ */
+@TestTargetClass(Document.class)
+public final class DocumentCreateElementNS extends DOMTestCase {
+
+ DOMDocumentBuilderFactory factory;
+
+ DocumentBuilder builder;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ try {
+ factory = new DOMDocumentBuilderFactory(DOMDocumentBuilderFactory
+ .getConfiguration1());
+ builder = factory.getBuilder();
+ } catch (Exception e) {
+ fail("Unexpected exception" + e.getMessage());
+ }
+ }
+
+ protected void tearDown() throws Exception {
+ factory = null;
+ builder = null;
+ super.tearDown();
+ }
+
+ /**
+ * Runs the test case.
+ *
+ * @throws Throwable
+ * Any uncaught exception causes test to fail
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies positive functionality.",
+ method = "createElementNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testCreateElementNS1() throws Throwable {
+ Document doc;
+ Element element;
+ String namespaceURI = "http://www.w3.org/DOM/Test/level2";
+ String qualifiedName = "XML:XML";
+ String nodeName;
+ String nsURI;
+ String localName;
+ String prefix;
+ String tagName;
+ doc = (Document) load("staffNS", builder);
+ element = doc.createElementNS(namespaceURI, qualifiedName);
+ nodeName = element.getNodeName();
+ nsURI = element.getNamespaceURI();
+ localName = element.getLocalName();
+ prefix = element.getPrefix();
+ tagName = element.getTagName();
+ assertEquals("documentcreateelementNS01_nodeName", "XML:XML", nodeName);
+ assertEquals("documentcreateelementNS01_namespaceURI",
+ "http://www.w3.org/DOM/Test/level2", nsURI);
+ assertEquals("documentcreateelementNS01_localName", "XML", localName);
+ assertEquals("documentcreateelementNS01_prefix", "XML", prefix);
+ assertEquals("documentcreateelementNS01_tagName", "XML:XML", tagName);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies that createElementNS throws DOMException with INVALID_CHARACTER_ERR code.",
+ method = "createElementNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testCreateElementNS2() throws Throwable {
+ Document doc;
+
+ String namespaceURI = null;
+
+ String qualifiedName = "^^";
+ doc = (Document) load("staffNS", builder);
+
+ {
+ boolean success = false;
+ try {
+ doc.createElementNS(namespaceURI, qualifiedName);
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.INVALID_CHARACTER_ERR);
+ }
+ assertTrue("documentcreateelementNS02", success);
+ }
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies that createElementNS throws DOMException with NAMESPACE_ERR code.",
+ method = "createElementNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testCreateElementNS5() throws Throwable {
+ Document doc;
+
+ String namespaceURI = null;
+
+ String qualifiedName = "null:xml";
+ doc = (Document) load("staffNS", builder);
+
+ {
+ boolean success = false;
+ try {
+ doc.createElementNS(namespaceURI, qualifiedName);
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.NAMESPACE_ERR);
+ }
+ assertTrue("documentcreateelementNS05", success);
+ }
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies that createElementNS throws DOMException with NAMESPACE_ERR code.",
+ method = "createElementNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testCreateElementNS6() throws Throwable {
+ Document doc;
+ Document newDoc;
+ DocumentType docType = null;
+
+ DOMImplementation domImpl;
+
+ String namespaceURI = "http://www.w3.org/xml/1998/namespace ";
+ String qualifiedName = "xml:root";
+ doc = (Document) load("staffNS", builder);
+ domImpl = doc.getImplementation();
+ newDoc = domImpl.createDocument("http://www.w3.org/DOM/Test",
+ "dom:doc", docType);
+
+ {
+ boolean success = false;
+ try {
+ newDoc.createElementNS(namespaceURI, qualifiedName);
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.NAMESPACE_ERR);
+ }
+ assertTrue("documentcreateelementNS06", success);
+ }
+ }
+}
diff --git a/xml/src/test/java/tests/org/w3c/dom/DocumentGetElementsByTagnameNS.java b/xml/src/test/java/tests/org/w3c/dom/DocumentGetElementsByTagnameNS.java
new file mode 100644
index 0000000..390bf11
--- /dev/null
+++ b/xml/src/test/java/tests/org/w3c/dom/DocumentGetElementsByTagnameNS.java
@@ -0,0 +1,150 @@
+package tests.org.w3c.dom;
+
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.DocumentType;
+import org.w3c.dom.DOMImplementation;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Element;
+
+import javax.xml.parsers.DocumentBuilder;
+
+/**
+ * The method getElementsByTagNameNS returns a NodeList of all the Elements with
+ * a given local name and namespace URI in the order in which they are
+ * encountered in a preorder traversal of the Document tree.
+ *
+ * Invoke the getElementsByTagNameNS method on a new Document object with the
+ * values of namespaceURI=* and localName=*. This should return a nodeList of 1
+ * item.
+ *
+ * @author IBM
+ * @author Neil Delima
+ * @see <a
+ * href="http://www.w3.org/TR/DOM-Level-2-Core/core">http://www.w3.org/TR/DOM-Level-2-Core/core</a>
+ * @see <a
+ * href="http://www.w3.org/TR/DOM-Level-2-Core/core#ID-getElBTNNS">http://www.w3.org/TR/DOM-Level-2-Core/core#ID-getElBTNNS</a>
+ * @see <a
+ * href="http://www.w3.org/Bugs/Public/show_bug.cgi?id=259">http://www.w3.org/Bugs/Public/show_bug.cgi?id=259</a>
+ */
+@TestTargetClass(Document.class)
+public final class DocumentGetElementsByTagnameNS extends DOMTestCase {
+
+ DOMDocumentBuilderFactory factory;
+
+ DocumentBuilder builder;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ try {
+ factory = new DOMDocumentBuilderFactory(DOMDocumentBuilderFactory
+ .getConfiguration2());
+ builder = factory.getBuilder();
+ } catch (Exception e) {
+ fail("Unexpected exception" + e.getMessage());
+ }
+ }
+
+ protected void tearDown() throws Exception {
+ factory = null;
+ builder = null;
+ super.tearDown();
+ }
+
+ /**
+ * Runs the test case.
+ *
+ * @throws Throwable
+ * Any uncaught exception causes test to fail
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies '*' as parameters.",
+ method = "getElementsByTagNameNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testGetElementsByTagNameNS1() throws Throwable {
+ Document doc;
+ Document newDoc;
+ DocumentType docType = null;
+
+ DOMImplementation domImpl;
+ NodeList childList;
+ String nullNS = null;
+
+ doc = (Document) load("staffNS", builder);
+ domImpl = doc.getImplementation();
+ newDoc = domImpl.createDocument(nullNS, "root", docType);
+ childList = newDoc.getElementsByTagNameNS("*", "*");
+ assertEquals("documentgetelementsbytagnameNS01", 1, childList
+ .getLength());
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies '*' as the first parameter.",
+ method = "getElementsByTagNameNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testGetElementsByTagNameNS2() throws Throwable {
+ Document doc;
+ Element docElem;
+ Element element;
+ NodeList childList;
+
+ doc = (Document) load("staffNS", builder);
+ docElem = doc.getDocumentElement();
+ element = doc.createElementNS("test", "employeeId");
+ docElem.appendChild(element);
+ childList = doc.getElementsByTagNameNS("*", "employeeId");
+ assertEquals("documentgetelementsbytagnameNS02", 6, childList
+ .getLength());
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies wrong namespaceURI as a parameter.",
+ method = "getElementsByTagNameNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testGetElementsByTagNameNS3() throws Throwable {
+ Document doc;
+ NodeList childList;
+ doc = (Document) load("staffNS", builder);
+ childList = doc.getElementsByTagNameNS("**", "*");
+ assertEquals("documentgetelementsbytagnameNS03", 0, childList
+ .getLength());
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies positive functionality.",
+ method = "getElementsByTagNameNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testGetElementsByTagNameNS4() throws Throwable {
+ Document doc;
+ NodeList childList;
+ String nullNS = null;
+
+ doc = (Document) load("staffNS", builder);
+ childList = doc.getElementsByTagNameNS(nullNS, "0");
+ assertEquals("documentgetelementsbytagnameNS04", 0, childList
+ .getLength());
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies positive functionality.",
+ method = "getElementsByTagNameNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testGetElementsByTagNameNS5() throws Throwable {
+ Document doc;
+ NodeList childList;
+ doc = (Document) load("staffNS", builder);
+ childList = doc.getElementsByTagNameNS("null", "elementId");
+ assertEquals("documentgetelementsbytagnameNS05", 0, childList
+ .getLength());
+ }
+}
diff --git a/xml/src/test/java/tests/org/w3c/dom/DocumentGeteEementById.java b/xml/src/test/java/tests/org/w3c/dom/DocumentGeteEementById.java
new file mode 100644
index 0000000..7c82ac7
--- /dev/null
+++ b/xml/src/test/java/tests/org/w3c/dom/DocumentGeteEementById.java
@@ -0,0 +1,72 @@
+package tests.org.w3c.dom;
+
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import javax.xml.parsers.DocumentBuilder;
+
+/**
+ * The method getElementById returns the element whose ID is given by elementId.
+ * If not such element exists, returns null.
+ *
+ * Invoke the getElementById method on this Document object with an invalid
+ * elementId. This should return a null element.
+ *
+ * @author IBM
+ * @author Neil Delima
+ * @see <a
+ * href="http://www.w3.org/TR/DOM-Level-2-Core/core">http://www.w3.org/TR/DOM-Level-2-Core/core</a>
+ * @see <a
+ * href="http://www.w3.org/TR/DOM-Level-2-Core/core#ID-getElBId">http://www.w3.org/TR/DOM-Level-2-Core/core#ID-getElBId</a>
+ */
+@TestTargetClass(Document.class)
+public final class DocumentGeteEementById extends DOMTestCase {
+
+ DOMDocumentBuilderFactory factory;
+
+ DocumentBuilder builder;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ try {
+ factory = new DOMDocumentBuilderFactory(DOMDocumentBuilderFactory
+ .getConfiguration1());
+ builder = factory.getBuilder();
+ } catch (Exception e) {
+ fail("Unexpected exception" + e.getMessage());
+ }
+ }
+
+ protected void tearDown() throws Exception {
+ factory = null;
+ builder = null;
+ super.tearDown();
+ }
+
+ /**
+ * Runs the test case.
+ *
+ * @throws Throwable
+ * Any uncaught exception causes test to fail
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Doesn't verify getElementById method for existent element.",
+ method = "getElementById",
+ args = {java.lang.String.class}
+ )
+ public void testGetElementById() throws Throwable {
+ Document doc;
+ Element element;
+ String elementId = "---";
+ doc = (Document) load("staffNS", builder);
+ element = doc.getElementById(elementId);
+ assertNull("documentgetelementbyid01", element);
+ }
+
+}
diff --git a/xml/src/test/java/tests/org/w3c/dom/DocumentImportNode.java b/xml/src/test/java/tests/org/w3c/dom/DocumentImportNode.java
new file mode 100644
index 0000000..426a0ad
--- /dev/null
+++ b/xml/src/test/java/tests/org/w3c/dom/DocumentImportNode.java
@@ -0,0 +1,699 @@
+package tests.org.w3c.dom;
+
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.Attr;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.DOMException;
+import org.w3c.dom.DocumentType;
+import org.w3c.dom.DOMImplementation;
+import org.w3c.dom.DocumentFragment;
+import org.w3c.dom.ProcessingInstruction;
+
+import javax.xml.parsers.DocumentBuilder;
+
+/**
+ * The importNode method imports a node from another document to this document.
+ * The returned node has no parent; (parentNode is null). The source node is not
+ * altered or removed from the original document but a new copy of the source
+ * node is created.
+ *
+ * Using the method importNode with deep=true, import the attribute, "street" of
+ * the second element node, from a list of nodes whose local names are "address"
+ * and namespaceURI "http://www.nist.gov" into the same document. Check the
+ * parentNode, nodeName, nodeType and nodeValue of the imported node to verify
+ * if it has been imported correctly.
+ *
+ * @author IBM
+ * @author Neil Delima
+ * @see <a
+ * href="http://www.w3.org/TR/DOM-Level-2-Core/core">http://www.w3.org/TR/DOM-Level-2-Core/core</a>
+ * @see <a
+ * href="http://www.w3.org/TR/DOM-Level-2-Core/core#Core-Document-importNode">http://www.w3.org/TR/DOM-Level-2-Core/core#Core-Document-importNode</a>
+ */
+@TestTargetClass(Document.class)
+public final class DocumentImportNode extends DOMTestCase {
+
+ DOMDocumentBuilderFactory factory;
+
+ DocumentBuilder builder;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ try {
+ factory = new DOMDocumentBuilderFactory(DOMDocumentBuilderFactory
+ .getConfiguration2());
+ builder = factory.getBuilder();
+ } catch (Exception e) {
+ fail("Unexpected exception" + e.getMessage());
+ }
+ }
+
+ protected void tearDown() throws Exception {
+ factory = null;
+ builder = null;
+ super.tearDown();
+ }
+
+ /**
+ * Runs the test case.
+ *
+ * @throws Throwable
+ * Any uncaught exception causes test to fail
+ */
+// Assumes validation.
+// public void testImportNode1() throws Throwable {
+// Document doc;
+// Element element;
+// Attr attr;
+// NodeList childList;
+// Node importedAttr;
+// String nodeName;
+// int nodeType;
+// String nodeValue;
+// doc = (Document) load("staffNS", builder);
+// childList = doc
+// .getElementsByTagNameNS("http://www.nist.gov", "address");
+// element = (Element) childList.item(1);
+// attr = element.getAttributeNode("street");
+// importedAttr = doc.importNode(attr, false);
+// nodeName = importedAttr.getNodeName();
+// nodeValue = importedAttr.getNodeValue();
+// nodeType = (int) importedAttr.getNodeType();
+// assertEquals("documentimportnode01_nodeName", "street", nodeName);
+// assertEquals("documentimportnode01_nodeType", 2, nodeType);
+// assertEquals("documentimportnode01_nodeValue", "Yes", nodeValue);
+// }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Doesn't verify DOMException exception.",
+ method = "importNode",
+ args = {org.w3c.dom.Node.class, boolean.class}
+ )
+ public void testImportNode2() throws Throwable {
+ Document doc;
+ Document docImported;
+ Element element;
+ Attr attr;
+ Node importedAttr;
+ String nodeName;
+ int nodeType;
+ String nodeValue;
+ NodeList addresses;
+ Node attrsParent;
+ doc = (Document) load("staffNS", builder);
+ docImported = (Document) load("staff", builder);
+ addresses = doc
+ .getElementsByTagNameNS("http://www.nist.gov", "address");
+ element = (Element) addresses.item(1);
+ attr = element.getAttributeNodeNS("http://www.nist.gov", "zone");
+ importedAttr = docImported.importNode(attr, false);
+ nodeName = importedAttr.getNodeName();
+ nodeType = (int) importedAttr.getNodeType();
+ nodeValue = importedAttr.getNodeValue();
+ attrsParent = importedAttr.getParentNode();
+ assertNull("documentimportnode02_parentNull", attrsParent);
+ assertEquals("documentimportnode02_nodeName", "emp:zone", nodeName);
+ assertEquals("documentimportnode02_nodeType", 2, nodeType);
+ assertEquals("documentimportnode02_nodeValue", "CANADA", nodeValue);
+ }
+
+// Assumes validation.
+// public void testImportNode3() throws Throwable {
+// Document doc;
+// Element element;
+// Attr attr;
+// NodeList childList;
+// Node importedAttr;
+// String nodeName;
+// int nodeType;
+// String nodeValue;
+// doc = (Document) load("staffNS", builder);
+// childList = doc.getElementsByTagNameNS("http://www.nist.gov",
+// "employee");
+// element = (Element) childList.item(1);
+// attr = element.getAttributeNode("defaultAttr");
+// importedAttr = doc.importNode(attr, false);
+// nodeName = importedAttr.getNodeName();
+// nodeValue = importedAttr.getNodeValue();
+// nodeType = (int) importedAttr.getNodeType();
+// assertEquals("documentimportnode03_nodeName", "defaultAttr", nodeName);
+// assertEquals("documentimportnode03_nodeType", 2, nodeType);
+// assertEquals("documentimportnode03_nodeValue", "defaultVal", nodeValue);
+// }
+
+// Assumes validation.
+// public void testImportNode4() throws Throwable {
+// Document doc;
+// Document newDoc;
+// DocumentType docType = null;
+//
+// DOMImplementation domImpl;
+// Element element;
+// Attr attr;
+// NodeList childList;
+// Node importedAttr;
+// String nodeName;
+// int nodeType;
+// String nodeValue;
+// doc = (Document) load("staffNS", builder);
+// domImpl = doc.getImplementation();
+// newDoc = domImpl.createDocument("http://www.w3.org/DOM/Test",
+// "l2:root", docType);
+// childList = doc.getElementsByTagNameNS("http://www.nist.gov",
+// "employee");
+// element = (Element) childList.item(1);
+// attr = element.getAttributeNode("defaultAttr");
+// importedAttr = newDoc.importNode(attr, true);
+// nodeName = importedAttr.getNodeName();
+// nodeValue = importedAttr.getNodeValue();
+// nodeType = (int) importedAttr.getNodeType();
+// assertEquals("documentimportnode04_nodeName", "defaultAttr", nodeName);
+// assertEquals("documentimportnode04_nodeType", 2, nodeType);
+// assertEquals("documentimportnode04_nodeValue", "defaultVal", nodeValue);
+// }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Doesn't verify DOMException exception.",
+ method = "importNode",
+ args = {org.w3c.dom.Node.class, boolean.class}
+ )
+ public void testImportNode5() throws Throwable {
+ Document doc;
+ Document docImported;
+ Attr attr;
+ Node importedAttr;
+ String nodeName;
+ int nodeType;
+ String nodeValue;
+ String namespaceURI;
+ doc = (Document) load("staffNS", builder);
+ docImported = (Document) load("staff", builder);
+ attr = doc.createAttributeNS("http://www.w3.org/DOM/Test", "a_:b0");
+ importedAttr = docImported.importNode(attr, false);
+ nodeName = importedAttr.getNodeName();
+ nodeValue = importedAttr.getNodeValue();
+ nodeType = (int) importedAttr.getNodeType();
+ namespaceURI = importedAttr.getNamespaceURI();
+ assertEquals("documentimportnode05_nodeName", "a_:b0", nodeName);
+ assertEquals("documentimportnode05_nodeType", 2, nodeType);
+ assertEquals("documentimportnode05_nodeValue", "", nodeValue);
+ assertEquals("documentimportnode05_namespaceURI",
+ "http://www.w3.org/DOM/Test", namespaceURI);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies that importNode method throws DOMException with NOT_SUPPORTED_ERR code.",
+ method = "importNode",
+ args = {org.w3c.dom.Node.class, boolean.class}
+ )
+ public void testImportNode6() throws Throwable {
+ Document doc;
+
+ doc = (Document) load("staffNS", builder);
+
+ {
+ boolean success = false;
+ try {
+ doc.importNode(doc, false);
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.NOT_SUPPORTED_ERR);
+ }
+ assertTrue("throw_NOT_SUPPORTED_ERR", success);
+ }
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies that importNode method throws DOMException with NOT_SUPPORTED_ERR code.",
+ method = "importNode",
+ args = {org.w3c.dom.Node.class, boolean.class}
+ )
+ public void testImportNode7() throws Throwable {
+ Document doc;
+
+ DocumentType docType;
+ doc = (Document) load("staffNS", builder);
+ docType = doc.getDoctype();
+
+ {
+ boolean success = false;
+ try {
+ doc.importNode(docType, true);
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.NOT_SUPPORTED_ERR);
+ }
+ assertTrue("throw_NOT_SUPPORTED_ERR", success);
+ }
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies that importNode method throws DOMException with NOT_SUPPORTED_ERR code.",
+ method = "importNode",
+ args = {org.w3c.dom.Node.class, boolean.class}
+ )
+ public void testImportNode8() throws Throwable {
+ Document doc;
+
+ DocumentType docType;
+ DOMImplementation domImpl;
+ String nullNS = null;
+
+ doc = (Document) load("staffNS", builder);
+ domImpl = doc.getImplementation();
+ docType = domImpl.createDocumentType("test:root", nullNS, nullNS);
+
+ {
+ boolean success = false;
+ try {
+ doc.importNode(docType, true);
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.NOT_SUPPORTED_ERR);
+ }
+ assertTrue("throw_NOT_SUPPORTED_ERR", success);
+ }
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Doesn't verify DOMException exception.",
+ method = "importNode",
+ args = {org.w3c.dom.Node.class, boolean.class}
+ )
+ public void testImportNode9() throws Throwable {
+ Document doc;
+ DocumentFragment docFragment;
+ NodeList childList;
+ boolean success;
+ Node addressNode;
+
+ Node importedDocFrag;
+ doc = (Document) load("staffNS", builder);
+ docFragment = doc.createDocumentFragment();
+ childList = doc.getElementsByTagNameNS("*", "address");
+ addressNode = childList.item(0);
+ docFragment.appendChild(addressNode);
+ importedDocFrag = doc.importNode(docFragment, false);
+ success = importedDocFrag.hasChildNodes();
+ assertFalse("documentimportnode09", success);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies positive functionality; doesn't verify DOMException exceptions.",
+ method = "importNode",
+ args = {org.w3c.dom.Node.class, boolean.class}
+ )
+ public void testImportNode10() throws Throwable {
+ Document doc;
+ DocumentFragment docFragment;
+ NodeList childList;
+ boolean success;
+ Node addressNode;
+
+ Node importedDocFrag;
+ doc = (Document) load("staffNS", builder);
+ docFragment = doc.createDocumentFragment();
+ childList = doc.getElementsByTagNameNS("*", "address");
+ addressNode = childList.item(0);
+ docFragment.appendChild(addressNode);
+ importedDocFrag = doc.importNode(docFragment, true);
+ success = importedDocFrag.hasChildNodes();
+ assertTrue("documentimportnode10", success);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Doesn't verify DOMException exception.",
+ method = "importNode",
+ args = {org.w3c.dom.Node.class, boolean.class}
+ )
+ public void testImportNode11() throws Throwable {
+ Document doc;
+ Element docElement;
+ Node imported;
+ boolean success;
+ String nodeNameOrig;
+ String nodeNameImported;
+ doc = (Document) load("staffNS", builder);
+ docElement = doc.getDocumentElement();
+ imported = doc.importNode(docElement, false);
+ success = imported.hasChildNodes();
+ assertFalse("documentimportnode11", success);
+ nodeNameImported = imported.getNodeName();
+ nodeNameOrig = docElement.getNodeName();
+ assertEquals("documentimportnode11_NodeName", nodeNameImported,
+ nodeNameOrig);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Doesn't verify DOMException exception.",
+ method = "importNode",
+ args = {org.w3c.dom.Node.class, boolean.class}
+ )
+ public void testImportNode12() throws Throwable {
+ Document doc;
+ NodeList childList;
+ Node imported;
+ Node addressElem;
+ NodeList addressElemChildren;
+ NodeList importedChildren;
+ int addressElemLen;
+ int importedLen;
+ doc = (Document) load("staffNS", builder);
+ childList = doc.getElementsByTagNameNS("*", "address");
+ addressElem = childList.item(0);
+ imported = doc.importNode(addressElem, true);
+ addressElemChildren = addressElem.getChildNodes();
+ importedChildren = imported.getChildNodes();
+ addressElemLen = (int) addressElemChildren.getLength();
+ importedLen = (int) importedChildren.getLength();
+ assertEquals("documentimportnode12", importedLen, addressElemLen);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Doesn't verify DOMException exception.",
+ method = "importNode",
+ args = {org.w3c.dom.Node.class, boolean.class}
+ )
+ public void testImportNode13() throws Throwable {
+ Document doc;
+ NodeList childList;
+ Node imported;
+ NodeList importedList;
+ Node employeeElem;
+ int importedLen;
+ doc = (Document) load("staffNS", builder);
+ childList = doc.getElementsByTagNameNS("*", "employee");
+ employeeElem = childList.item(0);
+ imported = doc.importNode(employeeElem, false);
+ importedList = imported.getChildNodes();
+ importedLen = (int) importedList.getLength();
+ assertEquals("documentimportnode13", 0, importedLen);
+ }
+
+// Assumes validation.
+// public void testImportNode14() throws Throwable {
+// Document doc;
+// Document newDoc;
+// DOMImplementation domImpl;
+// DocumentType nullDocType = null;
+//
+// NodeList childList;
+// Node imported;
+// Node employeeElem;
+// Attr attrNode;
+// String attrValue;
+// String nullNS = null;
+//
+// doc = (Document) load("staffNS", builder);
+// childList = doc.getElementsByTagNameNS("*", "employee");
+// employeeElem = childList.item(3);
+// domImpl = builder.getDOMImplementation();
+// newDoc = domImpl.createDocument(nullNS, "staff", nullDocType);
+// imported = newDoc.importNode(employeeElem, true);
+// attrNode = ((Element) /* Node */imported).getAttributeNodeNS(nullNS,
+// "defaultAttr");
+// assertNull("defaultAttrNotImported", attrNode);
+// attrValue = ((Element) /* Node */imported).getAttributeNS(
+// "http://www.w3.org/2000/xmlns/", "emp");
+// assertEquals("explicitAttrImported", "http://www.nist.gov", attrValue);
+// }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies import of TEXT_NODE.",
+ method = "importNode",
+ args = {org.w3c.dom.Node.class, boolean.class}
+ )
+ public void testImportNode15() throws Throwable {
+ Document doc;
+
+ Node textImport;
+ Node textToImport;
+ String nodeValue;
+ doc = (Document) load("staffNS", builder);
+
+ textToImport = doc
+ .createTextNode("Document.importNode test for a TEXT_NODE");
+ textImport = doc.importNode(textToImport, true);
+ nodeValue = textImport.getNodeValue();
+ assertEquals("documentimportnode15",
+ "Document.importNode test for a TEXT_NODE", nodeValue);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies import of COMMENT_NODE",
+ method = "importNode",
+ args = {org.w3c.dom.Node.class, boolean.class}
+ )
+ public void testImportNode17() throws Throwable {
+ Document doc;
+
+ Node commentImport;
+ Node commentToImport;
+ String nodeValue;
+ doc = (Document) load("staffNS", builder);
+
+ commentToImport = doc
+ .createComment("Document.importNode test for a COMMENT_NODE");
+ commentImport = doc.importNode(commentToImport, true);
+ nodeValue = commentImport.getNodeValue();
+ assertEquals("documentimportnode17",
+ "Document.importNode test for a COMMENT_NODE", nodeValue);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Doesn't verify DOMException exception.",
+ method = "importNode",
+ args = {org.w3c.dom.Node.class, boolean.class}
+ )
+ public void testImportNode18() throws Throwable {
+ Document doc;
+
+ ProcessingInstruction piImport;
+ ProcessingInstruction piToImport;
+ String piData;
+ String piTarget;
+ doc = (Document) load("staffNS", builder);
+
+ piToImport = doc.createProcessingInstruction("Target", "Data");
+ piImport = (ProcessingInstruction) doc.importNode(piToImport, false);
+ piTarget = piImport.getTarget();
+ piData = piImport.getData();
+ assertEquals("documentimportnode18_Target", "Target", piTarget);
+ assertEquals("documentimportnode18_Data", "Data", piData);
+ }
+
+// Assumes validation.
+// public void testImportNode19() throws Throwable {
+// Document doc;
+// DocumentType docTypeNull = null;
+//
+// Document docImp;
+// DOMImplementation domImpl;
+// DocumentType docType;
+// NamedNodeMap nodeMap;
+// Entity entity2;
+// Entity entity6;
+// Entity entityImp2;
+// Entity entityImp6;
+// String nodeName;
+// String systemId;
+// String notationName;
+// String nodeNameImp;
+// String systemIdImp;
+// String notationNameImp;
+// doc = (Document) load("staffNS", builder);
+// domImpl = doc.getImplementation();
+// docType = doc.getDoctype();
+// docImp = domImpl.createDocument("http://www.w3.org/DOM/Test", "a:b",
+// docTypeNull);
+// nodeMap = docType.getEntities();
+// assertNotNull("entitiesNotNull", nodeMap);
+// entity2 = (Entity) nodeMap.getNamedItem("ent2");
+// entity6 = (Entity) nodeMap.getNamedItem("ent6");
+// entityImp2 = (Entity) docImp.importNode(entity2, false);
+// entityImp6 = (Entity) docImp.importNode(entity6, true);
+// nodeName = entity2.getNodeName();
+// nodeNameImp = entityImp2.getNodeName();
+// assertEquals("documentimportnode19_Ent2NodeName", nodeName, nodeNameImp);
+// nodeName = entity6.getNodeName();
+// nodeNameImp = entityImp6.getNodeName();
+// assertEquals("documentimportnode19_Ent6NodeName", nodeName, nodeNameImp);
+// systemId = entity2.getSystemId();
+// systemIdImp = entityImp2.getSystemId();
+// assertEquals("documentimportnode19_Ent2SystemId", systemId, systemIdImp);
+// systemId = entity6.getSystemId();
+// systemIdImp = entityImp6.getSystemId();
+// assertEquals("documentimportnode19_Ent6SystemId", systemId, systemIdImp);
+// notationName = entity2.getNotationName();
+// notationNameImp = entityImp2.getNotationName();
+// assertEquals("documentimportnode19_Ent2NotationName", notationName,
+// notationNameImp);
+// notationName = entity6.getNotationName();
+// notationNameImp = entityImp6.getNotationName();
+// assertEquals("documentimportnode19_Ent6NotationName", notationName,
+// notationNameImp);
+// }
+
+// Assumes validation.
+// public void testImportNode20() throws Throwable {
+// Document doc;
+// Document docImp;
+// DOMImplementation domImpl;
+// DocumentType docType;
+// DocumentType docTypeNull = null;
+//
+// NamedNodeMap nodeMap;
+// Entity entity4;
+// Entity entityImp4;
+// Element element;
+// CharacterData cdata;
+// ProcessingInstruction pi;
+// NodeList childList;
+// NodeList elemchildList;
+// String ent4Name;
+// String ent4ImpName;
+// String cdataVal;
+// String piTargetVal;
+// String piDataVal;
+// doc = (Document) load("staffNS", builder);
+// domImpl = doc.getImplementation();
+// docType = doc.getDoctype();
+// docImp = domImpl.createDocument("http://www.w3.org/DOM/Test", "a:b",
+// docTypeNull);
+// nodeMap = docType.getEntities();
+// entity4 = (Entity) nodeMap.getNamedItem("ent4");
+// entityImp4 = (Entity) docImp.importNode(entity4, true);
+// childList = entityImp4.getChildNodes();
+// element = (Element) childList.item(0);
+// elemchildList = element.getChildNodes();
+// cdata = (CharacterData) elemchildList.item(0);
+// pi = (ProcessingInstruction) childList.item(1);
+// ent4Name = entity4.getNodeName();
+// ent4ImpName = entityImp4.getNodeName();
+// cdataVal = cdata.getData();
+// piTargetVal = pi.getTarget();
+// piDataVal = pi.getData();
+// assertEquals("documentimportnode20_Ent4NodeName", ent4Name, ent4ImpName);
+// assertEquals("documentimportnode20_Cdata", "Element data", cdataVal);
+// assertEquals("documentimportnode20_PITarget", "PItarget", piTargetVal);
+// assertEquals("documentimportnode20_PIData", "PIdata", piDataVal);
+// }
+
+// TODO Fails on JDK. Why?
+// public void testImportNode21() throws Throwable {
+//
+//
+// Document doc;
+// DocumentType docTypeNull = null;
+//
+// Document docImp;
+// DOMImplementation domImpl;
+// NodeList addressList;
+// NodeList addressChildList;
+// Element element;
+// EntityReference entRef2;
+// EntityReference entRefImp2;
+// EntityReference entRef3;
+// EntityReference entRefImp3;
+// String nodeName2;
+// String nodeName3;
+// String nodeNameImp2;
+// String nodeNameImp3;
+// NodeList nodes;
+// Node nodeImp3;
+// Node nodeImp2;
+// String nodeValueImp2;
+// String nodeValueImp3;
+// doc = (Document) load("staffNS", builder);
+// domImpl = doc.getImplementation();
+// docImp = domImpl.createDocument("http://www.w3.org/DOM/Test", "a:b",
+// docTypeNull);
+// addressList = doc.getElementsByTagName("address");
+// element = (Element) addressList.item(1);
+// addressChildList = element.getChildNodes();
+// entRef2 = (EntityReference) addressChildList.item(0);
+// entRef3 = (EntityReference) addressChildList.item(2);
+// entRefImp2 = (EntityReference) docImp.importNode(entRef2, true);
+// entRefImp3 = (EntityReference) docImp.importNode(entRef3, false);
+// nodeName2 = entRef2.getNodeName();
+// nodeName3 = entRef3.getNodeName();
+// nodeNameImp2 = entRefImp2.getNodeName();
+// nodeNameImp3 = entRefImp3.getNodeName();
+// assertEquals("documentimportnode21_Ent2NodeName", nodeName2,
+// nodeNameImp2);
+// assertEquals("documentimportnode21_Ent3NodeName", nodeName3,
+// nodeNameImp3);
+// entRefImp2 = (EntityReference) doc.importNode(entRef2, true);
+// entRefImp3 = (EntityReference) doc.importNode(entRef3, false);
+// nodes = entRefImp2.getChildNodes();
+// nodeImp2 = nodes.item(0);
+// nodeValueImp2 = nodeImp2.getNodeValue();
+// nodes = entRefImp3.getChildNodes();
+// nodeImp3 = nodes.item(0);
+// nodeValueImp3 = nodeImp3.getNodeValue();
+// assertEquals("documentimportnode21_Ent2NodeValue", "1900 Dallas Road",
+// nodeValueImp2);
+// assertEquals("documentimportnode21_Ent3Nodevalue", "Texas",
+// nodeValueImp3);
+//
+// }
+
+// Assumes validation.
+// public void testImportNode22() throws Throwable {
+// Document doc;
+// DocumentType docTypeNull = null;
+//
+// Document docImp;
+// DOMImplementation domImpl;
+// DocumentType docType;
+// NamedNodeMap nodeMap;
+// Notation notation1;
+// Notation notation2;
+//
+// String publicId1;
+// String publicId1Imp;
+// String publicId1NewImp;
+// String publicId2Imp;
+//
+// String systemId1Imp;
+// String systemId1NewImp;
+// String systemId2;
+// String systemId2Imp;
+// String systemId2NewImp;
+// doc = (Document) load("staffNS", builder);
+// domImpl = doc.getImplementation();
+// docType = doc.getDoctype();
+// docImp = domImpl.createDocument("http://www.w3.org/DOM/Test", "a:b",
+// docTypeNull);
+// nodeMap = docType.getNotations();
+// assertNotNull("notationsNotNull", nodeMap);
+// notation1 = (Notation) nodeMap.getNamedItem("notation1");
+// notation2 = (Notation) nodeMap.getNamedItem("notation2");
+// doc.importNode(notation1, true);
+// doc.importNode(notation2, false);
+// docImp.importNode(notation1, false);
+// docImp.importNode(notation2, true);
+// publicId1 = notation1.getPublicId();
+// publicId1Imp = notation1.getPublicId();
+// publicId1NewImp = notation1.getPublicId();
+// systemId1Imp = notation1.getSystemId();
+// systemId1NewImp = notation1.getSystemId();
+// publicId2Imp = notation2.getPublicId();
+// notation2.getPublicId();
+// systemId2 = notation2.getSystemId();
+// systemId2Imp = notation2.getSystemId();
+// systemId2NewImp = notation2.getSystemId();
+// assertEquals("documentimportnode22_N1PID", publicId1, publicId1Imp);
+// assertEquals("documentimportnode22_N1NPID", publicId1, publicId1NewImp);
+// assertNull("documentimportnode22_N1SID", systemId1Imp);
+// assertNull("documentimportnode22_N1NSID", systemId1NewImp);
+// assertEquals("documentimportnode22_N2SID", systemId2, systemId2Imp);
+// assertEquals("documentimportnode22_N2NSID", systemId2, systemId2NewImp);
+// assertNull("documentimportnode22_N2PID", publicId2Imp);
+// assertNull("documentimportnode22_N2NPID", publicId2Imp);
+// }
+}
diff --git a/xml/src/test/java/tests/org/w3c/dom/DocumentTypeInternalSubset.java b/xml/src/test/java/tests/org/w3c/dom/DocumentTypeInternalSubset.java
new file mode 100644
index 0000000..9e79788
--- /dev/null
+++ b/xml/src/test/java/tests/org/w3c/dom/DocumentTypeInternalSubset.java
@@ -0,0 +1,76 @@
+package tests.org.w3c.dom;
+
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import org.w3c.dom.DocumentType;
+import org.w3c.dom.Document;
+import org.w3c.dom.DOMImplementation;
+
+import javax.xml.parsers.DocumentBuilder;
+
+/**
+ * The method getInternalSubset() returns the internal subset as a string.
+ *
+ * Create a new DocumentType node with null values for publicId and systemId.
+ * Verify that its internal subset is null.
+ *
+ * @author IBM
+ * @author Neil Delima
+ * @see <a
+ * href="http://www.w3.org/TR/DOM-Level-2-Core/core#ID-Core-DocType-internalSubset">http://www.w3.org/TR/DOM-Level-2-Core/core#ID-Core-DocType-internalSubset</a>
+ * @see <a
+ * href="http://www.w3.org/Bugs/Public/show_bug.cgi?id=259">http://www.w3.org/Bugs/Public/show_bug.cgi?id=259</a>
+ */
+@TestTargetClass(DocumentType.class)
+public final class DocumentTypeInternalSubset extends DOMTestCase {
+
+ DOMDocumentBuilderFactory factory;
+
+ DocumentBuilder builder;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ try {
+ factory = new DOMDocumentBuilderFactory(DOMDocumentBuilderFactory
+ .getConfiguration1());
+ builder = factory.getBuilder();
+ } catch (Exception e) {
+ fail("Unexpected exception" + e.getMessage());
+ }
+ }
+
+ protected void tearDown() throws Exception {
+ factory = null;
+ builder = null;
+ super.tearDown();
+ }
+
+ /**
+ * Runs the test case.
+ *
+ * @throws Throwable
+ * Any uncaught exception causes test to fail
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Doesn't check positive case.",
+ method = "getInternalSubset",
+ args = {}
+ )
+ public void testGetInternalSubset() throws Throwable {
+ Document doc;
+ DocumentType docType;
+ DOMImplementation domImpl;
+ String internal;
+ String nullNS = null;
+
+ doc = (Document) load("staffNS", builder);
+ domImpl = doc.getImplementation();
+ docType = domImpl.createDocumentType("l2:root", nullNS, nullNS);
+ internal = docType.getInternalSubset();
+ assertNull("internalSubsetNull", internal);
+ }
+}
diff --git a/xml/src/test/java/tests/org/w3c/dom/DocumentTypePublicId.java b/xml/src/test/java/tests/org/w3c/dom/DocumentTypePublicId.java
new file mode 100644
index 0000000..26e9a5f
--- /dev/null
+++ b/xml/src/test/java/tests/org/w3c/dom/DocumentTypePublicId.java
@@ -0,0 +1,97 @@
+
+/*
+This Java source file was generated by test-to-java.xsl
+and is a derived work from the source document.
+The source document contained the following notice:
+
+
+
+Copyright (c) 2001-2003 World Wide Web Consortium,
+(Massachusetts Institute of Technology, Institut National de
+Recherche en Informatique et en Automatique, Keio University). All
+Rights Reserved. This program is distributed under the W3C's Software
+Intellectual Property License. This program is distributed in the
+hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE.
+
+See W3C License http://www.w3.org/Consortium/Legal/ for more details.
+
+
+*/
+
+package tests.org.w3c.dom;
+
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.DocumentType;
+import org.w3c.dom.DOMImplementation;
+
+import javax.xml.parsers.DocumentBuilder;
+
+
+
+/**
+ * The method getInternalSubset() returns the public identifier of the external subset.
+ *
+ * Create a new DocumentType node with the value "PUB" for its publicId.
+ * Check the value of the publicId attribute using getPublicId().
+* @author IBM
+* @author Neil Delima
+* @see <a href="http://www.w3.org/TR/DOM-Level-2-Core/core#ID-Core-DocType-publicId">http://www.w3.org/TR/DOM-Level-2-Core/core#ID-Core-DocType-publicId</a>
+* @see <a href="http://www.w3.org/Bugs/Public/show_bug.cgi?id=259">http://www.w3.org/Bugs/Public/show_bug.cgi?id=259</a>
+*/
+@TestTargetClass(DocumentType.class)
+public final class DocumentTypePublicId extends DOMTestCase {
+
+ DOMDocumentBuilderFactory factory;
+
+ DocumentBuilder builder;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ try {
+ factory = new DOMDocumentBuilderFactory(DOMDocumentBuilderFactory
+ .getConfiguration1());
+ builder = factory.getBuilder();
+ } catch (Exception e) {
+ fail("Unexpected exception" + e.getMessage());
+ }
+ }
+
+ protected void tearDown() throws Exception {
+ factory = null;
+ builder = null;
+ super.tearDown();
+ }
+
+ /**
+ * Runs the test case.
+ * @throws Throwable Any uncaught exception causes test to fail
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getPublicId",
+ args = {}
+ )
+ public void testGetPublicId() throws Throwable {
+ Document doc;
+ DocumentType docType;
+ DOMImplementation domImpl;
+ String publicId;
+ String nullNS = null;
+
+ doc = (Document) load("staffNS", builder);
+ domImpl = doc.getImplementation();
+ docType = domImpl.createDocumentType("l2:root", "PUB", nullNS);
+ publicId = docType.getPublicId();
+ assertEquals("documenttypepublicid01", "PUB", publicId);
+ }
+
+}
+
diff --git a/xml/src/test/java/tests/org/w3c/dom/DocumentTypeSystemId.java b/xml/src/test/java/tests/org/w3c/dom/DocumentTypeSystemId.java
new file mode 100644
index 0000000..fcad024
--- /dev/null
+++ b/xml/src/test/java/tests/org/w3c/dom/DocumentTypeSystemId.java
@@ -0,0 +1,95 @@
+
+/*
+This Java source file was generated by test-to-java.xsl
+and is a derived work from the source document.
+The source document contained the following notice:
+
+
+
+Copyright (c) 2001 World Wide Web Consortium,
+(Massachusetts Institute of Technology, Institut National de
+Recherche en Informatique et en Automatique, Keio University). All
+Rights Reserved. This program is distributed under the W3C's Software
+Intellectual Property License. This program is distributed in the
+hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE.
+
+See W3C License http://www.w3.org/Consortium/Legal/ for more details.
+
+
+*/
+
+package tests.org.w3c.dom;
+
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import org.w3c.dom.DocumentType;
+import org.w3c.dom.Document;
+import org.w3c.dom.DOMImplementation;
+
+import javax.xml.parsers.DocumentBuilder;
+
+/**
+ * The method getInternalSubset() returns the public identifier of the external subset.
+ *
+ * Create a new DocumentType node with the value "SYS" for its systemId and PUB for
+ * its publicId. Check the value of the systemId and pbulicId attributes.
+* @author IBM
+* @author Neil Delima
+* @see <a href="http://www.w3.org/TR/DOM-Level-2-Core/core#ID-Core-DocType-systemId">http://www.w3.org/TR/DOM-Level-2-Core/core#ID-Core-DocType-systemId</a>
+*/
+@TestTargetClass(DocumentType.class)
+public final class DocumentTypeSystemId extends DOMTestCase {
+ DOMDocumentBuilderFactory factory;
+
+ DocumentBuilder builder;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ try {
+ factory = new DOMDocumentBuilderFactory(DOMDocumentBuilderFactory
+ .getConfiguration1());
+ builder = factory.getBuilder();
+ } catch (Exception e) {
+ fail("Unexpected exception" + e.getMessage());
+ }
+ }
+
+ protected void tearDown() throws Exception {
+ factory = null;
+ builder = null;
+ super.tearDown();
+ }
+
+
+ /**
+ * Runs the test case.
+ * @throws Throwable Any uncaught exception causes test to fail
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getSystemId",
+ args = {}
+ )
+ public void testGetSystemId() throws Throwable {
+ Document doc;
+ DocumentType docType;
+ DOMImplementation domImpl;
+ String publicId;
+ String systemId;
+ doc = (Document) load("staffNS", builder);
+ domImpl = doc.getImplementation();
+ docType = domImpl.createDocumentType("l2:root", "PUB", "SYS");
+ publicId = docType.getPublicId();
+ systemId = docType.getSystemId();
+ assertEquals("documenttypepublicid01", "PUB", publicId);
+ assertEquals("documenttypesystemid01", "SYS", systemId);
+ }
+
+}
+
diff --git a/xml/src/test/java/tests/org/w3c/dom/ElementGetAttributeNS.java b/xml/src/test/java/tests/org/w3c/dom/ElementGetAttributeNS.java
new file mode 100644
index 0000000..8505459
--- /dev/null
+++ b/xml/src/test/java/tests/org/w3c/dom/ElementGetAttributeNS.java
@@ -0,0 +1,89 @@
+
+/*
+This Java source file was generated by test-to-java.xsl
+and is a derived work from the source document.
+The source document contained the following notice:
+
+
+
+Copyright (c) 2001-2004 World Wide Web Consortium,
+(Massachusetts Institute of Technology, Institut National de
+Recherche en Informatique et en Automatique, Keio University). All
+Rights Reserved. This program is distributed under the W3C's Software
+Intellectual Property License. This program is distributed in the
+hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE.
+
+See W3C License http://www.w3.org/Consortium/Legal/ for more details.
+
+
+*/
+
+package tests.org.w3c.dom;
+
+import dalvik.annotation.TestTargetClass;
+
+import javax.xml.parsers.DocumentBuilder;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+
+/**
+ * The method getAttributeNS retrieves an attribute value by local name and namespace URI.
+ * Using the getAttributeNodeNS, retreive and verify the value of the default
+ * attribute node.
+ *
+* @author IBM
+* @author Neil Delima
+* @see <a href="http://www.w3.org/TR/DOM-Level-2-Core/core#ID-ElGetAttrNS">http://www.w3.org/TR/DOM-Level-2-Core/core#ID-ElGetAttrNS</a>
+* @see <a href="http://www.w3.org/Bugs/Public/show_bug.cgi?id=259">http://www.w3.org/Bugs/Public/show_bug.cgi?id=259</a>
+*/
+@TestTargetClass(Element.class)
+public final class ElementGetAttributeNS extends DOMTestCase {
+
+ DOMDocumentBuilderFactory factory;
+
+ DocumentBuilder builder;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ try {
+ factory = new DOMDocumentBuilderFactory(DOMDocumentBuilderFactory
+ .getConfiguration2());
+ builder = factory.getBuilder();
+ } catch (Exception e) {
+ fail("Unexpected exception" + e.getMessage());
+ }
+ }
+
+ protected void tearDown() throws Exception {
+ factory = null;
+ builder = null;
+ super.tearDown();
+ }
+
+ /**
+ * Runs the test case.
+ * @throws Throwable Any uncaught exception causes test to fail
+ */
+// Assumes validation.
+// public void testGetAttributeNS() throws Throwable {
+// Document doc;
+// Element element;
+// String attrValue;
+// NodeList childList;
+// String nullNS = null;
+//
+// doc = (Document) load("staffNS", builder);
+// childList = doc.getElementsByTagNameNS("http://www.nist.gov",
+// "employee");
+// element = (Element) childList.item(1);
+// attrValue = element.getAttributeNS(nullNS, "defaultAttr");
+// assertEquals("elementgetattributens02", "defaultVal", attrValue);
+// }
+
+}
+
diff --git a/xml/src/test/java/tests/org/w3c/dom/ElementGetAttributeNodeNS.java b/xml/src/test/java/tests/org/w3c/dom/ElementGetAttributeNodeNS.java
new file mode 100644
index 0000000..7760ba8
--- /dev/null
+++ b/xml/src/test/java/tests/org/w3c/dom/ElementGetAttributeNodeNS.java
@@ -0,0 +1,139 @@
+package tests.org.w3c.dom;
+
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import org.w3c.dom.Element;
+import org.w3c.dom.Document;
+import org.w3c.dom.Attr;
+
+import javax.xml.parsers.DocumentBuilder;
+
+/**
+ * The method getAttributeNodeNS retrieves an Attr node by local name and
+ * namespace URI. Create a new element node and add 2 new attribute nodes to it
+ * that have the same local name but different namespaceURIs and prefixes.
+ * Retrieve an attribute using namespace and localname and check its value, name
+ * and namespaceURI.
+ *
+ * @author IBM
+ * @author Neil Delima
+ * @see <a
+ * href="http://www.w3.org/TR/DOM-Level-2-Core/core#ID-ElGetAtNodeNS">http://www.w3.org/TR/DOM-Level-2-Core/core#ID-ElGetAtNodeNS</a>
+ */
+@TestTargetClass(Element.class)
+public final class ElementGetAttributeNodeNS extends DOMTestCase {
+
+ DOMDocumentBuilderFactory factory;
+
+ DocumentBuilder builder;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ try {
+ factory = new DOMDocumentBuilderFactory(DOMDocumentBuilderFactory
+ .getConfiguration2());
+ builder = factory.getBuilder();
+ } catch (Exception e) {
+ fail("Unexpected exception" + e.getMessage());
+ }
+ }
+
+ protected void tearDown() throws Exception {
+ factory = null;
+ builder = null;
+ super.tearDown();
+ }
+
+ /**
+ * Runs the test case.
+ *
+ * @throws Throwable
+ * Any uncaught exception causes test to fail
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Doesn't verify DOMException.",
+ method = "getAttributeNodeNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testGetAttributeNodeNS1() throws Throwable {
+ Document doc;
+ Element element;
+ Attr attribute1;
+ Attr attribute2;
+
+
+ Attr attribute;
+ String attrValue;
+ String attrName;
+ String attNodeName;
+ String attrLocalName;
+ String attrNS;
+ doc = (Document) load("staffNS", builder);
+ element = doc.createElementNS("namespaceURI", "root");
+ attribute1 = doc.createAttributeNS("http://www.w3.org/DOM/Level2",
+ "l2:att");
+ element.setAttributeNodeNS(attribute1);
+ attribute2 = doc.createAttributeNS("http://www.w3.org/DOM/Level1",
+ "att");
+ element.setAttributeNodeNS(attribute2);
+ attribute = element.getAttributeNodeNS("http://www.w3.org/DOM/Level2",
+ "att");
+ attrValue = attribute.getNodeValue();
+ attrName = attribute.getName();
+ attNodeName = attribute.getNodeName();
+ attrLocalName = attribute.getLocalName();
+ attrNS = attribute.getNamespaceURI();
+ assertEquals("elementgetattributenodens01_attrValue", "", attrValue);
+ assertEquals("elementgetattributenodens01_attrName", "l2:att", attrName);
+ assertEquals("elementgetattributenodens01_attrNodeName", "l2:att",
+ attNodeName);
+ assertEquals("elementgetattributenodens01_attrLocalName", "att",
+ attrLocalName);
+ assertEquals("elementgetattributenodens01_attrNs",
+ "http://www.w3.org/DOM/Level2", attrNS);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Doesn't verify DOMException.",
+ method = "getAttributeNodeNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testGetAttributeNodeNS2() throws Throwable {
+ Document doc;
+ Element element;
+ Attr attribute;
+
+ String attrValue;
+ doc = (Document) load("staffNS", builder);
+ element = doc.createElementNS("namespaceURI", "root");
+ attribute = doc.createAttributeNS("http://www.w3.org/DOM/Level2",
+ "l2:att");
+ element.setAttributeNodeNS(attribute);
+ attribute = element.getAttributeNodeNS("http://www.w3.org/DOM/Level2",
+ "att");
+ attrValue = attribute.getNodeValue();
+ assertEquals("elementgetattributenodens02", "", attrValue);
+ }
+
+// Assumes validation.
+// public void testGetAttributeNodeNS3() throws Throwable {
+// Document doc;
+// Element element;
+// Attr attribute;
+// String attrValue;
+// NodeList childList;
+// String nullNS = null;
+//
+// doc = (Document) load("staffNS", builder);
+// childList = doc.getElementsByTagNameNS("http://www.nist.gov",
+// "employee");
+// element = (Element) childList.item(1);
+// attribute = element.getAttributeNodeNS(nullNS, "defaultAttr");
+// attrValue = attribute.getNodeValue();
+// assertEquals("elementgetattributenodens03", "defaultVal", attrValue);
+// }
+}
diff --git a/xml/src/test/java/tests/org/w3c/dom/ElementGetElementsByTagNameNS.java b/xml/src/test/java/tests/org/w3c/dom/ElementGetElementsByTagNameNS.java
new file mode 100644
index 0000000..f03007a
--- /dev/null
+++ b/xml/src/test/java/tests/org/w3c/dom/ElementGetElementsByTagNameNS.java
@@ -0,0 +1,122 @@
+package tests.org.w3c.dom;
+
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import org.w3c.dom.Element;
+import org.w3c.dom.Document;
+import org.w3c.dom.NodeList;
+
+import javax.xml.parsers.DocumentBuilder;
+
+/**
+ * The method getElementsByTagNameNS returns a NodeList of all the Elements with
+ * a given local name and namespace URI in the order in which they are
+ * encountered in a preorder traversal of the Document tree. Invoke
+ * getElementsByTagNameNS on the documentElement with values for namespaceURI
+ * '*' and localName '*'. Verify if this returns a nodeList of 0 elements.
+ *
+ * @author IBM
+ * @author Neil Delima
+ * @see <a
+ * href="http://www.w3.org/TR/DOM-Level-2-Core/core#ID-getElBTNNS">http://www.w3.org/TR/DOM-Level-2-Core/core#ID-getElBTNNS</a>
+ */
+@TestTargetClass(Element.class)
+public final class ElementGetElementsByTagNameNS extends DOMTestCase {
+
+ DOMDocumentBuilderFactory factory;
+
+ DocumentBuilder builder;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ try {
+ factory = new DOMDocumentBuilderFactory(DOMDocumentBuilderFactory
+ .getConfiguration2());
+ builder = factory.getBuilder();
+ } catch (Exception e) {
+ fail("Unexpected exception" + e.getMessage());
+ }
+ }
+
+ protected void tearDown() throws Exception {
+ factory = null;
+ builder = null;
+ super.tearDown();
+ }
+
+ /**
+ * Runs the test case.
+ *
+ * @throws Throwable
+ * Any uncaught exception causes test to fail
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Doesn't verify DOMException.",
+ method = "getElementsByTagNameNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testGetElementsByTagNameNS1() throws Throwable {
+ Document doc;
+ Element element;
+ NodeList elementList;
+ doc = (Document) load("staffNS", builder);
+ element = doc.getDocumentElement();
+ elementList = element.getElementsByTagNameNS("**", "*");
+ assertEquals("elementgetelementsbytagnamens02", 0, elementList
+ .getLength());
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Doesn't verify DOMException.",
+ method = "getElementsByTagNameNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testGetElementsByTagNameNS4() throws Throwable {
+ Document doc;
+ Element element;
+ Element child1;
+ Element child2;
+ Element child3;
+
+ NodeList elementList;
+ String nullNS = null;
+
+ doc = (Document) load("staffNS", builder);
+ element = doc.createElementNS("http://www.w3.org/DOM", "root");
+ child1 = doc.createElementNS("http://www.w3.org/DOM/Level1",
+ "dom:child");
+ child2 = doc.createElementNS(nullNS, "child");
+ child3 = doc.createElementNS("http://www.w3.org/DOM/Level2",
+ "dom:child");
+ element.appendChild(child1);
+ element.appendChild(child2);
+ element.appendChild(child3);
+ elementList = element.getElementsByTagNameNS(nullNS, "child");
+ assertEquals("elementgetelementsbytagnamens04_1", 1, elementList
+ .getLength());
+ elementList = element.getElementsByTagNameNS("*", "child");
+ assertEquals("elementgetelementsbytagnamens04_2", 3, elementList
+ .getLength());
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Doesn't verify DOMException.",
+ method = "getElementsByTagNameNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testGetElementsByTagNameNS5() throws Throwable {
+ Document doc;
+ Element element;
+ NodeList elementList;
+ doc = (Document) load("staffNS", builder);
+ element = doc.getDocumentElement();
+ elementList = element.getElementsByTagNameNS(
+ "http://www.altavista.com", "*");
+ assertEquals("elementgetelementsbytagnamens05", 1, elementList
+ .getLength());
+ }
+}
diff --git a/xml/src/test/java/tests/org/w3c/dom/ElementHasAttribute.java b/xml/src/test/java/tests/org/w3c/dom/ElementHasAttribute.java
new file mode 100644
index 0000000..711a1ab
--- /dev/null
+++ b/xml/src/test/java/tests/org/w3c/dom/ElementHasAttribute.java
@@ -0,0 +1,123 @@
+package tests.org.w3c.dom;
+
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import org.w3c.dom.Element;
+import org.w3c.dom.Document;
+import org.w3c.dom.Attr;
+
+import javax.xml.parsers.DocumentBuilder;
+
+/**
+ * The method hasAttribute returns true when an attribute with a given name is
+ * specified on this element or has a default value, false otherwise Invoke the
+ * hasAttribute method to check if the documentElement has attributres.
+ *
+ * @author IBM
+ * @author Neil Delima
+ * @see <a
+ * href="http://www.w3.org/TR/DOM-Level-2-Core/core#ID-NodeHasAttrs">http://www.w3.org/TR/DOM-Level-2-Core/core#ID-NodeHasAttrs</a>
+ */
+@TestTargetClass(Element.class)
+public final class ElementHasAttribute extends DOMTestCase {
+
+ DOMDocumentBuilderFactory factory;
+
+ DocumentBuilder builder;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ try {
+ factory = new DOMDocumentBuilderFactory(DOMDocumentBuilderFactory
+ .getConfiguration1());
+ builder = factory.getBuilder();
+ } catch (Exception e) {
+ fail("Unexpected exception" + e.getMessage());
+ }
+ }
+
+ protected void tearDown() throws Exception {
+ factory = null;
+ builder = null;
+ super.tearDown();
+ }
+
+ /**
+ * Runs the test case.
+ *
+ * @throws Throwable
+ * Any uncaught exception causes test to fail
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies hasAttribute method with empty string as a parameter.",
+ method = "hasAttribute",
+ args = {java.lang.String.class}
+ )
+ public void testHasAttribute1() throws Throwable {
+ Document doc;
+ Element element;
+ boolean state;
+ doc = (Document) load("staff", builder);
+ element = doc.getDocumentElement();
+ state = element.hasAttribute("");
+ assertFalse("elementhasattribute01", state);
+ }
+
+// Assumes validation.
+// public void testHasAttribute2() throws Throwable {
+// Document doc;
+// Element element;
+// boolean state;
+// NodeList elementList;
+// doc = (Document) load("staffNS", builder);
+// elementList = doc.getElementsByTagName("emp:employee");
+// element = (Element) elementList.item(0);
+// assertNotNull("empEmployeeNotNull", element);
+// state = element.hasAttribute("defaultAttr");
+// assertTrue("elementhasattribute02", state);
+// }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies positive functionality.",
+ method = "hasAttribute",
+ args = {java.lang.String.class}
+ )
+ public void testHasAttribute3() throws Throwable {
+ Document doc;
+ Element element;
+ boolean state;
+ Attr attribute;
+
+ doc = (Document) load("staff", builder);
+ element = doc.createElement("address");
+ attribute = doc.createAttribute("domestic");
+ state = element.hasAttribute("domestic");
+ assertFalse("elementhasattribute03_False", state);
+ element.setAttributeNode(attribute);
+ state = element.hasAttribute("domestic");
+ assertTrue("elementhasattribute03_True", state);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies positive functionality.",
+ method = "hasAttribute",
+ args = {java.lang.String.class}
+ )
+ public void testHasAttribute4() throws Throwable {
+ Document doc;
+ Element element;
+ boolean state;
+ Attr attribute;
+
+ doc = (Document) load("staff", builder);
+ element = doc.createElement("address");
+ attribute = doc.createAttribute("domestic");
+ element.setAttributeNode(attribute);
+ state = element.hasAttribute("domestic");
+ assertTrue("elementhasattribute04", state);
+ }
+}
diff --git a/xml/src/test/java/tests/org/w3c/dom/ElementHasAttributeNS.java b/xml/src/test/java/tests/org/w3c/dom/ElementHasAttributeNS.java
new file mode 100644
index 0000000..e0c9fd9
--- /dev/null
+++ b/xml/src/test/java/tests/org/w3c/dom/ElementHasAttributeNS.java
@@ -0,0 +1,139 @@
+/*
+ This Java source file was generated by test-to-java.xsl
+ and is a derived work from the source document.
+ The source document contained the following notice:
+
+
+
+ Copyright (c) 2001 World Wide Web Consortium,
+ (Massachusetts Institute of Technology, Institut National de
+ Recherche en Informatique et en Automatique, Keio University). All
+ Rights Reserved. This program is distributed under the W3C's Software
+ Intellectual Property License. This program is distributed in the
+ hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+ See W3C License http://www.w3.org/Consortium/Legal/ for more details.
+
+
+ */
+
+package tests.org.w3c.dom;
+
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import org.w3c.dom.Element;
+import org.w3c.dom.Document;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Attr;
+
+import javax.xml.parsers.DocumentBuilder;
+
+/**
+ * The method hasAttributeNS returns true when an attribute with a given local
+ * name and namespace URI is specified on this element or has a default value,
+ * false otherwise.
+ *
+ * Retreive the first employee element node. Invoke the hasAttributeNS method to
+ * check if it has the xmlns attribute that belongs to the namespace
+ * http://www.w3.org/2000/xmlns/.
+ *
+ * @author IBM
+ * @author Neil Delima
+ * @see <a
+ * href="http://www.w3.org/TR/DOM-Level-2-Core/core#ID-ElHasAttrNS">http://www.w3.org/TR/DOM-Level-2-Core/core#ID-ElHasAttrNS</a>
+ */
+@TestTargetClass(Element.class)
+public final class ElementHasAttributeNS extends DOMTestCase {
+
+ DOMDocumentBuilderFactory factory;
+
+ DocumentBuilder builder;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ try {
+ factory = new DOMDocumentBuilderFactory(DOMDocumentBuilderFactory
+ .getConfiguration2());
+ builder = factory.getBuilder();
+ } catch (Exception e) {
+ fail("Unexpected exception" + e.getMessage());
+ }
+ }
+
+ protected void tearDown() throws Exception {
+ factory = null;
+ builder = null;
+ super.tearDown();
+ }
+
+ /**
+ * Runs the test case.
+ *
+ * @throws Throwable
+ * Any uncaught exception causes test to fail
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Doesn't verify DOMException.",
+ method = "hasAttributeNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void _testHasAttributeNS1() throws Throwable {
+ Document doc;
+ Element element;
+ boolean state;
+ NodeList elementList;
+ doc = (Document) load("staffNS", builder);
+ elementList = doc.getElementsByTagNameNS("*", "employee");
+ element = (Element) elementList.item(0);
+ state = element
+ .hasAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns");
+ assertTrue("elementhasattributens01", state);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Doesn't verify DOMException.",
+ method = "hasAttributeNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testHasAttributeNS2() throws Throwable {
+ Document doc;
+ Element element;
+ boolean state;
+ Attr attribute;
+
+ doc = (Document) load("staff", builder);
+ element = doc.createElementNS("http://www.w3.org/DOM", "address");
+ attribute = doc.createAttributeNS("http://www.w3.org/DOM", "domestic");
+ element.setAttributeNode(attribute);
+ state = element.hasAttributeNS("http://www.w3.org/DOM", "domestic");
+ assertTrue("hasDomesticAttr", state);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Doesn't verify DOMException.",
+ method = "hasAttributeNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testHasAttributeNS3() throws Throwable {
+ Document doc;
+ Element element;
+ boolean state;
+ Attr attribute;
+
+ String nullNS = null;
+
+ doc = (Document) load("staff", builder);
+ element = doc.createElementNS("http://www.w3.org/DOM", "address");
+ assertNotNull("createElementNotNull", element);
+ attribute = doc.createAttributeNS(nullNS, "domestic");
+ element.setAttributeNode(attribute);
+ state = element.hasAttributeNS(nullNS, "domestic");
+ assertTrue("elementhasattributens03", state);
+ }
+}
diff --git a/xml/src/test/java/tests/org/w3c/dom/ElementRemoveAttributeNS.java b/xml/src/test/java/tests/org/w3c/dom/ElementRemoveAttributeNS.java
new file mode 100644
index 0000000..72c56e9
--- /dev/null
+++ b/xml/src/test/java/tests/org/w3c/dom/ElementRemoveAttributeNS.java
@@ -0,0 +1,80 @@
+package tests.org.w3c.dom;
+
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import org.w3c.dom.Element;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+
+import javax.xml.parsers.DocumentBuilder;
+
+/**
+ * The method removeAttributeNS removes an attribute by local name and namespace
+ * URI. Create a new element and add a new attribute node to it. Remove the
+ * attribute node using the removeAttributeNodeNS method. Check if the attribute
+ * was remove by invoking the hasAttributeNS method on the element and check if
+ * it returns false.
+ *
+ * @author IBM
+ * @author Neil Delima
+ * @see <a
+ * href="http://www.w3.org/TR/DOM-Level-2-Core/core#ID-ElRemAtNS">http://www.w3.org/TR/DOM-Level-2-Core/core#ID-ElRemAtNS</a>
+ */
+@TestTargetClass(Element.class)
+public final class ElementRemoveAttributeNS extends DOMTestCase {
+
+ DOMDocumentBuilderFactory factory;
+
+ DocumentBuilder builder;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ try {
+ factory = new DOMDocumentBuilderFactory(DOMDocumentBuilderFactory
+ .getConfiguration1());
+ builder = factory.getBuilder();
+ } catch (Exception e) {
+ fail("Unexpected exception" + e.getMessage());
+ }
+ }
+
+ protected void tearDown() throws Exception {
+ factory = null;
+ builder = null;
+ super.tearDown();
+ }
+
+ /**
+ * Runs the test case.
+ *
+ * @throws Throwable
+ * Any uncaught exception causes test to fail
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Doesn't verify DOMException.",
+ method = "removeAttributeNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testRemoveAttributeNS() throws Throwable {
+ Document doc;
+ Element element;
+ boolean state;
+ Attr attribute;
+
+ doc = (Document) load("staff", builder);
+ element = doc.createElementNS("http://www.w3.org/DOM", "elem");
+ attribute = doc.createAttributeNS(
+ "http://www.w3.org/DOM/Test/createAttributeNS", "attr");
+ element.setAttributeNodeNS(attribute);
+ element.removeAttributeNS(
+ "http://www.w3.org/DOM/Test/createAttributeNS", "attr");
+ state = element.hasAttributeNS(
+ "http://www.w3.org/DOM/Test/createAttributeNS", "attr");
+ assertFalse("elementremoveattributens01", state);
+ }
+
+}
diff --git a/xml/src/test/java/tests/org/w3c/dom/ElementSetAttributeNS.java b/xml/src/test/java/tests/org/w3c/dom/ElementSetAttributeNS.java
new file mode 100644
index 0000000..babd6f1
--- /dev/null
+++ b/xml/src/test/java/tests/org/w3c/dom/ElementSetAttributeNS.java
@@ -0,0 +1,266 @@
+package tests.org.w3c.dom;
+
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.w3c.dom.Element;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.DOMException;
+import org.w3c.dom.Node;
+
+import javax.xml.parsers.DocumentBuilder;
+
+/**
+ * The method setAttributeNS adds a new attribute. Create a new element and add
+ * a new attribute node to it using the setAttributeNS method. Check if the
+ * attribute was correctly set by invoking the getAttributeNodeNS method and
+ * checking the nodeName and nodeValue of the returned nodes.
+ *
+ * @author IBM
+ * @author Neil Delima
+ * @see <a
+ * href="http://www.w3.org/TR/DOM-Level-2-Core/core#ID-ElSetAttrNS">http://www.w3.org/TR/DOM-Level-2-Core/core#ID-ElSetAttrNS</a>
+ */
+@TestTargetClass(Element.class)
+public final class ElementSetAttributeNS extends DOMTestCase {
+
+ DOMDocumentBuilderFactory factory;
+
+ DocumentBuilder builder;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ try {
+ factory = new DOMDocumentBuilderFactory(DOMDocumentBuilderFactory
+ .getConfiguration2());
+ builder = factory.getBuilder();
+ } catch (Exception e) {
+ fail("Unexpected exception" + e.getMessage());
+ }
+ }
+
+ protected void tearDown() throws Exception {
+ factory = null;
+ builder = null;
+ super.tearDown();
+ }
+
+ /**
+ * Runs the test case.
+ *
+ * @throws Throwable
+ * Any uncaught exception causes test to fail
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Doesn't verify DOMException.",
+ method = "setAttributeNS",
+ args = {java.lang.String.class, java.lang.String.class, java.lang.String.class}
+ )
+ public void testSetAttributeNS1() throws Throwable {
+ Document doc;
+ Element element;
+ Attr attribute;
+ String attrName;
+ String attrValue;
+ doc = (Document) load("staff", builder);
+ element = doc.createElementNS("http://www.w3.org/DOM", "dom:elem");
+ element.setAttributeNS("http://www.w3.org/DOM/Test/setAttributeNS",
+ "attr", "value");
+ attribute = element.getAttributeNodeNS(
+ "http://www.w3.org/DOM/Test/setAttributeNS", "attr");
+ attrName = attribute.getNodeName();
+ attrValue = attribute.getNodeValue();
+ assertEquals("elementsetattributens01_attrName", "attr", attrName);
+ assertEquals("elementsetattributens01_attrValue", "value", attrValue);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Doesn't verify DOMException.",
+ method = "setAttributeNS",
+ args = {java.lang.String.class, java.lang.String.class, java.lang.String.class}
+ )
+ public void testSetAttributeNS2() throws Throwable {
+ Document doc;
+ Element element;
+ Attr attribute;
+ NodeList elementList;
+ String attrName;
+ String attrValue;
+ doc = (Document) load("staff", builder);
+ elementList = doc.getElementsByTagNameNS("*", "address");
+ element = (Element) elementList.item(0);
+ element.setAttributeNS("http://www.w3.org/DOM/Test/setAttributeNS",
+ "this:street", "Silver Street");
+ attribute = element.getAttributeNodeNS(
+ "http://www.w3.org/DOM/Test/setAttributeNS", "street");
+ attrName = attribute.getNodeName();
+ attrValue = attribute.getNodeValue();
+ assertEquals("elementsetattributens02_attrName", "this:street",
+ attrName);
+ assertEquals("elementsetattributens02_attrValue", "Silver Street",
+ attrValue);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Doesn't verify DOMException.",
+ method = "setAttributeNS",
+ args = {java.lang.String.class, java.lang.String.class, java.lang.String.class}
+ )
+ public void testSetAttributeNS3() throws Throwable {
+ Document doc;
+ Element element;
+ Attr attribute;
+ NodeList elementList;
+ String attrName;
+ String attrValue;
+ doc = (Document) load("staffNS", builder);
+ elementList = doc.getElementsByTagName("emp:employee");
+ element = (Element) elementList.item(0);
+ assertNotNull("empEmployeeNotNull", element);
+ element.setAttributeNS("http://www.w3.org/DOM/Test/1", "defaultAttr",
+ "default1");
+ element.setAttributeNS("http://www.w3.org/DOM/Test/2", "defaultAttr",
+ "default2");
+ attribute = element.getAttributeNodeNS("http://www.w3.org/DOM/Test/1",
+ "defaultAttr");
+ attrName = attribute.getNodeName();
+ attrValue = attribute.getNodeValue();
+ assertEquals("elementsetattributens03_attrName", "defaultAttr",
+ attrName);
+ assertEquals("elementsetattributens03_attrValue", "default1", attrValue);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies DOMException with INVALID_CHARACTER_ERR.",
+ method = "setAttributeNS",
+ args = {java.lang.String.class, java.lang.String.class, java.lang.String.class}
+ )
+ public void testSetAttributeNS4() throws Throwable {
+ Document doc;
+ Element element;
+ String qualifiedName;
+ List<String> qualifiedNames = new ArrayList<String>();
+ qualifiedNames.add("/");
+ qualifiedNames.add("//");
+ qualifiedNames.add("\\");
+ qualifiedNames.add(";");
+ qualifiedNames.add("&");
+ qualifiedNames.add("*");
+ qualifiedNames.add("]]");
+ qualifiedNames.add(">");
+ qualifiedNames.add("<");
+
+ doc = (Document) load("staffNS", builder);
+ element = doc.createElementNS("http://www.w3.org/DOM/Test/L2",
+ "dom:elem");
+ for (int indexN10058 = 0; indexN10058 < qualifiedNames.size(); indexN10058++) {
+ qualifiedName = (String) qualifiedNames.get(indexN10058);
+
+ {
+ boolean success = false;
+ try {
+ element.setAttributeNS("http://www.w3.org/DOM/Test/L2",
+ qualifiedName, "test");
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.INVALID_CHARACTER_ERR);
+ }
+ assertTrue("elementsetattributens04", success);
+ }
+ }
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies DOMException with NAMESPACE_ERR code.",
+ method = "setAttributeNS",
+ args = {java.lang.String.class, java.lang.String.class, java.lang.String.class}
+ )
+ public void testSetAttributeNS5() throws Throwable {
+ Document doc;
+ Element element;
+ String nullNS = null;
+
+ doc = (Document) load("staffNS", builder);
+ element = doc.createElementNS("http://www.w3.org/DOM/Test/L2",
+ "dom:elem");
+
+ {
+ boolean success = false;
+ try {
+ element.setAttributeNS(nullNS, "dom:root", "test");
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.NAMESPACE_ERR);
+ }
+ assertTrue("elementsetattributens05", success);
+ }
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies DOMException with NAMESPACE_ERR code.",
+ method = "setAttributeNS",
+ args = {java.lang.String.class, java.lang.String.class, java.lang.String.class}
+ )
+ public void testSetAttributeNS8() throws Throwable {
+ Document doc;
+ Element element;
+ doc = (Document) load("staffNS", builder);
+ element = doc.createElementNS("http://www.w3.org/DOMTest/level2",
+ "dom:elem");
+
+ {
+ boolean success = false;
+ try {
+ element.setAttributeNS("http://www.w3.org/DOMTest/level2",
+ "xmlns", "test");
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.NAMESPACE_ERR);
+ }
+ assertTrue("elementsetattributens08_Err1", success);
+ }
+
+ {
+ boolean success = false;
+ try {
+ element.setAttributeNS("http://www.w3.org/DOMTest/level2",
+ "xmlns:root", "test");
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.NAMESPACE_ERR);
+ }
+ assertTrue("elementsetattributens08_Err2", success);
+ }
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies DOMException with NAMESPACE_ERR code.",
+ method = "setAttributeNS",
+ args = {java.lang.String.class, java.lang.String.class, java.lang.String.class}
+ )
+ public void testSetAttributeNSURINull() throws Throwable {
+ String namespaceURI = null;
+
+ String qualifiedName = "emp:qualifiedName";
+ Document doc;
+ NodeList elementList;
+ Node testAddr;
+ doc = (Document) load("staff", builder);
+ elementList = doc.getElementsByTagName("employee");
+ testAddr = elementList.item(0);
+
+ {
+ boolean success = false;
+ try {
+ ((Element) /*Node */testAddr).setAttributeNS(namespaceURI, qualifiedName, "newValue");
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.NAMESPACE_ERR);
+ }
+ assertTrue("throw_NAMESPACE_ERR", success);
+ }
+ }
+}
diff --git a/xml/src/test/java/tests/org/w3c/dom/ElementSetAttributeNodeNS.java b/xml/src/test/java/tests/org/w3c/dom/ElementSetAttributeNodeNS.java
new file mode 100644
index 0000000..2a115e0
--- /dev/null
+++ b/xml/src/test/java/tests/org/w3c/dom/ElementSetAttributeNodeNS.java
@@ -0,0 +1,276 @@
+/*
+ This Java source file was generated by test-to-java.xsl
+ and is a derived work from the source document.
+ The source document contained the following notice:
+
+
+
+ Copyright (c) 2001 World Wide Web Consortium,
+ (Massachusetts Institute of Technology, Institut National de
+ Recherche en Informatique et en Automatique, Keio University). All
+ Rights Reserved. This program is distributed under the W3C's Software
+ Intellectual Property License. This program is distributed in the
+ hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+ See W3C License http://www.w3.org/Consortium/Legal/ for more details.
+
+
+ */
+
+package tests.org.w3c.dom;
+
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import org.w3c.dom.Element;
+import org.w3c.dom.Document;
+import org.w3c.dom.Attr;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.DOMException;
+import org.w3c.dom.EntityReference;
+
+import javax.xml.parsers.DocumentBuilder;
+
+/**
+ * Testing Element.setAttributeNodeNS: If an attribute with that local name and
+ * that namespace URI is already present in the element, it is replaced by the
+ * new one. Create a new element and two new attribute nodes (in the same
+ * namespace and same localNames). Add the two new attribute nodes to the
+ * element node using the setAttributeNodeNS method. Check that only one
+ * attribute is added, check the value of this attribute.
+ *
+ * @author IBM
+ * @author Neil Delima
+ * @see <a
+ * href="http://www.w3.org/TR/DOM-Level-2-Core/core#ID-ElSetAtNodeNS">http://www.w3.org/TR/DOM-Level-2-Core/core#ID-ElSetAtNodeNS</a>
+ */
+@TestTargetClass(Element.class)
+public final class ElementSetAttributeNodeNS extends DOMTestCase {
+
+ DOMDocumentBuilderFactory factory;
+
+ DocumentBuilder builder;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ try {
+ factory = new DOMDocumentBuilderFactory(DOMDocumentBuilderFactory
+ .getConfiguration2());
+ builder = factory.getBuilder();
+ } catch (Exception e) {
+ fail("Unexpected exception" + e.getMessage());
+ }
+ }
+
+ protected void tearDown() throws Exception {
+ factory = null;
+ builder = null;
+ super.tearDown();
+ }
+
+ /**
+ * Runs the test case.
+ *
+ * @throws Throwable
+ * Any uncaught exception causes test to fail
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Doesn't verify DOMException.",
+ method = "setAttributeNodeNS",
+ args = {org.w3c.dom.Attr.class}
+ )
+ public void testSetAttributeNodeNS1() throws Throwable {
+ Document doc;
+ Element element;
+ Attr attribute1;
+ Attr attribute2;
+ Attr attrNode;
+ String attrName;
+ String attrNS;
+
+ NamedNodeMap attributes;
+
+ int length;
+ doc = (Document) load("staff", builder);
+ element = doc.createElementNS("http://www.w3.org/DOM/Test/Level2",
+ "new:element");
+ attribute1 = doc.createAttributeNS("http://www.w3.org/DOM/Test/att1",
+ "p1:att");
+ attribute2 = doc.createAttributeNS("http://www.w3.org/DOM/Test/att1",
+ "p2:att");
+ attribute2.setValue("value2");
+ element.setAttributeNodeNS(attribute1);
+ element.setAttributeNodeNS(attribute2);
+ attrNode = element.getAttributeNodeNS(
+ "http://www.w3.org/DOM/Test/att1", "att");
+ attrName = attrNode.getNodeName();
+ attrNS = attrNode.getNamespaceURI();
+ assertEquals("elementsetattributenodens01_attrName", "p2:att", attrName);
+ assertEquals("elementsetattributenodens01_attrNS",
+ "http://www.w3.org/DOM/Test/att1", attrNS);
+ attributes = element.getAttributes();
+ length = (int) attributes.getLength();
+ assertEquals("length", 1, length);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Doesn't verify DOMException.",
+ method = "setAttributeNodeNS",
+ args = {org.w3c.dom.Attr.class}
+ )
+ public void testSetAttributeNodeNS2() throws Throwable {
+ Document doc;
+ Element element;
+ Element element2;
+ Attr attribute;
+ Attr attributeCloned;
+ Attr newAttr;
+ NodeList elementList;
+ String attrName;
+ String attrValue;
+ String nullNS = null;
+
+ doc = (Document) load("staffNS", builder);
+ elementList = doc.getElementsByTagNameNS("http://www.nist.gov",
+ "address");
+ element = (Element) elementList.item(1);
+ attribute = element.getAttributeNodeNS(nullNS, "street");
+ attributeCloned = (Attr) attribute.cloneNode(true);
+ element2 = (Element) elementList.item(2);
+ newAttr = element2.setAttributeNodeNS(attributeCloned);
+ attrName = newAttr.getNodeName();
+ attrValue = newAttr.getNodeValue();
+ assertEquals("elementsetattributenodens02_attrName", "street", attrName);
+ assertEquals("elementsetattributenodens02_attrValue", "Yes", attrValue);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies DOMException with INUSE_ATTRIBUTE_ERR code.",
+ method = "setAttributeNodeNS",
+ args = {org.w3c.dom.Attr.class}
+ )
+ public void testSetAttributeNodeNS3() throws Throwable {
+ Document doc;
+ Element element1;
+ Element element2;
+ Attr attribute;
+
+ NodeList elementList;
+ String nullNS = null;
+
+ doc = (Document) load("staffNS", builder);
+ elementList = doc.getElementsByTagNameNS("http://www.nist.gov",
+ "address");
+ element1 = (Element) elementList.item(1);
+ attribute = element1.getAttributeNodeNS(nullNS, "street");
+ element2 = (Element) elementList.item(2);
+
+ {
+ boolean success = false;
+ try {
+ element2.setAttributeNodeNS(attribute);
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.INUSE_ATTRIBUTE_ERR);
+ }
+ assertTrue("elementsetattributenodens03", success);
+ }
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies DOMException with INUSE_ATTRIBUTE_ERR code.",
+ method = "setAttributeNodeNS",
+ args = {org.w3c.dom.Attr.class}
+ )
+ public void testSetAttributeNodeNS4() throws Throwable {
+ Document doc;
+ Element element1;
+ Element element2;
+ Attr attribute;
+
+ doc = (Document) load("staffNS", builder);
+ element1 = doc.createElementNS("http://www.w3.org/DOM/Test", "elem1");
+ element2 = doc.createElementNS("http://www.w3.org/DOM/Test", "elem2");
+ attribute = doc.createAttributeNS("http://www.w3.org/DOM/Test", "attr");
+ element1.setAttributeNodeNS(attribute);
+
+ {
+ boolean success = false;
+ try {
+ element2.setAttributeNodeNS(attribute);
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.INUSE_ATTRIBUTE_ERR);
+ }
+ assertTrue("elementsetattributenodens04", success);
+ }
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies DOMException with WRONG_DOCUMENT_ERR code.",
+ method = "setAttributeNodeNS",
+ args = {org.w3c.dom.Attr.class}
+ )
+ public void testSetAttributeNodeNS5() throws Throwable {
+ Document doc;
+ Document docAlt;
+ Element element;
+ Attr attribute;
+
+ doc = (Document) load("staffNS", builder);
+ docAlt = (Document) load("staffNS", builder);
+ element = doc.createElementNS("http://www.w3.org/DOM/Test", "elem1");
+ attribute = docAlt.createAttributeNS("http://www.w3.org/DOM/Test",
+ "attr");
+
+ {
+ boolean success = false;
+ try {
+ element.setAttributeNodeNS(attribute);
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.WRONG_DOCUMENT_ERR);
+ }
+ assertTrue("throw_WRONG_DOCUMENT_ERR", success);
+ }
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies DOMException with NO_MODIFICATION_ALLOWED_ERR code.",
+ method = "setAttributeNodeNS",
+ args = {org.w3c.dom.Attr.class}
+ )
+ public void _testSetAttributeNodeNS6() throws Throwable {
+ Document doc;
+ Element element;
+ Attr attribute;
+ Attr attribute2;
+ EntityReference entRef;
+ NodeList elementList;
+
+ doc = (Document) load("staffNS", builder);
+ element = doc.createElementNS("http://www.w3.org/DOM/Test", "elem1");
+ attribute = doc.createAttributeNS("http://www.w3.org/DOM/Test", "attr");
+ entRef = doc.createEntityReference("ent4");
+ attribute.appendChild(entRef);
+ element.setAttributeNodeNS(attribute);
+ elementList = entRef.getChildNodes();
+ element = (Element) elementList.item(0);
+ attribute2 = doc.createAttributeNS("http://www.w3.org/DOM/Test",
+ "attr2");
+
+ {
+ boolean success = false;
+ try {
+ element.setAttributeNodeNS(attribute2);
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.NO_MODIFICATION_ALLOWED_ERR);
+ }
+ assertTrue("elementsetattributenodens06", success);
+ }
+ }
+
+}
diff --git a/xml/src/test/java/tests/org/w3c/dom/GetAttributeNS.java b/xml/src/test/java/tests/org/w3c/dom/GetAttributeNS.java
new file mode 100644
index 0000000..ae5936c
--- /dev/null
+++ b/xml/src/test/java/tests/org/w3c/dom/GetAttributeNS.java
@@ -0,0 +1,187 @@
+/*
+ This Java source file was generated by test-to-java.xsl
+ and is a derived work from the source document.
+ The source document contained the following notice:
+
+
+
+ Copyright (c) 2001-2003 World Wide Web Consortium,
+ (Massachusetts Institute of Technology, Institut National de
+ Recherche en Informatique et en Automatique, Keio University). All
+ Rights Reserved. This program is distributed under the W3C's Software
+ Intellectual Property License. This program is distributed in the
+ hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+ See W3C License http://www.w3.org/Consortium/Legal/ for more details.
+
+
+ */
+
+package tests.org.w3c.dom;
+
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import org.w3c.dom.Element;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.NodeList;
+
+import javax.xml.parsers.DocumentBuilder;
+
+/**
+ * The "getAttributeNS(namespaceURI,localName)" method retrieves an attribute
+ * value by local name and NamespaceURI.
+ *
+ * Retrieve the first "emp:address" element. The value returned by the
+ * "getAttributeNS()" method should be the value "DISTRICT" since the attribute
+ * has a default value.
+ *
+ * @author NIST
+ * @author Mary Brady
+ * @see <a
+ * href="http://www.w3.org/TR/DOM-Level-2-Core/core#ID-ElGetAttrNS">http://www.w3.org/TR/DOM-Level-2-Core/core#ID-ElGetAttrNS</a>
+ * @see <a
+ * href="http://www.w3.org/Bugs/Public/show_bug.cgi?id=238">http://www.w3.org/Bugs/Public/show_bug.cgi?id=238</a>
+ */
+@TestTargetClass(Element.class)
+public final class GetAttributeNS extends DOMTestCase {
+
+ DOMDocumentBuilderFactory factory;
+
+ DocumentBuilder builder;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ try {
+ factory = new DOMDocumentBuilderFactory(DOMDocumentBuilderFactory
+ .getConfiguration2());
+ builder = factory.getBuilder();
+ } catch (Exception e) {
+ fail("Unexpected exception" + e.getMessage());
+ }
+ }
+
+ protected void tearDown() throws Exception {
+ factory = null;
+ builder = null;
+ super.tearDown();
+ }
+
+ /**
+ * Runs the test case.
+ *
+ * @throws Throwable
+ * Any uncaught exception causes test to fail
+ */
+// Assumes validation.
+// public void testGetAttributeNS1() throws Throwable {
+// String namespaceURI = "http://www.nist.gov";
+// String localName = "district";
+//
+// Document doc;
+// NodeList elementList;
+// Element testAddr;
+// String attrValue;
+// doc = (Document) load("staffNS", builder);
+// elementList = doc.getElementsByTagName("emp:address");
+// testAddr = (Element) elementList.item(0);
+// attrValue = testAddr.getAttributeNS(namespaceURI, localName);
+// assertEquals("attrValue", "DISTRICT", attrValue);
+// }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Doesn't verify DOMException.",
+ method = "getAttributeNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testGetAttributeNS2() throws Throwable {
+ String namespaceURI = "http://www.nist.gov";
+ String localName = "district";
+ String qualifiedName = "emp:district";
+ Document doc;
+ Attr newAttribute;
+ NodeList elementList;
+ Element testAddr;
+
+ String attrValue;
+ doc = (Document) load("staffNS", builder);
+ newAttribute = doc.createAttributeNS(namespaceURI, qualifiedName);
+ elementList = doc.getElementsByTagName("emp:address");
+ testAddr = (Element) elementList.item(0);
+ assertNotNull("empAddrNotNull", testAddr);
+ testAddr.setAttributeNodeNS(newAttribute);
+ elementList = doc.getElementsByTagName("emp:address");
+ testAddr = (Element) elementList.item(0);
+ attrValue = testAddr.getAttributeNS(namespaceURI, localName);
+ assertEquals("throw_Equals", "", attrValue);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Doesn't verify DOMException.",
+ method = "getAttributeNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testGetAttributeNS3() throws Throwable {
+ String namespaceURI = "http://www.nist.gov";
+ String localName = "domestic";
+ Document doc;
+ NodeList elementList;
+ Element testAddr;
+ String attrValue;
+ doc = (Document) load("staffNS", builder);
+ elementList = doc.getElementsByTagName("emp:address");
+ testAddr = (Element) elementList.item(0);
+ assertNotNull("empAddrNotNull", testAddr);
+ testAddr.removeAttributeNS(namespaceURI, localName);
+ attrValue = testAddr.getAttributeNS(namespaceURI, localName);
+ assertEquals("throw_Equals", "", attrValue);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Doesn't verify DOMException.",
+ method = "getAttributeNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testGetAttributeNS4() throws Throwable {
+ String namespaceURI = "http://www.nist.gov";
+ String localName = "blank";
+ String qualifiedName = "emp:blank";
+ Document doc;
+
+ NodeList elementList;
+ Element testAddr;
+
+ String attrValue;
+ doc = (Document) load("staffNS", builder);
+ doc.createAttributeNS(namespaceURI, qualifiedName);
+ elementList = doc.getElementsByTagName("emp:address");
+ testAddr = (Element) elementList.item(0);
+ assertNotNull("empAddrNotNull", testAddr);
+ testAddr.setAttributeNS(namespaceURI, qualifiedName, "NewValue");
+ attrValue = testAddr.getAttributeNS(namespaceURI, localName);
+ assertEquals("throw_Equals", "NewValue", attrValue);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Doesn't verify DOMException.",
+ method = "getAttributeNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testGetAttributeNS5() throws Throwable {
+ Document doc;
+ NodeList elementList;
+ Element testAddr;
+ String attrValue;
+ doc = (Document) load("staffNS", builder);
+ elementList = doc.getElementsByTagName("emp:address");
+ testAddr = (Element) elementList.item(0);
+ assertNotNull("empAddrNotNull", testAddr);
+ attrValue = testAddr.getAttributeNS("http://www.nist.gov", "domestic");
+ assertEquals("attrValue", "Yes", attrValue);
+ }
+}
diff --git a/xml/src/test/java/tests/org/w3c/dom/GetAttributeNodeNS.java b/xml/src/test/java/tests/org/w3c/dom/GetAttributeNodeNS.java
new file mode 100644
index 0000000..7c72fe5
--- /dev/null
+++ b/xml/src/test/java/tests/org/w3c/dom/GetAttributeNodeNS.java
@@ -0,0 +1,121 @@
+/*
+ This Java source file was generated by test-to-java.xsl
+ and is a derived work from the source document.
+ The source document contained the following notice:
+
+
+
+ Copyright (c) 2001-2004 World Wide Web Consortium,
+ (Massachusetts Institute of Technology, Institut National de
+ Recherche en Informatique et en Automatique, Keio University). All
+ Rights Reserved. This program is distributed under the W3C's Software
+ Intellectual Property License. This program is distributed in the
+ hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+ See W3C License http://www.w3.org/Consortium/Legal/ for more details.
+
+
+ */
+
+package tests.org.w3c.dom;
+
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import org.w3c.dom.Element;
+import org.w3c.dom.Document;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Attr;
+
+import javax.xml.parsers.DocumentBuilder;
+
+/**
+ * The "getAttributeNodeNS(namespaceURI,localName)" method retrieves an
+ * attribute node by local name and NamespaceURI.
+ *
+ * Retrieve the first emp:address element node. The getAttributeNodeNS method
+ * returns an Attr node, the "value" can be examined to ensure the proper
+ * attribute node was retrieved. This attribute value should be null since there
+ * is no such attribute.
+ *
+ * @author NIST
+ * @author Mary Brady
+ * @see <a
+ * href="http://www.w3.org/TR/DOM-Level-2-Core/core#ID-ElGetAtNodeNS">http://www.w3.org/TR/DOM-Level-2-Core/core#ID-ElGetAtNodeNS</a>
+ */
+@TestTargetClass(Element.class)
+public final class GetAttributeNodeNS extends DOMTestCase {
+
+ DOMDocumentBuilderFactory factory;
+
+ DocumentBuilder builder;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ try {
+ factory = new DOMDocumentBuilderFactory(DOMDocumentBuilderFactory
+ .getConfiguration2());
+ builder = factory.getBuilder();
+ } catch (Exception e) {
+ fail("Unexpected exception" + e.getMessage());
+ }
+ }
+
+ protected void tearDown() throws Exception {
+ factory = null;
+ builder = null;
+ super.tearDown();
+ }
+
+ /**
+ * Runs the test case.
+ *
+ * @throws Throwable
+ * Any uncaught exception causes test to fail
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Doesn't verify DOMException.",
+ method = "getAttributeNodeNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testGetAttributeNodeNS1() throws Throwable {
+ String namespaceURI = "http://www.nist.gov";
+ String localName = "invalidlocalname";
+ Document doc;
+ NodeList elementList;
+ Element testAddr;
+ Attr attribute;
+ doc = (Document) load("staffNS", builder);
+ elementList = doc.getElementsByTagName("emp:address");
+ testAddr = (Element) elementList.item(0);
+ assertNotNull("empAddrNotNull", testAddr);
+ attribute = testAddr.getAttributeNodeNS(namespaceURI, localName);
+ assertNull("throw_Null", attribute);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Doesn't verify DOMException.",
+ method = "getAttributeNodeNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testGetAttributeNodeNS2() throws Throwable {
+ Document doc;
+ NodeList elementList;
+ Element testAddr;
+ Attr attribute;
+ String attrName;
+ doc = (Document) load("staffNS", builder);
+ elementList = doc.getElementsByTagName("emp:address");
+ testAddr = (Element) elementList.item(0);
+ assertNotNull("empAddrNotNull", testAddr);
+ attribute = testAddr.getAttributeNodeNS("http://www.nist.gov",
+ "domestic");
+ attrName = attribute.getNodeName();
+ assertEquals("attrName", "emp:domestic", attrName);
+ }
+}
diff --git a/xml/src/test/java/tests/org/w3c/dom/GetElementById.java b/xml/src/test/java/tests/org/w3c/dom/GetElementById.java
new file mode 100644
index 0000000..073df2f
--- /dev/null
+++ b/xml/src/test/java/tests/org/w3c/dom/GetElementById.java
@@ -0,0 +1,102 @@
+/*
+ This Java source file was generated by test-to-java.xsl
+ and is a derived work from the source document.
+ The source document contained the following notice:
+
+
+
+ Copyright (c) 2001-2003 World Wide Web Consortium,
+ (Massachusetts Institute of Technology, Institut National de
+ Recherche en Informatique et en Automatique, Keio University). All
+ Rights Reserved. This program is distributed under the W3C's Software
+ Intellectual Property License. This program is distributed in the
+ hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+ See W3C License http://www.w3.org/Consortium/Legal/ for more details.
+
+
+ */
+
+package tests.org.w3c.dom;
+
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import javax.xml.parsers.DocumentBuilder;
+
+/**
+ * The "getElementById(elementId)" method for a Document should return an
+ * element whose ID matches elementId.
+ *
+ * Invoke method getElementById(elementId) on this document with elementId
+ * equals "CANADA". Method should return an element whose tag name is
+ * "emp:address".
+ *
+ * @author NIST
+ * @author Mary Brady
+ * @see <a
+ * href="http://www.w3.org/TR/DOM-Level-2-Core/core#ID-104682815">http://www.w3.org/TR/DOM-Level-2-Core/core#ID-104682815</a>
+ * @see <a
+ * href="http://www.w3.org/Bugs/Public/show_bug.cgi?id=383">http://www.w3.org/Bugs/Public/show_bug.cgi?id=383</a>
+ */
+@TestTargetClass(Document.class)
+public final class GetElementById extends DOMTestCase {
+
+ DOMDocumentBuilderFactory factory;
+
+ DocumentBuilder builder;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ try {
+ factory = new DOMDocumentBuilderFactory(DOMDocumentBuilderFactory
+ .getConfiguration1());
+ builder = factory.getBuilder();
+ } catch (Exception e) {
+ fail("Unexpected exception" + e.getMessage());
+ }
+ }
+
+ protected void tearDown() throws Exception {
+ factory = null;
+ builder = null;
+ super.tearDown();
+ }
+
+ /**
+ * Runs the test case.
+ *
+ * @throws Throwable
+ * Any uncaught exception causes test to fail
+ */
+// Assumes validation.
+// public void testGetElementById1() throws Throwable {
+// Document doc;
+// Element element;
+// String tagname;
+// doc = (Document) load("staffNS", builder);
+// element = doc.getElementById("CANADA");
+// tagname = element.getTagName();
+// assertEquals("throw_Equals", "emp:address", tagname);
+// }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Doesn't verify getElementById method for existent element.",
+ method = "getElementById",
+ args = {java.lang.String.class}
+ )
+ public void testGetElementById2() throws Throwable {
+ Document doc;
+ Element element;
+ doc = (Document) load("staffNS", builder);
+ element = doc.getElementById("Cancun");
+ assertNull("throw_Null", element);
+ }
+}
diff --git a/xml/src/test/java/tests/org/w3c/dom/GetElementsByTagNameNS.java b/xml/src/test/java/tests/org/w3c/dom/GetElementsByTagNameNS.java
new file mode 100644
index 0000000..d5fa0bf
--- /dev/null
+++ b/xml/src/test/java/tests/org/w3c/dom/GetElementsByTagNameNS.java
@@ -0,0 +1,381 @@
+/*
+ This Java source file was generated by test-to-java.xsl
+ and is a derived work from the source document.
+ The source document contained the following notice:
+
+
+
+ Copyright (c) 2001 World Wide Web Consortium,
+ (Massachusetts Institute of Technology, Institut National de
+ Recherche en Informatique et en Automatique, Keio University). All
+ Rights Reserved. This program is distributed under the W3C's Software
+ Intellectual Property License. This program is distributed in the
+ hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+ See W3C License http://www.w3.org/Consortium/Legal/ for more details.
+
+
+ */
+
+package tests.org.w3c.dom;
+
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+import javax.xml.parsers.DocumentBuilder;
+
+/**
+ * The "getElementsByTagNameNS(namespaceURI,localName)" method for a Document
+ * should return a new NodeList of all Elements that have a namespace when local
+ * name is specified as ' '.
+ *
+ * Invoke method getElementsByTagNameNS(namespaceURI,localName) on this document
+ * with namespaceURI and localName as " ". Method should return a new NodeList
+ * of 37 elements.
+ *
+ * @author NIST
+ * @author Mary Brady
+ * @see <a
+ * href="http://www.w3.org/TR/DOM-Level-2-Core/core#ID-getElBTNNS">http://www.w3.org/TR/DOM-Level-2-Core/core#ID-getElBTNNS</a>
+ */
+@TestTargetClass(Document.class)
+public final class GetElementsByTagNameNS extends DOMTestCase {
+ DOMDocumentBuilderFactory factory;
+
+ DocumentBuilder builder;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ try {
+ factory = new DOMDocumentBuilderFactory(DOMDocumentBuilderFactory
+ .getConfiguration2());
+ builder = factory.getBuilder();
+ } catch (Exception e) {
+ fail("Unexpected exception" + e.getMessage());
+ }
+ }
+
+ protected void tearDown() throws Exception {
+ factory = null;
+ builder = null;
+ super.tearDown();
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies getElementsByTagNameNS method with * as parameters.",
+ method = "getElementsByTagNameNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testGetElementsByTagNameNS1() throws Throwable {
+ String namespaceURI = "*";
+ String localName = "*";
+ Document doc;
+ NodeList newList;
+ doc = (Document) load("staffNS", builder);
+ newList = doc.getElementsByTagNameNS(namespaceURI, localName);
+ // BEGIN android-changed: Was 37, but that assumed validation.
+ assertEquals("throw_Size", 36, newList.getLength());
+ // END android-changed
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies getElementsByTagNameNS with '*' as the first parameter.",
+ method = "getElementsByTagNameNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testGetElementsByTagNameNS2() throws Throwable {
+ Document doc;
+ NodeList newList;
+ Element newElement;
+ String prefix;
+ String lname;
+ doc = (Document) load("staffNS", builder);
+ newList = doc.getElementsByTagNameNS("*", "employee");
+ assertEquals("employeeCount", 5, newList.getLength());
+ newElement = (Element) newList.item(3);
+ prefix = newElement.getPrefix();
+ assertEquals("prefix", "emp", prefix);
+ lname = newElement.getLocalName();
+ assertEquals("lname", "employee", lname);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies getElementsByTagNameNS with '*' as the second parameter.",
+ method = "getElementsByTagNameNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testGetElementsByTagNameNS3() throws Throwable {
+ Document doc;
+ NodeList elementList;
+ Node child;
+ String childName;
+ List<String> result = new ArrayList<String>();
+
+ List<String> expectedResult = new ArrayList<String>();
+ expectedResult.add("employee");
+ expectedResult.add("employeeId");
+ expectedResult.add("name");
+ expectedResult.add("position");
+ expectedResult.add("salary");
+ expectedResult.add("gender");
+ expectedResult.add("address");
+ expectedResult.add("emp:employee");
+ expectedResult.add("emp:employeeId");
+ expectedResult.add("emp:position");
+ expectedResult.add("emp:salary");
+ expectedResult.add("emp:gender");
+ expectedResult.add("emp:address");
+ expectedResult.add("address");
+
+ doc = (Document) load("staffNS", builder);
+ elementList = doc.getElementsByTagNameNS("http://www.nist.gov", "*");
+ for (int indexN10076 = 0; indexN10076 < elementList.getLength(); indexN10076++) {
+ child = (Node) elementList.item(indexN10076);
+ childName = child.getNodeName();
+ result.add(childName);
+ }
+ assertEquals("nodeNames", expectedResult, result);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies getElementsByTagNameNS with '*' as the first parameter.",
+ method = "getElementsByTagNameNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testGetElementsByTagNameNS4() throws Throwable {
+ Document doc;
+ NodeList elementList;
+ Node child;
+ String childName;
+ List<String> result = new ArrayList<String>();
+
+ List<String> expectedResult = new ArrayList<String>();
+ expectedResult.add("address");
+ expectedResult.add("address");
+ expectedResult.add("address");
+ expectedResult.add("emp:address");
+ expectedResult.add("address");
+
+ doc = (Document) load("staffNS", builder);
+ elementList = doc.getElementsByTagNameNS("*", "address");
+ for (int indexN10059 = 0; indexN10059 < elementList.getLength(); indexN10059++) {
+ child = (Node) elementList.item(indexN10059);
+ childName = child.getNodeName();
+ result.add(childName);
+ }
+ assertEquals("nodeNames", expectedResult, result);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies negative case of getElementsByTagNameNS method.",
+ method = "getElementsByTagNameNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testGetElementsByTagNameNS5() throws Throwable {
+ String namespaceURI = "http://www.nist.gov";
+ String localName = "nomatch";
+ Document doc;
+ NodeList elementList;
+ doc = (Document) load("staffNS", builder);
+ elementList = doc.getElementsByTagNameNS(namespaceURI, localName);
+ assertEquals("throw_Size", 0, elementList.getLength());
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies negative case of getElementsByTagNameNS method.",
+ method = "getElementsByTagNameNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testGetElementsByTagNameNS6() throws Throwable {
+ Document doc;
+ NodeList elementList;
+ doc = (Document) load("staffNS", builder);
+ elementList = doc.getElementsByTagNameNS("http://www.nomatch.com",
+ "address");
+ assertEquals("matchSize", 0, elementList.getLength());
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies positive case of getElementsByTagNameNS method.",
+ method = "getElementsByTagNameNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testGetElementsByTagNameNS7() throws Throwable {
+ Document doc;
+ NodeList elementList;
+ doc = (Document) load("staffNS", builder);
+ elementList = doc.getElementsByTagNameNS("http://www.nist.gov",
+ "address");
+ assertEquals("addresses", 3, elementList.getLength());
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies getElementsByTagNameNS method with '*' as parameters; positive case.",
+ method = "getElementsByTagNameNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testGetElementsByTagNameNS8() throws Throwable {
+ Document doc;
+ Element docElem;
+ NodeList newList;
+ doc = (Document) load("staffNS", builder);
+ docElem = doc.getDocumentElement();
+ newList = docElem.getElementsByTagNameNS("*", "*");
+ assertEquals("listSize", 36, newList.getLength());
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies getElementsByTagNameNS method with '*' as the first parameter.",
+ method = "getElementsByTagNameNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testGetElementsByTagNameNS9() throws Throwable {
+ Document doc;
+ NodeList newList;
+ Element newElement;
+ String prefix;
+ String lname;
+ Element docElem;
+ doc = (Document) load("staffNS", builder);
+ docElem = doc.getDocumentElement();
+ newList = docElem.getElementsByTagNameNS("*", "employee");
+ assertEquals("employeeCount", 5, newList.getLength());
+ newElement = (Element) newList.item(3);
+ prefix = newElement.getPrefix();
+ assertEquals("prefix", "emp", prefix);
+ lname = newElement.getLocalName();
+ assertEquals("lname", "employee", lname);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies getElementsByTagNameNS method with '*' as the second parameter.",
+ method = "getElementsByTagNameNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testGetElementsByTagNameNS10() throws Throwable {
+ Document doc;
+ Element docElem;
+ NodeList elementList;
+ Node child;
+ String childName;
+ List<String> result = new ArrayList<String>();
+
+ List<String> expectedResult = new ArrayList<String>();
+ expectedResult.add("employee");
+ expectedResult.add("employeeId");
+ expectedResult.add("name");
+ expectedResult.add("position");
+ expectedResult.add("salary");
+ expectedResult.add("gender");
+ expectedResult.add("address");
+ expectedResult.add("emp:employee");
+ expectedResult.add("emp:employeeId");
+ expectedResult.add("emp:position");
+ expectedResult.add("emp:salary");
+ expectedResult.add("emp:gender");
+ expectedResult.add("emp:address");
+ expectedResult.add("address");
+
+ doc = (Document) load("staffNS", builder);
+ docElem = doc.getDocumentElement();
+ elementList = docElem
+ .getElementsByTagNameNS("http://www.nist.gov", "*");
+ for (int indexN1007E = 0; indexN1007E < elementList.getLength(); indexN1007E++) {
+ child = (Node) elementList.item(indexN1007E);
+ childName = child.getNodeName();
+ result.add(childName);
+ }
+ assertEquals("nodeNames", expectedResult, result);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies getElementsByTagNameNS method with '*' as the first parameter.",
+ method = "getElementsByTagNameNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testGetElementsByTagNameNS11() throws Throwable {
+ Document doc;
+ Element docElem;
+ NodeList elementList;
+ Node child;
+ String childName;
+ List<String> result = new ArrayList<String>();
+
+ List<String> expectedResult = new ArrayList<String>();
+ expectedResult.add("address");
+ expectedResult.add("address");
+ expectedResult.add("address");
+ expectedResult.add("emp:address");
+ expectedResult.add("address");
+
+ doc = (Document) load("staffNS", builder);
+ docElem = doc.getDocumentElement();
+ elementList = docElem.getElementsByTagNameNS("*", "address");
+ for (int indexN1005E = 0; indexN1005E < elementList.getLength(); indexN1005E++) {
+ child = (Node) elementList.item(indexN1005E);
+ childName = child.getNodeName();
+ result.add(childName);
+ }
+ assertEquals("nodeNames", expectedResult, result);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies negative case for getElementsByTagNameNS method.",
+ method = "getElementsByTagNameNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testGetElementsByTagNameNS12() throws Throwable {
+ Document doc;
+ Element docElem;
+ NodeList elementList;
+ doc = (Document) load("staffNS", builder);
+ docElem = doc.getDocumentElement();
+ elementList = docElem.getElementsByTagNameNS("http://www.nist.gov",
+ "nomatch");
+ assertEquals("size", 0, elementList.getLength());
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies negative case for getElementsByTagNameNS method.",
+ method = "getElementsByTagNameNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testGetElementsByTagNameNS13() throws Throwable {
+ Document doc;
+ Element docElem;
+ NodeList elementList;
+ doc = (Document) load("staffNS", builder);
+ docElem = doc.getDocumentElement();
+ elementList = docElem.getElementsByTagNameNS("http://www.nomatch.com",
+ "address");
+ assertEquals("matchSize", 0, elementList.getLength());
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies positive case for getElementsByTagNameNS method.",
+ method = "getElementsByTagNameNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testGetElementsByTagNameNS14() throws Throwable {
+ Document doc;
+ Element docElem;
+ NodeList elementList;
+ doc = (Document) load("staffNS", builder);
+ docElem = doc.getDocumentElement();
+ elementList = docElem.getElementsByTagNameNS("http://www.nist.gov",
+ "address");
+ assertEquals("addresses", 3, elementList.getLength());
+ }
+}
diff --git a/xml/src/test/java/tests/org/w3c/dom/GetNamedItemNS.java b/xml/src/test/java/tests/org/w3c/dom/GetNamedItemNS.java
new file mode 100644
index 0000000..270fe04
--- /dev/null
+++ b/xml/src/test/java/tests/org/w3c/dom/GetNamedItemNS.java
@@ -0,0 +1,135 @@
+package tests.org.w3c.dom;
+
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Document;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import javax.xml.parsers.DocumentBuilder;
+
+/**
+ * The "getNamedItemNS(namespaceURI,localName)" method for a NamedNodeMap should
+ * return a node specified by localName and namespaceURI
+ *
+ * Retrieve a list of elements with tag name "address". Access the second
+ * element from the list and get its attributes. Try to retrieve the attribute
+ * node with local name "domestic" and namespace uri "http://www.usa.com" with
+ * method getNamedItemNS(namespaceURI,localName).
+ *
+ * @author NIST
+ * @author Mary Brady
+ * @see <a
+ * href="http://www.w3.org/TR/DOM-Level-2-Core/core#ID-F68D095">http://www.w3.org/TR/DOM-Level-2-Core/core#ID-F68D095</a>
+ */
+@TestTargetClass(NamedNodeMap.class)
+public final class GetNamedItemNS extends DOMTestCase {
+
+ DOMDocumentBuilderFactory factory;
+
+ DocumentBuilder builder;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ try {
+ factory = new DOMDocumentBuilderFactory(DOMDocumentBuilderFactory
+ .getConfiguration2());
+ builder = factory.getBuilder();
+ } catch (Exception e) {
+ fail("Unexpected exception" + e.getMessage());
+ }
+ }
+
+ protected void tearDown() throws Exception {
+ factory = null;
+ builder = null;
+ super.tearDown();
+ }
+
+ /**
+ * Runs the test case.
+ *
+ * @throws Throwable
+ * Any uncaught exception causes test to fail
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Doesn't verify DOMException.",
+ method = "getNamedItem",
+ args = {java.lang.String.class}
+ )
+ public void testGetNamedItemNS1() throws Throwable {
+ Document doc;
+ NodeList elementList;
+ Node testEmployee;
+ NamedNodeMap attributes;
+ Attr domesticAttr;
+ String attrName;
+ doc = (Document) load("staffNS", builder);
+ elementList = doc.getElementsByTagName("address");
+ testEmployee = elementList.item(1);
+ attributes = testEmployee.getAttributes();
+ domesticAttr = (Attr) attributes.getNamedItemNS("http://www.usa.com",
+ "domestic");
+ attrName = domesticAttr.getNodeName();
+ assertEquals("attrName", "dmstc:domestic", attrName);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Doesn't verify DOMException.",
+ method = "getNamedItemNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testGetNamedItemNS2() throws Throwable {
+ String namespaceURI = "http://www.usa.com";
+ String localName = "domest";
+ Document doc;
+ NodeList elementList;
+ Node testEmployee;
+ NamedNodeMap attributes;
+ Attr newAttr;
+ doc = (Document) load("staffNS", builder);
+ elementList = doc.getElementsByTagName("address");
+ testEmployee = elementList.item(1);
+ attributes = testEmployee.getAttributes();
+ newAttr = (Attr) attributes.getNamedItemNS(namespaceURI, localName);
+ assertNull("throw_Null", newAttr);
+ }
+
+// Assumes validation.
+// public void testGetNamedItemNS3() throws Throwable {
+// Document doc;
+// DocumentType docType;
+// NamedNodeMap entities;
+// Entity entity;
+// String nullNS = null;
+//
+// doc = (Document) load("staffNS", builder);
+// docType = doc.getDoctype();
+// entities = docType.getEntities();
+// assertNotNull("entitiesNotNull", entities);
+// entity = (Entity) entities.getNamedItemNS(nullNS, "ent1");
+// assertNotNull("entityNull", entity);
+// }
+
+// Assumes validation.
+// public void testGetNamedItemNS4() throws Throwable {
+// Document doc;
+// DocumentType docType;
+// NamedNodeMap notations;
+// Notation notation;
+// String nullNS = null;
+//
+// doc = (Document) load("staffNS", builder);
+// docType = doc.getDoctype();
+// notations = docType.getNotations();
+// assertNotNull("notationsNotNull", notations);
+// notation = (Notation) notations.getNamedItemNS(nullNS, "notation1");
+// assertNotNull("notationNull", notation);
+// }
+}
diff --git a/xml/src/test/java/tests/org/w3c/dom/HCEntitiesRemoveNamedItemNS.java b/xml/src/test/java/tests/org/w3c/dom/HCEntitiesRemoveNamedItemNS.java
new file mode 100644
index 0000000..1cdd20f
--- /dev/null
+++ b/xml/src/test/java/tests/org/w3c/dom/HCEntitiesRemoveNamedItemNS.java
@@ -0,0 +1,102 @@
+/*
+ This Java source file was generated by test-to-java.xsl
+ and is a derived work from the source document.
+ The source document contained the following notice:
+
+
+ Copyright (c) 2004 World Wide Web Consortium,
+ (Massachusetts Institute of Technology, Institut National de
+ Recherche en Informatique et en Automatique, Keio University). All
+ Rights Reserved. This program is distributed under the W3C's Software
+ Intellectual Property License. This program is distributed in the
+ hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE.
+ See W3C License http://www.w3.org/Consortium/Legal/ for more details.
+
+ */
+
+package tests.org.w3c.dom;
+
+import dalvik.annotation.TestTargetClass;
+
+import javax.xml.parsers.DocumentBuilder;
+
+import org.w3c.dom.DOMException;
+import org.w3c.dom.Document;
+import org.w3c.dom.DocumentType;
+import org.w3c.dom.NamedNodeMap;
+
+/**
+ * An attempt to add remove an entity using removeNamedItemNS should result in a
+ * NO_MODIFICATION_ERR or a NOT_FOUND_ERR.
+ *
+ * @author Curt Arnold
+ * @see <a
+ * href="http://www.w3.org/TR/DOM-Level-2-Core/core#ID-1788794630">http://www.w3.org/TR/DOM-Level-2-Core/core#ID-1788794630</a>
+ * @see <a
+ * href="http://www.w3.org/TR/DOM-Level-2-Core/core#ID-removeNamedItemNS">http://www.w3.org/TR/DOM-Level-2-Core/core#ID-removeNamedItemNS</a>
+ */
+@TestTargetClass(NamedNodeMap.class)
+public final class HCEntitiesRemoveNamedItemNS extends DOMTestCase {
+
+ DOMDocumentBuilderFactory factory;
+
+ DocumentBuilder builder;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ try {
+ factory = new DOMDocumentBuilderFactory(DOMDocumentBuilderFactory
+ .getConfiguration1());
+ builder = factory.getBuilder();
+ } catch (Exception e) {
+ fail("Unexpected exception" + e.getMessage());
+ }
+ }
+
+ protected void tearDown() throws Exception {
+ factory = null;
+ builder = null;
+ super.tearDown();
+ }
+
+ /**
+ * Runs the test case.
+ *
+ * @throws Throwable
+ * Any uncaught exception causes test to fail
+ */
+// Assumes validation.
+// public void testRemoveNamedItemNS() throws Throwable {
+// Document doc;
+// NamedNodeMap entities;
+// DocumentType docType;
+//
+// doc = (Document) load("hc_staff", builder);
+// docType = doc.getDoctype();
+//
+// if (!(("text/html".equals(getContentType())))) {
+// assertNotNull("docTypeNotNull", docType);
+// entities = docType.getEntities();
+// assertNotNull("entitiesNotNull", entities);
+//
+// try {
+// entities.removeNamedItemNS(
+// "http://www.w3.org/1999/xhtml", "alpha");
+// fail("throw_NO_MOD_OR_NOT_FOUND_ERR");
+//
+// } catch (DOMException ex) {
+// switch (ex.code) {
+// case 7:
+// break;
+// case 8:
+// break;
+// default:
+// throw ex;
+// }
+// }
+// }
+// }
+
+}
diff --git a/xml/src/test/java/tests/org/w3c/dom/HCEntitiesSetNamedItemNS.java b/xml/src/test/java/tests/org/w3c/dom/HCEntitiesSetNamedItemNS.java
new file mode 100644
index 0000000..7e2917a
--- /dev/null
+++ b/xml/src/test/java/tests/org/w3c/dom/HCEntitiesSetNamedItemNS.java
@@ -0,0 +1,86 @@
+package tests.org.w3c.dom;
+
+import dalvik.annotation.TestTargetClass;
+
+import javax.xml.parsers.DocumentBuilder;
+
+import org.w3c.dom.DOMException;
+import org.w3c.dom.Document;
+import org.w3c.dom.DocumentType;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+
+/**
+ * An attempt to add an element to the named node map returned by entities
+ * should result in a NO_MODIFICATION_ERR or HIERARCHY_REQUEST_ERR.
+ *
+ * @author Curt Arnold
+ * @see <a
+ * href="http://www.w3.org/TR/DOM-Level-2-Core/core#ID-1788794630">http://www.w3.org/TR/DOM-Level-2-Core/core#ID-1788794630</a>
+ * @see <a
+ * href="http://www.w3.org/TR/DOM-Level-2-Core/core#ID-setNamedItemNS">http://www.w3.org/TR/DOM-Level-2-Core/core#ID-setNamedItemNS</a>
+ */
+@TestTargetClass(NamedNodeMap.class)
+public final class HCEntitiesSetNamedItemNS extends DOMTestCase {
+
+ DOMDocumentBuilderFactory factory;
+
+ DocumentBuilder builder;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ try {
+ factory = new DOMDocumentBuilderFactory(DOMDocumentBuilderFactory
+ .getConfiguration1());
+ builder = factory.getBuilder();
+ } catch (Exception e) {
+ fail("Unexpected exception" + e.getMessage());
+ }
+ }
+
+ protected void tearDown() throws Exception {
+ factory = null;
+ builder = null;
+ super.tearDown();
+ }
+
+ /**
+ * Runs the test case.
+ *
+ * @throws Throwable
+ * Any uncaught exception causes test to fail
+ */
+// Assumes validation.
+// public void testSetNamedItemNS() throws Throwable {
+// Document doc;
+// NamedNodeMap entities;
+// DocumentType docType;
+//
+// Element elem;
+// doc = (Document) load("hc_staff", builder);
+// docType = doc.getDoctype();
+//
+// if (!(("text/html".equals(getContentType())))) {
+// assertNotNull("docTypeNotNull", docType);
+// entities = docType.getEntities();
+// assertNotNull("entitiesNotNull", entities);
+// elem = doc.createElementNS("http://www.w3.org/1999/xhtml", "br");
+//
+// try {
+// entities.setNamedItemNS(elem);
+// fail("throw_HIER_OR_NO_MOD_ERR");
+//
+// } catch (DOMException ex) {
+// switch (ex.code) {
+// case 3:
+// break;
+// case 7:
+// break;
+// default:
+// throw ex;
+// }
+// }
+// }
+// }
+
+}
diff --git a/xml/src/test/java/tests/org/w3c/dom/HCNamedNodeMapInvalidType.java b/xml/src/test/java/tests/org/w3c/dom/HCNamedNodeMapInvalidType.java
new file mode 100644
index 0000000..d968bc4
--- /dev/null
+++ b/xml/src/test/java/tests/org/w3c/dom/HCNamedNodeMapInvalidType.java
@@ -0,0 +1,103 @@
+/*
+ This Java source file was generated by test-to-java.xsl
+ and is a derived work from the source document.
+ The source document contained the following notice:
+
+
+ Copyright (c) 2001-2004 World Wide Web Consortium,
+ (Massachusetts Institute of Technology, Institut National de
+ Recherche en Informatique et en Automatique, Keio University). All
+ Rights Reserved. This program is distributed under the W3C's Software
+ Intellectual Property License. This program is distributed in the
+ hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE.
+ See W3C License http://www.w3.org/Consortium/Legal/ for more details.
+
+ */
+
+package tests.org.w3c.dom;
+
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.DOMException;
+
+import javax.xml.parsers.DocumentBuilder;
+
+/**
+ * Attempt to insert an element into an attribute list, should raise a
+ * HIERARCHY_REQUEST_ERR.
+ *
+ * @author Curt Arnold
+ * @see <a
+ * href="http://www.w3.org/TR/1998/REC-DOM-Level-1-19981001/level-one-core#xpointer(id('ID-258A00AF')/constant[@name='HIERARCHY_REQUEST_ERR'])">http://www.w3.org/TR/1998/REC-DOM-Level-1-19981001/level-one-core#xpointer(id('ID-258A00AF')/constant[@name='HIERARCHY_REQUEST_ERR'])</a>
+ * @see <a
+ * href="http://www.w3.org/TR/1998/REC-DOM-Level-1-19981001/level-one-core#ID-1025163788">http://www.w3.org/TR/1998/REC-DOM-Level-1-19981001/level-one-core#ID-1025163788</a>
+ * @see <a
+ * href="http://www.w3.org/2000/11/DOM-Level-2-errata#core-4">http://www.w3.org/2000/11/DOM-Level-2-errata#core-4</a>
+ */
+@TestTargetClass(NamedNodeMap.class)
+public final class HCNamedNodeMapInvalidType extends DOMTestCase {
+
+ DOMDocumentBuilderFactory factory;
+
+ DocumentBuilder builder;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ try {
+ factory = new DOMDocumentBuilderFactory(DOMDocumentBuilderFactory
+ .getConfiguration1());
+ builder = factory.getBuilder();
+ } catch (Exception e) {
+ fail("Unexpected exception" + e.getMessage());
+ }
+ }
+
+ protected void tearDown() throws Exception {
+ factory = null;
+ builder = null;
+ super.tearDown();
+ }
+
+ /**
+ * Runs the test case.
+ *
+ * @throws Throwable
+ * Any uncaught exception causes test to fail
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Verifies that setNamedItem method throws DOMException with HIERARCHY_REQUEST_ERR code.",
+ method = "setNamedItem",
+ args = {org.w3c.dom.Node.class}
+ )
+ public void testNamedNodeMapInvalidType() throws Throwable {
+ Document doc;
+ NamedNodeMap attributes;
+ Element docElem;
+ Element newElem;
+
+ doc = (Document) load("hc_staff", builder);
+ docElem = doc.getDocumentElement();
+ attributes = docElem.getAttributes();
+ newElem = doc.createElement("html");
+
+ {
+ boolean success = false;
+ try {
+ attributes.setNamedItem(newElem);
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.HIERARCHY_REQUEST_ERR);
+ }
+ assertTrue("throw_HIERARCHY_REQUEST_ERR", success);
+ }
+ }
+
+}
diff --git a/xml/src/test/java/tests/org/w3c/dom/HCNodeDocumentFragmentNormalize.java b/xml/src/test/java/tests/org/w3c/dom/HCNodeDocumentFragmentNormalize.java
new file mode 100644
index 0000000..53317b3
--- /dev/null
+++ b/xml/src/test/java/tests/org/w3c/dom/HCNodeDocumentFragmentNormalize.java
@@ -0,0 +1,108 @@
+package tests.org.w3c.dom;
+
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import org.w3c.dom.Node;
+import org.w3c.dom.Document;
+import org.w3c.dom.DocumentFragment;
+import org.w3c.dom.Text;
+
+import javax.xml.parsers.DocumentBuilder;
+
+/**
+ * Create a document fragment with two adjacent text nodes, normalize and see if
+ * the text nodes were combined.
+ *
+ * @author Curt Arnold
+ * @see <a
+ * href="http://www.w3.org/TR/DOM-Level-2-Core/core#ID-F68D095">http://www.w3.org/TR/DOM-Level-2-Core/core#ID-F68D095</a>
+ * @see <a
+ * href="http://www.w3.org/TR/DOM-Level-2-Core/core#ID-B63ED1A3">http://www.w3.org/TR/DOM-Level-2-Core/core#ID-B63ED1A3</a>
+ */
+@TestTargetClass(Node.class)
+public final class HCNodeDocumentFragmentNormalize extends DOMTestCase {
+
+ DOMDocumentBuilderFactory factory;
+
+ DocumentBuilder builder;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ try {
+ factory = new DOMDocumentBuilderFactory(DOMDocumentBuilderFactory
+ .getConfiguration1());
+ builder = factory.getBuilder();
+ } catch (Exception e) {
+ fail("Unexpected exception" + e.getMessage());
+ }
+ }
+
+ protected void tearDown() throws Exception {
+ factory = null;
+ builder = null;
+ super.tearDown();
+ }
+
+ /**
+ * Runs the test case.
+ *
+ * @throws Throwable
+ * Any uncaught exception causes test to fail
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Verifies positive functionality of getNodeValue method, and that getNextSibling method returns null.",
+ method = "getNodeValue",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Verifies positive functionality of getNodeValue method, and that getNextSibling method returns null.",
+ method = "getNextSibling",
+ args = {}
+ )
+ })
+ public void testNodeDocumentFragmentNormalize1() throws Throwable {
+ Document doc;
+ DocumentFragment docFragment;
+ String nodeValue;
+ Text txtNode;
+ Node retval;
+
+ doc = (Document) load("hc_staff", builder);
+ docFragment = doc.createDocumentFragment();
+ txtNode = doc.createTextNode("foo");
+ retval = docFragment.appendChild(txtNode);
+ txtNode = doc.createTextNode("bar");
+ retval = docFragment.appendChild(txtNode);
+ docFragment.normalize();
+ txtNode = (Text) docFragment.getFirstChild();
+ nodeValue = txtNode.getNodeValue();
+ assertEquals("normalizedNodeValue", "foobar", nodeValue);
+ retval = txtNode.getNextSibling();
+ assertNull("singleChild", retval);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Verifies that getFirstChild method returns null.",
+ method = "getFirstChild",
+ args = {}
+ )
+ public void testNodeDocumentFragmentNormalize2() throws Throwable {
+ Document doc;
+ DocumentFragment docFragment;
+ Text txtNode;
+
+ doc = (Document) load("hc_staff", builder);
+ docFragment = doc.createDocumentFragment();
+ txtNode = doc.createTextNode("");
+ docFragment.appendChild(txtNode);
+ docFragment.normalize();
+ txtNode = (Text) docFragment.getFirstChild();
+ assertNull("noChild", txtNode);
+ }
+}
diff --git a/xml/src/test/java/tests/org/w3c/dom/HCNotationsRemoveNamedItemNS.java b/xml/src/test/java/tests/org/w3c/dom/HCNotationsRemoveNamedItemNS.java
new file mode 100644
index 0000000..3eab5fc
--- /dev/null
+++ b/xml/src/test/java/tests/org/w3c/dom/HCNotationsRemoveNamedItemNS.java
@@ -0,0 +1,110 @@
+/*
+ This Java source file was generated by test-to-java.xsl
+ and is a derived work from the source document.
+ The source document contained the following notice:
+
+
+ Copyright (c) 2004 World Wide Web Consortium,
+ (Massachusetts Institute of Technology, Institut National de
+ Recherche en Informatique et en Automatique, Keio University). All
+ Rights Reserved. This program is distributed under the W3C's Software
+ Intellectual Property License. This program is distributed in the
+ hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE.
+ See W3C License http://www.w3.org/Consortium/Legal/ for more details.
+
+ */
+
+package tests.org.w3c.dom;
+
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Document;
+import org.w3c.dom.DocumentType;
+import org.w3c.dom.DOMException;
+
+import javax.xml.parsers.DocumentBuilder;
+
+/**
+ * An attempt to add remove an notation using removeNamedItemNS should result in
+ * a NO_MODIFICATION_ERR or a NOT_FOUND_ERR.
+ *
+ * @author Curt Arnold
+ * @see <a
+ * href="http://www.w3.org/TR/DOM-Level-2-Core/core#ID-D46829EF">http://www.w3.org/TR/DOM-Level-2-Core/core#ID-D46829EF</a>
+ * @see <a
+ * href="http://www.w3.org/TR/DOM-Level-2-Core/core#ID-removeNamedItemNS">http://www.w3.org/TR/DOM-Level-2-Core/core#ID-removeNamedItemNS</a>
+ */
+@TestTargetClass(NamedNodeMap.class)
+public final class HCNotationsRemoveNamedItemNS extends DOMTestCase {
+
+ DOMDocumentBuilderFactory factory;
+
+ DocumentBuilder builder;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ try {
+ factory = new DOMDocumentBuilderFactory(DOMDocumentBuilderFactory
+ .getConfiguration1());
+ builder = factory.getBuilder();
+ } catch (Exception e) {
+ fail("Unexpected exception" + e.getMessage());
+ }
+ }
+
+ protected void tearDown() throws Exception {
+ factory = null;
+ builder = null;
+ super.tearDown();
+ }
+
+ /**
+ * Runs the test case.
+ *
+ * @throws Throwable
+ * Any uncaught exception causes test to fail
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies that removeNamedItemNS method throws DOMException.",
+ method = "removeNamedItemNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testRemoveNamedItemNS() throws Throwable {
+ Document doc;
+ NamedNodeMap notations;
+ DocumentType docType;
+
+ doc = (Document) load("hc_staff", builder);
+ docType = doc.getDoctype();
+
+ if (!(("text/html".equals(getContentType())))) {
+ assertNotNull("docTypeNotNull", docType);
+ notations = docType.getNotations();
+ assertNotNull("notationsNotNull", notations);
+
+ try {
+ notations.removeNamedItemNS("http://www.w3.org/1999/xhtml",
+ "alpha");
+ fail("throw_NO_MOD_OR_NOT_FOUND_ERR");
+
+ } catch (DOMException ex) {
+ switch (ex.code) {
+ case 7:
+ break;
+ case 8:
+ break;
+ default:
+ throw ex;
+ }
+ }
+ }
+ }
+
+}
diff --git a/xml/src/test/java/tests/org/w3c/dom/HCNotationsSetNamedItemNS.java b/xml/src/test/java/tests/org/w3c/dom/HCNotationsSetNamedItemNS.java
new file mode 100644
index 0000000..d5daee4
--- /dev/null
+++ b/xml/src/test/java/tests/org/w3c/dom/HCNotationsSetNamedItemNS.java
@@ -0,0 +1,112 @@
+/*
+ This Java source file was generated by test-to-java.xsl
+ and is a derived work from the source document.
+ The source document contained the following notice:
+
+
+ Copyright (c) 2004 World Wide Web Consortium,
+ (Massachusetts Institute of Technology, Institut National de
+ Recherche en Informatique et en Automatique, Keio University). All
+ Rights Reserved. This program is distributed under the W3C's Software
+ Intellectual Property License. This program is distributed in the
+ hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE.
+ See W3C License http://www.w3.org/Consortium/Legal/ for more details.
+
+ */
+
+package tests.org.w3c.dom;
+
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Document;
+import org.w3c.dom.DocumentType;
+import org.w3c.dom.Element;
+import org.w3c.dom.DOMException;
+
+import javax.xml.parsers.DocumentBuilder;
+
+/**
+ * An attempt to add an element to the named node map returned by notations
+ * should result in a NO_MODIFICATION_ERR or HIERARCHY_REQUEST_ERR.
+ *
+ * @author Curt Arnold
+ * @see <a
+ * href="http://www.w3.org/TR/DOM-Level-2-Core/core#ID-D46829EF">http://www.w3.org/TR/DOM-Level-2-Core/core#ID-D46829EF</a>
+ * @see <a
+ * href="http://www.w3.org/TR/DOM-Level-2-Core/core#ID-setNamedItemNS">http://www.w3.org/TR/DOM-Level-2-Core/core#ID-setNamedItemNS</a>
+ */
+@TestTargetClass(NamedNodeMap.class)
+public final class HCNotationsSetNamedItemNS extends DOMTestCase {
+
+ DOMDocumentBuilderFactory factory;
+
+ DocumentBuilder builder;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ try {
+ factory = new DOMDocumentBuilderFactory(DOMDocumentBuilderFactory
+ .getConfiguration1());
+ builder = factory.getBuilder();
+ } catch (Exception e) {
+ fail("Unexpected exception" + e.getMessage());
+ }
+ }
+
+ protected void tearDown() throws Exception {
+ factory = null;
+ builder = null;
+ super.tearDown();
+ }
+
+ /**
+ * Runs the test case.
+ *
+ * @throws Throwable
+ * Any uncaught exception causes test to fail
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies that setNamedItemNS throws DOMException.",
+ method = "setNamedItemNS",
+ args = {org.w3c.dom.Node.class}
+ )
+ public void testNotationsSetNamedItemNS() throws Throwable {
+ Document doc;
+ NamedNodeMap notations;
+ DocumentType docType;
+
+ Element elem;
+ doc = (Document) load("hc_staff", builder);
+ docType = doc.getDoctype();
+
+ if (!(("text/html".equals(getContentType())))) {
+ assertNotNull("docTypeNotNull", docType);
+ notations = docType.getNotations();
+ assertNotNull("notationsNotNull", notations);
+ elem = doc.createElementNS("http://www.w3.org/1999/xhtml", "br");
+
+ try {
+ notations.setNamedItemNS(elem);
+ fail("throw_HIER_OR_NO_MOD_ERR");
+
+ } catch (DOMException ex) {
+ switch (ex.code) {
+ case 3:
+ break;
+ case 7:
+ break;
+ default:
+ throw ex;
+ }
+ }
+ }
+ }
+
+}
diff --git a/xml/src/test/java/tests/org/w3c/dom/HasAttribute.java b/xml/src/test/java/tests/org/w3c/dom/HasAttribute.java
new file mode 100644
index 0000000..89eef88
--- /dev/null
+++ b/xml/src/test/java/tests/org/w3c/dom/HasAttribute.java
@@ -0,0 +1,119 @@
+package tests.org.w3c.dom;
+
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import org.w3c.dom.Element;
+import org.w3c.dom.Document;
+import org.w3c.dom.NodeList;
+
+import javax.xml.parsers.DocumentBuilder;
+
+/**
+ * The "hasAttribute()" method for an Element should return true if the element
+ * has an attribute with the given name. Retrieve the first "address" element
+ * and the "hasAttribute()" method should return false since the element does
+ * not have a default value.
+ *
+ * @author NIST
+ * @author Mary Brady
+ * @see <a
+ * href="http://www.w3.org/TR/DOM-Level-2-Core/core#ID-ElHasAttr">http://www.w3.org/TR/DOM-Level-2-Core/core#ID-ElHasAttr</a>
+ */
+@TestTargetClass(Element.class)
+public final class HasAttribute extends DOMTestCase {
+
+ DOMDocumentBuilderFactory factory;
+
+ DocumentBuilder builder;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ try {
+ factory = new DOMDocumentBuilderFactory(DOMDocumentBuilderFactory
+ .getConfiguration1());
+ builder = factory.getBuilder();
+ } catch (Exception e) {
+ fail("Unexpected exception" + e.getMessage());
+ }
+ }
+
+ protected void tearDown() throws Exception {
+ factory = null;
+ builder = null;
+ super.tearDown();
+ }
+
+ /**
+ * Runs the test case.
+ *
+ * @throws Throwable
+ * Any uncaught exception causes test to fail
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies that hasAttribute method returns false.",
+ method = "hasAttribute",
+ args = {java.lang.String.class}
+ )
+ public void testHasAttribute1() throws Throwable {
+ Document doc;
+ NodeList elementList;
+ Element testNode;
+ boolean state;
+ doc = (Document) load("staff", builder);
+ elementList = doc.getElementsByTagName("address");
+ testNode = (Element) elementList.item(4);
+ state = testNode.hasAttribute("domestic");
+ assertFalse("throw_False", state);
+ }
+
+// Assumes validation.
+// public void testHasAttribute2() throws Throwable {
+// Document doc;
+// NodeList elementList;
+// Element testNode;
+// boolean state;
+// doc = (Document) load("staff", builder);
+// elementList = doc.getElementsByTagName("address");
+// testNode = (Element) elementList.item(0);
+// state = testNode.hasAttribute("street");
+// assertTrue("throw_True", state);
+// }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies that hasAttribute method returns false.",
+ method = "hasAttribute",
+ args = {java.lang.String.class}
+ )
+ public void testHasAttribute3() throws Throwable {
+ Document doc;
+ NodeList elementList;
+ Element testNode;
+ boolean state;
+ doc = (Document) load("staff", builder);
+ elementList = doc.getElementsByTagName("address");
+ testNode = (Element) elementList.item(0);
+ state = testNode.hasAttribute("nomatch");
+ assertFalse("throw_False", state);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies that hasAttribute method returns true.",
+ method = "hasAttribute",
+ args = {java.lang.String.class}
+ )
+ public void testHasAttribute4() throws Throwable {
+ Document doc;
+ NodeList elementList;
+ Element testNode;
+ boolean state;
+ doc = (Document) load("staffNS", builder);
+ elementList = doc.getElementsByTagName("address");
+ testNode = (Element) elementList.item(0);
+ state = testNode.hasAttribute("dmstc:domestic");
+ assertTrue("hasDomesticAttr", state);
+ }
+}
diff --git a/xml/src/test/java/tests/org/w3c/dom/HasAttributeNS.java b/xml/src/test/java/tests/org/w3c/dom/HasAttributeNS.java
new file mode 100644
index 0000000..cf1b90e
--- /dev/null
+++ b/xml/src/test/java/tests/org/w3c/dom/HasAttributeNS.java
@@ -0,0 +1,172 @@
+/*
+ This Java source file was generated by test-to-java.xsl
+ and is a derived work from the source document.
+ The source document contained the following notice:
+
+
+
+ Copyright (c) 2001 World Wide Web Consortium,
+ (Massachusetts Institute of Technology, Institut National de
+ Recherche en Informatique et en Automatique, Keio University). All
+ Rights Reserved. This program is distributed under the W3C's Software
+ Intellectual Property License. This program is distributed in the
+ hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+ See W3C License http://www.w3.org/Consortium/Legal/ for more details.
+
+
+ */
+
+package tests.org.w3c.dom;
+
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import org.w3c.dom.Element;
+import org.w3c.dom.Document;
+import org.w3c.dom.NodeList;
+
+import javax.xml.parsers.DocumentBuilder;
+
+/**
+ *
+ * The "hasAttributeNS()" method for an Element should return false if the
+ * element does not have an attribute with the given local name and/or a
+ * namespace URI specified on this element or does not have a default value.
+ * Retrieve the first "address" element and the "hasAttributeNS()" method should
+ * return false since the element has "nomatch" as the local name and
+ * "http://www.usa.com" as the namespace URI.
+ *
+ * @author NIST
+ * @author Mary Brady
+ * @see <a
+ * href="http://www.w3.org/TR/DOM-Level-2-Core/core#ID-ElHasAttrNS">http://www.w3.org/TR/DOM-Level-2-Core/core#ID-ElHasAttrNS</a>
+ */
+@TestTargetClass(Element.class)
+public final class HasAttributeNS extends DOMTestCase {
+
+ DOMDocumentBuilderFactory factory;
+
+ DocumentBuilder builder;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ try {
+ factory = new DOMDocumentBuilderFactory(DOMDocumentBuilderFactory
+ .getConfiguration2());
+ builder = factory.getBuilder();
+ } catch (Exception e) {
+ fail("Unexpected exception" + e.getMessage());
+ }
+ }
+
+ protected void tearDown() throws Exception {
+ factory = null;
+ builder = null;
+ super.tearDown();
+ }
+
+ /**
+ * Runs the test case.
+ *
+ * @throws Throwable
+ * Any uncaught exception causes test to fail
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Doesn't verify DOMException.",
+ method = "hasAttributeNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testHasAttributeNS1() throws Throwable {
+ String localName = "nomatch";
+ String namespaceURI = "http://www.usa.com";
+ Document doc;
+ NodeList elementList;
+ Element testNode;
+ boolean state;
+ doc = (Document) load("staffNS", builder);
+ elementList = doc.getElementsByTagName("address");
+ testNode = (Element) elementList.item(0);
+ state = testNode.hasAttributeNS(namespaceURI, localName);
+ assertFalse("throw_False", state);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Doesn't verify DOMException.",
+ method = "hasAttributeNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testHasAttributeNS2() throws Throwable {
+ String localName = "domestic";
+ String namespaceURI = "http://www.nomatch.com";
+ Document doc;
+ NodeList elementList;
+ Element testNode;
+ boolean state;
+ doc = (Document) load("staffNS", builder);
+ elementList = doc.getElementsByTagName("address");
+ testNode = (Element) elementList.item(0);
+ state = testNode.hasAttributeNS(namespaceURI, localName);
+ assertFalse("throw_False", state);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Doesn't verify DOMException.",
+ method = "hasAttributeNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testHasAttributeNS3() throws Throwable {
+ String localName = "blank";
+ String namespaceURI = "http://www.nist.gov";
+ Document doc;
+ NodeList elementList;
+ Element testNode;
+ boolean state;
+ doc = (Document) load("staffNS", builder);
+ elementList = doc.getElementsByTagName("emp:address");
+ testNode = (Element) elementList.item(0);
+ assertNotNull("empAddrNotNull", testNode);
+ state = testNode.hasAttributeNS(namespaceURI, localName);
+ assertFalse("throw_False", state);
+ }
+
+// Assumes validation.
+// public void testHasAttributeNS4() throws Throwable {
+// String localName = "district";
+// String namespaceURI = "http://www.nist.gov";
+// Document doc;
+// NodeList elementList;
+// Element testNode;
+// boolean state;
+// doc = (Document) load("staffNS", builder);
+// elementList = doc.getElementsByTagName("emp:address");
+// testNode = (Element) elementList.item(0);
+// assertNotNull("empAddressNotNull", testNode);
+// state = testNode.hasAttributeNS(namespaceURI, localName);
+// assertTrue("hasAttribute", state);
+// }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Doesn't verify DOMException.",
+ method = "hasAttributeNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testHasAttributeNS5() throws Throwable {
+ String localName = "domestic";
+ String namespaceURI = "http://www.usa.com";
+ Document doc;
+ NodeList elementList;
+ Element testNode;
+ boolean state;
+ doc = (Document) load("staffNS", builder);
+ elementList = doc.getElementsByTagName("address");
+ testNode = (Element) elementList.item(0);
+ state = testNode.hasAttributeNS(namespaceURI, localName);
+ assertTrue("hasAttribute", state);
+ }
+}
diff --git a/xml/src/test/java/tests/org/w3c/dom/HasAttributes.java b/xml/src/test/java/tests/org/w3c/dom/HasAttributes.java
new file mode 100644
index 0000000..5d3954d
--- /dev/null
+++ b/xml/src/test/java/tests/org/w3c/dom/HasAttributes.java
@@ -0,0 +1,111 @@
+/*
+ This Java source file was generated by test-to-java.xsl
+ and is a derived work from the source document.
+ The source document contained the following notice:
+
+
+
+ Copyright (c) 2001 World Wide Web Consortium,
+ (Massachusetts Institute of Technology, Institut National de
+ Recherche en Informatique et en Automatique, Keio University). All
+ Rights Reserved. This program is distributed under the W3C's Software
+ Intellectual Property License. This program is distributed in the
+ hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+ See W3C License http://www.w3.org/Consortium/Legal/ for more details.
+
+
+ */
+
+package tests.org.w3c.dom;
+
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import org.w3c.dom.Node;
+import org.w3c.dom.Document;
+import org.w3c.dom.NodeList;
+
+import javax.xml.parsers.DocumentBuilder;
+
+/**
+ * The "hasAttributes()" method for a node should return false if the node does
+ * not have an attribute. Retrieve the first "name" node and invoke the
+ * "hasAttributes()" method. The method should return false since the node does
+ * not have an attribute.
+ *
+ * @author NIST
+ * @author Mary Brady
+ * @see <a
+ * href="http://www.w3.org/TR/DOM-Level-2-Core/core#ID-NodeHasAttrs">http://www.w3.org/TR/DOM-Level-2-Core/core#ID-NodeHasAttrs</a>
+ */
+@TestTargetClass(Node.class)
+public final class HasAttributes extends DOMTestCase {
+
+ DOMDocumentBuilderFactory factory;
+
+ DocumentBuilder builder;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ try {
+ factory = new DOMDocumentBuilderFactory(DOMDocumentBuilderFactory
+ .getConfiguration1());
+ builder = factory.getBuilder();
+ } catch (Exception e) {
+ fail("Unexpected exception" + e.getMessage());
+ }
+ }
+
+ protected void tearDown() throws Exception {
+ factory = null;
+ builder = null;
+ super.tearDown();
+ }
+
+ /**
+ * Runs the test case.
+ *
+ * @throws Throwable
+ * Any uncaught exception causes test to fail
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies that hasAttributes method returns false value.",
+ method = "hasAttributes",
+ args = {}
+ )
+ public void testHasAttributes1() throws Throwable {
+ Document doc;
+ NodeList addrList;
+ Node addrNode;
+ boolean state;
+ doc = (Document) load("staff", builder);
+ addrList = doc.getElementsByTagName("name");
+ addrNode = addrList.item(0);
+ state = addrNode.hasAttributes();
+ assertFalse("throw_False", state);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies that hasAttributes method returns true value.",
+ method = "hasAttributes",
+ args = {}
+ )
+ public void testHasAttributes2() throws Throwable {
+ Document doc;
+ NodeList addrList;
+ Node addrNode;
+ boolean state;
+ doc = (Document) load("staff", builder);
+ addrList = doc.getElementsByTagName("address");
+ addrNode = addrList.item(0);
+ state = addrNode.hasAttributes();
+ assertTrue("throw_True", state);
+ }
+
+}
diff --git a/xml/src/test/java/tests/org/w3c/dom/ImportNode.java b/xml/src/test/java/tests/org/w3c/dom/ImportNode.java
new file mode 100644
index 0000000..de39392
--- /dev/null
+++ b/xml/src/test/java/tests/org/w3c/dom/ImportNode.java
@@ -0,0 +1,604 @@
+/*
+ This Java source file was generated by test-to-java.xsl
+ and is a derived work from the source document.
+ The source document contained the following notice:
+
+
+
+ Copyright (c) 2001 World Wide Web Consortium,
+ (Massachusetts Institute of Technology, Institut National de
+ Recherche en Informatique et en Automatique, Keio University). All
+ Rights Reserved. This program is distributed under the W3C's Software
+ Intellectual Property License. This program is distributed in the
+ hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+ See W3C License http://www.w3.org/Consortium/Legal/ for more details.
+
+
+ */
+
+package tests.org.w3c.dom;
+
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Text;
+import org.w3c.dom.Node;
+import org.w3c.dom.Element;
+import org.w3c.dom.DocumentType;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.CDATASection;
+import org.w3c.dom.Comment;
+import org.w3c.dom.DocumentFragment;
+import org.w3c.dom.EntityReference;
+import org.w3c.dom.ProcessingInstruction;
+import org.w3c.dom.DOMException;
+
+import javax.xml.parsers.DocumentBuilder;
+
+/**
+ * The "importNode(importedNode,deep)" method for a Document should import the
+ * given importedNode into that Document. The importedNode is of type Attr. The
+ * ownerElement is set to null. Specified flag is set to true. Children is
+ * imported.
+ *
+ * Create a new attribute whose name is "elem:attr1" in a different document.
+ * Create a child Text node with value "importedText" for the attribute node
+ * above. Invoke method importNode(importedNode,deep) on this document with
+ * importedNode being the newly created attribute. Method should return a node
+ * whose name matches "elem:attr1" and a child node whose value equals
+ * "importedText". The returned node should belong to this document whose
+ * systemId is "staff.dtd"
+ *
+ * @author NIST
+ * @author Mary Brady
+ * @see <a
+ * href="http://www.w3.org/TR/DOM-Level-2-Core/core#Core-Document-importNode">http://www.w3.org/TR/DOM-Level-2-Core/core#Core-Document-importNode</a>
+ */
+@TestTargetClass(Document.class)
+public final class ImportNode extends DOMTestCase {
+
+ DOMDocumentBuilderFactory factory;
+
+ DocumentBuilder builder;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ try {
+ factory = new DOMDocumentBuilderFactory(DOMDocumentBuilderFactory
+ .getConfiguration2());
+ builder = factory.getBuilder();
+ } catch (Exception e) {
+ fail("Unexpected exception" + e.getMessage());
+ }
+ }
+
+ protected void tearDown() throws Exception {
+ factory = null;
+ builder = null;
+ super.tearDown();
+ }
+
+ /**
+ * Runs the test case.
+ *
+ * @throws Throwable
+ * Any uncaught exception causes test to fail
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Doesn't verify DOMException.",
+ method = "importNode",
+ args = {org.w3c.dom.Node.class, boolean.class}
+ )
+ public void _testImportNode1() throws Throwable {
+ Document doc;
+ Document aNewDoc;
+ Attr newAttr;
+ Text importedChild;
+ Node aNode;
+ Document ownerDocument;
+ Element attrOwnerElement;
+ DocumentType docType;
+ String system;
+ boolean specified;
+ NodeList childList;
+ String nodeName;
+ Node child;
+ String childValue;
+ List<String> expectedResult = new ArrayList<String>();
+ expectedResult.add("elem:attr1");
+ expectedResult.add("importedText");
+
+ doc = (Document) load("staffNS", builder);
+ aNewDoc = (Document) load("staffNS", builder);
+ newAttr = aNewDoc.createAttribute("elem:attr1");
+ importedChild = aNewDoc.createTextNode("importedText");
+ aNode = newAttr.appendChild(importedChild);
+ aNode = doc.importNode(newAttr, false);
+ ownerDocument = aNode.getOwnerDocument();
+ docType = ownerDocument.getDoctype();
+ system = docType.getSystemId();
+ assertNotNull("aNode", aNode);
+ assertURIEquals("systemId", null, null, null, "staffNS.dtd", null,
+ null, null, null, system);
+ attrOwnerElement = ((Attr) /* Node */aNode).getOwnerElement();
+ assertNull("ownerElement", attrOwnerElement);
+ specified = ((Attr) /* Node */aNode).getSpecified();
+ assertTrue("specified", specified);
+ childList = aNode.getChildNodes();
+ assertEquals("childList", 1, childList.getLength());
+ nodeName = aNode.getNodeName();
+ assertEquals("nodeName", "elem:attr1", nodeName);
+ child = aNode.getFirstChild();
+ childValue = child.getNodeValue();
+ assertEquals("childValue", "importedText", childValue);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Doesn't verify DOMException.",
+ method = "importNode",
+ args = {org.w3c.dom.Node.class, boolean.class}
+ )
+ public void testImportNode2() throws Throwable {
+ Document doc;
+ Document aNewDoc;
+ CDATASection cDataSec;
+ Node aNode;
+ Document ownerDocument;
+ DocumentType docType;
+ String system;
+ String value;
+ doc = (Document) load("staffNS", builder);
+ aNewDoc = (Document) load("staffNS", builder);
+ cDataSec = aNewDoc.createCDATASection("this is CDATASection data");
+ aNode = doc.importNode(cDataSec, false);
+ ownerDocument = aNode.getOwnerDocument();
+ assertNotNull("ownerDocumentNotNull", ownerDocument);
+ docType = ownerDocument.getDoctype();
+ system = docType.getSystemId();
+ assertURIEquals("dtdSystemId", null, null, null, "staffNS.dtd", null,
+ null, null, null, system);
+ value = aNode.getNodeValue();
+ assertEquals("nodeValue", "this is CDATASection data", value);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Doesn't verify DOMException.",
+ method = "importNode",
+ args = {org.w3c.dom.Node.class, boolean.class}
+ )
+ public void testImportNode3() throws Throwable {
+ Document doc;
+ Document aNewDoc;
+ Comment comment;
+ Node aNode;
+ Document ownerDocument;
+ DocumentType docType;
+ String system;
+ String value;
+ doc = (Document) load("staffNS", builder);
+ aNewDoc = (Document) load("staffNS", builder);
+ comment = aNewDoc.createComment("this is a comment");
+ aNode = doc.importNode(comment, false);
+ ownerDocument = aNode.getOwnerDocument();
+ assertNotNull("ownerDocumentNotNull", ownerDocument);
+ docType = ownerDocument.getDoctype();
+ system = docType.getSystemId();
+ assertURIEquals("systemId", null, null, null, "staffNS.dtd", null,
+ null, null, null, system);
+ value = aNode.getNodeValue();
+ assertEquals("nodeValue", "this is a comment", value);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Doesn't verify DOMException.",
+ method = "importNode",
+ args = {org.w3c.dom.Node.class, boolean.class}
+ )
+ public void testImportNode4() throws Throwable {
+ Document doc;
+ Document aNewDoc;
+ DocumentFragment docFrag;
+ Comment comment;
+ Node aNode;
+ NodeList children;
+ Node child;
+ String childValue;
+ doc = (Document) load("staff", builder);
+ aNewDoc = (Document) load("staff", builder);
+ docFrag = aNewDoc.createDocumentFragment();
+ comment = aNewDoc.createComment("descendant1");
+ aNode = docFrag.appendChild(comment);
+ aNode = doc.importNode(docFrag, true);
+ children = aNode.getChildNodes();
+ assertEquals("throw_Size", 1, children.getLength());
+ child = aNode.getFirstChild();
+ childValue = child.getNodeValue();
+ assertEquals("descendant1", "descendant1", childValue);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Doesn't verify DOMException.",
+ method = "importNode",
+ args = {org.w3c.dom.Node.class, boolean.class}
+ )
+ public void testImportNode5() throws Throwable {
+ Document doc;
+ Document aNewDoc;
+ Element element;
+ Node aNode;
+ boolean hasChild;
+ Document ownerDocument;
+ DocumentType docType;
+ String system;
+ String name;
+ NodeList addresses;
+ doc = (Document) load("staffNS", builder);
+ aNewDoc = (Document) load("staffNS", builder);
+ addresses = aNewDoc.getElementsByTagName("emp:address");
+ element = (Element) addresses.item(0);
+ assertNotNull("empAddressNotNull", element);
+ aNode = doc.importNode(element, false);
+ hasChild = aNode.hasChildNodes();
+ assertFalse("hasChild", hasChild);
+ ownerDocument = aNode.getOwnerDocument();
+ docType = ownerDocument.getDoctype();
+ system = docType.getSystemId();
+ assertURIEquals("dtdSystemId", null, null, null, "staffNS.dtd", null,
+ null, null, null, system);
+ name = aNode.getNodeName();
+ assertEquals("nodeName", "emp:address", name);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Doesn't verify DOMException.",
+ method = "importNode",
+ args = {org.w3c.dom.Node.class, boolean.class}
+ )
+ public void testImportNode6() throws Throwable {
+ Document doc;
+ Document aNewDoc;
+ Element element;
+ Node aNode;
+ boolean hasChild;
+ String name;
+ Node child;
+ String value;
+ NodeList addresses;
+ doc = (Document) load("staffNS", builder);
+ aNewDoc = (Document) load("staffNS", builder);
+ addresses = aNewDoc.getElementsByTagName("emp:address");
+ element = (Element) addresses.item(0);
+ assertNotNull("empAddressNotNull", element);
+ aNode = doc.importNode(element, true);
+ hasChild = aNode.hasChildNodes();
+ assertTrue("throw_True", hasChild);
+ name = aNode.getNodeName();
+ assertEquals("nodeName", "emp:address", name);
+ child = aNode.getFirstChild();
+ value = child.getNodeValue();
+ assertEquals("nodeValue", "27 South Road. Dallas, texas 98556", value);
+ }
+
+// Assumes validation.
+// public void testImportNode7() throws Throwable {
+// Document doc;
+// Document aNewDoc;
+// Element element;
+// Node aNode;
+// NamedNodeMap attributes;
+// String name;
+// Node attr;
+// String lname;
+// String namespaceURI = "http://www.nist.gov";
+// String qualifiedName = "emp:employee";
+// doc = (Document) load("staffNS", builder);
+// aNewDoc = (Document) load("staff", builder);
+// element = aNewDoc.createElementNS(namespaceURI, qualifiedName);
+// aNode = doc.importNode(element, false);
+// attributes = aNode.getAttributes();
+// assertEquals("throw_Size", 1, attributes.getLength());
+// name = aNode.getNodeName();
+// assertEquals("nodeName", "emp:employee", name);
+// attr = attributes.item(0);
+// lname = attr.getLocalName();
+// assertEquals("lname", "defaultAttr", lname);
+// }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Doesn't verify DOMException.",
+ method = "importNode",
+ args = {org.w3c.dom.Node.class, boolean.class}
+ )
+ public void testImportNode8() throws Throwable {
+ Document doc;
+ Document aNewDoc;
+ DocumentFragment docFrag;
+ Node aNode;
+ boolean hasChild;
+ Document ownerDocument;
+ DocumentType docType;
+ String system;
+ doc = (Document) load("staffNS", builder);
+ aNewDoc = (Document) load("staffNS", builder);
+ docFrag = aNewDoc.createDocumentFragment();
+ aNode = doc.importNode(docFrag, false);
+ hasChild = aNode.hasChildNodes();
+ assertFalse("hasChild", hasChild);
+ ownerDocument = aNode.getOwnerDocument();
+ docType = ownerDocument.getDoctype();
+ system = docType.getSystemId();
+ assertURIEquals("system", null, null, null, "staffNS.dtd", null, null,
+ null, null, system);
+ }
+
+// Assumes validation.
+// public void testImportNode9() throws Throwable {
+// Document doc;
+// Document aNewDoc;
+//
+// NamedNodeMap entityList;
+// Entity entity2;
+// Entity entity1;
+// Document ownerDocument;
+// DocumentType docType;
+// String system;
+// String entityName;
+// String publicVal;
+// String notationName;
+// doc = (Document) load("staffNS", builder);
+// aNewDoc = (Document) load("staffNS", builder);
+// docType = aNewDoc.getDoctype();
+// entityList = docType.getEntities();
+// assertNotNull("entitiesNotNull", entityList);
+// entity2 = (Entity) entityList.getNamedItem("ent6");
+// entity1 = (Entity) doc.importNode(entity2, false);
+// ownerDocument = entity1.getOwnerDocument();
+// docType = ownerDocument.getDoctype();
+// system = docType.getSystemId();
+// assertURIEquals("dtdSystemId", null, null, null, "staffNS.dtd", null,
+// null, null, null, system);
+// entityName = entity1.getNodeName();
+// assertEquals("entityName", "ent6", entityName);
+// publicVal = entity1.getPublicId();
+// assertEquals("entityPublicId", "uri", publicVal);
+// system = entity1.getSystemId();
+// assertURIEquals("entitySystemId", null, null, null, "file", null, null,
+// null, null, system);
+// notationName = entity1.getNotationName();
+// assertEquals("notationName", "notation2", notationName);
+// }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Doesn't verify DOMException.",
+ method = "importNode",
+ args = {org.w3c.dom.Node.class, boolean.class}
+ )
+ public void testImportNode10() throws Throwable {
+ Document doc;
+ Document aNewDoc;
+ EntityReference entRef;
+ Node aNode;
+ Document ownerDocument;
+ DocumentType docType;
+ String system;
+ String name;
+ doc = (Document) load("staffNS", builder);
+ aNewDoc = (Document) load("staffNS", builder);
+ entRef = aNewDoc.createEntityReference("entRef1");
+ assertNotNull("createdEntRefNotNull", entRef);
+ entRef.setNodeValue("entRef1Value");
+ aNode = doc.importNode(entRef, false);
+ ownerDocument = aNode.getOwnerDocument();
+ docType = ownerDocument.getDoctype();
+ system = docType.getSystemId();
+ assertURIEquals("systemId", null, null, null, "staffNS.dtd", null,
+ null, null, null, system);
+ name = aNode.getNodeName();
+ assertEquals("nodeName", "entRef1", name);
+ }
+
+// Assumes validation
+// public void testImportNode11() throws Throwable {
+// Document doc;
+// Document aNewDoc;
+// EntityReference entRef;
+// Node aNode;
+// String name;
+// Node child;
+// String childValue;
+// doc = (Document) load("staff", builder);
+// aNewDoc = (Document) load("staff", builder);
+// entRef = aNewDoc.createEntityReference("ent3");
+// assertNotNull("createdEntRefNotNull", entRef);
+// aNode = doc.importNode(entRef, true);
+// name = aNode.getNodeName();
+// assertEquals("entityName", "ent3", name);
+// child = aNode.getFirstChild();
+// assertNotNull("child", child);
+// childValue = child.getNodeValue();
+// assertEquals("childValue", "Texas", childValue);
+// }
+
+// Assumes validation.
+// public void testImportNode12() throws Throwable {
+// Document doc;
+// Document aNewDoc;
+// DocumentType doc1Type;
+// NamedNodeMap entityList;
+// Entity entity2;
+// Entity entity1;
+// Document ownerDocument;
+// DocumentType docType;
+// String system;
+// String entityName;
+// Node child;
+// String childName;
+// doc = (Document) load("staffNS", builder);
+// aNewDoc = (Document) load("staffNS", builder);
+// doc1Type = aNewDoc.getDoctype();
+// entityList = doc1Type.getEntities();
+// assertNotNull("entitiesNotNull", entityList);
+// entity2 = (Entity) entityList.getNamedItem("ent4");
+// entity1 = (Entity) doc.importNode(entity2, true);
+// ownerDocument = entity1.getOwnerDocument();
+// docType = ownerDocument.getDoctype();
+// system = docType.getSystemId();
+// assertURIEquals("systemId", null, null, null, "staffNS.dtd", null,
+// null, null, null, system);
+// entityName = entity1.getNodeName();
+// assertEquals("entityName", "ent4", entityName);
+// child = entity1.getFirstChild();
+// assertNotNull("notnull", child);
+// childName = child.getNodeName();
+// assertEquals("childName", "entElement1", childName);
+// }
+
+// Assumes validation
+// public void testImportNode13() throws Throwable {
+// Document doc;
+// Document aNewDoc;
+// DocumentType doc1Type;
+// NamedNodeMap notationList;
+// Notation notation;
+// Notation aNode;
+// Document ownerDocument;
+// DocumentType docType;
+// String system;
+// String publicVal;
+// doc = (Document) load("staffNS", builder);
+// aNewDoc = (Document) load("staffNS", builder);
+// doc1Type = aNewDoc.getDoctype();
+// notationList = doc1Type.getNotations();
+// assertNotNull("notationsNotNull", notationList);
+// notation = (Notation) notationList.getNamedItem("notation1");
+// aNode = (Notation) doc.importNode(notation, false);
+// ownerDocument = aNode.getOwnerDocument();
+// docType = ownerDocument.getDoctype();
+// system = docType.getSystemId();
+// assertURIEquals("systemId", null, null, null, "staffNS.dtd", null,
+// null, null, null, system);
+// publicVal = aNode.getPublicId();
+// assertEquals("publicId", "notation1File", publicVal);
+// system = aNode.getSystemId();
+// assertNull("notationSystemId", system);
+// }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Doesn't verify DOMException.",
+ method = "importNode",
+ args = {org.w3c.dom.Node.class, boolean.class}
+ )
+ public void testImportNode14() throws Throwable {
+ Document doc;
+ Document aNewDoc;
+ ProcessingInstruction pi;
+ ProcessingInstruction aNode;
+ Document ownerDocument;
+ DocumentType docType;
+ String system;
+ String target;
+ String data;
+
+ doc = (Document) load("staffNS", builder);
+ aNewDoc = (Document) load("staffNS", builder);
+ pi = aNewDoc.createProcessingInstruction("target1", "data1");
+ aNode = (ProcessingInstruction) doc.importNode(pi, false);
+ ownerDocument = aNode.getOwnerDocument();
+ assertNotNull("ownerDocumentNotNull", ownerDocument);
+ docType = ownerDocument.getDoctype();
+ system = docType.getSystemId();
+ assertURIEquals("systemId", null, null, null, "staffNS.dtd", null,
+ null, null, null, system);
+ target = aNode.getTarget();
+ assertEquals("piTarget", "target1", target);
+ data = aNode.getData();
+ assertEquals("piData", "data1", data);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Doesn't verify DOMException.",
+ method = "importNode",
+ args = {org.w3c.dom.Node.class, boolean.class}
+ )
+ public void testImportNode15() throws Throwable {
+ Document doc;
+ Document aNewDoc;
+ Text text;
+ Node aNode;
+ Document ownerDocument;
+ DocumentType docType;
+ String system;
+ String value;
+ doc = (Document) load("staffNS", builder);
+ aNewDoc = (Document) load("staffNS", builder);
+ text = aNewDoc.createTextNode("this is text data");
+ aNode = doc.importNode(text, false);
+ ownerDocument = aNode.getOwnerDocument();
+ assertNotNull("ownerDocumentNotNull", ownerDocument);
+ docType = ownerDocument.getDoctype();
+ system = docType.getSystemId();
+ assertURIEquals("systemId", null, null, null, "staffNS.dtd", null,
+ null, null, null, system);
+ value = aNode.getNodeValue();
+ assertEquals("nodeValue", "this is text data", value);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies that importNode method throws DOMException with NOT_SUPPORTED_ERR code.",
+ method = "importNode",
+ args = {org.w3c.dom.Node.class, boolean.class}
+ )
+ public void testImportNode16() throws Throwable {
+ Document doc;
+ Document anotherDoc;
+ DocumentType docType;
+
+ doc = (Document) load("staffNS", builder);
+ anotherDoc = (Document) load("staffNS", builder);
+ docType = anotherDoc.getDoctype();
+
+ {
+ boolean success = false;
+ try {
+ doc.importNode(docType, false);
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.NOT_SUPPORTED_ERR);
+ }
+ assertTrue("throw_NOT_SUPPORTED_ERR", success);
+ }
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies that importNode method throws DOMException with NOT_SUPPORTED_ERR code.",
+ method = "importNode",
+ args = {org.w3c.dom.Node.class, boolean.class}
+ )
+ public void testImportNode17() throws Throwable {
+ Document doc;
+ Document anotherDoc;
+
+ doc = (Document) load("staffNS", builder);
+ anotherDoc = (Document) load("staffNS", builder);
+
+ {
+ boolean success = false;
+ try {
+ doc.importNode(anotherDoc, false);
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.NOT_SUPPORTED_ERR);
+ }
+ assertTrue("throw_NOT_SUPPORTED_ERR", success);
+ }
+ }
+}
diff --git a/xml/src/test/java/tests/org/w3c/dom/InternalSubset.java b/xml/src/test/java/tests/org/w3c/dom/InternalSubset.java
new file mode 100644
index 0000000..f8f306c
--- /dev/null
+++ b/xml/src/test/java/tests/org/w3c/dom/InternalSubset.java
@@ -0,0 +1,92 @@
+
+/*
+This Java source file was generated by test-to-java.xsl
+and is a derived work from the source document.
+The source document contained the following notice:
+
+
+
+Copyright (c) 2001-2004 World Wide Web Consortium,
+(Massachusetts Institute of Technology, Institut National de
+Recherche en Informatique et en Automatique, Keio University). All
+Rights Reserved. This program is distributed under the W3C's Software
+Intellectual Property License. This program is distributed in the
+hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE.
+
+See W3C License http://www.w3.org/Consortium/Legal/ for more details.
+
+
+*/
+
+package tests.org.w3c.dom;
+
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import org.w3c.dom.DocumentType;
+import org.w3c.dom.Document;
+
+import javax.xml.parsers.DocumentBuilder;
+
+/**
+ * The "getInternalSubset()" method returns
+ * the internal subset as a string or null if there is none.
+ * This does not contain the delimiting brackets.
+ *
+ * Retrieve the documenttype.
+ * Apply the "getInternalSubset()" method. Null is returned since there
+ * is not an internal subset.
+* @author NIST
+* @author Mary Brady
+* @see <a href="http://www.w3.org/TR/DOM-Level-2-Core/core#ID-Core-DocType-internalSubset">http://www.w3.org/TR/DOM-Level-2-Core/core#ID-Core-DocType-internalSubset</a>
+*/
+@TestTargetClass(DocumentType.class)
+public final class InternalSubset extends DOMTestCase {
+
+ DOMDocumentBuilderFactory factory;
+
+ DocumentBuilder builder;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ try {
+ factory = new DOMDocumentBuilderFactory(DOMDocumentBuilderFactory
+ .getConfiguration1());
+ builder = factory.getBuilder();
+ } catch (Exception e) {
+ fail("Unexpected exception" + e.getMessage());
+ }
+ }
+
+ protected void tearDown() throws Exception {
+ factory = null;
+ builder = null;
+ super.tearDown();
+ }
+
+ /**
+ * Runs the test case.
+ * @throws Throwable Any uncaught exception causes test to fail
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Doesn't verify that getInternalSubset method returns the internal subset as a string.",
+ method = "getInternalSubset",
+ args = {}
+ )
+ public void testGetInternalSubset() throws Throwable {
+ Document doc;
+ DocumentType docType;
+ String internal;
+ doc = (Document) load("staff2", builder);
+ docType = doc.getDoctype();
+ internal = docType.getInternalSubset();
+ assertNull("internalSubsetNull", internal);
+ }
+
+}
+
diff --git a/xml/src/test/java/tests/org/w3c/dom/IsSupported.java b/xml/src/test/java/tests/org/w3c/dom/IsSupported.java
new file mode 100644
index 0000000..318a81d
--- /dev/null
+++ b/xml/src/test/java/tests/org/w3c/dom/IsSupported.java
@@ -0,0 +1,272 @@
+package tests.org.w3c.dom;
+
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+
+import javax.xml.parsers.DocumentBuilder;
+
+/**
+ * The "feature" parameter in the isSupported(feature,version)" method is the
+ * name of the feature and the version is the version number of the feature to
+ * test. XXX is NOT a legal value for the feature parameter. The method should
+ * return "false" since XXX is not a valid feature.
+ *
+ * Retrieve the root node of the DOM document by invoking the
+ * "getDocumentElement()" method. This should create a node object on which the
+ * "isSupported(feature,version)" method is invoked with "feature" equal to
+ * "XXX" and version to "1.0". The method should return a boolean "false" since
+ * XXX is not a valid feature.
+ *
+ * @author NIST
+ * @author Mary Brady
+ * @see <a
+ * href="http://www.w3.org/TR/DOM-Level-2-Core/core#Level-2-Core-Node-supports">http://www.w3.org/TR/DOM-Level-2-Core/core#Level-2-Core-Node-supports</a>
+ */
+@TestTargetClass(Document.class)
+public final class IsSupported extends DOMTestCase {
+
+ DOMDocumentBuilderFactory factory;
+
+ DocumentBuilder builder;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ try {
+ factory = new DOMDocumentBuilderFactory(DOMDocumentBuilderFactory
+ .getConfiguration1());
+ builder = factory.getBuilder();
+ } catch (Exception e) {
+ fail("Unexpected exception" + e.getMessage());
+ }
+ }
+
+ protected void tearDown() throws Exception {
+ factory = null;
+ builder = null;
+ super.tearDown();
+ }
+
+ /**
+ * Runs the test case.
+ *
+ * @throws Throwable
+ * Any uncaught exception causes test to fail
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Verifies that isSupported method returns false.",
+ method = "isSupported",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testIsSupported1() throws Throwable {
+ Document doc;
+ Node rootNode;
+ boolean state;
+ doc = (Document) load("staff", builder);
+ rootNode = doc.getDocumentElement();
+ state = rootNode.isSupported("XXX", "1.0");
+ assertFalse("throw_False", state);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Verifies that isSupported method returns false value.",
+ method = "isSupported",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testIsSupported2() throws Throwable {
+ Document doc;
+ Node rootNode;
+ boolean state;
+ doc = (Document) load("staff", builder);
+ rootNode = doc.getDocumentElement();
+ state = rootNode.isSupported("XML", "9.0");
+ assertFalse("throw_False", state);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Verifies that isSupported method returns true value.",
+ method = "isSupported",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testIsSupported4() throws Throwable {
+ Document doc;
+ Node rootNode;
+ boolean state;
+ doc = (Document) load("staff", builder);
+ rootNode = doc.getDocumentElement();
+ state = rootNode.isSupported("xml", "1.0");
+ assertTrue("throw_True", state);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Verifies that isSupported method returns true value.",
+ method = "isSupported",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testIsSupported5() throws Throwable {
+ Document doc;
+ Node rootNode;
+ boolean state;
+ doc = (Document) load("staff", builder);
+ rootNode = doc.getDocumentElement();
+ state = rootNode.isSupported("core", "2.0");
+ assertTrue("throw_True", state);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Verifies that isSupported method returns true value.",
+ method = "isSupported",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testIsSupported6() throws Throwable {
+ Document doc;
+ Node rootNode;
+ boolean state;
+ doc = (Document) load("staff", builder);
+ rootNode = doc.getDocumentElement();
+ state = rootNode.isSupported("xml", "2.0");
+ assertTrue("throw_True", state);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Verifies that isSupported method returns true value.",
+ method = "isSupported",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testIsSupported7() throws Throwable {
+ Document doc;
+ Node rootNode;
+ boolean state;
+ doc = (Document) load("staff", builder);
+ rootNode = doc.getDocumentElement();
+ state = rootNode.isSupported("XML", "");
+ assertTrue("throw_True", state);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Verifies that isSupported method returns true value.",
+ method = "isSupported",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testIsSupported9() throws Throwable {
+ Document doc;
+ Node rootNode;
+ boolean state;
+ doc = (Document) load("staff", builder);
+ rootNode = doc.getDocumentElement();
+ state = rootNode.isSupported("XML", "1.0");
+ assertTrue("throw_True", state);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Verifies that isSupported method returns true.",
+ method = "isSupported",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testIsSupported10() throws Throwable {
+ Document doc;
+ Node rootNode;
+ boolean state;
+ doc = (Document) load("staff", builder);
+ rootNode = doc.getDocumentElement();
+ state = rootNode.isSupported("CORE", "2.0");
+ assertTrue("throw_True", state);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Verifies that isSupported method returns true.",
+ method = "isSupported",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testIsSupported11() throws Throwable {
+ Document doc;
+ Node rootNode;
+ boolean state;
+ doc = (Document) load("staff", builder);
+ rootNode = doc.getDocumentElement();
+ state = rootNode.isSupported("XML", "2.0");
+ assertTrue("throw_True", state);
+ }
+
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "",
+ method = "isSupported",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testIsSupported12() throws Throwable {
+ List<String> features = new ArrayList<String>();
+ features.add("Core");
+ features.add("XML");
+ features.add("HTML");
+ features.add("Views");
+ features.add("StyleSheets");
+ features.add("CSS");
+ features.add("CSS2");
+ features.add("Events");
+ features.add("UIEvents");
+ features.add("MouseEvents");
+ features.add("MutationEvents");
+ features.add("HTMLEvents");
+ features.add("Range");
+ features.add("Traversal");
+ features.add("bogus.bogus.bogus");
+
+ Document doc;
+ Node rootNode;
+ String featureElement;
+ boolean state;
+ doc = (Document) load("staff", builder);
+ rootNode = doc.getDocumentElement();
+ state = rootNode.isSupported("Core", "2.0");
+ assertTrue("Core2", state);
+ for (int indexN10078 = 0; indexN10078 < features.size(); indexN10078++) {
+ featureElement = (String) features.get(indexN10078);
+ state = rootNode.isSupported(featureElement, "1.0");
+ }
+ for (int indexN10083 = 0; indexN10083 < features.size(); indexN10083++) {
+ featureElement = (String) features.get(indexN10083);
+ state = rootNode.isSupported(featureElement, "2.0");
+ }
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Verifies that isSupported method returns correct value if it has empty string as a version parameter.",
+ method = "isSupported",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testIsSupported13() throws Throwable {
+ Document doc;
+ Node rootNode;
+ boolean state;
+ doc = (Document) load("staff", builder);
+ rootNode = doc.getDocumentElement();
+ state = rootNode.isSupported("Core", "");
+ assertTrue("Core", state);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Verifies that isSupported method returns correct value if it has null as a version parameter.",
+ method = "isSupported",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testIsSupported14() throws Throwable {
+ Document doc;
+ Node rootNode;
+ boolean state;
+ String nullString = null;
+
+ doc = (Document) load("staff", builder);
+ rootNode = doc.getDocumentElement();
+ state = rootNode.isSupported("Core", nullString);
+ assertTrue("Core", state);
+ }
+}
diff --git a/xml/src/test/java/tests/org/w3c/dom/LocalName.java b/xml/src/test/java/tests/org/w3c/dom/LocalName.java
new file mode 100644
index 0000000..3f1d9c3
--- /dev/null
+++ b/xml/src/test/java/tests/org/w3c/dom/LocalName.java
@@ -0,0 +1,132 @@
+package tests.org.w3c.dom;
+
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import org.w3c.dom.Node;
+import org.w3c.dom.Document;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Element;
+import org.w3c.dom.Attr;
+
+import javax.xml.parsers.DocumentBuilder;
+
+/**
+ * The "getLocalName()" method for a Node returns the local part of the
+ * qualified name of this node, and for nodes of any type other than
+ * ELEMENT_NODE and ATTRIBUTE_NODE and nodes created with a DOM Level 1 method,
+ * this is null.
+ *
+ * Retrieve the first emp:address node and get the attributes of this node."
+ * Then apply the getLocalName() method to the emp:domestic attribute. The
+ * method should return "domestic".
+ *
+ * @author NIST
+ * @author Mary Brady
+ * @see <a
+ * href="http://www.w3.org/TR/DOM-Level-2-Core/core#ID-NodeNSLocalN">http://www.w3.org/TR/DOM-Level-2-Core/core#ID-NodeNSLocalN</a>
+ */
+@TestTargetClass(Node.class)
+public final class LocalName extends DOMTestCase {
+
+ DOMDocumentBuilderFactory factory;
+
+ DocumentBuilder builder;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ try {
+ factory = new DOMDocumentBuilderFactory(DOMDocumentBuilderFactory
+ .getConfiguration2());
+ builder = factory.getBuilder();
+ } catch (Exception e) {
+ fail("Unexpected exception" + e.getMessage());
+ }
+ }
+
+ protected void tearDown() throws Exception {
+ factory = null;
+ builder = null;
+ super.tearDown();
+ }
+
+ /**
+ * Runs the test case.
+ *
+ * @throws Throwable
+ * Any uncaught exception causes test to fail
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies positive functionality.",
+ method = "getLocalName",
+ args = {}
+ )
+ public void testGetLocalName1() throws Throwable {
+ Document doc;
+ NodeList elementList;
+ Element testAddr;
+ Attr addrAttr;
+ String localName;
+ doc = (Document) load("staffNS", builder);
+ elementList = doc.getElementsByTagName("emp:address");
+ testAddr = (Element) elementList.item(0);
+ assertNotNull("empAddrNotNull", testAddr);
+ addrAttr = testAddr.getAttributeNode("emp:domestic");
+ localName = addrAttr.getLocalName();
+ assertEquals("localName", "domestic", localName);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies that getLocalName method returns null.",
+ method = "getLocalName",
+ args = {}
+ )
+ public void testGetLocalName2() throws Throwable {
+ Document doc;
+ Node createdNode;
+ String localName;
+ doc = (Document) load("staffNS", builder);
+ createdNode = doc.createElement("test:employee");
+ localName = createdNode.getLocalName();
+ assertNull("localNameNull", localName);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies that getLocalName method returns null.",
+ method = "getLocalName",
+ args = {}
+ )
+ public void testGetLocalName3() throws Throwable {
+ Document doc;
+ NodeList elementList;
+ Node testEmployee;
+ Node textNode;
+ String localName;
+ doc = (Document) load("staffNS", builder);
+ elementList = doc.getElementsByTagName("employeeId");
+ testEmployee = elementList.item(0);
+ textNode = testEmployee.getFirstChild();
+ localName = textNode.getLocalName();
+ assertNull("textNodeLocalName", localName);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies positive functionality.",
+ method = "getLocalName",
+ args = {}
+ )
+ public void testGetLocalName4() throws Throwable {
+ Document doc;
+ NodeList elementList;
+ Node testEmployee;
+ String employeeLocalName;
+ doc = (Document) load("staffNS", builder);
+ elementList = doc.getElementsByTagName("employee");
+ testEmployee = elementList.item(0);
+ employeeLocalName = testEmployee.getLocalName();
+ assertEquals("lname", "employee", employeeLocalName);
+ }
+}
diff --git a/xml/src/test/java/tests/org/w3c/dom/NamedNodeMapGetNamedItemNS.java b/xml/src/test/java/tests/org/w3c/dom/NamedNodeMapGetNamedItemNS.java
new file mode 100644
index 0000000..e4ab1df
--- /dev/null
+++ b/xml/src/test/java/tests/org/w3c/dom/NamedNodeMapGetNamedItemNS.java
@@ -0,0 +1,229 @@
+/*
+ This Java source file was generated by test-to-java.xsl
+ and is a derived work from the source document.
+ The source document contained the following notice:
+
+
+
+ Copyright (c) 2001-2004 World Wide Web Consortium,
+ (Massachusetts Institute of Technology, Institut National de
+ Recherche en Informatique et en Automatique, Keio University). All
+ Rights Reserved. This program is distributed under the W3C's Software
+ Intellectual Property License. This program is distributed in the
+ hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+ See W3C License http://www.w3.org/Consortium/Legal/ for more details.
+
+
+ */
+
+package tests.org.w3c.dom;
+
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Element;
+
+import javax.xml.parsers.DocumentBuilder;
+
+/**
+ * Using the method getNamedItemNS, retreive the entity "ent1" and notation
+ * "notation1" from a NamedNodeMap of this DocumentTypes entities and notations.
+ * Both should be null since entities and notations are not namespaced.
+ *
+ * @author IBM
+ * @author Neil Delima
+ * @see <a
+ * href="http://www.w3.org/TR/DOM-Level-2-Core/core#ID-getNamedItemNS">http://www.w3.org/TR/DOM-Level-2-Core/core#ID-getNamedItemNS</a>
+ * @see <a
+ * href="http://www.w3.org/Bugs/Public/show_bug.cgi?id=259">http://www.w3.org/Bugs/Public/show_bug.cgi?id=259</a>
+ * @see <a
+ * href="http://www.w3.org/Bugs/Public/show_bug.cgi?id=407">http://www.w3.org/Bugs/Public/show_bug.cgi?id=407</a>
+ * @see <a
+ * href="http://lists.w3.org/Archives/Member/w3c-dom-ig/2003Nov/0016.html">http://lists.w3.org/Archives/Member/w3c-dom-ig/2003Nov/0016.html</a>
+ */
+@TestTargetClass(NamedNodeMap.class)
+public final class NamedNodeMapGetNamedItemNS extends DOMTestCase {
+
+ DOMDocumentBuilderFactory factory;
+
+ DocumentBuilder builder;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ try {
+ factory = new DOMDocumentBuilderFactory(DOMDocumentBuilderFactory
+ .getConfiguration2());
+ builder = factory.getBuilder();
+ } catch (Exception e) {
+ fail("Unexpected exception" + e.getMessage());
+ }
+ }
+
+ protected void tearDown() throws Exception {
+ factory = null;
+ builder = null;
+ super.tearDown();
+ }
+
+ /**
+ * Runs the test case.
+ *
+ * @throws Throwable
+ * Any uncaught exception causes test to fail
+ */
+// Assumes validation.
+// public void testGetNamedItemNS1() throws Throwable {
+// Document doc;
+// DocumentType docType;
+// NamedNodeMap entities;
+// NamedNodeMap notations;
+// Entity entity;
+// Notation notation;
+//
+// String nullNS = null;
+//
+// doc = (Document) load("staffNS", builder);
+// docType = doc.getDoctype();
+// entities = docType.getEntities();
+// assertNotNull("entitiesNotNull", entities);
+// notations = docType.getNotations();
+// assertNotNull("notationsNotNull", notations);
+// entity = (Entity) entities.getNamedItemNS(nullNS, "ent1");
+// assertNotNull("entityNull", entity);
+// notation = (Notation) notations.getNamedItemNS(nullNS, "notation1");
+// assertNotNull("notationNull", notation);
+// }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Doesn't verify DOMException.",
+ method = "getNamedItemNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testGetNamedItemNS2() throws Throwable {
+ Document doc;
+ NamedNodeMap attributes;
+ Node element;
+ Attr attribute;
+ NodeList elementList;
+ String attrName;
+ doc = (Document) load("staffNS", builder);
+ elementList = doc.getElementsByTagNameNS("http://www.nist.gov",
+ "address");
+ element = elementList.item(1);
+ attributes = element.getAttributes();
+ attribute = (Attr) attributes.getNamedItemNS("http://www.nist.gov",
+ "domestic");
+ attrName = attribute.getNodeName();
+ assertEquals("namednodemapgetnameditemns02", "emp:domestic", attrName);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Doesn't verify DOMException.",
+ method = "getNamedItemNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testGetNamedItemNS3() throws Throwable {
+ Document doc;
+ NamedNodeMap attributes;
+ Node element;
+ Attr attribute;
+ Attr newAttr1;
+ Attr newAttr2;
+
+ String attrName;
+ doc = (Document) load("staffNS", builder);
+ element = doc.createElementNS("http://www.w3.org/DOM/Test", "root");
+ newAttr1 = doc.createAttributeNS("http://www.w3.org/DOM/L1", "L1:att");
+ ((Element) /* Node */element).setAttributeNodeNS(newAttr1);
+ newAttr2 = doc.createAttributeNS("http://www.w3.org/DOM/L2", "L2:att");
+ ((Element) /* Node */element).setAttributeNodeNS(newAttr2);
+ attributes = element.getAttributes();
+ attribute = (Attr) attributes.getNamedItemNS(
+ "http://www.w3.org/DOM/L2", "att");
+ attrName = attribute.getNodeName();
+ assertEquals("namednodemapgetnameditemns03", "L2:att", attrName);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Doesn't verify DOMException.",
+ method = "getNamedItemNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testGetNamedItemNS4() throws Throwable {
+ Document doc;
+ NamedNodeMap attributes;
+ Element element;
+ Attr attribute;
+ Attr newAttr1;
+ NodeList elementList;
+ String attrName;
+ doc = (Document) load("staffNS", builder);
+ elementList = doc.getElementsByTagNameNS("*", "address");
+ element = (Element) elementList.item(1);
+ newAttr1 = doc.createAttributeNS("http://www.w3.org/DOM/L1", "street");
+ element.setAttributeNodeNS(newAttr1);
+ attributes = element.getAttributes();
+ attribute = (Attr) attributes.getNamedItemNS(
+ "http://www.w3.org/DOM/L1", "street");
+ attrName = attribute.getNodeName();
+ assertEquals("namednodemapgetnameditemns04", "street", attrName);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Doesn't verify DOMException.",
+ method = "getNamedItemNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testGetNamedItemNS5() throws Throwable {
+ Document doc;
+ NamedNodeMap attributes;
+ Node element;
+ Attr attribute;
+ NodeList elementList;
+ doc = (Document) load("staffNS", builder);
+ elementList = doc.getElementsByTagNameNS("*", "address");
+ element = elementList.item(1);
+ attributes = element.getAttributes();
+ attribute = (Attr) attributes.getNamedItemNS("*", "street");
+ assertNull("namednodemapgetnameditemns05", attribute);
+ }
+
+// Assumes validation.
+// public void testGetNamedItemNS6() throws Throwable {
+// Document doc;
+// NamedNodeMap attributesMap1;
+// NamedNodeMap attributesMap2;
+// Element element;
+// Attr attribute;
+// Attr newAttr1;
+//
+// NodeList elementList;
+// String attrName;
+// doc = (Document) load("staffNS", builder);
+// elementList = doc.getElementsByTagNameNS("*", "address");
+// element = (Element) elementList.item(1);
+// attributesMap1 = element.getAttributes();
+// attributesMap2 = element.getAttributes();
+// newAttr1 = doc.createAttributeNS("http://www.w3.org/DOM/L1", "street");
+// element.setAttributeNodeNS(newAttr1);
+// attribute = (Attr) attributesMap1.getNamedItemNS(
+// "http://www.w3.org/DOM/L1", "street");
+// attrName = attribute.getNodeName();
+// assertEquals("namednodemapgetnameditemnsMap106", "street", attrName);
+// attribute = (Attr) attributesMap2.getNamedItemNS(
+// "http://www.w3.org/DOM/L1", "street");
+// attrName = attribute.getNodeName();
+// assertEquals("namednodemapgetnameditemnsMap206", "street", attrName);
+// }
+
+}
diff --git a/xml/src/test/java/tests/org/w3c/dom/NamedNodeMapRemoveNamedItemNS.java b/xml/src/test/java/tests/org/w3c/dom/NamedNodeMapRemoveNamedItemNS.java
new file mode 100644
index 0000000..16a6cda
--- /dev/null
+++ b/xml/src/test/java/tests/org/w3c/dom/NamedNodeMapRemoveNamedItemNS.java
@@ -0,0 +1,342 @@
+/*
+ This Java source file was generated by test-to-java.xsl
+ and is a derived work from the source document.
+ The source document contained the following notice:
+
+
+
+ Copyright (c) 2001 World Wide Web Consortium,
+ (Massachusetts Institute of Technology, Institut National de
+ Recherche en Informatique et en Automatique, Keio University). All
+ Rights Reserved. This program is distributed under the W3C's Software
+ Intellectual Property License. This program is distributed in the
+ hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+ See W3C License http://www.w3.org/Consortium/Legal/ for more details.
+
+
+ */
+
+package tests.org.w3c.dom;
+
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Element;
+import org.w3c.dom.DOMException;
+
+import javax.xml.parsers.DocumentBuilder;
+
+/**
+ * The method removeNamedItemNS removes a node specified by local name and
+ * namespace
+ *
+ * Retreive an attribute node and then remove from the NamedNodeMap. Verify if
+ * the attribute node was actually remove from the node map.
+ *
+ * @author IBM
+ * @author Neil Delima
+ * @see <a
+ * href="http://www.w3.org/TR/DOM-Level-2-Core/core#ID-D58B193">http://www.w3.org/TR/DOM-Level-2-Core/core#ID-D58B193</a>
+ */
+@TestTargetClass(NamedNodeMap.class)
+public final class NamedNodeMapRemoveNamedItemNS extends DOMTestCase {
+
+ DOMDocumentBuilderFactory factory;
+
+ DocumentBuilder builder;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ try {
+ factory = new DOMDocumentBuilderFactory(DOMDocumentBuilderFactory
+ .getConfiguration2());
+ builder = factory.getBuilder();
+ } catch (Exception e) {
+ fail("Unexpected exception" + e.getMessage());
+ }
+ }
+
+ protected void tearDown() throws Exception {
+ factory = null;
+ builder = null;
+ super.tearDown();
+ }
+
+ /**
+ * Runs the test case.
+ *
+ * @throws Throwable
+ * Any uncaught exception causes test to fail
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Doesn't verify DOMException.",
+ method = "removeNamedItemNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testRemoveNamedItemNS1() throws Throwable {
+ Document doc;
+ NamedNodeMap attributes;
+ Node element;
+ Attr attribute;
+ NodeList elementList;
+ doc = (Document) load("staffNS", builder);
+ elementList = doc.getElementsByTagNameNS("http://www.nist.gov",
+ "address");
+ element = elementList.item(1);
+ attributes = element.getAttributes();
+ attribute = (Attr) attributes.removeNamedItemNS("http://www.nist.gov",
+ "domestic");
+ attribute = (Attr) attributes.getNamedItemNS("http://www.nist.gov",
+ "domestic");
+ assertNull("namednodemapremovenameditemns01", attribute);
+ }
+
+// Assumes validation.
+// public void testRemoveNamedItemNS2() throws Throwable {
+// Document doc;
+// NamedNodeMap attributes;
+// Node element;
+// Attr attribute;
+// NodeList elementList;
+// String attrValue;
+// String nullNS = null;
+//
+// doc = (Document) load("staffNS", builder);
+// elementList = doc.getElementsByTagNameNS("http://www.nist.gov",
+// "employee");
+// element = elementList.item(1);
+// attributes = element.getAttributes();
+// attribute = (Attr) attributes.removeNamedItemNS(nullNS, "defaultAttr");
+// attribute = (Attr) attributes.getNamedItemNS(nullNS, "defaultAttr");
+// attrValue = attribute.getNodeValue();
+// assertNotNull("namednodemapremovenameditemns02", attribute);
+// assertEquals("namednodemapremovenameditemns02_attrValue", "defaultVal",
+// attrValue);
+// }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Doesn't verify DOMException.",
+ method = "removeNamedItemNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testRemoveNamedItemNS3() throws Throwable {
+ Document doc;
+ NamedNodeMap attributes;
+ Node element;
+ Attr attribute;
+
+ Attr attribute1;
+ Attr attribute2;
+ String nodeName;
+ doc = (Document) load("staffNS", builder);
+ element = doc.createElementNS("http://www.w3.org/DOM/Test", "root");
+ attribute1 = doc
+ .createAttributeNS("http://www.w3.org/DOM/L1", "L1:att");
+ ((Element) /* Node */element).setAttributeNodeNS(attribute1);
+ attribute2 = doc
+ .createAttributeNS("http://www.w3.org/DOM/L2", "L2:att");
+ ((Element) /* Node */element).setAttributeNodeNS(attribute2);
+ attributes = element.getAttributes();
+ attribute = (Attr) attributes.removeNamedItemNS(
+ "http://www.w3.org/DOM/L1", "att");
+ attribute = (Attr) attributes.getNamedItemNS(
+ "http://www.w3.org/DOM/L2", "att");
+ nodeName = attribute.getNodeName();
+ assertEquals("namednodemapremovenameditemns02", "L2:att", nodeName);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Doesn't verify DOMException.",
+ method = "removeNamedItemNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void _testRemoveNamedItemNS4() throws Throwable {
+ Document doc;
+ NamedNodeMap attributes;
+ Node element;
+ Attr attribute;
+
+ NodeList elementList;
+ doc = (Document) load("staffNS", builder);
+ elementList = doc.getElementsByTagNameNS("*", "employee");
+ element = elementList.item(0);
+ attributes = element.getAttributes();
+ attributes.removeNamedItemNS("http://www.w3.org/2000/xmlns/", "xmlns");
+ attribute = (Attr) attributes.getNamedItemNS(
+ "http://www.w3.org/2000/xmlns/", "xmlns");
+ assertNull("namednodemapremovenameditemns04_1", attribute);
+ attributes.removeNamedItemNS("http://www.w3.org/2000/xmlns/", "dmstc");
+ attribute = (Attr) attributes.getNamedItemNS(
+ "http://www.w3.org/2000/xmlns/", "dmstc");
+ assertNull("namednodemapremovenameditemns04_2", attribute);
+ }
+
+// Assumes validation.
+// public void testRemoveNamedItemNS5() throws Throwable {
+// Document doc;
+// DocumentType docType;
+// NamedNodeMap entities;
+// NamedNodeMap notations;
+//
+// String nullNS = null;
+//
+// doc = (Document) load("staffNS", builder);
+// docType = doc.getDoctype();
+// entities = docType.getEntities();
+// assertNotNull("entitiesNotNull", entities);
+// notations = docType.getNotations();
+// assertNotNull("notationsNotNull", notations);
+//
+// try {
+// entities.removeNamedItemNS(nullNS, "ent1");
+// fail("entity_throw_DOMException");
+//
+// } catch (DOMException ex) {
+// switch (ex.code) {
+// case 8:
+// break;
+// case 7:
+// break;
+// default:
+// throw ex;
+// }
+// }
+//
+// try {
+// notations.removeNamedItemNS(nullNS, "notation1");
+// fail("notation_throw_DOMException");
+//
+// } catch (DOMException ex) {
+// switch (ex.code) {
+// case 8:
+// break;
+// case 7:
+// break;
+// default:
+// throw ex;
+// }
+// }
+// }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies that removeNamedItemNS method throws DOMException with NOT_FOUND_ERR code.",
+ method = "removeNamedItemNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testRemoveNamedItemNS6() throws Throwable {
+ Document doc;
+ NamedNodeMap attributes;
+ Node element;
+
+ NodeList elementList;
+ doc = (Document) load("staffNS", builder);
+ elementList = doc.getElementsByTagNameNS("http://www.nist.gov",
+ "employee");
+ element = elementList.item(1);
+ attributes = element.getAttributes();
+
+ {
+ boolean success = false;
+ try {
+ attributes.removeNamedItemNS("http://www.Nist.gov", "domestic");
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.NOT_FOUND_ERR);
+ }
+ assertTrue("throw_NOT_FOUND_ERR", success);
+ }
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies that removeNamedItemNS method throws DOMException with NOT_FOUND_ERR code.",
+ method = "removeNamedItemNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testRemoveNamedItemNS7() throws Throwable {
+ Document doc;
+ NamedNodeMap attributes;
+ Node element;
+
+ NodeList elementList;
+ doc = (Document) load("staffNS", builder);
+ elementList = doc.getElementsByTagNameNS("http://www.nist.gov",
+ "employee");
+ element = elementList.item(1);
+ attributes = element.getAttributes();
+
+ {
+ boolean success = false;
+ try {
+ attributes.removeNamedItemNS("http://www.nist.gov", "domestic");
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.NOT_FOUND_ERR);
+ }
+ assertTrue("throw_NOT_FOUND_ERR", success);
+ }
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies that removeNamedItemNS method throws DOMException with NOT_FOUND_ERR code.",
+ method = "removeNamedItemNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testRemoveNamedItemNS8() throws Throwable {
+ Document doc;
+ NamedNodeMap attributes;
+ Element element;
+
+ NodeList elementList;
+ doc = (Document) load("staffNS", builder);
+ elementList = doc.getElementsByTagNameNS("http://www.nist.gov",
+ "address");
+ element = (Element) elementList.item(1);
+ attributes = element.getAttributes();
+ element.removeAttributeNS("http://www.nist.gov", "domestic");
+
+ {
+ boolean success = false;
+ try {
+ attributes.removeNamedItemNS("http://www.nist.gov", "domestic");
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.NOT_FOUND_ERR);
+ }
+ assertTrue("throw_NOT_FOUND_ERR", success);
+ }
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Doesn't verify DOMException.",
+ method = "removeNamedItemNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testRemoveNamedItemNS9() throws Throwable {
+ Document doc;
+ NamedNodeMap attributes;
+ NamedNodeMap newAttributes;
+ Element element;
+ Attr attribute;
+ NodeList elementList;
+ doc = (Document) load("staffNS", builder);
+ elementList = doc.getElementsByTagNameNS("http://www.nist.gov",
+ "address");
+ element = (Element) elementList.item(1);
+ attributes = element.getAttributes();
+ attribute = (Attr) attributes.removeNamedItemNS("http://www.nist.gov",
+ "domestic");
+ newAttributes = element.getAttributes();
+ attribute = (Attr) newAttributes.getNamedItemNS("http://www.nist.gov",
+ "domestic");
+ assertNull("namednodemapremovenameditemns09", attribute);
+ }
+
+}
diff --git a/xml/src/test/java/tests/org/w3c/dom/NamedNodeMapSetNamedItemNS.java b/xml/src/test/java/tests/org/w3c/dom/NamedNodeMapSetNamedItemNS.java
new file mode 100644
index 0000000..e0ec0df
--- /dev/null
+++ b/xml/src/test/java/tests/org/w3c/dom/NamedNodeMapSetNamedItemNS.java
@@ -0,0 +1,451 @@
+/*
+ This Java source file was generated by test-to-java.xsl
+ and is a derived work from the source document.
+ The source document contained the following notice:
+
+
+
+ Copyright (c) 2001 World Wide Web Consortium,
+ (Massachusetts Institute of Technology, Institut National de
+ Recherche en Informatique et en Automatique, Keio University). All
+ Rights Reserved. This program is distributed under the W3C's Software
+ Intellectual Property License. This program is distributed in the
+ hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+ See W3C License http://www.w3.org/Consortium/Legal/ for more details.
+
+
+ */
+
+package tests.org.w3c.dom;
+
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Document;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Element;
+import org.w3c.dom.DOMException;
+import org.w3c.dom.DOMImplementation;
+import org.w3c.dom.DocumentType;
+
+import javax.xml.parsers.DocumentBuilder;
+
+/**
+ * The method setNamedItemNS adds a node using its namespaceURI and localName.
+ * If a node with that namespace URI and that local name is already present in
+ * this map, it is replaced by the new one.
+ *
+ * Retreive the first element whose localName is address and namespaceURI
+ * http://www.nist.gov", and put its attributes into a named node map. Create a
+ * new attribute node and add it to this map. Verify if the attr node was
+ * successfully added by checking the nodeName of the retreived atttribute.
+ *
+ * @author IBM
+ * @author Neil Delima
+ * @see <a
+ * href="http://www.w3.org/TR/DOM-Level-2-Core/core#ID-getNamedItemNS">http://www.w3.org/TR/DOM-Level-2-Core/core#ID-getNamedItemNS</a>
+ */
+@TestTargetClass(NamedNodeMap.class)
+public final class NamedNodeMapSetNamedItemNS extends DOMTestCase {
+
+ DOMDocumentBuilderFactory factory;
+
+ DocumentBuilder builder;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ try {
+ // Changed to configuration #2. This test case just doesn't make
+ // sense without a namespace-aware parser. It actually fails even
+ // on the JDK in that case.
+ factory = new DOMDocumentBuilderFactory(DOMDocumentBuilderFactory
+ .getConfiguration2());
+ builder = factory.getBuilder();
+ } catch (Exception e) {
+ fail("Unexpected exception" + e.getMessage());
+ }
+ }
+
+ protected void tearDown() throws Exception {
+ factory = null;
+ builder = null;
+ super.tearDown();
+ }
+
+ /**
+ * Runs the test case.
+ *
+ * @throws Throwable
+ * Any uncaught exception causes test to fail
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Doesn't verify DOMException.",
+ method = "setNamedItemNS",
+ args = {org.w3c.dom.Node.class}
+ )
+ public void testSetNamedItemNS1() throws Throwable {
+ Document doc;
+ NamedNodeMap attributes;
+ Node element;
+ Attr attribute;
+
+ Attr newAttr1;
+ NodeList elementList;
+ String attrName;
+ doc = (Document) load("staffNS", builder);
+ elementList = doc.getElementsByTagNameNS("http://www.nist.gov",
+ "address");
+ element = elementList.item(0);
+ attributes = element.getAttributes();
+ newAttr1 = doc.createAttributeNS("http://www.w3.org/DOM/L1", "streets");
+ ((Element) /* Node */element).setAttributeNodeNS(newAttr1);
+ attribute = (Attr) attributes.getNamedItemNS(
+ "http://www.w3.org/DOM/L1", "streets");
+ attrName = attribute.getNodeName();
+ assertEquals("namednodemapsetnameditemns01", "streets", attrName);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Doesn't verify DOMException.",
+ method = "setNamedItemNS",
+ args = {org.w3c.dom.Node.class}
+ )
+ public void testSetNamedItemNS2() throws Throwable {
+ Document doc;
+ NamedNodeMap attributes;
+ Element element;
+ Attr attribute;
+ Attr attribute1;
+
+ String attrName;
+ doc = (Document) load("staffNS", builder);
+ element = doc.createElementNS("http://www.w3.org/DOM/Test", "root");
+ attribute1 = doc
+ .createAttributeNS("http://www.w3.org/DOM/L1", "L1:att");
+ attributes = element.getAttributes();
+ attributes.setNamedItemNS(attribute1);
+ attribute = (Attr) attributes.getNamedItemNS(
+ "http://www.w3.org/DOM/L1", "att");
+ attrName = attribute.getNodeName();
+ assertEquals("namednodemapsetnameditemns02", "L1:att", attrName);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Verifies that setNamedItemNS throws DOMException with WRONG_DOCUMENT_ERR code.",
+ method = "setNamedItemNS",
+ args = {org.w3c.dom.Node.class}
+ )
+ public void testSetNamedItemNS3() throws Throwable {
+
+ Document doc;
+ Document docAlt;
+ NamedNodeMap attributes;
+ NamedNodeMap attributesAlt;
+ NodeList elementList;
+ NodeList elementListAlt;
+ Element element;
+ Element elementAlt;
+ Attr attr;
+
+ String nullNS = null;
+
+ doc = (Document) load("staffNS", builder);
+ elementList = doc.getElementsByTagNameNS("*", "address");
+ element = (Element) elementList.item(1);
+ attributes = element.getAttributes();
+ docAlt = (Document) load("staffNS", builder);
+ elementListAlt = docAlt.getElementsByTagNameNS("*", "address");
+ elementAlt = (Element) elementListAlt.item(1);
+ attributesAlt = elementAlt.getAttributes();
+ attr = (Attr) attributesAlt.getNamedItemNS(nullNS, "street");
+ attributesAlt.removeNamedItemNS(nullNS, "street");
+
+ {
+ boolean success = false;
+ try {
+ attributes.setNamedItemNS(attr);
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.WRONG_DOCUMENT_ERR);
+ }
+ assertTrue("throw_WRONG_DOCUMENT_ERR", success);
+ }
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Verifies that setNamedItemNS throws DOMException with WRONG_DOCUMENT_ERR code.",
+ method = "setNamedItemNS",
+ args = {org.w3c.dom.Node.class}
+ )
+ public void testSetNamedItemNS4() throws Throwable {
+ Document doc;
+ DOMImplementation domImpl;
+ Document docAlt;
+ DocumentType docType = null;
+
+ NamedNodeMap attributes;
+ NodeList elementList;
+ Element element;
+ Attr attrAlt;
+
+ String nullNS = null;
+
+ doc = (Document) load("staffNS", builder);
+ elementList = doc.getElementsByTagNameNS("*", "address");
+ element = (Element) elementList.item(1);
+ attributes = element.getAttributes();
+ domImpl = doc.getImplementation();
+ docAlt = domImpl.createDocument(nullNS, "newDoc", docType);
+ attrAlt = docAlt.createAttributeNS(nullNS, "street");
+
+ {
+ boolean success = false;
+ try {
+ attributes.setNamedItemNS(attrAlt);
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.WRONG_DOCUMENT_ERR);
+ }
+ assertTrue("throw_WRONG_DOCUMENT_ERR", success);
+ }
+ }
+
+// Assumes validation.
+// public void testSetNamedItemNS5() throws Throwable {
+// Document doc;
+// DocumentType docType;
+// NamedNodeMap entities;
+// NamedNodeMap notations;
+// Entity entity;
+// Notation notation;
+//
+// doc = (Document) load("staffNS", builder);
+// docType = doc.getDoctype();
+// entities = docType.getEntities();
+// assertNotNull("entitiesNotNull", entities);
+// notations = docType.getNotations();
+// assertNotNull("notationsNotNull", notations);
+// entity = (Entity) entities.getNamedItem("ent1");
+// notation = (Notation) notations.getNamedItem("notation1");
+//
+// {
+// boolean success = false;
+// try {
+// entities.setNamedItemNS(entity);
+// } catch (DOMException ex) {
+// success = (ex.code == DOMException.NO_MODIFICATION_ALLOWED_ERR);
+// }
+// assertTrue("throw_NO_MODIFICATION_ALLOWED_ERR_entities", success);
+// }
+//
+// {
+// boolean success = false;
+// try {
+// notations.setNamedItemNS(notation);
+// } catch (DOMException ex) {
+// success = (ex.code == DOMException.NO_MODIFICATION_ALLOWED_ERR);
+// }
+// assertTrue("throw_NO_MODIFICATION_ALLOWED_ERR_notations", success);
+// }
+// }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Verifies that setNamedItemNS throws DOMException with INUSE_ATTRIBUTE_ERR code.",
+ method = "setNamedItemNS",
+ args = {org.w3c.dom.Node.class}
+ )
+ public void testSetNamedItemNS6() throws Throwable {
+ Document doc;
+ NamedNodeMap attributes;
+ NodeList elementList;
+ Element element;
+ Attr attr;
+
+ doc = (Document) load("staffNS", builder);
+ elementList = doc.getElementsByTagNameNS("*", "address");
+ element = (Element) elementList.item(0);
+ attributes = element.getAttributes();
+ attr = (Attr) attributes.getNamedItemNS("http://www.usa.com",
+ "domestic");
+ element = (Element) elementList.item(1);
+ attributes = element.getAttributes();
+
+ {
+ boolean success = false;
+ try {
+ attributes.setNamedItemNS(attr);
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.INUSE_ATTRIBUTE_ERR);
+ }
+ assertTrue("namednodemapsetnameditemns06", success);
+ }
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Verifies that setNamedItemNS throws DOMException with INUSE_ATTRIBUTE_ERR code.",
+ method = "setNamedItemNS",
+ args = {org.w3c.dom.Node.class}
+ )
+ public void testSetNamedItemNS7() throws Throwable {
+ Document doc;
+ NamedNodeMap attributes;
+ NodeList elementList;
+ Element element;
+ Attr attr;
+
+ doc = (Document) load("staffNS", builder);
+ elementList = doc.getElementsByTagNameNS("*", "address");
+ element = (Element) elementList.item(0);
+ attributes = element.getAttributes();
+ attr = (Attr) attributes.getNamedItemNS("http://www.usa.com",
+ "domestic");
+ element = (Element) elementList.item(1);
+ attributes = element.getAttributes();
+
+ {
+ boolean success = false;
+ try {
+ attributes.setNamedItemNS(attr);
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.INUSE_ATTRIBUTE_ERR);
+ }
+ assertTrue("namednodemapsetnameditemns07", success);
+ }
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Verifies that setNamedItemNS throws DOMException with INUSE_ATTRIBUTE_ERR code.",
+ method = "setNamedItemNS",
+ args = {org.w3c.dom.Node.class}
+ )
+ public void testSetNamedItemNS8() throws Throwable {
+ Document doc;
+ NamedNodeMap attributes;
+ NodeList elementList;
+ Element element;
+ Attr attr;
+
+ doc = (Document) load("staffNS", builder);
+ elementList = doc.getElementsByTagNameNS("*", "address");
+ element = (Element) elementList.item(0);
+ attributes = element.getAttributes();
+ attr = (Attr) attributes.getNamedItemNS("http://www.usa.com",
+ "domestic");
+ element = (Element) elementList.item(1);
+ attributes = element.getAttributes();
+
+ {
+ boolean success = false;
+ try {
+ attributes.setNamedItemNS(attr);
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.INUSE_ATTRIBUTE_ERR);
+ }
+ assertTrue("namednodemapsetnameditemns08", success);
+ }
+ }
+
+// Assumes validation.
+// public void testSetNamedItemNS9() throws Throwable {
+// Document doc;
+// DocumentType docType;
+// NamedNodeMap entities;
+// NamedNodeMap notations;
+// Attr attr;
+// doc = (Document) load("staffNS", builder);
+// docType = doc.getDoctype();
+// entities = docType.getEntities();
+// notations = docType.getNotations();
+// attr = doc.createAttributeNS("http://www.w3.org/DOM/Test", "test");
+//
+// {
+// boolean success = false;
+// try {
+// entities.setNamedItemNS(attr);
+// } catch (DOMException ex) {
+// success = (ex.code == DOMException.NO_MODIFICATION_ALLOWED_ERR);
+// }
+// assertTrue("throw_NO_MODIFICATION_ALLOWED_ERR_entities", success);
+// }
+//
+// {
+// boolean success = false;
+// try {
+// notations.setNamedItemNS(attr);
+// } catch (DOMException ex) {
+// success = (ex.code == DOMException.NO_MODIFICATION_ALLOWED_ERR);
+// }
+// assertTrue("throw_NO_MODIFICATION_ALLOWED_ERR_notations", success);
+// }
+// }
+
+// Assumes validation.
+// public void testSetNamedItemNS10() throws Throwable {
+// Document doc;
+// DocumentType docType;
+// NamedNodeMap entities;
+// NamedNodeMap attributes;
+// Entity entity;
+//
+// Element element;
+// NodeList elementList;
+//
+// doc = (Document) load("staffNS", builder);
+// docType = doc.getDoctype();
+// entities = docType.getEntities();
+// assertNotNull("entitiesNotNull", entities);
+// entity = (Entity) entities.getNamedItem("ent1");
+// elementList = doc.getElementsByTagNameNS("http://www.nist.gov",
+// "address");
+// element = (Element) elementList.item(0);
+// attributes = element.getAttributes();
+//
+// {
+// boolean success = false;
+// try {
+// attributes.setNamedItemNS(entity);
+// } catch (DOMException ex) {
+// success = (ex.code == DOMException.HIERARCHY_REQUEST_ERR);
+// }
+// assertTrue("throw_HIERARCHY_REQUEST_ERR", success);
+// }
+// }
+
+// Assumes validation.
+// public void testSetNamedItemNS11() throws Throwable {
+// Document doc;
+// DocumentType docType;
+// NamedNodeMap notations;
+// NamedNodeMap attributes;
+// Notation notation;
+// Element element;
+// NodeList elementList;
+//
+// doc = (Document) load("staffNS", builder);
+// docType = doc.getDoctype();
+// notations = docType.getNotations();
+// assertNotNull("notationsNotNull", notations);
+// notation = (Notation) notations.getNamedItem("notation1");
+// elementList = doc.getElementsByTagNameNS("http://www.nist.gov",
+// "address");
+// element = (Element) elementList.item(0);
+// attributes = element.getAttributes();
+//
+// {
+// boolean success = false;
+// try {
+// attributes.setNamedItemNS(notation);
+// } catch (DOMException ex) {
+// success = (ex.code == DOMException.HIERARCHY_REQUEST_ERR);
+// }
+// assertTrue("throw_HIERARCHY_REQUEST_ERR", success);
+// }
+// }
+}
diff --git a/xml/src/test/java/tests/org/w3c/dom/NamespaceURI.java b/xml/src/test/java/tests/org/w3c/dom/NamespaceURI.java
new file mode 100644
index 0000000..dba8b86
--- /dev/null
+++ b/xml/src/test/java/tests/org/w3c/dom/NamespaceURI.java
@@ -0,0 +1,153 @@
+/*
+ This Java source file was generated by test-to-java.xsl
+ and is a derived work from the source document.
+ The source document contained the following notice:
+
+
+
+ Copyright (c) 2001-2003 World Wide Web Consortium,
+ (Massachusetts Institute of Technology, Institut National de
+ Recherche en Informatique et en Automatique, Keio University). All
+ Rights Reserved. This program is distributed under the W3C's Software
+ Intellectual Property License. This program is distributed in the
+ hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+ See W3C License http://www.w3.org/Consortium/Legal/ for more details.
+
+
+ */
+
+package tests.org.w3c.dom;
+
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+import javax.xml.parsers.DocumentBuilder;
+
+/**
+ * The "getNamespaceURI()" method for an Attribute returns the namespace URI of
+ * this node, or null if unspecified.
+ *
+ * Retrieve the first "emp:address" node which has an attribute of
+ * "emp:district" that is specified in the DTD. Invoke the "getNamespaceURI()"
+ * method on the attribute. The method should return "http://www.nist.gov".
+ *
+ * @author NIST
+ * @author Mary Brady
+ * @see <a
+ * href="http://www.w3.org/TR/DOM-Level-2-Core/core#ID-NodeNSname">http://www.w3.org/TR/DOM-Level-2-Core/core#ID-NodeNSname</a>
+ * @see <a
+ * href="http://www.w3.org/Bugs/Public/show_bug.cgi?id=238">http://www.w3.org/Bugs/Public/show_bug.cgi?id=238</a>
+ */
+@TestTargetClass(Attr.class)
+public final class NamespaceURI extends DOMTestCase {
+
+ DOMDocumentBuilderFactory factory;
+
+ DocumentBuilder builder;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ try {
+ factory = new DOMDocumentBuilderFactory(DOMDocumentBuilderFactory
+ .getConfiguration2());
+ builder = factory.getBuilder();
+ } catch (Exception e) {
+ fail("Unexpected exception" + e.getMessage());
+ }
+ }
+
+ protected void tearDown() throws Exception {
+ factory = null;
+ builder = null;
+ super.tearDown();
+ }
+
+ /**
+ * Runs the test case.
+ *
+ * @throws Throwable
+ * Any uncaught exception causes test to fail
+ */
+// Assumes validation.
+// public void testGetNamespaceURI1() throws Throwable {
+// Document doc;
+// NodeList elementList;
+// Element testAddr;
+// Attr addrAttr;
+// String attrNamespaceURI;
+// doc = (Document) load("staffNS", builder);
+// elementList = doc.getElementsByTagName("emp:address");
+// testAddr = (Element) elementList.item(0);
+// addrAttr = testAddr.getAttributeNodeNS("http://www.nist.gov",
+// "district");
+// attrNamespaceURI = addrAttr.getNamespaceURI();
+// assertEquals("namespaceURI", "http://www.nist.gov", attrNamespaceURI);
+// }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Doesn't verify that getNamespaceURI method returns null.",
+ method = "getNamespaceURI",
+ args = {}
+ )
+ public void testGetNamespaceURI2() throws Throwable {
+ Document doc;
+ NodeList elementList;
+ Element testAddr;
+ Attr addrAttr;
+ String attrNamespaceURI;
+ doc = (Document) load("staffNS", builder);
+ elementList = doc.getElementsByTagName("emp:address");
+ testAddr = (Element) elementList.item(0);
+ assertNotNull("empAddressNotNull", testAddr);
+ addrAttr = testAddr.getAttributeNodeNS("http://www.nist.gov",
+ "domestic");
+ attrNamespaceURI = addrAttr.getNamespaceURI();
+ assertEquals("namespaceURI", "http://www.nist.gov", attrNamespaceURI);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Doesn't verify that getNamespaceURI method returns null.",
+ method = "getNamespaceURI",
+ args = {}
+ )
+ public void testGetNamespaceURI3() throws Throwable {
+ Document doc;
+ NodeList elementList;
+ Node testEmployee;
+ String employeeNamespace;
+ doc = (Document) load("staffNS", builder);
+ elementList = doc.getElementsByTagName("employee");
+ testEmployee = elementList.item(0);
+ assertNotNull("employeeNotNull", testEmployee);
+ employeeNamespace = testEmployee.getNamespaceURI();
+ assertEquals("namespaceURI", "http://www.nist.gov", employeeNamespace);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Verifies that getNamespaceURI method returns null.",
+ method = "getNamespaceURI",
+ args = {}
+ )
+ public void testGetNamespaceURI4() throws Throwable {
+ Document doc;
+ NodeList elementList;
+ Node testEmployee;
+ String employeeNamespace;
+ doc = (Document) load("staffNS", builder);
+ elementList = doc.getElementsByTagName("employee");
+ testEmployee = elementList.item(1);
+ employeeNamespace = testEmployee.getNamespaceURI();
+ assertNull("throw_Null", employeeNamespace);
+ }
+}
diff --git a/xml/src/test/java/tests/org/w3c/dom/NodeGetLocalName.java b/xml/src/test/java/tests/org/w3c/dom/NodeGetLocalName.java
new file mode 100644
index 0000000..d508465
--- /dev/null
+++ b/xml/src/test/java/tests/org/w3c/dom/NodeGetLocalName.java
@@ -0,0 +1,107 @@
+
+/*
+This Java source file was generated by test-to-java.xsl
+and is a derived work from the source document.
+The source document contained the following notice:
+
+
+
+Copyright (c) 2001 World Wide Web Consortium,
+(Massachusetts Institute of Technology, Institut National de
+Recherche en Informatique et en Automatique, Keio University). All
+Rights Reserved. This program is distributed under the W3C's Software
+Intellectual Property License. This program is distributed in the
+hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE.
+
+See W3C License http://www.w3.org/Consortium/Legal/ for more details.
+
+
+*/
+
+package tests.org.w3c.dom;
+
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import org.w3c.dom.Node;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Attr;
+
+import javax.xml.parsers.DocumentBuilder;
+
+/**
+ * The method getLocalName returns the local part of the qualified name of this node.
+ *
+ * Ceate two new element nodes and atribute nodes, with and without namespace prefixes.
+ * Retreive the local part of their qualified names using getLocalName and verrify
+ * if it is correct.
+* @author IBM
+* @author Neil Delima
+* @see <a href="http://www.w3.org/TR/DOM-Level-2-Core/core#ID-NodeNSLocalN">http://www.w3.org/TR/DOM-Level-2-Core/core#ID-NodeNSLocalN</a>
+*/
+@TestTargetClass(Node.class)
+public final class NodeGetLocalName extends DOMTestCase {
+
+ DOMDocumentBuilderFactory factory;
+
+ DocumentBuilder builder;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ try {
+ factory = new DOMDocumentBuilderFactory(DOMDocumentBuilderFactory
+ .getConfiguration1());
+ builder = factory.getBuilder();
+ } catch (Exception e) {
+ fail("Unexpected exception" + e.getMessage());
+ }
+ }
+
+ protected void tearDown() throws Exception {
+ factory = null;
+ builder = null;
+ super.tearDown();
+ }
+
+ /**
+ * Runs the test case.
+ * @throws Throwable Any uncaught exception causes test to fail
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Doesn't verify that getLocalName method returns null.",
+ method = "getLocalName",
+ args = {}
+ )
+ public void testGetLocalName() throws Throwable {
+ Document doc;
+ Element element;
+ Element qelement;
+ Attr attr;
+ Attr qattr;
+ String localElemName;
+ String localQElemName;
+ String localAttrName;
+ String localQAttrName;
+ doc = (Document) load("staff", builder);
+ element = doc.createElementNS("http://www.w3.org/DOM/Test/elem", "elem");
+ qelement = doc.createElementNS("http://www.w3.org/DOM/Test/elem", "qual:qelem");
+ attr = doc.createAttributeNS("http://www.w3.org/DOM/Test/attr", "attr");
+ qattr = doc.createAttributeNS("http://www.w3.org/DOM/Test/attr", "qual:qattr");
+ localElemName = element.getLocalName();
+ localQElemName = qelement.getLocalName();
+ localAttrName = attr.getLocalName();
+ localQAttrName = qattr.getLocalName();
+ assertEquals("nodegetlocalname03_localElemName", "elem", localElemName);
+ assertEquals("nodegetlocalname03_localQElemName", "qelem", localQElemName);
+ assertEquals("nodegetlocalname03_localAttrName", "attr", localAttrName);
+ assertEquals("nodegetlocalname03_localQAttrName", "qattr", localQAttrName);
+ }
+
+}
+
diff --git a/xml/src/test/java/tests/org/w3c/dom/NodeGetNamespaceURI.java b/xml/src/test/java/tests/org/w3c/dom/NodeGetNamespaceURI.java
new file mode 100644
index 0000000..5ed1e29
--- /dev/null
+++ b/xml/src/test/java/tests/org/w3c/dom/NodeGetNamespaceURI.java
@@ -0,0 +1,111 @@
+
+/*
+This Java source file was generated by test-to-java.xsl
+and is a derived work from the source document.
+The source document contained the following notice:
+
+
+
+Copyright (c) 2001-2003 World Wide Web Consortium,
+(Massachusetts Institute of Technology, Institut National de
+Recherche en Informatique et en Automatique, Keio University). All
+Rights Reserved. This program is distributed under the W3C's Software
+Intellectual Property License. This program is distributed in the
+hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE.
+
+See W3C License http://www.w3.org/Consortium/Legal/ for more details.
+
+
+*/
+
+package tests.org.w3c.dom;
+
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import org.w3c.dom.Node;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Attr;
+
+import javax.xml.parsers.DocumentBuilder;
+
+/**
+ * The method getNamespaceURI returns the namespace URI of this node, or null if it is unspecified
+ * For nodes of any type other than ELEMENT_NODE and ATTRIBUTE_NODE and nodes created with
+ * a DOM Level 1 method, such as createElement from the Document interface, this is always null.
+ *
+ * Ceate two new element nodes and atribute nodes, with and without namespace prefixes.
+ * Retreive their namespaceURI's using getNamespaceURI and verrify if it is correct.
+* @author IBM
+* @author Neil Delima
+* @see <a href="http://www.w3.org/TR/DOM-Level-2-Core/core#ID-NodeNSname">http://www.w3.org/TR/DOM-Level-2-Core/core#ID-NodeNSname</a>
+* @see <a href="http://www.w3.org/Bugs/Public/show_bug.cgi?id=259">http://www.w3.org/Bugs/Public/show_bug.cgi?id=259</a>
+*/
+@TestTargetClass(Node.class)
+public final class NodeGetNamespaceURI extends DOMTestCase {
+
+ DOMDocumentBuilderFactory factory;
+
+ DocumentBuilder builder;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ try {
+ factory = new DOMDocumentBuilderFactory(DOMDocumentBuilderFactory
+ .getConfiguration1());
+ builder = factory.getBuilder();
+ } catch (Exception e) {
+ fail("Unexpected exception" + e.getMessage());
+ }
+ }
+
+ protected void tearDown() throws Exception {
+ factory = null;
+ builder = null;
+ super.tearDown();
+ }
+
+ /**
+ * Runs the test case.
+ * @throws Throwable Any uncaught exception causes test to fail
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getNamespaceURI",
+ args = {}
+ )
+ public void testGetNamespaceURI() throws Throwable {
+ Document doc;
+ Element element;
+ Element elementNS;
+ Attr attr;
+ Attr attrNS;
+ String elemNSURI;
+ String elemNSURINull;
+ String attrNSURI;
+ String attrNSURINull;
+ String nullNS = null;
+
+ doc = (Document) load("staff", builder);
+ element = doc.createElementNS(nullNS, "elem");
+ elementNS = doc.createElementNS("http://www.w3.org/DOM/Test/elem", "qual:qelem");
+ attr = doc.createAttributeNS(nullNS, "attr");
+ attrNS = doc.createAttributeNS("http://www.w3.org/DOM/Test/attr", "qual:qattr");
+ elemNSURI = elementNS.getNamespaceURI();
+ elemNSURINull = element.getNamespaceURI();
+ attrNSURI = attrNS.getNamespaceURI();
+ attrNSURINull = attr.getNamespaceURI();
+ assertEquals("nodegetnamespaceuri03_elemNSURI", "http://www.w3.org/DOM/Test/elem", elemNSURI);
+ assertNull("nodegetnamespaceuri03_1", elemNSURINull);
+ assertEquals("nodegetnamespaceuri03_attrNSURI", "http://www.w3.org/DOM/Test/attr", attrNSURI);
+ assertNull("nodegetnamespaceuri03_2", attrNSURINull);
+ }
+
+}
+
diff --git a/xml/src/test/java/tests/org/w3c/dom/NodeGetOwnerDocument.java b/xml/src/test/java/tests/org/w3c/dom/NodeGetOwnerDocument.java
new file mode 100644
index 0000000..3579c15
--- /dev/null
+++ b/xml/src/test/java/tests/org/w3c/dom/NodeGetOwnerDocument.java
@@ -0,0 +1,128 @@
+/*
+ This Java source file was generated by test-to-java.xsl
+ and is a derived work from the source document.
+ The source document contained the following notice:
+
+
+
+ Copyright (c) 2001-2003 World Wide Web Consortium,
+ (Massachusetts Institute of Technology, Institut National de
+ Recherche en Informatique et en Automatique, Keio University). All
+ Rights Reserved. This program is distributed under the W3C's Software
+ Intellectual Property License. This program is distributed in the
+ hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+ See W3C License http://www.w3.org/Consortium/Legal/ for more details.
+
+
+ */
+
+package tests.org.w3c.dom;
+
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import org.w3c.dom.Node;
+import org.w3c.dom.Document;
+import org.w3c.dom.DocumentType;
+import org.w3c.dom.DOMImplementation;
+import org.w3c.dom.Element;
+
+import javax.xml.parsers.DocumentBuilder;
+
+/**
+ * The method getOwnerDocument returns the Document object associated with this
+ * node
+ *
+ * Create a new DocumentType node. Since this node is not used with any Document
+ * yet verify if the ownerDocument is null.
+ *
+ * @author IBM
+ * @author Neil Delima
+ * @see <a
+ * href="http://www.w3.org/TR/DOM-Level-2-Core/core#node-ownerDoc">http://www.w3.org/TR/DOM-Level-2-Core/core#node-ownerDoc</a>
+ * @see <a
+ * href="http://www.w3.org/Bugs/Public/show_bug.cgi?id=259">http://www.w3.org/Bugs/Public/show_bug.cgi?id=259</a>
+ */
+@TestTargetClass(Node.class)
+public final class NodeGetOwnerDocument extends DOMTestCase {
+
+ DOMDocumentBuilderFactory factory;
+
+ DocumentBuilder builder;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ try {
+ factory = new DOMDocumentBuilderFactory(DOMDocumentBuilderFactory
+ .getConfiguration1());
+ builder = factory.getBuilder();
+ } catch (Exception e) {
+ fail("Unexpected exception" + e.getMessage());
+ }
+ }
+
+ protected void tearDown() throws Exception {
+ factory = null;
+ builder = null;
+ super.tearDown();
+ }
+
+ /**
+ * Runs the test case.
+ *
+ * @throws Throwable
+ * Any uncaught exception causes test to fail
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Verifies that getOwnerDocument method returns null.",
+ method = "getOwnerDocument",
+ args = {}
+ )
+ public void testGetOwnerDocument1() throws Throwable {
+ Document doc;
+ Document ownerDoc;
+ DOMImplementation domImpl;
+ DocumentType docType;
+ String nullID = null;
+
+ doc = (Document) load("staff", builder);
+ domImpl = doc.getImplementation();
+ docType = domImpl.createDocumentType("mydoc", nullID, nullID);
+ ownerDoc = docType.getOwnerDocument();
+ assertNull("nodegetownerdocument01", ownerDoc);
+ }
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getOwnerDocument",
+ args = {}
+ )
+ public void testGetOwnerDocument2() throws Throwable {
+ Document doc;
+ Document newDoc;
+ Element newElem;
+ Document ownerDocDoc;
+ Document ownerDocElem;
+ DOMImplementation domImpl;
+ DocumentType docType;
+ String nullNS = null;
+
+ doc = (Document) load("staff", builder);
+ domImpl = doc.getImplementation();
+ docType = domImpl.createDocumentType("mydoc", nullNS, nullNS);
+ newDoc = domImpl.createDocument("http://www.w3.org/DOM/Test", "mydoc",
+ docType);
+ ownerDocDoc = newDoc.getOwnerDocument();
+ assertNull("nodegetownerdocument02_1", ownerDocDoc);
+ newElem = newDoc
+ .createElementNS("http://www.w3.org/DOM/Test", "myelem");
+ ownerDocElem = newElem.getOwnerDocument();
+ assertNotNull("nodegetownerdocument02_2", ownerDocElem);
+ }
+}
diff --git a/xml/src/test/java/tests/org/w3c/dom/NodeGetPrefix.java b/xml/src/test/java/tests/org/w3c/dom/NodeGetPrefix.java
new file mode 100644
index 0000000..bcf8bba
--- /dev/null
+++ b/xml/src/test/java/tests/org/w3c/dom/NodeGetPrefix.java
@@ -0,0 +1,108 @@
+
+/*
+This Java source file was generated by test-to-java.xsl
+and is a derived work from the source document.
+The source document contained the following notice:
+
+
+
+Copyright (c) 2001 World Wide Web Consortium,
+(Massachusetts Institute of Technology, Institut National de
+Recherche en Informatique et en Automatique, Keio University). All
+Rights Reserved. This program is distributed under the W3C's Software
+Intellectual Property License. This program is distributed in the
+hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE.
+
+See W3C License http://www.w3.org/Consortium/Legal/ for more details.
+
+
+*/
+
+package tests.org.w3c.dom;
+
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import org.w3c.dom.Node;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Attr;
+
+import javax.xml.parsers.DocumentBuilder;
+
+/**
+ * The method getPrefix returns the namespace prefix of this node, or null if it is unspecified.
+ *
+ * Ceate two new element nodes and atribute nodes, with and without namespace prefixes.
+ * Retreive the prefix part of their qualified names using getPrefix and verify
+ * if it is correct.
+* @author IBM
+* @author Neil Delima
+* @see <a href="http://www.w3.org/TR/DOM-Level-2-Core/core#ID-NodeNSPrefix">http://www.w3.org/TR/DOM-Level-2-Core/core#ID-NodeNSPrefix</a>
+*/
+@TestTargetClass(Node.class)
+public final class NodeGetPrefix extends DOMTestCase {
+
+ DOMDocumentBuilderFactory factory;
+
+ DocumentBuilder builder;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ try {
+ factory = new DOMDocumentBuilderFactory(DOMDocumentBuilderFactory
+ .getConfiguration1());
+ builder = factory.getBuilder();
+ } catch (Exception e) {
+ fail("Unexpected exception" + e.getMessage());
+ }
+ }
+
+ protected void tearDown() throws Exception {
+ factory = null;
+ builder = null;
+ super.tearDown();
+ }
+
+
+ /**
+ * Runs the test case.
+ * @throws Throwable Any uncaught exception causes test to fail
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getPrefix",
+ args = {}
+ )
+ public void testGetPrefix() throws Throwable {
+ Document doc;
+ Element element;
+ Element qelement;
+ Attr attr;
+ Attr qattr;
+ String elemNoPrefix;
+ String elemPrefix;
+ String attrNoPrefix;
+ String attrPrefix;
+ doc = (Document) load("staff", builder);
+ element = doc.createElementNS("http://www.w3.org/DOM/Test/elem", "elem");
+ qelement = doc.createElementNS("http://www.w3.org/DOM/Test/elem", "qual:qelem");
+ attr = doc.createAttributeNS("http://www.w3.org/DOM/Test/attr", "attr");
+ qattr = doc.createAttributeNS("http://www.w3.org/DOM/Test/attr", "qual:qattr");
+ elemNoPrefix = element.getPrefix();
+ elemPrefix = qelement.getPrefix();
+ attrNoPrefix = attr.getPrefix();
+ attrPrefix = qattr.getPrefix();
+ assertNull("nodegetprefix03_1", elemNoPrefix);
+ assertEquals("nodegetprefix03_2", "qual", elemPrefix);
+ assertNull("nodegetprefix03_3", attrNoPrefix);
+ assertEquals("nodegetprefix03_4", "qual", attrPrefix);
+ }
+
+}
+
diff --git a/xml/src/test/java/tests/org/w3c/dom/NodeHasAttributes.java b/xml/src/test/java/tests/org/w3c/dom/NodeHasAttributes.java
new file mode 100644
index 0000000..514b205
--- /dev/null
+++ b/xml/src/test/java/tests/org/w3c/dom/NodeHasAttributes.java
@@ -0,0 +1,171 @@
+/*
+ This Java source file was generated by test-to-java.xsl
+ and is a derived work from the source document.
+ The source document contained the following notice:
+
+
+
+ Copyright (c) 2001 World Wide Web Consortium,
+ (Massachusetts Institute of Technology, Institut National de
+ Recherche en Informatique et en Automatique, Keio University). All
+ Rights Reserved. This program is distributed under the W3C's Software
+ Intellectual Property License. This program is distributed in the
+ hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+ See W3C License http://www.w3.org/Consortium/Legal/ for more details.
+
+
+ */
+
+package tests.org.w3c.dom;
+
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import org.w3c.dom.Node;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.DocumentType;
+import org.w3c.dom.Attr;
+import org.w3c.dom.DOMImplementation;
+
+import javax.xml.parsers.DocumentBuilder;
+
+/**
+ * The method hasAttributes returns whether this node (if it is an element) has
+ * any attributes. Retreive an element node without attributes. Verify if
+ * hasAttributes returns false. Retreive another element node with attributes.
+ * Verify if hasAttributes returns true.
+ *
+ * @author IBM
+ * @author Neil Delima
+ * @see <a
+ * href="http://www.w3.org/TR/DOM-Level-2-Core/core#ID-NodeHasAttrs">http://www.w3.org/TR/DOM-Level-2-Core/core#ID-NodeHasAttrs</a>
+ */
+@TestTargetClass(Node.class)
+public final class NodeHasAttributes extends DOMTestCase {
+
+ DOMDocumentBuilderFactory factory;
+
+ DocumentBuilder builder;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ try {
+ factory = new DOMDocumentBuilderFactory(DOMDocumentBuilderFactory
+ .getConfiguration1());
+ builder = factory.getBuilder();
+ } catch (Exception e) {
+ fail("Unexpected exception" + e.getMessage());
+ }
+ }
+
+ protected void tearDown() throws Exception {
+ factory = null;
+ builder = null;
+ super.tearDown();
+ }
+
+ /**
+ * Runs the test case.
+ *
+ * @throws Throwable
+ * Any uncaught exception causes test to fail
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "hasAttributes",
+ args = {}
+ )
+ public void testHasAttributes1() throws Throwable {
+ Document doc;
+ Element element;
+ NodeList elementList;
+ boolean hasAttributes;
+ doc = (Document) load("staff", builder);
+ elementList = doc.getElementsByTagName("employee");
+ element = (Element) elementList.item(0);
+ hasAttributes = element.hasAttributes();
+ assertFalse("nodehasattributes01_1", hasAttributes);
+ elementList = doc.getElementsByTagName("address");
+ element = (Element) elementList.item(0);
+ hasAttributes = element.hasAttributes();
+ assertTrue("nodehasattributes01_2", hasAttributes);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Verifies that hasAttributes method returns false value.",
+ method = "hasAttributes",
+ args = {}
+ )
+ public void testHasAttributes2() throws Throwable {
+ Document doc;
+ DocumentType docType;
+ boolean hasAttributes;
+ doc = (Document) load("staffNS", builder);
+ docType = doc.getDoctype();
+ hasAttributes = docType.hasAttributes();
+ assertFalse("nodehasattributes02", hasAttributes);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Verifies that hasAttributes method returns true value.",
+ method = "hasAttributes",
+ args = {}
+ )
+ public void testHasAttributes3() throws Throwable {
+ Document doc;
+ Element element;
+ NodeList elementList;
+ boolean hasAttributes;
+ doc = (Document) load("staffNS", builder);
+ elementList = doc.getElementsByTagName("emp:employee");
+ element = (Element) elementList.item(0);
+ assertNotNull("empEmployeeNotNull", element);
+ hasAttributes = element.hasAttributes();
+ assertTrue("hasAttributes", hasAttributes);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Verifies that hasAttributes method returns true value.",
+ method = "hasAttributes",
+ args = {}
+ )
+ public void testHasAttributes4() throws Throwable {
+ Document doc;
+ Document newDoc;
+ DocumentType docType = null;
+
+ DOMImplementation domImpl;
+ Element element;
+ Element elementTest;
+ Element elementDoc;
+ Attr attribute;
+
+
+ NodeList elementList;
+ boolean hasAttributes;
+ doc = (Document) load("staffNS", builder);
+ domImpl = doc.getImplementation();
+ newDoc = domImpl.createDocument("http://www.w3.org/DOM/Test", "test",
+ docType);
+ element = newDoc.createElementNS("http://www.w3.org/DOM/Test",
+ "dom:elem");
+ attribute = newDoc.createAttribute("attr");
+ element.setAttributeNode(attribute);
+ elementDoc = newDoc.getDocumentElement();
+ elementDoc.appendChild(element);
+ elementList = newDoc.getElementsByTagNameNS(
+ "http://www.w3.org/DOM/Test", "elem");
+ elementTest = (Element) elementList.item(0);
+ hasAttributes = elementTest.hasAttributes();
+ assertTrue("nodehasattributes04", hasAttributes);
+ }
+
+}
diff --git a/xml/src/test/java/tests/org/w3c/dom/NodeIsSupported.java b/xml/src/test/java/tests/org/w3c/dom/NodeIsSupported.java
new file mode 100644
index 0000000..d88cb86
--- /dev/null
+++ b/xml/src/test/java/tests/org/w3c/dom/NodeIsSupported.java
@@ -0,0 +1,216 @@
+/*
+ This Java source file was generated by test-to-java.xsl
+ and is a derived work from the source document.
+ The source document contained the following notice:
+
+
+
+ Copyright (c) 2001-2003 World Wide Web Consortium,
+ (Massachusetts Institute of Technology, Institut National de
+ Recherche en Informatique et en Automatique, Keio University). All
+ Rights Reserved. This program is distributed under the W3C's Software
+ Intellectual Property License. This program is distributed in the
+ hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+ See W3C License http://www.w3.org/Consortium/Legal/ for more details.
+
+
+ */
+
+package tests.org.w3c.dom;
+
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.w3c.dom.Node;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Attr;
+import org.w3c.dom.DocumentType;
+import org.w3c.dom.EntityReference;
+import org.w3c.dom.ProcessingInstruction;
+
+import javax.xml.parsers.DocumentBuilder;
+
+/**
+ * The method "isSupported(feature,version)" Tests whether the DOM
+ * implementation implements a specific feature and that feature is supported by
+ * this node.
+ *
+ * Call the isSupported method on the document element node with a combination
+ * of features versions and versions as below. Valid feature names are case
+ * insensitive and versions "2.0", "1.0" and if the version is not specified,
+ * supporting any version of the feature should return true. Check if the value
+ * returned value was true.
+ *
+ * @author IBM
+ * @author Neil Delima
+ * @see <a
+ * href="http://www.w3.org/TR/DOM-Level-2-Core/core#Level-2-Core-Node-supports">http://www.w3.org/TR/DOM-Level-2-Core/core#Level-2-Core-Node-supports</a>
+ */
+@TestTargetClass(Node.class)
+public final class NodeIsSupported extends DOMTestCase {
+
+ DOMDocumentBuilderFactory factory;
+
+ DocumentBuilder builder;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ try {
+ factory = new DOMDocumentBuilderFactory(DOMDocumentBuilderFactory
+ .getConfiguration1());
+ builder = factory.getBuilder();
+ } catch (Exception e) {
+ fail("Unexpected exception" + e.getMessage());
+ }
+ }
+
+ protected void tearDown() throws Exception {
+ factory = null;
+ builder = null;
+ super.tearDown();
+ }
+
+ /**
+ * Runs the test case.
+ *
+ * @throws Throwable
+ * Any uncaught exception causes test to fail
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Doesn't verify that isSupported method can return false value.",
+ method = "isSupported",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testIsSupported1() throws Throwable {
+ Document doc;
+ Element element;
+ String version = "";
+ String version1 = "1.0";
+ String version2 = "2.0";
+ String featureCore;
+ String featureXML;
+ boolean success;
+ List<String> featuresXML = new ArrayList<String>();
+ featuresXML.add("XML");
+ featuresXML.add("xmL");
+
+ List<String> featuresCore = new ArrayList<String>();
+ featuresCore.add("Core");
+ featuresCore.add("CORE");
+
+ doc = (Document) load("staffNS", builder);
+ element = doc.getDocumentElement();
+ for (int indexN10063 = 0; indexN10063 < featuresXML.size(); indexN10063++) {
+ featureXML = (String) featuresXML.get(indexN10063);
+ success = element.isSupported(featureXML, version);
+ assertTrue("nodeissupported01_XML1", success);
+ success = element.isSupported(featureXML, version1);
+ assertTrue("nodeissupported01_XML2", success);
+ }
+ for (int indexN1007C = 0; indexN1007C < featuresCore.size(); indexN1007C++) {
+ featureCore = (String) featuresCore.get(indexN1007C);
+ success = element.isSupported(featureCore, version);
+ assertTrue("nodeissupported01_Core1", success);
+ success = element.isSupported(featureCore, version1);
+ success = element.isSupported(featureCore, version2);
+ assertTrue("nodeissupported01_Core3", success);
+ }
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Doesn't verify that isSupported method can return false value.",
+ method = "isSupported",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testIsSupported2() throws Throwable {
+ Document doc;
+ Attr attribute;
+ String version = "";
+ String version1 = "1.0";
+ String version2 = "2.0";
+ String featureCore;
+ String featureXML;
+ boolean success;
+ List<String> featuresXML = new ArrayList<String>();
+ featuresXML.add("XML");
+ featuresXML.add("xmL");
+
+ List<String> featuresCore = new ArrayList<String>();
+ featuresCore.add("Core");
+ featuresCore.add("CORE");
+
+ doc = (Document) load("staffNS", builder);
+ attribute = doc.createAttribute("TestAttr");
+ for (int indexN10064 = 0; indexN10064 < featuresXML.size(); indexN10064++) {
+ featureXML = (String) featuresXML.get(indexN10064);
+ success = attribute.isSupported(featureXML, version);
+ assertTrue("nodeissupported02_XML1", success);
+ success = attribute.isSupported(featureXML, version1);
+ assertTrue("nodeissupported02_XML2", success);
+ }
+ for (int indexN1007D = 0; indexN1007D < featuresCore.size(); indexN1007D++) {
+ featureCore = (String) featuresCore.get(indexN1007D);
+ success = attribute.isSupported(featureCore, version);
+ assertTrue("nodeissupported02_Core1", success);
+ success = attribute.isSupported(featureCore, version1);
+ success = attribute.isSupported(featureCore, version2);
+ assertTrue("nodeissupported02_Core3", success);
+ }
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Verifies that isSupported method returns false value if it's called with empty strings as parameters.",
+ method = "isSupported",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testIsSupported3() throws Throwable {
+ Document doc;
+ DocumentType docType;
+ boolean success;
+ doc = (Document) load("staffNS", builder);
+ docType = doc.getDoctype();
+ success = docType.isSupported("", "");
+ assertFalse("nodeissupported03", success);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Verifies that isSupported method returns false value.",
+ method = "isSupported",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testIsSupported4() throws Throwable {
+ Document doc;
+ EntityReference entRef;
+ boolean success;
+ doc = (Document) load("staffNS", builder);
+ entRef = doc.createEntityReference("ent1");
+ assertNotNull("createdEntRefNotNull", entRef);
+ success = entRef.isSupported("XML CORE", "");
+ assertFalse("nodeissupported04", success);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Verifies that isSupported method returns false value.",
+ method = "isSupported",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testIsSupported5() throws Throwable {
+ Document doc;
+ ProcessingInstruction pi;
+ boolean success;
+ doc = (Document) load("staffNS", builder);
+ pi = doc.createProcessingInstruction("PITarget", "PIData");
+ success = pi.isSupported("-", "+");
+ assertFalse("nodeissupported05", success);
+ }
+}
diff --git a/xml/src/test/java/tests/org/w3c/dom/NodeNormalize.java b/xml/src/test/java/tests/org/w3c/dom/NodeNormalize.java
new file mode 100644
index 0000000..d66ce58
--- /dev/null
+++ b/xml/src/test/java/tests/org/w3c/dom/NodeNormalize.java
@@ -0,0 +1,209 @@
+/*
+ This Java source file was generated by test-to-java.xsl
+ and is a derived work from the source document.
+ The source document contained the following notice:
+
+
+
+ Copyright (c) 2001-2004 World Wide Web Consortium,
+ (Massachusetts Institute of Technology, Institut National de
+ Recherche en Informatique et en Automatique, Keio University). All
+ Rights Reserved. This program is distributed under the W3C's Software
+ Intellectual Property License. This program is distributed in the
+ hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+ See W3C License http://www.w3.org/Consortium/Legal/ for more details.
+
+
+ */
+
+package tests.org.w3c.dom;
+
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import org.w3c.dom.Node;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.DocumentType;
+import org.w3c.dom.Text;
+import org.w3c.dom.DOMImplementation;
+import org.w3c.dom.EntityReference;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.CDATASection;
+import org.w3c.dom.ProcessingInstruction;
+import org.w3c.dom.Comment;
+
+import javax.xml.parsers.DocumentBuilder;
+
+/**
+ * The method "normalize" puts all Text nodes in the full depth of the sub-tree
+ * underneath this Node, including attribute nodes, into a "normal" form where
+ * only structure (e.g., elements, comments, processing instructions, CDATA
+ * sections, and entity references) separates Text nodes, i.e., there are
+ * neither adjacent Text nodes nor empty Text nodes.
+ *
+ * Create a dom tree consisting of elements, comments, processing instructions,
+ * CDATA sections, and entity references nodes seperated by text nodes. Check
+ * the length of the node list of each before and after normalize has been
+ * called.
+ *
+ * @author IBM
+ * @author Neil Delima
+ * @see <a
+ * href="http://www.w3.org/TR/DOM-Level-2-Core/core#ID-normalize">http://www.w3.org/TR/DOM-Level-2-Core/core#ID-normalize</a>
+ */
+@TestTargetClass(Node.class)
+public final class NodeNormalize extends DOMTestCase {
+
+ DOMDocumentBuilderFactory factory;
+
+ DocumentBuilder builder;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ try {
+ factory = new DOMDocumentBuilderFactory(DOMDocumentBuilderFactory
+ .getConfiguration1());
+ builder = factory.getBuilder();
+ } catch (Exception e) {
+ fail("Unexpected exception" + e.getMessage());
+ }
+ }
+
+ protected void tearDown() throws Exception {
+ factory = null;
+ builder = null;
+ super.tearDown();
+ }
+
+ /**
+ * Runs the test case.
+ *
+ * @throws Throwable
+ * Any uncaught exception causes test to fail
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "normalize",
+ args = {}
+ )
+ public void testNormalize() throws Throwable {
+ Document doc;
+ Document newDoc;
+ DOMImplementation domImpl;
+
+ DocumentType docTypeNull = null;
+
+ Element documentElement;
+ Element element1;
+ Element element2;
+ Element element3;
+ Element element4;
+ Element element5;
+ Element element6;
+ Element element7;
+ Text text1;
+ Text text2;
+ Text text3;
+ ProcessingInstruction pi;
+ CDATASection cData;
+ Comment comment;
+ EntityReference entRef;
+ NodeList elementList;
+
+ doc = (Document) load("staffNS", builder);
+ domImpl = doc.getImplementation();
+ newDoc = domImpl.createDocument("http://www.w3.org/DOM/Test",
+ "dom:root", docTypeNull);
+ element1 = newDoc.createElement("element1");
+ element2 = newDoc.createElement("element2");
+ element3 = newDoc.createElement("element3");
+ element4 = newDoc.createElement("element4");
+ element5 = newDoc.createElement("element5");
+ element6 = newDoc.createElement("element6");
+ element7 = newDoc.createElement("element7");
+ text1 = newDoc.createTextNode("text1");
+ text2 = newDoc.createTextNode("text2");
+ text3 = newDoc.createTextNode("text3");
+ cData = newDoc.createCDATASection("Cdata");
+ comment = newDoc.createComment("comment");
+ pi = newDoc.createProcessingInstruction("PITarget", "PIData");
+ entRef = newDoc.createEntityReference("EntRef");
+ assertNotNull("createdEntRefNotNull", entRef);
+ documentElement = newDoc.getDocumentElement();
+ documentElement.appendChild(element1);
+ element2.appendChild(text1);
+ element2.appendChild(text2);
+ element2.appendChild(text3);
+ element1.appendChild(element2);
+ text1 = (Text) text1.cloneNode(false);
+ text2 = (Text) text2.cloneNode(false);
+ element3.appendChild(entRef);
+ element3.appendChild(text1);
+ element3.appendChild(text2);
+ element1.appendChild(element3);
+ text1 = (Text) text1.cloneNode(false);
+ text2 = (Text) text2.cloneNode(false);
+ element4.appendChild(cData);
+ element4.appendChild(text1);
+ element4.appendChild(text2);
+ element1.appendChild(element4);
+ text2 = (Text) text2.cloneNode(false);
+ text3 = (Text) text3.cloneNode(false);
+ element5.appendChild(comment);
+ element5.appendChild(text2);
+ element5.appendChild(text3);
+ element1.appendChild(element5);
+ text2 = (Text) text2.cloneNode(false);
+ text3 = (Text) text3.cloneNode(false);
+ element6.appendChild(pi);
+ element6.appendChild(text2);
+ element6.appendChild(text3);
+ element1.appendChild(element6);
+ entRef = (EntityReference) entRef.cloneNode(false);
+ text1 = (Text) text1.cloneNode(false);
+ text2 = (Text) text2.cloneNode(false);
+ text3 = (Text) text3.cloneNode(false);
+ element7.appendChild(entRef);
+ element7.appendChild(text1);
+ element7.appendChild(text2);
+ element7.appendChild(text3);
+ element1.appendChild(element7);
+ elementList = element1.getChildNodes();
+ assertEquals("nodeNormalize01_1Bef", 6, elementList.getLength());
+ elementList = element2.getChildNodes();
+ assertEquals("nodeNormalize01_2Bef", 3, elementList.getLength());
+ elementList = element3.getChildNodes();
+ assertEquals("nodeNormalize01_3Bef", 3, elementList.getLength());
+ elementList = element4.getChildNodes();
+ assertEquals("nodeNormalize01_4Bef", 3, elementList.getLength());
+ elementList = element5.getChildNodes();
+ assertEquals("nodeNormalize01_5Bef", 3, elementList.getLength());
+ elementList = element6.getChildNodes();
+ assertEquals("nodeNormalize01_6Bef", 3, elementList.getLength());
+ elementList = element7.getChildNodes();
+ assertEquals("nodeNormalize01_7Bef", 4, elementList.getLength());
+ newDoc.normalize();
+ elementList = element1.getChildNodes();
+ assertEquals("nodeNormalize01_1Aft", 6, elementList.getLength());
+ elementList = element2.getChildNodes();
+ assertEquals("nodeNormalize01_2Aft", 1, elementList.getLength());
+ elementList = element3.getChildNodes();
+ assertEquals("nodeNormalize01_3Aft", 2, elementList.getLength());
+ elementList = element4.getChildNodes();
+ assertEquals("nodeNormalize01_4Aft", 2, elementList.getLength());
+ elementList = element5.getChildNodes();
+ assertEquals("nodeNormalize01_5Aft", 2, elementList.getLength());
+ elementList = element6.getChildNodes();
+ assertEquals("nodeNormalize01_6Aft", 2, elementList.getLength());
+ elementList = element7.getChildNodes();
+ assertEquals("nodeNormalize01_7Aft", 2, elementList.getLength());
+ }
+
+}
diff --git a/xml/src/test/java/tests/org/w3c/dom/NodeSetPrefix.java b/xml/src/test/java/tests/org/w3c/dom/NodeSetPrefix.java
new file mode 100644
index 0000000..dbecc30
--- /dev/null
+++ b/xml/src/test/java/tests/org/w3c/dom/NodeSetPrefix.java
@@ -0,0 +1,314 @@
+/*
+ This Java source file was generated by test-to-java.xsl
+ and is a derived work from the source document.
+ The source document contained the following notice:
+
+
+
+ Copyright (c) 2001 World Wide Web Consortium,
+ (Massachusetts Institute of Technology, Institut National de
+ Recherche en Informatique et en Automatique, Keio University). All
+ Rights Reserved. This program is distributed under the W3C's Software
+ Intellectual Property License. This program is distributed in the
+ hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+ See W3C License http://www.w3.org/Consortium/Legal/ for more details.
+
+
+ */
+
+package tests.org.w3c.dom;
+
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.w3c.dom.Node;
+import org.w3c.dom.Document;
+import org.w3c.dom.DocumentFragment;
+import org.w3c.dom.Element;
+import org.w3c.dom.DOMException;
+import org.w3c.dom.Attr;
+import org.w3c.dom.NodeList;
+
+import javax.xml.parsers.DocumentBuilder;
+
+/**
+ * The method setPrefix sets the namespace prefix of this node. Note that
+ * setting this attribute, when permitted, changes the nodeName attribute, which
+ * holds the qualified name, as well as the tagName and name attributes of the
+ * Element and Attr interfaces, when applicable.
+ *
+ * Create a new element node with a namespace prefix. Add it to a new
+ * DocumentFragment Node without a prefix. Call setPrefix on the elemen node.
+ * Check if the prefix was set correctly on the element.
+ *
+ * @author IBM
+ * @author Neil Delima
+ * @see <a
+ * href="http://www.w3.org/TR/DOM-Level-2-Core/core#ID-NodeNSPrefix">http://www.w3.org/TR/DOM-Level-2-Core/core#ID-NodeNSPrefix</a>
+ */
+@TestTargetClass(Node.class)
+public final class NodeSetPrefix extends DOMTestCase {
+
+ DOMDocumentBuilderFactory factory;
+
+ DocumentBuilder builder;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ try {
+ factory = new DOMDocumentBuilderFactory(DOMDocumentBuilderFactory
+ .getConfiguration1());
+ builder = factory.getBuilder();
+ } catch (Exception e) {
+ fail("Unexpected exception" + e.getMessage());
+ }
+ }
+
+ protected void tearDown() throws Exception {
+ factory = null;
+ builder = null;
+ super.tearDown();
+ }
+
+ /**
+ * Runs the test case.
+ *
+ * @throws Throwable
+ * Any uncaught exception causes test to fail
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Doesn't verify DOMException.",
+ method = "setPrefix",
+ args = {java.lang.String.class}
+ )
+ public void testSetPrefix1() throws Throwable {
+ Document doc;
+ DocumentFragment docFragment;
+ Element element;
+ String elementTagName;
+ String elementNodeName;
+
+ doc = (Document) load("staff", builder);
+ docFragment = doc.createDocumentFragment();
+ element = doc.createElementNS("http://www.w3.org/DOM/Test",
+ "emp:address");
+ docFragment.appendChild(element);
+ element.setPrefix("dmstc");
+ elementTagName = element.getTagName();
+ elementNodeName = element.getNodeName();
+ assertEquals("nodesetprefix01_tagname", "dmstc:address", elementTagName);
+ assertEquals("nodesetprefix01_nodeName", "dmstc:address",
+ elementNodeName);
+ }
+
+// TODO Fails on JDK. Why?
+// public void testSetPrefix2() throws Throwable {
+// Document doc;
+// Element element;
+// Attr attribute;
+// Attr newAttribute;
+//
+// NodeList elementList;
+// String attrName;
+// String newAttrName;
+// doc = (Document) load("staffNS", builder);
+// elementList = doc.getElementsByTagName("address");
+// element = (Element) elementList.item(1);
+// newAttribute = doc.createAttributeNS("http://www.w3.org/DOM/Test",
+// "test:address");
+// element.setAttributeNodeNS(newAttribute);
+// newAttribute.setPrefix("dom");
+// attribute = element
+// .getAttributeNodeNS("http://www.usa.com", "domestic");
+// attrName = attribute.getNodeName();
+// newAttrName = newAttribute.getNodeName();
+// assertEquals("nodesetprefix02_attrName", "dmstc:domestic", attrName);
+// assertEquals("nodesetprefix02_newAttrName", "dom:address", newAttrName);
+// }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies DOMException with NAMESPACE_ERR code.",
+ method = "setPrefix",
+ args = {java.lang.String.class}
+ )
+ public void testSetPrefix3() throws Throwable {
+ Document doc;
+ Element element;
+ doc = (Document) load("staffNS", builder);
+ element = doc.createElement("address");
+
+ {
+ boolean success = false;
+ try {
+ element.setPrefix("test");
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.NAMESPACE_ERR);
+ }
+ assertTrue("throw_NAMESPACE_ERR", success);
+ }
+ }
+
+// Relies on validation, which we don't support.
+// public void testSetPrefix4() throws Throwable {
+// Document doc;
+// Element element;
+// Attr attribute;
+// NodeList elementList;
+// String nullNS = null;
+//
+// doc = (Document) load("staffNS", builder);
+// elementList = doc.getElementsByTagName("emp:employee");
+// element = (Element) elementList.item(0);
+// assertNotNull("empEmployeeNotNull", element);
+// attribute = element.getAttributeNodeNS(nullNS, "defaultAttr");
+//
+// {
+// boolean success = false;
+// try {
+// attribute.setPrefix("test");
+// } catch (DOMException ex) {
+// success = (ex.code == DOMException.NAMESPACE_ERR);
+// }
+// assertTrue("nodesetprefix04", success);
+// }
+// }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies DOMException with NAMESPACE_ERR code.",
+ method = "setPrefix",
+ args = {java.lang.String.class}
+ )
+ public void testSetPrefix5() throws Throwable {
+ Document doc;
+ Element element;
+ String prefixValue;
+ List<String> prefixValues = new ArrayList<String>();
+ prefixValues.add("_:");
+ prefixValues.add(":0");
+ prefixValues.add(":");
+ prefixValues.add("_::");
+ prefixValues.add("a:0:c");
+
+ doc = (Document) load("staffNS", builder);
+ element = doc.createElementNS("http://www.w3.org/DOM/Test/L2",
+ "dom:elem");
+ for (int indexN10050 = 0; indexN10050 < prefixValues.size(); indexN10050++) {
+ prefixValue = (String) prefixValues.get(indexN10050);
+
+ {
+ boolean success = false;
+ try {
+ element.setPrefix(prefixValue);
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.NAMESPACE_ERR);
+ }
+ assertTrue("throw_NAMESPACE_ERR", success);
+ }
+ }
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies DOMException with NAMESPACE_ERR code.",
+ method = "setPrefix",
+ args = {java.lang.String.class}
+ )
+ public void testSetPrefix6() throws Throwable {
+ Document doc;
+ Element element;
+ doc = (Document) load("staffNS", builder);
+ element = doc.createElementNS("http://www.w3.org/DOM/Test/L2",
+ "dom:elem");
+
+ {
+ boolean success = false;
+ try {
+ element.setPrefix("xml");
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.NAMESPACE_ERR);
+ }
+ assertTrue("throw_NAMESPACE_ERR", success);
+ }
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies DOMException with NAMESPACE_ERR code.",
+ method = "setPrefix",
+ args = {java.lang.String.class}
+ )
+ public void testSetPrefix7() throws Throwable {
+ Document doc;
+ Attr attribute;
+ doc = (Document) load("staffNS", builder);
+ attribute = doc.createAttributeNS("http://www.w3.org/DOM/Test/L2",
+ "abc:elem");
+
+ {
+ boolean success = false;
+ try {
+ attribute.setPrefix("xmlns");
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.NAMESPACE_ERR);
+ }
+ assertTrue("throw_NAMESPACE_ERR", success);
+ }
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies DOMException with NAMESPACE_ERR.",
+ method = "setPrefix",
+ args = {java.lang.String.class}
+ )
+ public void testSetPrefix8() throws Throwable {
+ Document doc;
+ Element element;
+ NodeList elementList;
+ Attr attribute;
+ doc = (Document) load("staffNS", builder);
+ elementList = doc.getElementsByTagName("employee");
+ element = (Element) elementList.item(0);
+ attribute = element.getAttributeNode("xmlns");
+
+ {
+ boolean success = false;
+ try {
+ attribute.setPrefix("xml");
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.NAMESPACE_ERR);
+ }
+ assertTrue("throw_NAMESPACE_ERR", success);
+ }
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies DOMException with INVALID_CHARACTER_ERR code.",
+ method = "setPrefix",
+ args = {java.lang.String.class}
+ )
+ public void _testSetPrefix9() throws Throwable {
+ Document doc;
+ String value = "#$%&'()@";
+ Element element;
+ doc = (Document) load("staffNS", builder);
+ element = doc.createElementNS("http://www.w3.org/DOM/Test/L2",
+ "dom:elem");
+
+ {
+ boolean success = false;
+ try {
+ element.setPrefix(value);
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.INVALID_CHARACTER_ERR);
+ }
+ assertTrue("throw_INVALID_CHARACTER_ERR", success);
+ }
+ }
+}
diff --git a/xml/src/test/java/tests/org/w3c/dom/Normalize.java b/xml/src/test/java/tests/org/w3c/dom/Normalize.java
new file mode 100644
index 0000000..36ff43c
--- /dev/null
+++ b/xml/src/test/java/tests/org/w3c/dom/Normalize.java
@@ -0,0 +1,106 @@
+
+/*
+This Java source file was generated by test-to-java.xsl
+and is a derived work from the source document.
+The source document contained the following notice:
+
+
+
+Copyright (c) 2001 World Wide Web Consortium,
+(Massachusetts Institute of Technology, Institut National de
+Recherche en Informatique et en Automatique, Keio University). All
+Rights Reserved. This program is distributed under the W3C's Software
+Intellectual Property License. This program is distributed in the
+hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE.
+
+See W3C License http://www.w3.org/Consortium/Legal/ for more details.
+
+
+*/
+
+package tests.org.w3c.dom;
+
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import org.w3c.dom.Element;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.CharacterData;
+
+import javax.xml.parsers.DocumentBuilder;
+
+/**
+ * The "normalize()" method puts all the nodes in the full
+ * depth of the sub-tree underneath this element into a
+ * "normal" form.
+ *
+ * Retrieve the third employee and access its second child.
+ * This child contains a block of text that is spread
+ * across multiple lines. The content of the "name" child
+ * should be parsed and treated as a single Text node.
+ * This appears to be a duplicate of elementnormalize.xml in DOM L1 Test Suite
+* @author NIST
+* @author Mary Brady
+* @see <a href="http://www.w3.org/TR/DOM-Level-2-Core/core#ID-normalize">http://www.w3.org/TR/DOM-Level-2-Core/core#ID-normalize</a>
+* @see <a href="http://www.w3.org/TR/DOM-Level-2-Core/core#ID-72AB8359">http://www.w3.org/TR/DOM-Level-2-Core/core#ID-72AB8359</a>
+*/
+@TestTargetClass(Element.class)
+public final class Normalize extends DOMTestCase {
+
+ DOMDocumentBuilderFactory factory;
+
+ DocumentBuilder builder;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ try {
+ factory = new DOMDocumentBuilderFactory(DOMDocumentBuilderFactory
+ .getConfiguration1());
+ builder = factory.getBuilder();
+ } catch (Exception e) {
+ fail("Unexpected exception" + e.getMessage());
+ }
+ }
+
+ protected void tearDown() throws Exception {
+ factory = null;
+ builder = null;
+ super.tearDown();
+ }
+ /**
+ * Runs the test case.
+ * @throws Throwable Any uncaught exception causes test to fail
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "normalize",
+ args = {}
+ )
+ public void testNormalize() throws Throwable {
+ Document doc;
+ Element root;
+ NodeList elementList;
+ Node firstChild;
+ NodeList textList;
+ CharacterData textNode;
+ String data;
+ doc = (Document) load("staff", builder);
+ root = doc.getDocumentElement();
+ root.normalize();
+ elementList = root.getElementsByTagName("name");
+ firstChild = elementList.item(2);
+ textList = firstChild.getChildNodes();
+ textNode = (CharacterData) textList.item(0);
+ data = textNode.getData();
+ assertEquals("data", "Roger\n Jones", data);
+ }
+
+}
+
diff --git a/xml/src/test/java/tests/org/w3c/dom/OwnerDocument.java b/xml/src/test/java/tests/org/w3c/dom/OwnerDocument.java
new file mode 100644
index 0000000..b5b0e94
--- /dev/null
+++ b/xml/src/test/java/tests/org/w3c/dom/OwnerDocument.java
@@ -0,0 +1,88 @@
+
+/*
+This Java source file was generated by test-to-java.xsl
+and is a derived work from the source document.
+The source document contained the following notice:
+
+
+
+Copyright (c) 2001 World Wide Web Consortium,
+(Massachusetts Institute of Technology, Institut National de
+Recherche en Informatique et en Automatique, Keio University). All
+Rights Reserved. This program is distributed under the W3C's Software
+Intellectual Property License. This program is distributed in the
+hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE.
+
+See W3C License http://www.w3.org/Consortium/Legal/ for more details.
+
+
+*/
+
+package tests.org.w3c.dom;
+
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.DocumentType;
+
+import javax.xml.parsers.DocumentBuilder;
+
+/**
+ * The "getOwnerDocument()" method returns null if the target
+ * node itself is a DocumentType which is not used with any document yet.
+ *
+ * Invoke the "getOwnerDocument()" method on the master
+ * document. The DocumentType returned should be null.
+* @author NIST
+* @author Mary Brady
+* @see <a href="http://www.w3.org/TR/DOM-Level-2-Core/core#node-ownerDoc">http://www.w3.org/TR/DOM-Level-2-Core/core#node-ownerDoc</a>
+*/
+@TestTargetClass(Document.class)
+public final class OwnerDocument extends DOMTestCase {
+
+ DOMDocumentBuilderFactory factory;
+
+ DocumentBuilder builder;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ try {
+ factory = new DOMDocumentBuilderFactory(DOMDocumentBuilderFactory
+ .getConfiguration1());
+ builder = factory.getBuilder();
+ } catch (Exception e) {
+ fail("Unexpected exception" + e.getMessage());
+ }
+ }
+
+ protected void tearDown() throws Exception {
+ factory = null;
+ builder = null;
+ super.tearDown();
+ }
+
+ /**
+ * Runs the test case.
+ * @throws Throwable Any uncaught exception causes test to fail
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Dosn't verify that getOwnerDocument can return not null value.",
+ method = "getOwnerDocument",
+ args = {}
+ )
+ public void testGetOwnerDocument() throws Throwable {
+ Document doc;
+ DocumentType ownerDocument;
+ doc = (Document) load("staff", builder);
+ ownerDocument = (DocumentType) doc.getOwnerDocument();
+ assertNull("throw_Null", ownerDocument);
+ }
+
+}
+
diff --git a/xml/src/test/java/tests/org/w3c/dom/OwnerElement.java b/xml/src/test/java/tests/org/w3c/dom/OwnerElement.java
new file mode 100644
index 0000000..a4af36a
--- /dev/null
+++ b/xml/src/test/java/tests/org/w3c/dom/OwnerElement.java
@@ -0,0 +1,118 @@
+/*
+ This Java source file was generated by test-to-java.xsl
+ and is a derived work from the source document.
+ The source document contained the following notice:
+
+
+
+ Copyright (c) 2001 World Wide Web Consortium,
+ (Massachusetts Institute of Technology, Institut National de
+ Recherche en Informatique et en Automatique, Keio University). All
+ Rights Reserved. This program is distributed under the W3C's Software
+ Intellectual Property License. This program is distributed in the
+ hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+ See W3C License http://www.w3.org/Consortium/Legal/ for more details.
+
+
+ */
+
+package tests.org.w3c.dom;
+
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import org.w3c.dom.Node;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Element;
+
+import javax.xml.parsers.DocumentBuilder;
+
+/**
+ * The "getOwnerElement()" will return the Element node this attribute is
+ * attached to or null if this attribute is not in use. Get the "domestic"
+ * attribute from the first "address" node. Apply the "getOwnerElement()" method
+ * to get the Element associated with the attribute. The value returned should
+ * be "address".
+ *
+ * @author NIST
+ * @author Mary Brady
+ * @see <a
+ * href="http://www.w3.org/TR/DOM-Level-2-Core/core#ID-F68D095">http://www.w3.org/TR/DOM-Level-2-Core/core#ID-F68D095</a>
+ */
+@TestTargetClass(Attr.class)
+public final class OwnerElement extends DOMTestCase {
+
+ DOMDocumentBuilderFactory factory;
+
+ DocumentBuilder builder;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ try {
+ factory = new DOMDocumentBuilderFactory(DOMDocumentBuilderFactory
+ .getConfiguration1());
+ builder = factory.getBuilder();
+ } catch (Exception e) {
+ fail("Unexpected exception" + e.getMessage());
+ }
+ }
+
+ protected void tearDown() throws Exception {
+ factory = null;
+ builder = null;
+ super.tearDown();
+ }
+
+ /**
+ * Runs the test case.
+ *
+ * @throws Throwable
+ * Any uncaught exception causes test to fail
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Verifies positive functionlity.",
+ method = "getOwnerElement",
+ args = {}
+ )
+ public void testGetOwnerElement1() throws Throwable {
+ Document doc;
+ NodeList addressList;
+ Node testNode;
+ NamedNodeMap attributes;
+ Attr domesticAttr;
+ Element elementNode;
+ String name;
+ doc = (Document) load("staff", builder);
+ addressList = doc.getElementsByTagName("address");
+ testNode = addressList.item(0);
+ attributes = testNode.getAttributes();
+ domesticAttr = (Attr) attributes.getNamedItem("domestic");
+ elementNode = domesticAttr.getOwnerElement();
+ name = elementNode.getNodeName();
+ assertEquals("throw_Equals", "address", name);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Verifies that getOwnerElement method returns null.",
+ method = "getOwnerElement",
+ args = {}
+ )
+ public void testGetOwnerElement2() throws Throwable {
+ Document doc;
+ Attr newAttr;
+ Element elementNode;
+ doc = (Document) load("staff", builder);
+ newAttr = doc.createAttribute("newAttribute");
+ elementNode = newAttr.getOwnerElement();
+ assertNull("throw_Null", elementNode);
+ }
+}
diff --git a/xml/src/test/java/tests/org/w3c/dom/Prefix.java b/xml/src/test/java/tests/org/w3c/dom/Prefix.java
new file mode 100644
index 0000000..f45144a
--- /dev/null
+++ b/xml/src/test/java/tests/org/w3c/dom/Prefix.java
@@ -0,0 +1,337 @@
+/*
+ This Java source file was generated by test-to-java.xsl
+ and is a derived work from the source document.
+ The source document contained the following notice:
+
+
+
+ Copyright (c) 2001 World Wide Web Consortium,
+ (Massachusetts Institute of Technology, Institut National de
+ Recherche en Informatique et en Automatique, Keio University). All
+ Rights Reserved. This program is distributed under the W3C's Software
+ Intellectual Property License. This program is distributed in the
+ hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+ See W3C License http://www.w3.org/Consortium/Legal/ for more details.
+
+
+ */
+
+package tests.org.w3c.dom;
+
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import org.w3c.dom.Node;
+import org.w3c.dom.Document;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Element;
+import org.w3c.dom.Attr;
+import org.w3c.dom.DOMException;
+
+import javax.xml.parsers.DocumentBuilder;
+
+/**
+ * The "getPrefix()" method for a Node returns the namespace prefix of the node,
+ * and for nodes of any type other than ELEMENT_NODE and ATTRIBUTE_NODE and
+ * nodes created with a DOM Level 1 method, this is null.
+ *
+ * Create an new Element with the createElement() method. Invoke the
+ * "getPrefix()" method on the newly created element node will cause "null" to
+ * be returned.
+ *
+ * @author NIST
+ * @author Mary Brady
+ * @see <a
+ * href="http://www.w3.org/TR/DOM-Level-2-Core/core#ID-NodeNSPrefix">http://www.w3.org/TR/DOM-Level-2-Core/core#ID-NodeNSPrefix</a>
+ */
+@TestTargetClass(Node.class)
+public final class Prefix extends DOMTestCase {
+
+ DOMDocumentBuilderFactory factory;
+
+ DocumentBuilder builder;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ try {
+ factory = new DOMDocumentBuilderFactory(DOMDocumentBuilderFactory
+ .getConfiguration2());
+ builder = factory.getBuilder();
+ } catch (Exception e) {
+ fail("Unexpected exception" + e.getMessage());
+ }
+ }
+
+ protected void tearDown() throws Exception {
+ factory = null;
+ builder = null;
+ super.tearDown();
+ }
+
+ /**
+ * Runs the test case.
+ *
+ * @throws Throwable
+ * Any uncaught exception causes test to fail
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Verifies that getPrefix method can return null.",
+ method = "getPrefix",
+ args = {}
+ )
+ public void testGetPrefix1() throws Throwable {
+ Document doc;
+ Node createdNode;
+ String prefix;
+ doc = (Document) load("staffNS", builder);
+ createdNode = doc.createElement("test:employee");
+ prefix = createdNode.getPrefix();
+ assertNull("throw_Null", prefix);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Verifies positive functionality of getPrefix method.",
+ method = "getPrefix",
+ args = {}
+ )
+ public void testGetPrefix2() throws Throwable {
+ Document doc;
+ NodeList elementList;
+ Node testEmployee;
+ Node textNode;
+ String prefix;
+ doc = (Document) load("staffNS", builder);
+ elementList = doc.getElementsByTagName("emp:employeeId");
+ testEmployee = elementList.item(0);
+ assertNotNull("empEmployeeNotNull", testEmployee);
+ textNode = testEmployee.getFirstChild();
+ prefix = textNode.getPrefix();
+ assertNull("textNodePrefix", prefix);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Verifies positive functionality of getPrefix method.",
+ method = "getPrefix",
+ args = {}
+ )
+ public void testGetPrefix3() throws Throwable {
+ Document doc;
+ NodeList elementList;
+ Node testEmployee;
+ String prefix;
+ doc = (Document) load("staffNS", builder);
+ elementList = doc.getElementsByTagName("emp:employee");
+ testEmployee = elementList.item(0);
+ assertNotNull("empEmployeeNotNull", testEmployee);
+ prefix = testEmployee.getPrefix();
+ assertEquals("prefix", "emp", prefix);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Verifies that getPrefix method returns null.",
+ method = "getPrefix",
+ args = {}
+ )
+ public void testGetPrefix4() throws Throwable {
+ Document doc;
+ NodeList elementList;
+ Node testEmployee;
+ String prefix;
+ doc = (Document) load("staffNS", builder);
+ elementList = doc.getElementsByTagName("employee");
+ testEmployee = elementList.item(0);
+ prefix = testEmployee.getPrefix();
+ assertNull("throw_Null", prefix);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Verifies that getPrefix method throws DOMException with NAMESPACE_ERR code.",
+ method = "getPrefix",
+ args = {}
+ )
+ public void testGetPrefix5() throws Throwable {
+ Document doc;
+ NodeList elementList;
+ Element addrNode;
+ Attr addrAttr;
+ doc = (Document) load("staffNS", builder);
+ elementList = doc.getElementsByTagName("emp:address");
+ addrNode = (Element) elementList.item(0);
+ assertNotNull("empAddrNotNull", addrNode);
+ addrAttr = addrNode.getAttributeNode("emp:domestic");
+
+ {
+ boolean success = false;
+ try {
+ addrAttr.setPrefix("xmlns");
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.NAMESPACE_ERR);
+ }
+ assertTrue("throw_NAMESPACE_ERR", success);
+ }
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Verifies that getPrefix method throws DOMException with INVALID_CHARACTER_ERR code.",
+ method = "getPrefix",
+ args = {}
+ )
+ public void _testGetPrefix6() throws Throwable {
+ Document doc;
+ NodeList elementList;
+ Node employeeNode;
+ doc = (Document) load("staffNS", builder);
+ elementList = doc.getElementsByTagName("employee");
+ employeeNode = elementList.item(0);
+
+ {
+ boolean success = false;
+ try {
+ employeeNode.setPrefix("pre^fix xmlns='http//www.nist.gov'");
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.INVALID_CHARACTER_ERR);
+ }
+ assertTrue("throw_INVALID_CHARACTER_ERR", success);
+ }
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Verifies that getPrefix method throws DOMException with NAMESPACE_ERR code.",
+ method = "getPrefix",
+ args = {}
+ )
+ public void testGetPrefix7() throws Throwable {
+ Document doc;
+ NodeList elementList;
+ Node employeeNode;
+ doc = (Document) load("staffNS", builder);
+ elementList = doc.getElementsByTagName("employee");
+ employeeNode = elementList.item(0);
+
+ {
+ boolean success = false;
+ try {
+ employeeNode.setPrefix("emp::");
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.NAMESPACE_ERR);
+ }
+ assertTrue("throw_NAMESPACE_ERR", success);
+ }
+ }
+
+// Assumes validation.
+// public void testGetPrefix8() throws Throwable {
+// Document doc;
+// NodeList genderList;
+// Node genderNode;
+// Node entRef;
+// Node entElement;
+//
+// int nodeType;
+// doc = (Document) load("staff", builder);
+// genderList = doc.getElementsByTagName("gender");
+// genderNode = genderList.item(2);
+// entRef = genderNode.getFirstChild();
+// nodeType = (int) entRef.getNodeType();
+//
+// if (1 == nodeType) {
+// entRef = doc.createEntityReference("ent4");
+// assertNotNull("createdEntRefNotNull", entRef);
+// }
+// entElement = entRef.getFirstChild();
+// assertNotNull("entElement", entElement);
+// doc.createElement("text3");
+//
+// {
+// boolean success = false;
+// try {
+// entElement.setPrefix("newPrefix");
+// } catch (DOMException ex) {
+// success = (ex.code == DOMException.NO_MODIFICATION_ALLOWED_ERR);
+// }
+// assertTrue("throw_NO_MODIFICATION_ALLOWED_ERR", success);
+// }
+// }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Verifies that getPrefix method throws DOMException with NAMESPACE_ERR code.",
+ method = "getPrefix",
+ args = {}
+ )
+ public void _testGetPrefix9() throws Throwable {
+ Document doc;
+ NodeList elementList;
+ Element addrNode;
+ Attr addrAttr;
+ doc = (Document) load("staffNS", builder);
+ elementList = doc.getElementsByTagName("address");
+ addrNode = (Element) elementList.item(3);
+ addrAttr = addrNode.getAttributeNode("xmlns");
+
+ {
+ boolean success = false;
+ try {
+ addrAttr.setPrefix("xxx");
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.NAMESPACE_ERR);
+ }
+ assertTrue("throw_NAMESPACE_ERR", success);
+ }
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Verifies that getPrefix method throws DOMException with NAMESPACE_ERR code.",
+ method = "getPrefix",
+ args = {}
+ )
+ public void testGetPrefix10() throws Throwable {
+ Document doc;
+ NodeList elementList;
+ Node employeeNode;
+ doc = (Document) load("staffNS", builder);
+ elementList = doc.getElementsByTagName("employee");
+ employeeNode = elementList.item(1);
+
+ {
+ boolean success = false;
+ try {
+ employeeNode.setPrefix("xml");
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.NAMESPACE_ERR);
+ }
+ assertTrue("throw_NAMESPACE_ERR", success);
+ }
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Verifies that getPrefix method throws DOMException with NAMESPACE_ERR code.",
+ method = "getPrefix",
+ args = {}
+ )
+ public void testGetPrefix11() throws Throwable {
+ Document doc;
+ NodeList elementList;
+ Node employeeNode;
+
+ doc = (Document) load("staffNS", builder);
+ elementList = doc.getElementsByTagName("employee");
+ employeeNode = elementList.item(1);
+ employeeNode.getNamespaceURI();
+
+ {
+ boolean success = false;
+ try {
+ employeeNode.setPrefix("employee1");
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.NAMESPACE_ERR);
+ }
+ assertTrue("throw_NAMESPACE_ERR", success);
+ }
+ }
+}
diff --git a/xml/src/test/java/tests/org/w3c/dom/PublicId.java b/xml/src/test/java/tests/org/w3c/dom/PublicId.java
new file mode 100644
index 0000000..8165b2c
--- /dev/null
+++ b/xml/src/test/java/tests/org/w3c/dom/PublicId.java
@@ -0,0 +1,91 @@
+
+/*
+This Java source file was generated by test-to-java.xsl
+and is a derived work from the source document.
+The source document contained the following notice:
+
+
+
+Copyright (c) 2001 World Wide Web Consortium,
+(Massachusetts Institute of Technology, Institut National de
+Recherche en Informatique et en Automatique, Keio University). All
+Rights Reserved. This program is distributed under the W3C's Software
+Intellectual Property License. This program is distributed in the
+hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE.
+
+See W3C License http://www.w3.org/Consortium/Legal/ for more details.
+
+
+*/
+
+package tests.org.w3c.dom;
+
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import org.w3c.dom.DocumentType;
+import org.w3c.dom.Document;
+
+import javax.xml.parsers.DocumentBuilder;
+
+/**
+ * The "getPublicId()" method of a documenttype node contains
+ * the public identifier associated with the external subset.
+ *
+ * Retrieve the documenttype.
+ * Apply the "getPublicId()" method. The string "STAFF" should be
+ * returned.
+* @author NIST
+* @author Mary Brady
+* @see <a href="http://www.w3.org/TR/DOM-Level-2-Core/core#ID-Core-DocType-publicId">http://www.w3.org/TR/DOM-Level-2-Core/core#ID-Core-DocType-publicId</a>
+*/
+@TestTargetClass(DocumentType.class)
+public final class PublicId extends DOMTestCase {
+
+ DOMDocumentBuilderFactory factory;
+
+ DocumentBuilder builder;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ try {
+ factory = new DOMDocumentBuilderFactory(DOMDocumentBuilderFactory
+ .getConfiguration1());
+ builder = factory.getBuilder();
+ } catch (Exception e) {
+ fail("Unexpected exception" + e.getMessage());
+ }
+ }
+
+ protected void tearDown() throws Exception {
+ factory = null;
+ builder = null;
+ super.tearDown();
+ }
+
+ /**
+ * Runs the test case.
+ * @throws Throwable Any uncaught exception causes test to fail
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getPublicId",
+ args = {}
+ )
+ public void testGetPublicId() throws Throwable {
+ Document doc;
+ DocumentType docType;
+ String publicId;
+ doc = (Document) load("staffNS", builder);
+ docType = doc.getDoctype();
+ publicId = docType.getPublicId();
+ assertEquals("throw_Equals", "STAFF", publicId);
+ }
+
+}
+
diff --git a/xml/src/test/java/tests/org/w3c/dom/RemoveAttributeNS.java b/xml/src/test/java/tests/org/w3c/dom/RemoveAttributeNS.java
new file mode 100644
index 0000000..6a84d1b
--- /dev/null
+++ b/xml/src/test/java/tests/org/w3c/dom/RemoveAttributeNS.java
@@ -0,0 +1,147 @@
+/*
+ This Java source file was generated by test-to-java.xsl
+ and is a derived work from the source document.
+ The source document contained the following notice:
+
+
+
+ Copyright (c) 2001-2004 World Wide Web Consortium,
+ (Massachusetts Institute of Technology, Institut National de
+ Recherche en Informatique et en Automatique, Keio University). All
+ Rights Reserved. This program is distributed under the W3C's Software
+ Intellectual Property License. This program is distributed in the
+ hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+ See W3C License http://www.w3.org/Consortium/Legal/ for more details.
+
+
+ */
+
+package tests.org.w3c.dom;
+
+import dalvik.annotation.TestTargetClass;
+
+import javax.xml.parsers.DocumentBuilder;
+
+import org.w3c.dom.Attr;
+import org.w3c.dom.DOMException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * The "removeAttributeNS(namespaceURI,localName)" method for an attribute
+ * causes the DOMException NO_MODIFICATION_ALLOWED_ERR to be raised if the node
+ * is readonly.
+ *
+ * Obtain the children of the THIRD "gender" element. The elements content is an
+ * entity reference. Try to remove an attribute from the entity reference by
+ * executing the "removeAttributeNS(namespaceURI,localName)" method. This causes
+ * a NO_MODIFICATION_ALLOWED_ERR DOMException to be thrown.
+ *
+ * @author NIST
+ * @author Mary Brady
+ * @see <a
+ * href="http://www.w3.org/TR/DOM-Level-2-Core/core#xpointer(id('ID-258A00AF')/constant[@name='NO_MODIFICATION_ALLOWED_ERR'])">http://www.w3.org/TR/DOM-Level-2-Core/core#xpointer(id('ID-258A00AF')/constant[@name='NO_MODIFICATION_ALLOWED_ERR'])</a>
+ * @see <a
+ * href="http://www.w3.org/TR/DOM-Level-2-Core/core#ID-ElRemAtNS">http://www.w3.org/TR/DOM-Level-2-Core/core#ID-ElRemAtNS</a>
+ * @see <a
+ * href="http://www.w3.org/TR/DOM-Level-2-Core/core#xpointer(id('ID-ElRemAtNS')/raises/exception[@name='DOMException']/descr/p[substring-before(.,':')='NO_MODIFICATION_ALLOWED_ERR'])">http://www.w3.org/TR/DOM-Level-2-Core/core#xpointer(id('ID-ElRemAtNS')/raises/exception[@name='DOMException']/descr/p[substring-before(.,':')='NO_MODIFICATION_ALLOWED_ERR'])</a>
+ */
+@TestTargetClass(Attr.class)
+public final class RemoveAttributeNS extends DOMTestCase {
+
+ DOMDocumentBuilderFactory factory;
+
+ DocumentBuilder builder;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ try {
+ factory = new DOMDocumentBuilderFactory(DOMDocumentBuilderFactory
+ .getConfiguration2());
+ builder = factory.getBuilder();
+ } catch (Exception e) {
+ fail("Unexpected exception" + e.getMessage());
+ }
+ }
+
+ protected void tearDown() throws Exception {
+ factory = null;
+ builder = null;
+ super.tearDown();
+ }
+
+ /**
+ * Runs the test case.
+ *
+ * @throws Throwable
+ * Any uncaught exception causes test to fail
+ */
+// Assumes validation.
+// public void testRemoveAttributeNS1() throws Throwable {
+// Document doc;
+// NodeList genderList;
+// Node gender;
+// Node gen;
+// NodeList gList;
+// Element genElement;
+// int nodeType;
+// doc = (Document) load("staffNS", builder);
+// genderList = doc.getElementsByTagName("gender");
+// gender = genderList.item(2);
+// gen = gender.getFirstChild();
+// nodeType = (int) gen.getNodeType();
+//
+// if (1 == nodeType) {
+// gen = doc.createEntityReference("ent4");
+// assertNotNull("createdEntRefNotNull", gen);
+// }
+// gList = gen.getChildNodes();
+// genElement = (Element) gList.item(0);
+// assertNotNull("notnull", genElement);
+//
+// {
+// boolean success = false;
+// try {
+// genElement.removeAttributeNS("www.xyz.com", "local1");
+// } catch (DOMException ex) {
+// success = (ex.code == DOMException.NO_MODIFICATION_ALLOWED_ERR);
+// }
+// assertTrue("throw_NO_MODIFICATION_ALLOWED_ERR", success);
+// }
+// }
+
+// Assumes validation
+// public void testRemoveAttributeNS2() throws Throwable {
+// Document doc;
+// NodeList elementList;
+// Node testAddr;
+// Attr addrAttr;
+// String attr;
+// String namespaceURI;
+// String localName;
+// String prefix;
+// doc = (Document) load("staffNS", builder);
+// elementList = doc.getElementsByTagName("emp:address");
+// testAddr = elementList.item(0);
+// ((Element) /* Node */testAddr).removeAttributeNS("http://www.nist.gov",
+// "local1");
+// elementList = doc.getElementsByTagName("emp:address");
+// testAddr = elementList.item(0);
+// addrAttr = ((Element) /* Node */testAddr).getAttributeNodeNS(
+// "http://www.nist.gov", "local1");
+// attr = ((Element) /* Node */testAddr).getAttributeNS(
+// "http://www.nist.gov", "local1");
+// namespaceURI = addrAttr.getNamespaceURI();
+// localName = addrAttr.getLocalName();
+// prefix = testAddr.getPrefix();
+// assertEquals("attr", "FALSE", attr);
+// assertEquals("uri", "http://www.nist.gov", namespaceURI);
+// assertEquals("lname", "local1", localName);
+// assertEquals("prefix", "emp", prefix);
+// }
+}
diff --git a/xml/src/test/java/tests/org/w3c/dom/RemoveNamedItemNS.java b/xml/src/test/java/tests/org/w3c/dom/RemoveNamedItemNS.java
new file mode 100644
index 0000000..e745e74
--- /dev/null
+++ b/xml/src/test/java/tests/org/w3c/dom/RemoveNamedItemNS.java
@@ -0,0 +1,178 @@
+/*
+ This Java source file was generated by test-to-java.xsl
+ and is a derived work from the source document.
+ The source document contained the following notice:
+
+
+
+ Copyright (c) 2001 World Wide Web Consortium,
+ (Massachusetts Institute of Technology, Institut National de
+ Recherche en Informatique et en Automatique, Keio University). All
+ Rights Reserved. This program is distributed under the W3C's Software
+ Intellectual Property License. This program is distributed in the
+ hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+ See W3C License http://www.w3.org/Consortium/Legal/ for more details.
+
+
+ */
+
+package tests.org.w3c.dom;
+
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Attr;
+import org.w3c.dom.DOMException;
+
+import javax.xml.parsers.DocumentBuilder;
+
+/**
+ * The "removeNamedItemNS(namespaceURI,localName)" method for a NamedNodeMap
+ * should remove a node specified by localName and namespaceURI.
+ *
+ * Retrieve a list of elements with tag name "address". Access the second
+ * element from the list and get its attributes. Try to remove the attribute
+ * node with local name "domestic" and namespace uri "http://www.usa.com" with
+ * method removeNamedItemNS(namespaceURI,localName). Check to see if the node
+ * has been removed.
+ *
+ * @author NIST
+ * @author Mary Brady
+ * @see <a
+ * href="http://www.w3.org/TR/DOM-Level-2-Core/core#ID-1074577549">http://www.w3.org/TR/DOM-Level-2-Core/core#ID-1074577549</a>
+ */
+@TestTargetClass(NamedNodeMap.class)
+public final class RemoveNamedItemNS extends DOMTestCase {
+
+ DOMDocumentBuilderFactory factory;
+
+ DocumentBuilder builder;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ try {
+ factory = new DOMDocumentBuilderFactory(DOMDocumentBuilderFactory
+ .getConfiguration2());
+ builder = factory.getBuilder();
+ } catch (Exception e) {
+ fail("Unexpected exception" + e.getMessage());
+ }
+ }
+
+ protected void tearDown() throws Exception {
+ factory = null;
+ builder = null;
+ super.tearDown();
+ }
+
+ /**
+ * Runs the test case.
+ *
+ * @throws Throwable
+ * Any uncaught exception causes test to fail
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Doesn't verify DOMException exception.",
+ method = "removeNamedItemNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testRemoveNamedItemNS1() throws Throwable {
+ Document doc;
+ NodeList elementList;
+ Node testAddress;
+ NamedNodeMap attributes;
+ Attr newAttr;
+ Node removedNode;
+ doc = (Document) load("staffNS", builder);
+ elementList = doc.getElementsByTagName("address");
+ testAddress = elementList.item(1);
+ attributes = testAddress.getAttributes();
+ removedNode = attributes.removeNamedItemNS("http://www.usa.com",
+ "domestic");
+ assertNotNull("retval", removedNode);
+ newAttr = (Attr) attributes.getNamedItem("dmstc:domestic");
+ assertNull("nodeRemoved", newAttr);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Verifies DOMException with NOT_FOUND_ERR code.",
+ method = "removeNamedItemNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testRemoveNamedItemNS2() throws Throwable {
+ String namespaceURI = "http://www.usa.com";
+ String localName = "domest";
+ Document doc;
+ NodeList elementList;
+ Node testAddress;
+ NamedNodeMap attributes;
+
+ doc = (Document) load("staffNS", builder);
+ elementList = doc.getElementsByTagName("address");
+ testAddress = elementList.item(1);
+ attributes = testAddress.getAttributes();
+
+ {
+ boolean success = false;
+ try {
+ attributes.removeNamedItemNS(namespaceURI,
+ localName);
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.NOT_FOUND_ERR);
+ }
+ assertTrue("throw_NOT_FOUND_ERR", success);
+ }
+ }
+
+// Assumes validation.
+// public void testRemoveNamedItemNS3() throws Throwable {
+// String namespaceURI = "http://www.w3.org/2000/xmlns/";
+// String localName = "local1";
+// Document doc;
+// NodeList elementList;
+// Node testAddress;
+// NodeList nList;
+// Node child;
+// NodeList n2List;
+// Node child2;
+// NamedNodeMap attributes;
+//
+// int nodeType;
+// doc = (Document) load("staffNS", builder);
+// elementList = doc.getElementsByTagName("gender");
+// testAddress = elementList.item(2);
+// nList = testAddress.getChildNodes();
+// child = nList.item(0);
+// nodeType = (int) child.getNodeType();
+//
+// if (1 == nodeType) {
+// child = doc.createEntityReference("ent4");
+// assertNotNull("createdEntRefNotNull", child);
+// }
+// n2List = child.getChildNodes();
+// child2 = n2List.item(0);
+// assertNotNull("notnull", child2);
+// attributes = child2.getAttributes();
+//
+// {
+// boolean success = false;
+// try {
+// attributes.removeNamedItemNS(namespaceURI,
+// localName);
+// } catch (DOMException ex) {
+// success = (ex.code == DOMException.NO_MODIFICATION_ALLOWED_ERR);
+// }
+// assertTrue("throw_NO_MODIFICATION_ALLOWED_ERR", success);
+// }
+// }
+}
diff --git a/xml/src/test/java/tests/org/w3c/dom/SetAttributeNS.java b/xml/src/test/java/tests/org/w3c/dom/SetAttributeNS.java
new file mode 100644
index 0000000..58c146f
--- /dev/null
+++ b/xml/src/test/java/tests/org/w3c/dom/SetAttributeNS.java
@@ -0,0 +1,353 @@
+/*
+ This Java source file was generated by test-to-java.xsl
+ and is a derived work from the source document.
+ The source document contained the following notice:
+
+
+
+ Copyright (c) 2001 World Wide Web Consortium,
+ (Massachusetts Institute of Technology, Institut National de
+ Recherche en Informatique et en Automatique, Keio University). All
+ Rights Reserved. This program is distributed under the W3C's Software
+ Intellectual Property License. This program is distributed in the
+ hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+ See W3C License http://www.w3.org/Consortium/Legal/ for more details.
+
+
+ */
+
+package tests.org.w3c.dom;
+
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import org.w3c.dom.Element;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.DOMException;
+import org.w3c.dom.Attr;
+
+import javax.xml.parsers.DocumentBuilder;
+
+/**
+ * The "setAttributeNS(namespaceURI,qualifiedName,Value)" method raises a
+ * INVALID_CHARACTER_ERR DOMException if the specified prefix contains an
+ * illegal character.
+ *
+ * Attempt to add a new attribute on the first employee node. An exception
+ * should be raised since the "qualifiedName" has an invalid character.
+ *
+ * @author NIST
+ * @author Mary Brady
+ * @see <a
+ * href="http://www.w3.org/TR/DOM-Level-2-Core/core#xpointer(id('ID-258A00AF')/constant[@name='INVALID_CHARACTER_ERR'])">http://www.w3.org/TR/DOM-Level-2-Core/core#xpointer(id('ID-258A00AF')/constant[@name='INVALID_CHARACTER_ERR'])</a>
+ * @see <a
+ * href="http://www.w3.org/TR/DOM-Level-2-Core/core#ID-ElSetAttrNS">http://www.w3.org/TR/DOM-Level-2-Core/core#ID-ElSetAttrNS</a>
+ * @see <a
+ * href="http://www.w3.org/TR/DOM-Level-2-Core/core#xpointer(id('ID-ElSetAttrNS')/raises/exception[@name='DOMException']/descr/p[substring-before(.,':')='INVALID_CHARACTER_ERR'])">http://www.w3.org/TR/DOM-Level-2-Core/core#xpointer(id('ID-ElSetAttrNS')/raises/exception[@name='DOMException']/descr/p[substring-before(.,':')='INVALID_CHARACTER_ERR'])</a>
+ */
+@TestTargetClass(Element.class)
+public final class SetAttributeNS extends DOMTestCase {
+
+ DOMDocumentBuilderFactory factory;
+
+ DocumentBuilder builder;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ try {
+ factory = new DOMDocumentBuilderFactory(DOMDocumentBuilderFactory
+ .getConfiguration1());
+ builder = factory.getBuilder();
+ } catch (Exception e) {
+ fail("Unexpected exception" + e.getMessage());
+ }
+ }
+
+ protected void tearDown() throws Exception {
+ factory = null;
+ builder = null;
+ super.tearDown();
+ }
+
+ /**
+ * Runs the test case.
+ *
+ * @throws Throwable
+ * Any uncaught exception causes test to fail
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies DOMException with INVALID_CHARACTER_ERR code.",
+ method = "setAttributeNS",
+ args = {java.lang.String.class, java.lang.String.class, java.lang.String.class}
+ )
+ public void testSetAttributeNS1() throws Throwable {
+ String namespaceURI = "http://www.nist.gov";
+ String qualifiedName = "emp:qual?name";
+ Document doc;
+ NodeList elementList;
+ Node testAddr;
+ doc = (Document) load("staffNS", builder);
+ elementList = doc.getElementsByTagName("employee");
+ testAddr = elementList.item(0);
+
+ {
+ boolean success = false;
+ try {
+ ((Element) /* Node */testAddr).setAttributeNS(namespaceURI,
+ qualifiedName, "newValue");
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.INVALID_CHARACTER_ERR);
+ }
+ assertTrue("throw_INVALID_CHARACTER_ERR", success);
+ }
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies DOMException with NAMESPACE_ERR code.",
+ method = "setAttributeNS",
+ args = {java.lang.String.class, java.lang.String.class, java.lang.String.class}
+ )
+ public void testSetAttributeNS2() throws Throwable {
+ String namespaceURI = "http://www.nist.gov";
+ String qualifiedName = "emp:";
+ Document doc;
+ NodeList elementList;
+ Node testAddr;
+ doc = (Document) load("staffNS", builder);
+ elementList = doc.getElementsByTagName("emp:employee");
+ testAddr = elementList.item(0);
+
+ {
+ boolean success = false;
+ try {
+ ((Element) /* Node */testAddr).setAttributeNS(namespaceURI,
+ qualifiedName, "newValue");
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.NAMESPACE_ERR);
+ }
+ assertTrue("throw_NAMESPACE_ERR", success);
+ }
+ }
+
+// Assumes validation.
+// public void testSetAttributeNS3() throws Throwable {
+// String namespaceURI = "www.xyz.com";
+// String qualifiedName = "emp:local1";
+// Document doc;
+// NodeList genderList;
+// Node gender;
+// NodeList genList;
+// Node gen;
+// NodeList gList;
+// Element genElement;
+// int nodeType;
+// doc = (Document) load("staffNS", builder);
+// genderList = doc.getElementsByTagName("gender");
+// gender = genderList.item(2);
+// genList = gender.getChildNodes();
+// gen = genList.item(0);
+// nodeType = (int) gen.getNodeType();
+//
+// if (1 == nodeType) {
+// gen = doc.createEntityReference("ent4");
+// assertNotNull("createdEntRefNotNull", gen);
+// }
+// gList = gen.getChildNodes();
+// genElement = (Element) gList.item(0);
+// assertNotNull("notnull", genElement);
+//
+// {
+// boolean success = false;
+// try {
+// genElement.setAttributeNS(namespaceURI, qualifiedName,
+// "newValue");
+// } catch (DOMException ex) {
+// success = (ex.code == DOMException.NO_MODIFICATION_ALLOWED_ERR);
+// }
+// assertTrue("throw_NO_MODIFICATION_ALLOWED_ERR", success);
+// }
+// }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies positive functionality.",
+ method = "setAttributeNS",
+ args = {String.class, String.class, String.class}
+ )
+ public void testSetAttributeNS4() throws Throwable {
+ Document doc;
+ NodeList elementList;
+ Node testAddr;
+ Attr addrAttr;
+ String resultAttr;
+ String resultNamespaceURI;
+ String resultLocalName;
+ String resultPrefix;
+ doc = (Document) load("staffNS", builder);
+ elementList = doc.getElementsByTagName("emp:address");
+ testAddr = elementList.item(0);
+ assertNotNull("empAddrNotNull", testAddr);
+ ((Element) /* Node */testAddr).setAttributeNS("http://www.nist.gov",
+ "newprefix:zone", "newValue");
+ addrAttr = ((Element) /* Node */testAddr).getAttributeNodeNS(
+ "http://www.nist.gov", "zone");
+ resultAttr = ((Element) /* Node */testAddr).getAttributeNS(
+ "http://www.nist.gov", "zone");
+ assertEquals("attrValue", "newValue", resultAttr);
+ resultNamespaceURI = addrAttr.getNamespaceURI();
+ assertEquals("nsuri", "http://www.nist.gov", resultNamespaceURI);
+ resultLocalName = addrAttr.getLocalName();
+ assertEquals("lname", "zone", resultLocalName);
+ resultPrefix = addrAttr.getPrefix();
+ assertEquals("prefix", "newprefix", resultPrefix);
+ }
+
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies positive functionality.",
+ method = "setAttributeNS",
+ args = {java.lang.String.class, java.lang.String.class, java.lang.String.class}
+ )
+ public void testSetAttributeNS5() throws Throwable {
+ String localName = "newAttr";
+ String namespaceURI = "http://www.newattr.com";
+ String qualifiedName = "emp:newAttr";
+ Document doc;
+ NodeList elementList;
+ Node testAddr;
+
+ String resultAttr;
+ doc = (Document) load("staffNS", builder);
+ elementList = doc.getElementsByTagName("emp:address");
+ testAddr = elementList.item(0);
+ assertNotNull("empAddrNotNull", testAddr);
+ ((Element) /* Node */testAddr).setAttributeNS(namespaceURI,
+ qualifiedName, "<newValue>");
+ resultAttr = ((Element) /* Node */testAddr).getAttributeNS(
+ namespaceURI, localName);
+ assertEquals("throw_Equals", "<newValue>", resultAttr);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies DOMException with NAMESPACE_ERR code.",
+ method = "setAttributeNS",
+ args = {java.lang.String.class, java.lang.String.class, java.lang.String.class}
+ )
+ public void testSetAttributeNS6() throws Throwable {
+ String namespaceURI = "http://www.nist.gov";
+ String qualifiedName = "xml:qualifiedName";
+ Document doc;
+ NodeList elementList;
+ Node testAddr;
+ doc = (Document) load("staffNS", builder);
+ elementList = doc.getElementsByTagName("employee");
+ testAddr = elementList.item(0);
+
+ {
+ boolean success = false;
+ try {
+ ((Element) /* Node */testAddr).setAttributeNS(namespaceURI,
+ qualifiedName, "newValue");
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.NAMESPACE_ERR);
+ }
+ assertTrue("throw_NAMESPACE_ERR", success);
+ }
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies DOMException with NAMESPACE_ERR.",
+ method = "setAttributeNS",
+ args = {java.lang.String.class, java.lang.String.class, java.lang.String.class}
+ )
+ public void testSetAttributeNS7() throws Throwable {
+ String namespaceURI = "http://www.nist.gov";
+ String qualifiedName = "xmlns";
+ Document doc;
+ NodeList elementList;
+ Node testAddr;
+ doc = (Document) load("staffNS", builder);
+ elementList = doc.getElementsByTagName("employee");
+ testAddr = elementList.item(0);
+
+ {
+ boolean success = false;
+ try {
+ ((Element) /* Node */testAddr).setAttributeNS(namespaceURI,
+ qualifiedName, "newValue");
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.NAMESPACE_ERR);
+ }
+ assertTrue("throw_NAMESPACE_ERR", success);
+ }
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies positive functionality.",
+ method = "setAttributeNS",
+ args = {java.lang.String.class, java.lang.String.class, java.lang.String.class}
+ )
+ public void testSetAttributeNS9() throws Throwable {
+ String localName = "newAttr";
+ String namespaceURI = "http://www.newattr.com";
+ String qualifiedName = "emp:newAttr";
+ Document doc;
+ NodeList elementList;
+ Node testAddr;
+ Attr addrAttr;
+ String resultAttr;
+ String resultNamespaceURI;
+ String resultLocalName;
+ String resultPrefix;
+ doc = (Document) load("staffNS", builder);
+ elementList = doc.getElementsByTagName("emp:address");
+ testAddr = elementList.item(0);
+ assertNotNull("empAddrNotNull", testAddr);
+ ((Element) /* Node */testAddr).setAttributeNS(namespaceURI,
+ qualifiedName, "newValue");
+ addrAttr = ((Element) /* Node */testAddr).getAttributeNodeNS(
+ namespaceURI, localName);
+ resultAttr = ((Element) /* Node */testAddr).getAttributeNS(
+ namespaceURI, localName);
+ assertEquals("attrValue", "newValue", resultAttr);
+ resultNamespaceURI = addrAttr.getNamespaceURI();
+ assertEquals("nsuri", "http://www.newattr.com", resultNamespaceURI);
+ resultLocalName = addrAttr.getLocalName();
+ assertEquals("lname", "newAttr", resultLocalName);
+ resultPrefix = addrAttr.getPrefix();
+ assertEquals("prefix", "emp", resultPrefix);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies DOMException with NAMESPACE_ERR code.",
+ method = "setAttributeNS",
+ args = {java.lang.String.class, java.lang.String.class, java.lang.String.class}
+ )
+ public void testSetAttributeNS10() throws Throwable {
+ String namespaceURI = "http://www.example.gov";
+ Document doc;
+ NodeList elementList;
+ Node testAddr;
+ doc = (Document) load("hc_staff", builder);
+ elementList = doc.getElementsByTagName("em");
+ testAddr = elementList.item(0);
+
+ {
+ boolean success = false;
+ try {
+ ((Element) /* Node */testAddr).setAttributeNS(namespaceURI, "",
+ "newValue");
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.NAMESPACE_ERR);
+ }
+ assertTrue("throw_NAMESPACE_ERR", success);
+ }
+ }
+}
diff --git a/xml/src/test/java/tests/org/w3c/dom/SetAttributeNodeNS.java b/xml/src/test/java/tests/org/w3c/dom/SetAttributeNodeNS.java
new file mode 100644
index 0000000..3960a4f
--- /dev/null
+++ b/xml/src/test/java/tests/org/w3c/dom/SetAttributeNodeNS.java
@@ -0,0 +1,237 @@
+/*
+ This Java source file was generated by test-to-java.xsl
+ and is a derived work from the source document.
+ The source document contained the following notice:
+
+
+
+ Copyright (c) 2001-2004 World Wide Web Consortium,
+ (Massachusetts Institute of Technology, Institut National de
+ Recherche en Informatique et en Automatique, Keio University). All
+ Rights Reserved. This program is distributed under the W3C's Software
+ Intellectual Property License. This program is distributed in the
+ hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+ See W3C License http://www.w3.org/Consortium/Legal/ for more details.
+
+
+ */
+
+package tests.org.w3c.dom;
+
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import org.w3c.dom.Element;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Attr;
+import org.w3c.dom.DOMException;
+
+import javax.xml.parsers.DocumentBuilder;
+
+/**
+ * The "setAttributeNode(newAttr)" method raises an "INUSE_ATTRIBUTE_ERR
+ * DOMException if the "newAttr" is already an attribute of another element.
+ *
+ * Retrieve the first emp:address and append a newly created element. The
+ * "createAttributeNS(namespaceURI,qualifiedName)" and
+ * "setAttributeNodeNS(newAttr)" methods are invoked to create and add a new
+ * attribute to the newly created Element. The "setAttributeNodeNS(newAttr)"
+ * method is once again called to add the new attribute causing an exception to
+ * be raised since the attribute is already an attribute of another element.
+ *
+ * @author NIST
+ * @author Mary Brady
+ * @see <a
+ * href="http://www.w3.org/TR/DOM-Level-2-Core/core#xpointer(id('ID-258A00AF')/constant[@name='INUSE_ATTRIBUTE_ERR'])">http://www.w3.org/TR/DOM-Level-2-Core/core#xpointer(id('ID-258A00AF')/constant[@name='INUSE_ATTRIBUTE_ERR'])</a>
+ * @see <a
+ * href="http://www.w3.org/TR/DOM-Level-2-Core/core#ID-ElSetAtNodeNS">http://www.w3.org/TR/DOM-Level-2-Core/core#ID-ElSetAtNodeNS</a>
+ * @see <a
+ * href="http://www.w3.org/TR/DOM-Level-2-Core/core#xpointer(id('ID-ElSetAtNodeNS')/raises/exception[@name='DOMException']/descr/p[substring-before(.,':')='INUSE_ATTRIBUTE_ERR'])">http://www.w3.org/TR/DOM-Level-2-Core/core#xpointer(id('ID-ElSetAtNodeNS')/raises/exception[@name='DOMException']/descr/p[substring-before(.,':')='INUSE_ATTRIBUTE_ERR'])</a>
+ */
+@TestTargetClass(Element.class)
+public final class SetAttributeNodeNS extends DOMTestCase {
+
+ DOMDocumentBuilderFactory factory;
+
+ DocumentBuilder builder;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ try {
+ factory = new DOMDocumentBuilderFactory(DOMDocumentBuilderFactory
+ .getConfiguration2());
+ builder = factory.getBuilder();
+ } catch (Exception e) {
+ fail("Unexpected exception" + e.getMessage());
+ }
+ }
+
+ protected void tearDown() throws Exception {
+ factory = null;
+ builder = null;
+ super.tearDown();
+ }
+
+ /**
+ * Runs the test case.
+ *
+ * @throws Throwable
+ * Any uncaught exception causes test to fail
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies DOMException with INUSE_ATTRIBUTE_ERR code.",
+ method = "setAttributeNodeNS",
+ args = {org.w3c.dom.Attr.class}
+ )
+ public void testSetAttributeNode1() throws Throwable {
+ String namespaceURI = "http://www.newattr.com";
+ String qualifiedName = "emp:newAttr";
+ Document doc;
+ Element newElement;
+ Attr newAttr;
+ NodeList elementList;
+ Node testAddr;
+
+ doc = (Document) load("staffNS", builder);
+ elementList = doc.getElementsByTagName("emp:address");
+ testAddr = elementList.item(0);
+ assertNotNull("empAddrNotNull", testAddr);
+ newElement = doc.createElement("newElement");
+ testAddr.appendChild(newElement);
+ newAttr = doc.createAttributeNS(namespaceURI, qualifiedName);
+ newElement.setAttributeNodeNS(newAttr);
+
+ {
+ boolean success = false;
+ try {
+ ((Element) /* Node */testAddr).setAttributeNodeNS(newAttr);
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.INUSE_ATTRIBUTE_ERR);
+ }
+ assertTrue("throw_INUSE_ATTRIBUTE_ERR", success);
+ }
+ }
+
+// Assumes validation.
+// public void testSetAttributeNode2() throws Throwable {
+// Document doc;
+// NodeList genderList;
+// Node gender;
+// NodeList genList;
+// Node gen;
+// NodeList gList;
+// Element genElement;
+// Attr newAttr;
+//
+// doc = (Document) load("staffNS", builder);
+//
+// if (!factory.isExpandEntityReferences()) {
+// genderList = doc.getElementsByTagName("gender");
+// gender = genderList.item(2);
+// genList = gender.getChildNodes();
+// gen = genList.item(0);
+// } else {
+// gen = doc.createEntityReference("ent4");
+// }
+//
+// gList = gen.getChildNodes();
+// genElement = (Element) gList.item(0);
+// assertNotNull("notnull", genElement);
+// newAttr = doc.createAttributeNS("www.xyz.com", "emp:local1");
+//
+// {
+// boolean success = false;
+// try {
+// genElement.setAttributeNodeNS(newAttr);
+// } catch (DOMException ex) {
+// success = (ex.code == DOMException.NO_MODIFICATION_ALLOWED_ERR);
+// }
+// assertTrue("throw_NO_MODIFICATION_ALLOWED_ERR", success);
+// }
+// }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Doesn't verify DOMException.",
+ method = "setAttributeNodeNS",
+ args = {org.w3c.dom.Attr.class}
+ )
+ public void testSetAttributeNode3() throws Throwable {
+ String namespaceURI = "http://www.newattr.com";
+ String qualifiedName = "emp:newAttr";
+ Document doc;
+ NodeList elementList;
+ Node testAddr;
+ Attr newAttr;
+ Attr newAddrAttr;
+ doc = (Document) load("staffNS", builder);
+ elementList = doc.getElementsByTagName("emp:address");
+ testAddr = elementList.item(0);
+ assertNotNull("empAddrNotNull", testAddr);
+ newAttr = doc.createAttributeNS(namespaceURI, qualifiedName);
+ newAddrAttr = ((Element) /* Node */testAddr)
+ .setAttributeNodeNS(newAttr);
+ assertNull("throw_Null", newAddrAttr);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Doesn't verify DOMException.",
+ method = "setAttributeNodeNS",
+ args = {org.w3c.dom.Attr.class}
+ )
+ public void testSetAttributeNode4() throws Throwable {
+ Document doc;
+ NodeList elementList;
+ Node testAddr;
+ Attr newAttr;
+ Attr newAddrAttr;
+ String newName;
+ doc = (Document) load("staffNS", builder);
+ elementList = doc.getElementsByTagName("emp:address");
+ testAddr = elementList.item(0);
+ assertNotNull("empAddrNotNull", testAddr);
+ newAttr = doc.createAttributeNS("http://www.nist.gov", "xxx:domestic");
+ newAddrAttr = ((Element) /* Node */testAddr)
+ .setAttributeNodeNS(newAttr);
+ newName = newAddrAttr.getNodeName();
+ assertEquals("nodeName", "emp:domestic", newName);
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies DOMException with WRONG_DOCUMENT_ERR code.",
+ method = "setAttributeNodeNS",
+ args = {org.w3c.dom.Attr.class}
+ )
+ public void testSetAttributeNode5() throws Throwable {
+ String namespaceURI = "http://www.newattr.com";
+ String qualifiedName = "emp:newAttr";
+ Document doc1;
+ Document doc2;
+ Attr newAttr;
+ NodeList elementList;
+ Node testAddr;
+
+ doc1 = (Document) load("staffNS", builder);
+ doc2 = (Document) load("staffNS", builder);
+ newAttr = doc2.createAttributeNS(namespaceURI, qualifiedName);
+ elementList = doc1.getElementsByTagName("emp:address");
+ testAddr = elementList.item(0);
+
+ {
+ boolean success = false;
+ try {
+ ((Element) /* Node */testAddr).setAttributeNodeNS(newAttr);
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.WRONG_DOCUMENT_ERR);
+ }
+ assertTrue("throw_WRONG_DOCUMENT_ERR", success);
+ }
+ }
+}
diff --git a/xml/src/test/java/tests/org/w3c/dom/SetNamedItemNS.java b/xml/src/test/java/tests/org/w3c/dom/SetNamedItemNS.java
new file mode 100644
index 0000000..ae364ec
--- /dev/null
+++ b/xml/src/test/java/tests/org/w3c/dom/SetNamedItemNS.java
@@ -0,0 +1,248 @@
+
+/*
+This Java source file was generated by test-to-java.xsl
+and is a derived work from the source document.
+The source document contained the following notice:
+
+
+
+Copyright (c) 2001 World Wide Web Consortium,
+(Massachusetts Institute of Technology, Institut National de
+Recherche en Informatique et en Automatique, Keio University). All
+Rights Reserved. This program is distributed under the W3C's Software
+Intellectual Property License. This program is distributed in the
+hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE.
+
+See W3C License http://www.w3.org/Consortium/Legal/ for more details.
+
+
+*/
+
+package tests.org.w3c.dom;
+
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.DOMException;
+
+import javax.xml.parsers.DocumentBuilder;
+
+/**
+ * The "setNamedItemNS(arg)" method for a
+ * NamedNodeMap should raise INUSE_ATTRIBUTE_ERR DOMException if
+ * arg is an Attr that is already an attribute of another Element object.
+ *
+ * Retrieve an attr node from the third "address" element whose local name
+ * is "domestic" and namespaceURI is "http://www.netzero.com".
+ * Invoke method setNamedItemNS(arg) on the map of the first "address" element with
+ * arg being the attr node from above. Method should raise
+ * INUSE_ATTRIBUTE_ERR DOMException.
+* @author NIST
+* @author Mary Brady
+* @see <a href="http://www.w3.org/TR/DOM-Level-2-Core/core#xpointer(id('ID-258A00AF')/constant[@name='INUSE_ATTRIBUTE_ERR'])">http://www.w3.org/TR/DOM-Level-2-Core/core#xpointer(id('ID-258A00AF')/constant[@name='INUSE_ATTRIBUTE_ERR'])</a>
+* @see <a href="http://www.w3.org/TR/DOM-Level-2-Core/core#ID-setNamedItemNS">http://www.w3.org/TR/DOM-Level-2-Core/core#ID-setNamedItemNS</a>
+* @see <a href="http://www.w3.org/TR/DOM-Level-2-Core/core#xpointer(id('ID-setNamedItemNS')/raises/exception[@name='DOMException']/descr/p[substring-before(.,':')='INUSE_ATTRIBUTE_ERR'])">http://www.w3.org/TR/DOM-Level-2-Core/core#xpointer(id('ID-setNamedItemNS')/raises/exception[@name='DOMException']/descr/p[substring-before(.,':')='INUSE_ATTRIBUTE_ERR'])</a>
+*/
+@TestTargetClass(NamedNodeMap.class)
+public final class SetNamedItemNS extends DOMTestCase {
+
+ DOMDocumentBuilderFactory factory;
+
+ DocumentBuilder builder;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ try {
+ factory = new DOMDocumentBuilderFactory(DOMDocumentBuilderFactory
+ .getConfiguration2());
+ builder = factory.getBuilder();
+ } catch (Exception e) {
+ fail("Unexpected exception" + e.getMessage());
+ }
+ }
+
+ protected void tearDown() throws Exception {
+ factory = null;
+ builder = null;
+ super.tearDown();
+ }
+
+ /**
+ * Runs the test case.
+ * @throws Throwable Any uncaught exception causes test to fail
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies DOMException with INUSE_ATTRIBUTE_ERR code.",
+ method = "setNamedItemNS",
+ args = {org.w3c.dom.Node.class}
+ )
+ public void testSetNamedItemNS1() throws Throwable {
+ Document doc;
+ NodeList elementList;
+ Node anotherElement;
+ NamedNodeMap anotherMap;
+ Node arg;
+ Node testAddress;
+ NamedNodeMap map;
+
+ doc = (Document) load("staffNS", builder);
+ elementList = doc.getElementsByTagName("address");
+ anotherElement = elementList.item(2);
+ anotherMap = anotherElement.getAttributes();
+ arg = anotherMap.getNamedItemNS("http://www.netzero.com", "domestic");
+ testAddress = elementList.item(0);
+ map = testAddress.getAttributes();
+
+ {
+ boolean success = false;
+ try {
+ map.setNamedItemNS(arg);
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.INUSE_ATTRIBUTE_ERR);
+ }
+ assertTrue("throw_INUSE_ATTRIBUTE_ERR", success);
+ }
+}
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies DOMException with WRONG_DOCUMENT_ERR code.",
+ method = "setNamedItemNS",
+ args = {org.w3c.dom.Node.class}
+ )
+ public void testSetNamedItemNS2() throws Throwable {
+ String namespaceURI = "http://www.usa.com";
+ String qualifiedName = "dmstc:domestic";
+ Document doc;
+ Document anotherDoc;
+ Node arg;
+ NodeList elementList;
+ Node testAddress;
+ NamedNodeMap attributes;
+
+ doc = (Document) load("staffNS", builder);
+ anotherDoc = (Document) load("staffNS", builder);
+ arg = anotherDoc.createAttributeNS(namespaceURI, qualifiedName);
+ arg.setNodeValue("Maybe");
+ elementList = doc.getElementsByTagName("address");
+ testAddress = elementList.item(0);
+ attributes = testAddress.getAttributes();
+
+ {
+ boolean success = false;
+ try {
+ attributes.setNamedItemNS(arg);
+ } catch (DOMException ex) {
+ success = (ex.code == DOMException.WRONG_DOCUMENT_ERR);
+ }
+ assertTrue("throw_WRONG_DOCUMENT_ERR", success);
+ }
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies positive fnctionality.",
+ method = "getNamedItemNS",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testSetNamedItemNS3() throws Throwable {
+ String namespaceURI = "http://www.nist.gov";
+ String qualifiedName = "prefix:newAttr";
+ Document doc;
+ Node arg;
+ NodeList elementList;
+ Node testAddress;
+ NamedNodeMap attributes;
+ Node retnode;
+ String value;
+
+ doc = (Document) load("staffNS", builder);
+ arg = doc.createAttributeNS(namespaceURI, qualifiedName);
+ arg.setNodeValue("newValue");
+ elementList = doc.getElementsByTagName("address");
+ testAddress = elementList.item(0);
+ attributes = testAddress.getAttributes();
+ attributes.setNamedItemNS(arg);
+ retnode = attributes.getNamedItemNS(namespaceURI, "newAttr");
+ value = retnode.getNodeValue();
+ assertEquals("throw_Equals", "newValue", value);
+ }
+
+// Assumes validation.
+// public void testSetNamedItemNS4() throws Throwable {
+// String namespaceURI = "http://www.w3.org/2000/xmlns/";
+// String localName = "local1";
+// Document doc;
+// NodeList elementList;
+// Node testAddress;
+// NodeList nList;
+// Node child;
+// NodeList n2List;
+// Node child2;
+// NamedNodeMap attributes;
+// Node arg;
+//
+// int nodeType;
+// doc = (Document) load("staffNS", builder);
+// elementList = doc.getElementsByTagName("gender");
+// testAddress = elementList.item(2);
+// nList = testAddress.getChildNodes();
+// child = nList.item(0);
+// nodeType = (int) child.getNodeType();
+//
+// if (1 == nodeType) {
+// child = doc.createEntityReference("ent4");
+// assertNotNull("createdEntRefNotNull", child);
+// }
+// n2List = child.getChildNodes();
+// child2 = n2List.item(0);
+// assertNotNull("notnull", child2);
+// attributes = child2.getAttributes();
+// arg = attributes.getNamedItemNS(namespaceURI, localName);
+//
+// {
+// boolean success = false;
+// try {
+// attributes.setNamedItemNS(arg);
+// } catch (DOMException ex) {
+// success = (ex.code == DOMException.NO_MODIFICATION_ALLOWED_ERR);
+// }
+// assertTrue("throw_NO_MODIFICATION_ALLOWED_ERR", success);
+// }
+// }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies positive fnctionality.",
+ method = "setNamedItemNS",
+ args = {org.w3c.dom.Node.class}
+ )
+ public void testSetNamedItemNS5() throws Throwable {
+ String namespaceURI = "http://www.usa.com";
+ String qualifiedName = "dmstc:domestic";
+ Document doc;
+ Node arg;
+ NodeList elementList;
+ Node testAddress;
+ NamedNodeMap attributes;
+ Node retnode;
+ String value;
+ doc = (Document) load("staffNS", builder);
+ arg = doc.createAttributeNS(namespaceURI, qualifiedName);
+ arg.setNodeValue("newValue");
+ elementList = doc.getElementsByTagName("address");
+ testAddress = elementList.item(0);
+ attributes = testAddress.getAttributes();
+ retnode = attributes.setNamedItemNS(arg);
+ value = retnode.getNodeValue();
+ assertEquals("throw_Equals", "Yes", value);
+ }
+
+}
+
diff --git a/xml/src/test/java/tests/org/w3c/dom/SystemId.java b/xml/src/test/java/tests/org/w3c/dom/SystemId.java
new file mode 100644
index 0000000..3e1b903
--- /dev/null
+++ b/xml/src/test/java/tests/org/w3c/dom/SystemId.java
@@ -0,0 +1,94 @@
+/*
+ This Java source file was generated by test-to-java.xsl
+ and is a derived work from the source document.
+ The source document contained the following notice:
+
+
+
+ Copyright (c) 2001 World Wide Web Consortium,
+ (Massachusetts Institute of Technology, Institut National de
+ Recherche en Informatique et en Automatique, Keio University). All
+ Rights Reserved. This program is distributed under the W3C's Software
+ Intellectual Property License. This program is distributed in the
+ hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+ See W3C License http://www.w3.org/Consortium/Legal/ for more details.
+
+
+ */
+
+package tests.org.w3c.dom;
+
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import org.w3c.dom.DocumentType;
+import org.w3c.dom.Document;
+
+import javax.xml.parsers.DocumentBuilder;
+
+/**
+ * The "getSystemId()" method of a documenttype node contains the system
+ * identifier associated with the external subset.
+ *
+ * Retrieve the documenttype. Apply the "getSystemId()" method. The string
+ * "staffNS.dtd" should be returned.
+ *
+ * @author NIST
+ * @author Mary Brady
+ * @see <a
+ * href="http://www.w3.org/TR/DOM-Level-2-Core/core#ID-Core-DocType-systemId">http://www.w3.org/TR/DOM-Level-2-Core/core#ID-Core-DocType-systemId</a>
+ */
+@TestTargetClass(DocumentType.class)
+public final class SystemId extends DOMTestCase {
+
+ DOMDocumentBuilderFactory factory;
+
+ DocumentBuilder builder;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ try {
+ factory = new DOMDocumentBuilderFactory(DOMDocumentBuilderFactory
+ .getConfiguration1());
+ builder = factory.getBuilder();
+ } catch (Exception e) {
+ fail("Unexpected exception" + e.getMessage());
+ }
+ }
+
+ protected void tearDown() throws Exception {
+ factory = null;
+ builder = null;
+ super.tearDown();
+ }
+
+ /**
+ * Runs the test case.
+ *
+ * @throws Throwable
+ * Any uncaught exception causes test to fail
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getSystemId",
+ args = {}
+ )
+ public void testGetSystemId() throws Throwable {
+ Document doc;
+ DocumentType docType;
+ String systemId;
+
+ doc = (Document) load("staffNS", builder);
+ docType = doc.getDoctype();
+ systemId = docType.getSystemId();
+ assertURIEquals("systemId", null, null, null, "staffNS.dtd", null,
+ null, null, null, systemId);
+ }
+
+}
diff --git a/xml/src/test/java/tests/xml/AllTests.java b/xml/src/test/java/tests/xml/AllTests.java
new file mode 100644
index 0000000..eefae50
--- /dev/null
+++ b/xml/src/test/java/tests/xml/AllTests.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.xml;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class AllTests {
+
+ public static Test suite() {
+ TestSuite suite = tests.TestSuiteFactory.createTestSuite();
+
+ suite.addTestSuite(SimpleParserTest.class);
+ suite.addTestSuite(SimpleBuilderTest.class);
+
+ //suite.addTest(tests.org.w3c.dom.AllTests.suite());
+ suite.addTest(tests.api.javax.xml.parsers.AllTests.suite());
+
+ suite.addTest(tests.api.org.xml.sax.AllTests.suite());
+
+ return suite;
+ }
+
+}
diff --git a/xml/src/test/java/tests/xml/SimpleBuilderTest.java b/xml/src/test/java/tests/xml/SimpleBuilderTest.java
new file mode 100644
index 0000000..1a555c6
--- /dev/null
+++ b/xml/src/test/java/tests/xml/SimpleBuilderTest.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.xml;
+
+import dalvik.annotation.BrokenTest;
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import junit.framework.TestCase;
+
+import org.w3c.dom.Comment;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+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 javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+@TestTargetClass(DocumentBuilder.class)
+public class SimpleBuilderTest extends TestCase {
+
+ private DocumentBuilder builder;
+
+ protected void setUp() throws Exception {
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ factory.setValidating(false);
+ factory.setNamespaceAware(true);
+
+ builder = factory.newDocumentBuilder();
+ }
+
+ protected void tearDown() throws Exception {
+ builder = null;
+ }
+
+ private String getTextContent(Node node) {
+ String result = (node instanceof Text ? ((Text) node).getData() : "");
+
+ Node child = node.getFirstChild();
+ while (child != null) {
+ result = result + getTextContent(child);
+ child = child.getNextSibling();
+ }
+
+ return result;
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Regression test.",
+ method = "parse",
+ args = {java.io.InputStream.class}
+ )
+ public void testGoodFile1() throws Exception {
+ Document document = builder.parse(getClass().getResourceAsStream(
+ "/SimpleBuilderTest.xml"));
+
+ Element root = document.getDocumentElement();
+ assertNotNull(root);
+ assertEquals("http://www.foo.bar", root.getNamespaceURI());
+ assertEquals("t", root.getPrefix());
+ assertEquals("stuff", root.getLocalName());
+
+ NodeList list = root.getElementsByTagName("nestedStuff");
+ assertNotNull(list);
+ assertEquals(list.getLength(), 4);
+
+ Element one = (Element) list.item(0);
+ Element two = (Element) list.item(1);
+ Element three = (Element) list.item(2);
+ Element four = (Element) list.item(3);
+
+ assertEquals("This space intentionally left blank.",
+ getTextContent(one));
+ assertEquals("Nothing to see here - please get along!",
+ getTextContent(two));
+ assertEquals("Rent this space!", getTextContent(three));
+ assertEquals("", getTextContent(four));
+
+ assertEquals("eins", one.getAttribute("one"));
+ assertEquals("zwei", two.getAttribute("two"));
+ assertEquals("drei", three.getAttribute("three"));
+
+ assertEquals("vier", four.getAttribute("t:four"));
+ assertEquals("vier", four.getAttributeNS("http://www.foo.bar", "four"));
+
+ list = document.getChildNodes();
+ assertNotNull(list);
+
+ String proinst = "";
+ String comment = "";
+
+ for (int i = 0; i < list.getLength(); i++) {
+ Node node = list.item(i);
+
+ if (node instanceof ProcessingInstruction) {
+ proinst = proinst + node.getNodeValue();
+ } else if (node instanceof Comment) {
+ comment = comment + node.getNodeValue();
+ }
+ }
+
+ assertEquals("The quick brown fox jumps over the lazy dog.", proinst);
+ assertEquals(" Fragile! Handle me with care! ", comment);
+ }
+ @TestTargetNew(
+ level = TestLevel.ADDITIONAL,
+ method = "!todo parse",
+ args = {java.io.InputStream.class}
+ )
+ @BrokenTest("Doesn't verify anything.")
+ public void testGoodFile2() throws Exception {
+ Document document = builder.parse(getClass().getResourceAsStream(
+ "/staffNS.xml"));
+
+ Element root = document.getDocumentElement();
+ assertNotNull(root);
+
+ // dump("", root);
+ }
+
+ private void dump(String prefix, Element element) {
+ System.out.print(prefix + "<" + element.getTagName());
+
+ NamedNodeMap attrs = element.getAttributes();
+ for (int i = 0; i < attrs.getLength(); i++) {
+ Node item = attrs.item(i);
+ System.out.print(" " + item.getNodeName() + "=" + item.getNodeValue());
+ }
+
+ System.out.println(">");
+
+ NodeList children = element.getChildNodes();
+ for (int i = 0; i < children.getLength(); i++) {
+ Node item = children.item(i);
+ if (item instanceof Element) {
+ dump(prefix + " ", (Element)item);
+ }
+ }
+
+ System.out.println(prefix + "</" + element.getTagName() + ">");
+ }
+}
diff --git a/xml/src/test/java/tests/xml/SimpleParserTest.java b/xml/src/test/java/tests/xml/SimpleParserTest.java
new file mode 100644
index 0000000..4651039
--- /dev/null
+++ b/xml/src/test/java/tests/xml/SimpleParserTest.java
@@ -0,0 +1,289 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.xml;
+
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import junit.framework.TestCase;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+@TestTargetClass(SAXParser.class)
+public class SimpleParserTest extends TestCase implements ContentHandler {
+
+ private SAXParser parser;
+
+ private StringBuffer instructions;
+
+ private Map<String, String> namespaces1;
+ private Map<String, String> namespaces2;
+
+ private StringBuffer elements1;
+ private StringBuffer elements2;
+
+ private Map<String, String> attributes1;
+ private Map<String, String> attributes2;
+
+ private StringBuffer text;
+
+ @Override
+ protected void setUp() throws Exception {
+ SAXParserFactory factory = SAXParserFactory.newInstance();
+ factory.setValidating(false);
+ factory.setNamespaceAware(true);
+
+ parser = factory.newSAXParser();
+ parser.getXMLReader().setContentHandler(this);
+
+ instructions = new StringBuffer();
+ namespaces1 = new HashMap<String, String>();
+ namespaces2 = new HashMap<String, String>();
+ elements1 = new StringBuffer();
+ elements2 = new StringBuffer();
+ attributes1 = new HashMap<String, String>();
+ attributes2 = new HashMap<String, String>();
+ text = new StringBuffer();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ instructions = null;
+ parser = null;
+ namespaces1 = null;
+ namespaces2 = null;
+ attributes1 = null;
+ attributes2 = null;
+ elements1 = null;
+ elements2 = null;
+ text = null;
+ }
+
+ public void characters(char[] ch, int start, int length) {
+
+ String s = new String(ch, start, length).trim();
+ if (s.length() != 0) {
+ if (text.length() != 0) {
+ text.append(",");
+ }
+
+ text.append(s);
+ }
+ }
+
+ public void endDocument() {
+ }
+
+ public void endElement(String uri, String localName, String qName) {
+ }
+
+ public void endPrefixMapping(String prefix) {
+ }
+
+ public void ignorableWhitespace(char[] ch, int start, int length) {
+ }
+
+ public void processingInstruction(String target, String data) {
+ String s = target + ":" + data;
+
+ if (instructions.length() != 0) {
+ instructions.append(",");
+ }
+
+ instructions.append(s);
+ }
+
+ public void setDocumentLocator(Locator locator) {
+ }
+
+ public void skippedEntity(String name) {
+ }
+
+ public void startDocument() {
+ }
+
+ public void startElement(String uri, String localName, String qName,
+ Attributes atts) {
+
+ if (elements1.length() != 0) {
+ elements1.append(",");
+ }
+
+ elements1.append(localName);
+
+ if (!"".equals(uri)) {
+ namespaces1.put(localName, uri);
+ }
+
+ for (int i = 0; i < atts.getLength(); i++) {
+ attributes1.put(atts.getLocalName(i), atts.getValue(i));
+ }
+
+ if (elements2.length() != 0) {
+ elements2.append(",");
+ }
+
+ elements2.append(qName);
+
+ if (!"".equals(uri)) {
+ namespaces2.put(qName, uri);
+ }
+
+ for (int i = 0; i < atts.getLength(); i++) {
+ attributes2.put(atts.getQName(i), atts.getValue(i));
+ }
+ }
+
+ public void startPrefixMapping(String prefix, String uri) {
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "",
+ method = "parse",
+ args = {java.io.InputStream.class, org.xml.sax.helpers.DefaultHandler.class}
+ )
+ public void testWorkingFile1() throws Exception {
+ SAXParserFactory factory = SAXParserFactory.newInstance();
+ factory.setValidating(false);
+ factory.setNamespaceAware(true);
+
+ SAXParser parser = factory.newSAXParser();
+ parser.getXMLReader().setContentHandler(this);
+
+ parser.parse(getClass().getResourceAsStream("/SimpleParserTest.xml"),
+ (DefaultHandler) null);
+
+ assertEquals("The:quick,brown:fox", instructions.toString());
+
+ assertEquals("stuff,nestedStuff,nestedStuff,nestedStuff", elements1
+ .toString());
+
+ assertEquals("Some text here,some more here...", text.toString());
+
+ assertEquals("eins", attributes1.get("one"));
+ assertEquals("zwei", attributes1.get("two"));
+ assertEquals("drei", attributes1.get("three"));
+
+ assertEquals("http://www.foobar.org", namespaces1.get("stuff"));
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "",
+ method = "parse",
+ args = {java.io.InputStream.class, org.xml.sax.helpers.DefaultHandler.class}
+ )
+ public void testWorkingFile2() throws Exception {
+ SAXParserFactory factory = SAXParserFactory.newInstance();
+
+ factory.setValidating(false);
+ factory.setNamespaceAware(false);
+ factory.setFeature("http://xml.org/sax/features/namespace-prefixes",
+ true);
+
+ SAXParser parser = factory.newSAXParser();
+ parser.getXMLReader().setContentHandler(this);
+ parser.parse(getClass().getResourceAsStream("/SimpleParserTest.xml"),
+ (DefaultHandler) null);
+
+ assertFalse(parser.isNamespaceAware());
+
+ assertEquals("The:quick,brown:fox", instructions.toString());
+
+ assertEquals("t:stuff,nestedStuff,nestedStuff,nestedStuff", elements2
+ .toString());
+
+ assertEquals("Some text here,some more here...", text.toString());
+
+ assertEquals("eins", attributes2.get("one"));
+ assertEquals("zwei", attributes2.get("two"));
+ assertEquals("drei", attributes2.get("three"));
+
+ assertEquals(0, namespaces2.size());
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Doesn't verify exceptions.",
+ method = "parse",
+ args = {java.io.InputStream.class, org.xml.sax.helpers.DefaultHandler.class}
+ )
+ public void testEntityResolver() throws Exception {
+ final StringBuilder text = new StringBuilder();
+ DefaultHandler handler = new DefaultHandler() {
+ public void characters(char[] ch, int start, int length) {
+ String s = new String(ch, start, length).trim();
+ if (s.length() != 0) {
+ if (text.length() != 0) {
+ text.append(",");
+ }
+ text.append(s);
+ }
+ }
+
+ public InputSource resolveEntity(String publicId, String systemId)
+ throws IOException, SAXException {
+ return new InputSource(new InputStreamReader(
+ new ByteArrayInputStream("test".getBytes())));
+ }
+ };
+
+ SAXParserFactory spf = SAXParserFactory.newInstance();
+ spf.setValidating(false);
+ parser = spf.newSAXParser();
+ parser.parse(this.getClass().getResourceAsStream("/staffEntRes.xml"),
+ handler);
+ assertTrue(
+ "resolved external entity must be in parser character stream",
+ text.toString().contains("test"));
+ }
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Doesn't verify exceptions.",
+ method = "parse",
+ args = {java.io.InputStream.class, org.xml.sax.helpers.DefaultHandler.class}
+ )
+ public void testGetValue() throws Exception{
+ parser.parse(getClass().getResourceAsStream("/staffNS.xml"),
+ new DefaultHandler() {
+ boolean firstAddressElem = true;
+ @Override
+ public void startElement (String uri, String localName,
+ String qName, Attributes attributes) {
+ if(firstAddressElem && localName.equals("address")) {
+ firstAddressElem = false;
+ assertNotNull(attributes.getValue("http://www.usa.com",
+ "domestic"));
+ }
+ }
+ });
+ }
+}
diff --git a/xml/src/test/resources/SimpleBuilderTest.xml b/xml/src/test/resources/SimpleBuilderTest.xml
new file mode 100644
index 0000000..23edce7
--- /dev/null
+++ b/xml/src/test/resources/SimpleBuilderTest.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0"?>
+
+<!-- Fragile! -->
+
+<!-- Handle me with care! -->
+
+<?cmd The quick brown fox ?>
+
+<t:stuff xmlns:t="http://www.foo.bar" xmlns:u="http://www.bar.foo">
+
+ <nestedStuff one="eins">This space intentionally left blank.</nestedStuff>
+
+ <nestedStuff two="zwei">Nothing to see here - please get along!</nestedStuff>
+
+ <nestedStuff three="drei" title="">Rent this space!</nestedStuff>
+
+ <nestedStuff t:four="vier"/>
+
+</t:stuff>
+
+<?cmd jumps over the lazy dog.?>
diff --git a/xml/src/test/resources/SimpleParserTest.xml b/xml/src/test/resources/SimpleParserTest.xml
new file mode 100644
index 0000000..e18bf3e
--- /dev/null
+++ b/xml/src/test/resources/SimpleParserTest.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0"?>
+
+<!-- This space intentionally left blank. -->
+
+<?The quick?>
+
+<t:stuff xmlns:t="http://www.foobar.org">
+
+ <nestedStuff one="eins"> Some text here </nestedStuff>
+
+ <nestedStuff two="zwei"></nestedStuff>
+
+ some more here...
+
+ <nestedStuff three="drei" />
+
+</t:stuff>
+
+<?brown fox?>
diff --git a/xml/src/test/resources/hc_staff.xml b/xml/src/test/resources/hc_staff.xml
new file mode 100644
index 0000000..2df9a74
--- /dev/null
+++ b/xml/src/test/resources/hc_staff.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0"?><?TEST-STYLE PIDATA?>
+<!DOCTYPE html
+ PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "xhtml1-strict.dtd" [
+ <!ENTITY alpha "&#945;">
+ <!ENTITY beta "&#946;">
+ <!ENTITY gamma "&#947;">
+ <!ENTITY delta "&#948;">
+ <!ENTITY epsilon "&#949;">
+ <!ENTITY alpha "&#950;">
+ <!NOTATION notation1 PUBLIC "notation1File">
+ <!NOTATION notation2 SYSTEM "notation2File">
+ <!ATTLIST acronym dir CDATA "ltr">
+]>
+<!-- This is comment number 1.-->
+<html xmlns='http://www.w3.org/1999/xhtml'><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/><title>hc_staff</title><script type="text/javascript" src="svgunit.js"/><script charset="UTF-8" type="text/javascript" src="svgtest.js"/><script type='text/javascript'>function loadComplete() { startTest(); }</script></head><body onload="parent.loadComplete()">
+ <p>
+ <em>EMP0001</em>
+ <strong>Margaret Martin</strong>
+ <code>Accountant</code>
+ <sup>56,000</sup>
+ <var>Female</var>
+ <acronym title="Yes">1230 North Ave. Dallas, Texas 98551</acronym>
+ </p>
+ <p>
+ <em>EMP0002</em>
+ <strong>Martha RaynoldsThis is a CDATASection with EntityReference number 2 &amp;ent2;
+This is an adjacent CDATASection with a reference to a tab &amp;tab;</strong>
+ <code>Secretary</code>
+ <sup>35,000</sup>
+ <var>Female</var>
+ <acronym title="Yes" class="Yes">&beta; Dallas, &gamma;
+ 98554</acronym>
+ </p>
+ <p>
+ <em>EMP0003</em>
+ <strong>Roger
+ Jones</strong>
+ <code>Department Manager</code>
+ <sup>100,000</sup>
+ <var>&delta;</var>
+ <acronym title="Yes" class="No">PO Box 27 Irving, texas 98553</acronym>
+ </p>
+ <p>
+ <em>EMP0004</em>
+ <strong>Jeny Oconnor</strong>
+ <code>Personnel Director</code>
+ <sup>95,000</sup>
+ <var>Female</var>
+ <acronym title="Yes" class="Y&alpha;">27 South Road. Dallas, Texas 98556</acronym>
+ </p>
+ <p>
+ <em>EMP0005</em>
+ <strong>Robert Myers</strong>
+ <code>Computer Specialist</code>
+ <sup>90,000</sup>
+ <var>male</var>
+ <acronym title="Yes">1821 Nordic. Road, Irving Texas 98558</acronym>
+ </p>
+</body></html>
diff --git a/xml/src/test/resources/nwf/staff.dtd b/xml/src/test/resources/nwf/staff.dtd
new file mode 100644
index 0000000..02a994d
--- /dev/null
+++ b/xml/src/test/resources/nwf/staff.dtd
@@ -0,0 +1,17 @@
+<!ELEMENT employeeId (#PCDATA)>
+<!ELEMENT name (#PCDATA)>
+<!ELEMENT position (#PCDATA)>
+<!ELEMENT salary (#PCDATA)>
+<!ELEMENT address (#PCDATA)>
+<!ELEMENT entElement ( #PCDATA ) >
+<!ELEMENT gender ( #PCDATA | entElement )* >
+<!ELEMENT employee (employeeId, name, position, salary, gender, address) >
+<!ELEMENT staff (employee)+>
+<!ATTLIST entElement
+ attr1 CDATA "Attr">
+<!ATTLIST address
+ domestic CDATA #IMPLIED
+ street CDATA "Yes">
+<!ATTLIST entElement
+ domestic CDATA "MALE" >
+
diff --git a/xml/src/test/resources/nwf/staff.xml b/xml/src/test/resources/nwf/staff.xml
new file mode 100644
index 0000000..b600fcf
--- /dev/null
+++ b/xml/src/test/resources/nwf/staff.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0"?><?TEST-STYLE PIDATA?>
+<!DOCTYPE staff SYSTEM "staff.dtd" [
+ <!ENTITY ent1 "es">
+ <!ENTITY ent2 "1900 Dallas Road">
+ <!ENTITY ent3 "Texas">
+ <!ENTITY ent4 "<entElement domestic='Yes'>Element data</entElement><?PItarget PIdata?>">
+ <!ENTITY ent5 PUBLIC "entityURI" "entityFile" NDATA notation1>
+ <!ENTITY ent1 "This entity should be discarded">
+ <!NOTATION notation1 PUBLIC "notation1File">
+ <!NOTATION notation2 SYSTEM "notation2File">
+]>
+<!-- This is comment number 1.-->
+<staff>
+ <employee22>
+ <employeeId>EMP0001</employeeId>
+ <name>Margaret Martin</name>
+ <position>Accountant</position>
+ <salary>56,000</salary>
+ <gender>Female</gender>
+ <address domestic="Yes">1230 North Ave. Dallas, Texas 98551</address>
+ </employee>
+ <employee>
+ <employeeId>EMP0002</employeeId>
+ <name>Martha Raynolds<![CDATA[This is a CDATASection with EntityReference number 2 &ent2;]]>
+<![CDATA[This is an adjacent CDATASection with a reference to a tab &tab;]]></name>
+ <position>Secretary</position>
+ <salary>35,000</salary>
+ <gender>Female</gender>
+ <address domestic="Yes" street="Yes">&ent2; Dallas, &ent3;
+ 98554</address>
+ </employee>
+ <employee>
+ <employeeId>EMP0003</employeeId>
+ <name>Roger
+ Jones</name>
+ <position>Department Manager</position>
+ <salary>100,000</salary>
+ <gender>&ent4;</gender>
+ <address domestic="Yes" street="No">PO Box 27 Irving, texas 98553</address>
+ </employee>
+ <employee>
+ <employeeId>EMP0004</employeeId>
+ <name>Jeny Oconnor</name>
+ <position>Personnel Director</position>
+ <salary>95,000</salary>
+ <gender>Female</gender>
+ <address domestic="Yes" street="Y&ent1;">27 South Road. Dallas, Texas 98556</address>
+ </employee>
+ <employee>
+ <employeeId>EMP0005</employeeId>
+ <name>Robert Myers</name>
+ <position>Computer Specialist</position>
+ <salary>90,000</salary>
+ <gender>male</gender>
+ <address street="Yes">1821 Nordic. Road, Irving Texas 98558</address>
+ </employee>
+ </staff>
diff --git a/xml/src/test/resources/out_dh/staff.out b/xml/src/test/resources/out_dh/staff.out
new file mode 100644
index 0000000..467fd08
--- /dev/null
+++ b/xml/src/test/resources/out_dh/staff.out
@@ -0,0 +1,45 @@
+true^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^#true^#
+
+ EMP0001
+ Margaret Martin
+ Accountant
+ 56,000
+ Female
+ 1230 North Ave. Dallas, Texas 98551
+
+
+ EMP0002
+ Martha RaynoldsThis is a CDATASection with EntityReference number 2 &ent2;
+This is an adjacent CDATASection with a reference to a tab &tab;
+ Secretary
+ 35,000
+ Female
+ 1900 Dallas Road Dallas, Texas
+ 98554
+
+
+ EMP0003
+ Roger
+ Jones
+ Department Manager
+ 100,000
+ Element data
+ PO Box 27 Irving, texas 98553
+
+
+ EMP0004
+ Jeny Oconnor
+ Personnel Director
+ 95,000
+ Female
+ 27 South Road. Dallas, Texas 98556
+
+
+ EMP0005
+ Robert Myers
+ Computer Specialist
+ 90,000
+ male
+ 1821 Nordic. Road, Irving Texas 98558
+
+ ####$employeeId$employeeId^$name$name^$position$position^$salary$salary^$gender$gender^$address$address^$employee$employee^$employeeId$employeeId^$name$name^$position$position^$salary$salary^$gender$gender^$address$address^$employee$employee^$employeeId$employeeId^$name$name^$position$position^$salary$salary^$entElement$entElement^$gender$gender^$address$address^$employee$employee^$employeeId$employeeId^$name$name^$position$position^$salary$salary^$gender$gender^$address$address^$employee$employee^$employeeId$employeeId^$name$name^$position$position^$salary$salary^$gender$gender^$address$address^$employee$employee^$staff$staff^##TEST-STYLE$PIDATA^PItarget$PIdata^##$staff$staff$employee$employee$employeeId$employeeId$name$name$position$position$salary$salary$gender$gender$address$address$domestic$Yes$employee$employee$employeeId$employeeId$name$name$position$position$salary$salary$gender$gender$address$address$domestic$Yes$street$Yes$employee$employee$employeeId$employeeId$name$name$position$position$salary$salary$gender$gender$entElement$entElement$domestic$Yes$address$address$domestic$Yes$street$No$employee$employee$employeeId$employeeId$name$name$position$position$salary$salary$gender$gender$address$address$domestic$Yes$street$Yes$employee$employee$employeeId$employeeId$name$name$position$position$salary$salary$gender$gender$address$address$street$Yes##
diff --git a/xml/src/test/resources/out_hb/staff.out b/xml/src/test/resources/out_hb/staff.out
new file mode 100644
index 0000000..c6d61ad
--- /dev/null
+++ b/xml/src/test/resources/out_hb/staff.out
@@ -0,0 +1,45 @@
+true^#true^#
+
+ EMP0001
+ Margaret Martin
+ Accountant
+ 56,000
+ Female
+ 1230 North Ave. Dallas, Texas 98551
+
+
+ EMP0002
+ Martha RaynoldsThis is a CDATASection with EntityReference number 2 &ent2;
+This is an adjacent CDATASection with a reference to a tab &tab;
+ Secretary
+ 35,000
+ Female
+ 1900 Dallas Road Dallas, Texas
+ 98554
+
+
+ EMP0003
+ Roger
+ Jones
+ Department Manager
+ 100,000
+ Element data
+ PO Box 27 Irving, texas 98553
+
+
+ EMP0004
+ Jeny Oconnor
+ Personnel Director
+ 95,000
+ Female
+ 27 South Road. Dallas, Texas 98556
+
+
+ EMP0005
+ Robert Myers
+ Computer Specialist
+ 90,000
+ male
+ 1821 Nordic. Road, Irving Texas 98558
+
+ ######TEST-STYLE$PIDATA^PItarget$PIdata^####
diff --git a/xml/src/test/resources/recipe.xml b/xml/src/test/resources/recipe.xml
new file mode 100644
index 0000000..d7cf0fb
--- /dev/null
+++ b/xml/src/test/resources/recipe.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE collection SYSTEM "./recipt.dtd">
+<!--comment1 -->
+<collection>
+ <description>
+ Some recipes used for the XML tutorial.
+ </description>
+ <recipe>
+ <title>Beef Parmesan<![CDATA[<title> with Garlic Angel Hair Pasta</title>]]></title>
+ <ingredient name="beef cube steak" amount="1.5" unit="pound"/>
+ <preparation>
+ <step>
+ Preheat oven to 350 degrees F (175 degrees C).
+ </step>
+ </preparation>
+ <comment>
+ Make the meat ahead of time, and refrigerate over night, the acid in the
+ tomato sauce will tenderize the meat even more. If you do this, save the
+ mozzarella till the last minute.
+ </comment>
+ <nutrition calories="1167" fat="23" carbohydrates="45" protein="32"/>
+ </recipe>
+</collection>
+<!--comment2 -->
diff --git a/xml/src/test/resources/recipe1.xml b/xml/src/test/resources/recipe1.xml
new file mode 100644
index 0000000..d7cf0fb
--- /dev/null
+++ b/xml/src/test/resources/recipe1.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE collection SYSTEM "./recipt.dtd">
+<!--comment1 -->
+<collection>
+ <description>
+ Some recipes used for the XML tutorial.
+ </description>
+ <recipe>
+ <title>Beef Parmesan<![CDATA[<title> with Garlic Angel Hair Pasta</title>]]></title>
+ <ingredient name="beef cube steak" amount="1.5" unit="pound"/>
+ <preparation>
+ <step>
+ Preheat oven to 350 degrees F (175 degrees C).
+ </step>
+ </preparation>
+ <comment>
+ Make the meat ahead of time, and refrigerate over night, the acid in the
+ tomato sauce will tenderize the meat even more. If you do this, save the
+ mozzarella till the last minute.
+ </comment>
+ <nutrition calories="1167" fat="23" carbohydrates="45" protein="32"/>
+ </recipe>
+</collection>
+<!--comment2 -->
diff --git a/xml/src/test/resources/recipt.dtd b/xml/src/test/resources/recipt.dtd
new file mode 100644
index 0000000..370112c
--- /dev/null
+++ b/xml/src/test/resources/recipt.dtd
@@ -0,0 +1,17 @@
+<!ELEMENT collection (description,recipe+)>
+<!ELEMENT description ANY>
+<!ELEMENT recipe (title,ingredient*,preparation,comment?,nutrition)>
+<!ELEMENT title (#PCDATA)>
+<!ELEMENT ingredient (ingredient*,preparation)?>
+<!ATTLIST ingredient name CDATA #REQUIRED
+ amount CDATA #IMPLIED
+ unit CDATA #IMPLIED>
+<!ELEMENT preparation (step*)>
+<!ELEMENT step (#PCDATA)>
+<!ELEMENT comment (#PCDATA)>
+<!ELEMENT nutrition EMPTY>
+<!ATTLIST nutrition protein CDATA #REQUIRED
+ carbohydrates CDATA #REQUIRED
+ fat CDATA #REQUIRED
+ calories CDATA #REQUIRED
+ alcohol CDATA #IMPLIED>
diff --git a/xml/src/test/resources/recipt.xml b/xml/src/test/resources/recipt.xml
new file mode 100644
index 0000000..d7cf0fb
--- /dev/null
+++ b/xml/src/test/resources/recipt.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE collection SYSTEM "./recipt.dtd">
+<!--comment1 -->
+<collection>
+ <description>
+ Some recipes used for the XML tutorial.
+ </description>
+ <recipe>
+ <title>Beef Parmesan<![CDATA[<title> with Garlic Angel Hair Pasta</title>]]></title>
+ <ingredient name="beef cube steak" amount="1.5" unit="pound"/>
+ <preparation>
+ <step>
+ Preheat oven to 350 degrees F (175 degrees C).
+ </step>
+ </preparation>
+ <comment>
+ Make the meat ahead of time, and refrigerate over night, the acid in the
+ tomato sauce will tenderize the meat even more. If you do this, save the
+ mozzarella till the last minute.
+ </comment>
+ <nutrition calories="1167" fat="23" carbohydrates="45" protein="32"/>
+ </recipe>
+</collection>
+<!--comment2 -->
diff --git a/xml/src/test/resources/reciptWrong.xml b/xml/src/test/resources/reciptWrong.xml
new file mode 100644
index 0000000..ce32d09
--- /dev/null
+++ b/xml/src/test/resources/reciptWrong.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE collection SYSTEM "./recipt.dtd">
+<!--comment1 -->
+<collection>
+ <recipe>
+ <title>Beef Parmesan<![CDATA[<title> with Garlic Angel Hair Pasta</title>]]></title>
+ <ingredient name="beef cube steak" amount="1.5" unit="pound"/>
+ <preparation>
+ <step>
+ Preheat oven to 350 degrees F (175 degrees C).
+ </step>
+ </preparation>
+ <comment>
+ Make the meat ahead of time, and refrigerate over night, the acid in the
+ tomato sauce will tenderize the meat even more. If you do this, save the
+ mozzarella till the last minute.
+ </comment>
+ <nutrition calories="1167" fat="23" carbohydrates="45" protein="32"/>
+ </recipe>
+</collection>
+<!--comment2 -->
diff --git a/xml/src/test/resources/simple.xml b/xml/src/test/resources/simple.xml
new file mode 100644
index 0000000..de39181
--- /dev/null
+++ b/xml/src/test/resources/simple.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!-- Edited with XML Spy v2007 (http://www.altova.com) -->
+<breakfast_menu>
+ <food>
+ <name>Belgian Waffles</name>
+ <price>$5.95</price>
+ <description>two of our famous Belgian Waffles with plenty of real maple syrup</description>
+ <calories>650</calories>
+ </food>
+ <food>
+ <name>Strawberry Belgian Waffles</name>
+ <price>$7.95</price>
+ <description>light Belgian waffles covered with strawberries and whipped cream</description>
+ <calories>900</calories>
+ </food>
+ <food>
+ <name>Berry-Berry Belgian Waffles</name>
+ <price>$8.95</price>
+ <description>light Belgian waffles covered with an assortment of fresh berries and whipped cream</description>
+ <calories>900</calories>
+ </food>
+ <food>
+ <name>French Toast</name>
+ <price>$4.50</price>
+ <description>thick slices made from our homemade sourdough bread</description>
+ <calories>600</calories>
+ </food>
+ <food>
+ <name>Homestyle Breakfast</name>
+ <price>$6.95</price>
+ <description>two eggs, bacon or sausage, toast, and our ever-popular hash browns</description>
+ <calories>950</calories>
+ </food>
+</breakfast_menu>
diff --git a/xml/src/test/resources/simple_ns.dtd b/xml/src/test/resources/simple_ns.dtd
new file mode 100644
index 0000000..7643773
--- /dev/null
+++ b/xml/src/test/resources/simple_ns.dtd
@@ -0,0 +1,45 @@
+<!ELEMENT staff (employee+,emp:employee,employee) >
+<!ELEMENT employee (employeeId,name,position,salary,gender,address) >
+<!ATTLIST employee xmlns CDATA #IMPLIED>
+<!ATTLIST employee xmlns:dmstc CDATA #IMPLIED>
+<!ATTLIST employee xmlns:emp2 CDATA #IMPLIED>
+
+<!ELEMENT employeeId (#PCDATA) >
+
+<!ELEMENT name (#PCDATA) >
+
+<!ELEMENT position (#PCDATA) >
+
+<!ELEMENT salary (#PCDATA) >
+
+<!ELEMENT entElement1 (#PCDATA) >
+<!ELEMENT gender (#PCDATA | entElement1)* >
+<!ATTLIST entElement1 xmlns:local1 CDATA #IMPLIED >
+
+<!ELEMENT address (#PCDATA) >
+<!ATTLIST address dmstc:domestic CDATA #IMPLIED>
+<!ATTLIST address street CDATA #IMPLIED>
+<!ATTLIST address domestic CDATA #IMPLIED>
+<!ATTLIST address xmlns CDATA #IMPLIED>
+
+<!ELEMENT emp:employee (emp:employeeId,nm:name,emp:position,emp:salary,emp:gender,emp:address) >
+<!ATTLIST emp:employee xmlns:emp CDATA #IMPLIED>
+<!ATTLIST emp:employee xmlns:nm CDATA #IMPLIED>
+<!ATTLIST emp:employee defaultAttr CDATA 'defaultVal'>
+
+<!ELEMENT emp:employeeId (#PCDATA) >
+
+<!ELEMENT nm:name (#PCDATA) >
+
+<!ELEMENT emp:position (#PCDATA) >
+
+<!ELEMENT emp:salary (#PCDATA) >
+
+<!ELEMENT emp:gender (#PCDATA) >
+
+<!ELEMENT emp:address (#PCDATA) >
+<!ATTLIST emp:address emp:domestic CDATA #IMPLIED>
+<!ATTLIST emp:address street CDATA #IMPLIED>
+<!ATTLIST emp:address emp:zone ID #IMPLIED>
+<!ATTLIST emp:address emp:district CDATA 'DISTRICT'>
+<!ATTLIST emp:address emp:local1 CDATA 'FALSE'>
diff --git a/xml/src/test/resources/simple_ns.xml b/xml/src/test/resources/simple_ns.xml
new file mode 100644
index 0000000..a5dc4a3
--- /dev/null
+++ b/xml/src/test/resources/simple_ns.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0"?><?TEST-STYLE PIDATA?>
+<!DOCTYPE staff PUBLIC "STAFF" "simple_ns.dtd"
+[
+ <!ENTITY ent1 "es">
+ <!ENTITY ent2 "1900 Dallas Road">
+ <!ENTITY ent3 "Texas">
+ <!ENTITY ent4 "<entElement1 xmlns:local1='www.xyz.com'>Element data</entElement1><?PItarget PIdata?>">
+ <!ENTITY ent5 PUBLIC "entityURI" "entityFile" NDATA notation1>
+ <!ENTITY ent6 PUBLIC "uri" "file" NDATA notation2>
+ <!ENTITY ent1 "This entity should be discarded">
+ <!NOTATION notation1 PUBLIC "notation1File">
+ <!NOTATION notation2 SYSTEM "notation2File">
+]>
+<!-- This is comment number 1.-->
+<staff>
+ <employee xmlns="http://www.nist.gov" xmlns:dmstc="http://www.usa.com">
+ <employeeId>EMP0001</employeeId>
+ <name>Margaret Martin</name>
+ <position>Accountant</position>
+ <salary>56,000</salary>
+ <gender>Female</gender>
+ <address dmstc:domestic="Yes">1230 North Ave. Dallas, Texas 98551</address>
+ </employee>
+ <employee xmlns:dmstc="http://www.usa.com">
+ <employeeId>EMP0002</employeeId>
+ <name>Martha Raynolds
+<![CDATA[This is a CDATASection with EntityReference number 2 &ent2;]]>
+<![CDATA[This is an adjacent CDATASection with a reference to a tab &tab;]]></name>
+ <position>Secretary</position>
+ <salary>35,000</salary>
+ <gender>Female</gender>
+ <address dmstc:domestic="Yes" street="Yes">&ent2; Dallas, &ent3;
+ 98554</address>
+ </employee>
+ <employee xmlns:dmstc="http://www.netzero.com">
+ <employeeId>EMP0003</employeeId>
+ <name>Roger
+ Jones</name>
+ <position>Department Manager</position>
+ <salary>100,000</salary>
+ <gender>&ent4;</gender>
+ <address dmstc:domestic="Yes" street="No">PO Box 27 Irving, texas 98553</address>
+ </employee>
+ <emp:employee xmlns:emp="http://www.nist.gov" xmlns:nm="http://www.altavista.com" > <emp:employeeId>EMP0004</emp:employeeId>
+ <nm:name>Jeny Oconnor</nm:name>
+ <emp:position>Personnel Director</emp:position>
+ <emp:salary>95,000</emp:salary>
+ <emp:gender>Female</emp:gender>
+ <emp:address emp:domestic="Yes" street="Y&ent1;" emp:zone="CANADA" emp:local1="TRUE">27 South Road. Dallas, texas 98556</emp:address>
+ </emp:employee>
+ <employee xmlns:emp2="http://www.nist.gov">
+ <employeeId>EMP0005</employeeId>
+ <name>Robert Myers</name>
+ <position>Computer Specialist</position>
+ <salary>90,000</salary>
+ <gender>male</gender>
+ <address street="Yes" xmlns="http://www.nist.gov">1821 Nordic. Road, Irving Texas 98558</address>
+ </employee>
+ </staff>
diff --git a/xml/src/test/resources/staff.dtd b/xml/src/test/resources/staff.dtd
new file mode 100644
index 0000000..02a994d
--- /dev/null
+++ b/xml/src/test/resources/staff.dtd
@@ -0,0 +1,17 @@
+<!ELEMENT employeeId (#PCDATA)>
+<!ELEMENT name (#PCDATA)>
+<!ELEMENT position (#PCDATA)>
+<!ELEMENT salary (#PCDATA)>
+<!ELEMENT address (#PCDATA)>
+<!ELEMENT entElement ( #PCDATA ) >
+<!ELEMENT gender ( #PCDATA | entElement )* >
+<!ELEMENT employee (employeeId, name, position, salary, gender, address) >
+<!ELEMENT staff (employee)+>
+<!ATTLIST entElement
+ attr1 CDATA "Attr">
+<!ATTLIST address
+ domestic CDATA #IMPLIED
+ street CDATA "Yes">
+<!ATTLIST entElement
+ domestic CDATA "MALE" >
+
diff --git a/xml/src/test/resources/staff.xml b/xml/src/test/resources/staff.xml
new file mode 100644
index 0000000..f89c510
--- /dev/null
+++ b/xml/src/test/resources/staff.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0"?><?TEST-STYLE PIDATA?>
+<!DOCTYPE staff SYSTEM "staff.dtd" [
+ <!ENTITY ent1 "es">
+ <!ENTITY ent2 "1900 Dallas Road">
+ <!ENTITY ent3 "Texas">
+ <!ENTITY ent4 "<entElement domestic='Yes'>Element data</entElement><?PItarget PIdata?>">
+ <!ENTITY ent5 PUBLIC "entityURI" "entityFile" NDATA notation1>
+ <!ENTITY ent1 "This entity should be discarded">
+ <!NOTATION notation1 PUBLIC "notation1File">
+ <!NOTATION notation2 SYSTEM "notation2File">
+]>
+<!-- This is comment number 1.-->
+<staff>
+ <employee>
+ <employeeId>EMP0001</employeeId>
+ <name>Margaret Martin</name>
+ <position>Accountant</position>
+ <salary>56,000</salary>
+ <gender>Female</gender>
+ <address domestic="Yes">1230 North Ave. Dallas, Texas 98551</address>
+ </employee>
+ <employee>
+ <employeeId>EMP0002</employeeId>
+ <name>Martha Raynolds<![CDATA[This is a CDATASection with EntityReference number 2 &ent2;]]>
+<![CDATA[This is an adjacent CDATASection with a reference to a tab &tab;]]></name>
+ <position>Secretary</position>
+ <salary>35,000</salary>
+ <gender>Female</gender>
+ <address domestic="Yes" street="Yes">&ent2; Dallas, &ent3;
+ 98554</address>
+ </employee>
+ <employee>
+ <employeeId>EMP0003</employeeId>
+ <name>Roger
+ Jones</name>
+ <position>Department Manager</position>
+ <salary>100,000</salary>
+ <gender>&ent4;</gender>
+ <address domestic="Yes" street="No">PO Box 27 Irving, texas 98553</address>
+ </employee>
+ <employee>
+ <employeeId>EMP0004</employeeId>
+ <name>Jeny Oconnor</name>
+ <position>Personnel Director</position>
+ <salary>95,000</salary>
+ <gender>Female</gender>
+ <address domestic="Yes" street="Y&ent1;">27 South Road. Dallas, Texas 98556</address>
+ </employee>
+ <employee>
+ <employeeId>EMP0005</employeeId>
+ <name>Robert Myers</name>
+ <position>Computer Specialist</position>
+ <salary>90,000</salary>
+ <gender>male</gender>
+ <address street="Yes">1821 Nordic. Road, Irving Texas 98558</address>
+ </employee>
+ </staff>
diff --git a/xml/src/test/resources/staff2.dtd b/xml/src/test/resources/staff2.dtd
new file mode 100644
index 0000000..0bac8f2
--- /dev/null
+++ b/xml/src/test/resources/staff2.dtd
@@ -0,0 +1,24 @@
+<!ELEMENT employeeId (#PCDATA)>
+<!ELEMENT name (#PCDATA)>
+<!ELEMENT position (#PCDATA)>
+<!ELEMENT salary (#PCDATA)>
+<!ELEMENT address (#PCDATA)>
+<!ELEMENT gender ( #PCDATA)>
+<!ELEMENT employee (employeeId, name, position, salary, gender, address) >
+<!ATTLIST employee xmlns CDATA #IMPLIED>
+<!ELEMENT staff (employee)+>
+<!ELEMENT svg (rect, script, employee+)>
+<!ATTLIST svg
+ xmlns CDATA #FIXED "http://www.w3.org/2000/svg"
+ name CDATA #IMPLIED>
+<!ELEMENT rect EMPTY>
+<!ATTLIST rect
+ x CDATA #REQUIRED
+ y CDATA #REQUIRED
+ width CDATA #REQUIRED
+ height CDATA #REQUIRED>
+<!ELEMENT script (#PCDATA)>
+<!ATTLIST script type CDATA #IMPLIED>
+<!ENTITY svgunit SYSTEM "svgunit.js">
+<!ENTITY svgtest SYSTEM "internalSubset01.js">
+
diff --git a/xml/src/test/resources/staff2.xml b/xml/src/test/resources/staff2.xml
new file mode 100644
index 0000000..d3d9a13
--- /dev/null
+++ b/xml/src/test/resources/staff2.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0"?><?TEST-STYLE PIDATA?>
+<!DOCTYPE staff SYSTEM "staff2.dtd" []>
+<!-- This is comment number 1.-->
+<staff>
+ <employee>
+ <employeeId>EMP0001</employeeId>
+ <name>Margaret Martin</name>
+ <position>Accountant</position>
+ <salary>56,000</salary>
+ <gender>Female</gender>
+ <address>1230 North Ave. Dallas, Texas 98551</address>
+ </employee>
+ </staff>
diff --git a/xml/src/test/resources/staffEntRes.xml b/xml/src/test/resources/staffEntRes.xml
new file mode 100644
index 0000000..0c24c83
--- /dev/null
+++ b/xml/src/test/resources/staffEntRes.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0"?><?TEST-STYLE PIDATA?>
+<!DOCTYPE staff
+[
+ <!ENTITY ent1 "es">
+ <!ENTITY ent2 "1900 Dallas Road">
+ <!ENTITY ent3 "Texas">
+ <!ENTITY chap1 SYSTEM "chap1.xml">
+ <!ENTITY ent4 "<entElement1 xmlns:local1='www.xyz.com'>Element data</entElement1><?PItarget PIdata?>">
+ <!ENTITY ent5 PUBLIC "entityURI" "entityFile" NDATA notation1>
+ <!ENTITY ent6 PUBLIC "uri" "file" NDATA notation2>
+ <!ENTITY ent1 "This entity should be discarded">
+ <!NOTATION notation1 PUBLIC "notation1File">
+ <!NOTATION notation2 SYSTEM "notation2File">
+]>
+<!-- This is comment number 1.-->
+<staff>
+ <employee xmlns="http://www.nist.gov" xmlns:dmstc="http://www.usa.com">
+ <employeeId>EMP0001</employeeId>
+ <name>Margaret Martin</name>
+ <position>Accountant</position>
+ <salary>56,000</salary>
+ <gender>Female</gender>
+ <address dmstc:domestic="Yes">1230 North Ave. Dallas, Texas 98551</address>
+ </employee>
+ <employee xmlns:dmstc="http://www.usa.com">
+ <employeeId>EMP0002</employeeId>
+ <name>Martha Raynolds &chap1;
+<![CDATA[This is a CDATASection with EntityReference number 2 &ent2;]]>
+<![CDATA[This is an adjacent CDATASection with a reference to a tab &tab;]]></name>
+ <position>Secretary</position>
+ <salary>35,000</salary>
+ <gender>Female</gender>
+ <address dmstc:domestic="Yes" street="Yes">&ent2; Dallas, &ent3;
+ 98554</address>
+ </employee>
+ <employee xmlns:dmstc="http://www.netzero.com">
+ <employeeId>EMP0003</employeeId>
+ <name>Roger
+ Jones</name>
+ <position>Department Manager</position>
+ <salary>100,000</salary>
+ <gender>&ent4;</gender>
+ <address dmstc:domestic="Yes" street="No">PO Box 27 Irving, texas 98553</address>
+ </employee>
+ <emp:employee xmlns:emp="http://www.nist.gov" xmlns:nm="http://www.altavista.com" > <emp:employeeId>EMP0004</emp:employeeId>
+ <nm:name>Jeny Oconnor</nm:name>
+ <emp:position>Personnel Director</emp:position>
+ <emp:salary>95,000</emp:salary>
+ <emp:gender>Female</emp:gender>
+ <emp:address emp:domestic="Yes" street="Y&ent1;" emp:zone="CANADA" emp:local1="TRUE">27 South Road. Dallas, texas 98556</emp:address>
+ </emp:employee>
+ <employee xmlns:emp2="http://www.nist.gov">
+ <employeeId>EMP0005</employeeId>
+ <name>Robert Myers</name>
+ <position>Computer Specialist</position>
+ <salary>90,000</salary>
+ <gender>male</gender>
+ <address street="Yes" xmlns="http://www.nist.gov">1821 Nordic. Road, Irving Texas 98558</address>
+ </employee>
+ </staff>
diff --git a/xml/src/test/resources/staffNS.dtd b/xml/src/test/resources/staffNS.dtd
new file mode 100644
index 0000000..7643773
--- /dev/null
+++ b/xml/src/test/resources/staffNS.dtd
@@ -0,0 +1,45 @@
+<!ELEMENT staff (employee+,emp:employee,employee) >
+<!ELEMENT employee (employeeId,name,position,salary,gender,address) >
+<!ATTLIST employee xmlns CDATA #IMPLIED>
+<!ATTLIST employee xmlns:dmstc CDATA #IMPLIED>
+<!ATTLIST employee xmlns:emp2 CDATA #IMPLIED>
+
+<!ELEMENT employeeId (#PCDATA) >
+
+<!ELEMENT name (#PCDATA) >
+
+<!ELEMENT position (#PCDATA) >
+
+<!ELEMENT salary (#PCDATA) >
+
+<!ELEMENT entElement1 (#PCDATA) >
+<!ELEMENT gender (#PCDATA | entElement1)* >
+<!ATTLIST entElement1 xmlns:local1 CDATA #IMPLIED >
+
+<!ELEMENT address (#PCDATA) >
+<!ATTLIST address dmstc:domestic CDATA #IMPLIED>
+<!ATTLIST address street CDATA #IMPLIED>
+<!ATTLIST address domestic CDATA #IMPLIED>
+<!ATTLIST address xmlns CDATA #IMPLIED>
+
+<!ELEMENT emp:employee (emp:employeeId,nm:name,emp:position,emp:salary,emp:gender,emp:address) >
+<!ATTLIST emp:employee xmlns:emp CDATA #IMPLIED>
+<!ATTLIST emp:employee xmlns:nm CDATA #IMPLIED>
+<!ATTLIST emp:employee defaultAttr CDATA 'defaultVal'>
+
+<!ELEMENT emp:employeeId (#PCDATA) >
+
+<!ELEMENT nm:name (#PCDATA) >
+
+<!ELEMENT emp:position (#PCDATA) >
+
+<!ELEMENT emp:salary (#PCDATA) >
+
+<!ELEMENT emp:gender (#PCDATA) >
+
+<!ELEMENT emp:address (#PCDATA) >
+<!ATTLIST emp:address emp:domestic CDATA #IMPLIED>
+<!ATTLIST emp:address street CDATA #IMPLIED>
+<!ATTLIST emp:address emp:zone ID #IMPLIED>
+<!ATTLIST emp:address emp:district CDATA 'DISTRICT'>
+<!ATTLIST emp:address emp:local1 CDATA 'FALSE'>
diff --git a/xml/src/test/resources/staffNS.xml b/xml/src/test/resources/staffNS.xml
new file mode 100644
index 0000000..1cb1459
--- /dev/null
+++ b/xml/src/test/resources/staffNS.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0"?><?TEST-STYLE PIDATA?>
+<!DOCTYPE staff PUBLIC "STAFF" "staffNS.dtd"
+[
+ <!ENTITY ent1 "es">
+ <!ENTITY ent2 "1900 Dallas Road">
+ <!ENTITY ent3 "Texas">
+ <!ENTITY ent4 "<entElement1 xmlns:local1='www.xyz.com'>Element data</entElement1><?PItarget PIdata?>">
+ <!ENTITY ent5 PUBLIC "entityURI" "entityFile" NDATA notation1>
+ <!ENTITY ent6 PUBLIC "uri" "file" NDATA notation2>
+ <!ENTITY ent1 "This entity should be discarded">
+ <!NOTATION notation1 PUBLIC "notation1File">
+ <!NOTATION notation2 SYSTEM "notation2File">
+]>
+<!-- This is comment number 1.-->
+<staff>
+ <employee xmlns="http://www.nist.gov" xmlns:dmstc="http://www.usa.com">
+ <employeeId>EMP0001</employeeId>
+ <name>Margaret Martin</name>
+ <position>Accountant</position>
+ <salary>56,000</salary>
+ <gender>Female</gender>
+ <address dmstc:domestic="Yes">1230 North Ave. Dallas, Texas 98551</address>
+ </employee>
+ <employee xmlns:dmstc="http://www.usa.com">
+ <employeeId>EMP0002</employeeId>
+ <name>Martha Raynolds
+<![CDATA[This is a CDATASection with EntityReference number 2 &ent2;]]>
+<![CDATA[This is an adjacent CDATASection with a reference to a tab &tab;]]></name>
+ <position>Secretary</position>
+ <salary>35,000</salary>
+ <gender>Female</gender>
+ <address dmstc:domestic="Yes" street="Yes">&ent2; Dallas, &ent3;
+ 98554</address>
+ </employee>
+ <employee xmlns:dmstc="http://www.netzero.com">
+ <employeeId>EMP0003</employeeId>
+ <name>Roger
+ Jones</name>
+ <position>Department Manager</position>
+ <salary>100,000</salary>
+ <gender>&ent4;</gender>
+ <address dmstc:domestic="Yes" street="No">PO Box 27 Irving, texas 98553</address>
+ </employee>
+ <emp:employee xmlns:emp="http://www.nist.gov" xmlns:nm="http://www.altavista.com" > <emp:employeeId>EMP0004</emp:employeeId>
+ <nm:name>Jeny Oconnor</nm:name>
+ <emp:position>Personnel Director</emp:position>
+ <emp:salary>95,000</emp:salary>
+ <emp:gender>Female</emp:gender>
+ <emp:address emp:domestic="Yes" street="Y&ent1;" emp:zone="CANADA" emp:local1="TRUE">27 South Road. Dallas, texas 98556</emp:address>
+ </emp:employee>
+ <employee xmlns:emp2="http://www.nist.gov">
+ <employeeId>EMP0005</employeeId>
+ <name>Robert Myers</name>
+ <position>Computer Specialist</position>
+ <salary>90,000</salary>
+ <gender>male</gender>
+ <address street="Yes" xmlns="http://www.nist.gov">1821 Nordic. Road, Irving Texas 98558</address>
+ </employee>
+ </staff>
diff --git a/xml/src/test/resources/systemid.xml b/xml/src/test/resources/systemid.xml
new file mode 100644
index 0000000..d7cf0fb
--- /dev/null
+++ b/xml/src/test/resources/systemid.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE collection SYSTEM "./recipt.dtd">
+<!--comment1 -->
+<collection>
+ <description>
+ Some recipes used for the XML tutorial.
+ </description>
+ <recipe>
+ <title>Beef Parmesan<![CDATA[<title> with Garlic Angel Hair Pasta</title>]]></title>
+ <ingredient name="beef cube steak" amount="1.5" unit="pound"/>
+ <preparation>
+ <step>
+ Preheat oven to 350 degrees F (175 degrees C).
+ </step>
+ </preparation>
+ <comment>
+ Make the meat ahead of time, and refrigerate over night, the acid in the
+ tomato sauce will tenderize the meat even more. If you do this, save the
+ mozzarella till the last minute.
+ </comment>
+ <nutrition calories="1167" fat="23" carbohydrates="45" protein="32"/>
+ </recipe>
+</collection>
+<!--comment2 -->
diff --git a/xml/src/test/resources/systemid/recipt.dtd b/xml/src/test/resources/systemid/recipt.dtd
new file mode 100644
index 0000000..370112c
--- /dev/null
+++ b/xml/src/test/resources/systemid/recipt.dtd
@@ -0,0 +1,17 @@
+<!ELEMENT collection (description,recipe+)>
+<!ELEMENT description ANY>
+<!ELEMENT recipe (title,ingredient*,preparation,comment?,nutrition)>
+<!ELEMENT title (#PCDATA)>
+<!ELEMENT ingredient (ingredient*,preparation)?>
+<!ATTLIST ingredient name CDATA #REQUIRED
+ amount CDATA #IMPLIED
+ unit CDATA #IMPLIED>
+<!ELEMENT preparation (step*)>
+<!ELEMENT step (#PCDATA)>
+<!ELEMENT comment (#PCDATA)>
+<!ELEMENT nutrition EMPTY>
+<!ATTLIST nutrition protein CDATA #REQUIRED
+ carbohydrates CDATA #REQUIRED
+ fat CDATA #REQUIRED
+ calories CDATA #REQUIRED
+ alcohol CDATA #IMPLIED>
diff --git a/xml/src/test/resources/systemid/staff.dtd b/xml/src/test/resources/systemid/staff.dtd
new file mode 100644
index 0000000..02a994d
--- /dev/null
+++ b/xml/src/test/resources/systemid/staff.dtd
@@ -0,0 +1,17 @@
+<!ELEMENT employeeId (#PCDATA)>
+<!ELEMENT name (#PCDATA)>
+<!ELEMENT position (#PCDATA)>
+<!ELEMENT salary (#PCDATA)>
+<!ELEMENT address (#PCDATA)>
+<!ELEMENT entElement ( #PCDATA ) >
+<!ELEMENT gender ( #PCDATA | entElement )* >
+<!ELEMENT employee (employeeId, name, position, salary, gender, address) >
+<!ELEMENT staff (employee)+>
+<!ATTLIST entElement
+ attr1 CDATA "Attr">
+<!ATTLIST address
+ domestic CDATA #IMPLIED
+ street CDATA "Yes">
+<!ATTLIST entElement
+ domestic CDATA "MALE" >
+
diff --git a/xml/src/test/resources/wf/staff.dtd b/xml/src/test/resources/wf/staff.dtd
new file mode 100644
index 0000000..02a994d
--- /dev/null
+++ b/xml/src/test/resources/wf/staff.dtd
@@ -0,0 +1,17 @@
+<!ELEMENT employeeId (#PCDATA)>
+<!ELEMENT name (#PCDATA)>
+<!ELEMENT position (#PCDATA)>
+<!ELEMENT salary (#PCDATA)>
+<!ELEMENT address (#PCDATA)>
+<!ELEMENT entElement ( #PCDATA ) >
+<!ELEMENT gender ( #PCDATA | entElement )* >
+<!ELEMENT employee (employeeId, name, position, salary, gender, address) >
+<!ELEMENT staff (employee)+>
+<!ATTLIST entElement
+ attr1 CDATA "Attr">
+<!ATTLIST address
+ domestic CDATA #IMPLIED
+ street CDATA "Yes">
+<!ATTLIST entElement
+ domestic CDATA "MALE" >
+
diff --git a/xml/src/test/resources/wf/staff.xml b/xml/src/test/resources/wf/staff.xml
new file mode 100644
index 0000000..f89c510
--- /dev/null
+++ b/xml/src/test/resources/wf/staff.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0"?><?TEST-STYLE PIDATA?>
+<!DOCTYPE staff SYSTEM "staff.dtd" [
+ <!ENTITY ent1 "es">
+ <!ENTITY ent2 "1900 Dallas Road">
+ <!ENTITY ent3 "Texas">
+ <!ENTITY ent4 "<entElement domestic='Yes'>Element data</entElement><?PItarget PIdata?>">
+ <!ENTITY ent5 PUBLIC "entityURI" "entityFile" NDATA notation1>
+ <!ENTITY ent1 "This entity should be discarded">
+ <!NOTATION notation1 PUBLIC "notation1File">
+ <!NOTATION notation2 SYSTEM "notation2File">
+]>
+<!-- This is comment number 1.-->
+<staff>
+ <employee>
+ <employeeId>EMP0001</employeeId>
+ <name>Margaret Martin</name>
+ <position>Accountant</position>
+ <salary>56,000</salary>
+ <gender>Female</gender>
+ <address domestic="Yes">1230 North Ave. Dallas, Texas 98551</address>
+ </employee>
+ <employee>
+ <employeeId>EMP0002</employeeId>
+ <name>Martha Raynolds<![CDATA[This is a CDATASection with EntityReference number 2 &ent2;]]>
+<![CDATA[This is an adjacent CDATASection with a reference to a tab &tab;]]></name>
+ <position>Secretary</position>
+ <salary>35,000</salary>
+ <gender>Female</gender>
+ <address domestic="Yes" street="Yes">&ent2; Dallas, &ent3;
+ 98554</address>
+ </employee>
+ <employee>
+ <employeeId>EMP0003</employeeId>
+ <name>Roger
+ Jones</name>
+ <position>Department Manager</position>
+ <salary>100,000</salary>
+ <gender>&ent4;</gender>
+ <address domestic="Yes" street="No">PO Box 27 Irving, texas 98553</address>
+ </employee>
+ <employee>
+ <employeeId>EMP0004</employeeId>
+ <name>Jeny Oconnor</name>
+ <position>Personnel Director</position>
+ <salary>95,000</salary>
+ <gender>Female</gender>
+ <address domestic="Yes" street="Y&ent1;">27 South Road. Dallas, Texas 98556</address>
+ </employee>
+ <employee>
+ <employeeId>EMP0005</employeeId>
+ <name>Robert Myers</name>
+ <position>Computer Specialist</position>
+ <salary>90,000</salary>
+ <gender>male</gender>
+ <address street="Yes">1821 Nordic. Road, Irving Texas 98558</address>
+ </employee>
+ </staff>
diff --git a/xml/src/test/resources/wrong.xml b/xml/src/test/resources/wrong.xml
new file mode 100644
index 0000000..9d4b41d
--- /dev/null
+++ b/xml/src/test/resources/wrong.xml
@@ -0,0 +1 @@
+<wrong1>wrong</wrong2> \ No newline at end of file
diff --git a/xml/src/test/resources/xhtml1-strict.dtd b/xml/src/test/resources/xhtml1-strict.dtd
new file mode 100644
index 0000000..60bbaf7
--- /dev/null
+++ b/xml/src/test/resources/xhtml1-strict.dtd
@@ -0,0 +1,65 @@
+<!--
+
+Copyright (c) 2001-2004 World Wide Web Consortium,
+(Massachusetts Institute of Technology, Institut National de
+Recherche en Informatique et en Automatique, Keio University). All
+Rights Reserved. This program is distributed under the W3C's Software
+Intellectual Property License. This program is distributed in the
+hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE.
+
+See W3C License http://www.w3.org/Consortium/Legal/ for more details.
+
+-->
+
+<!--
+
+This is a radically simplified DTD for use in the DOM Test Suites
+due to a XML non-conformance of one implementation in processing
+parameter entities. When that non-conformance is resolved,
+this DTD can be replaced by the normal DTD for XHTML.
+
+-->
+
+
+<!ELEMENT html (head, body)>
+<!ATTLIST html xmlns CDATA #IMPLIED>
+<!ELEMENT head (meta,title,script*)>
+<!ELEMENT meta EMPTY>
+<!ATTLIST meta
+ http-equiv CDATA #IMPLIED
+ content CDATA #IMPLIED>
+<!ELEMENT title (#PCDATA)>
+<!ELEMENT body (p*)>
+<!ATTLIST body onload CDATA #IMPLIED>
+<!ELEMENT p (#PCDATA|em|strong|code|sup|var|acronym|abbr)*>
+<!ATTLIST p
+ xmlns:dmstc CDATA #IMPLIED
+ xmlns:nm CDATA #IMPLIED
+ xmlns:emp2 CDATA #IMPLIED
+ id ID #IMPLIED
+>
+<!ELEMENT em (#PCDATA)>
+<!ELEMENT span (#PCDATA)>
+<!ELEMENT strong (#PCDATA)>
+<!ELEMENT code (#PCDATA)>
+<!ELEMENT sup (#PCDATA)>
+<!ELEMENT var (#PCDATA|span)*>
+<!ELEMENT acronym (#PCDATA)>
+<!ATTLIST acronym
+ title CDATA #IMPLIED
+ class CDATA #IMPLIED
+ id ID #IMPLIED
+>
+<!ELEMENT abbr (#PCDATA)>
+<!ATTLIST abbr
+ title CDATA #IMPLIED
+ class CDATA #IMPLIED
+ id ID #IMPLIED
+>
+<!ELEMENT script (#PCDATA)>
+<!ATTLIST script
+ type CDATA #IMPLIED
+ src CDATA #IMPLIED
+ charset CDATA #IMPLIED>