1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // autogenerated file with codegen.pl 29 30 #include <testshl/simpleheader.hxx> 31 32 #include <rtl/ref.hxx> 33 #include <osl/file.hxx> 34 #include <osl/process.h> 35 #include <comphelper/seqstream.hxx> 36 #include <comphelper/sequence.hxx> 37 #include <cppuhelper/compbase1.hxx> 38 #include <cppuhelper/bootstrap.hxx> 39 #include <cppuhelper/basemutex.hxx> 40 41 #include <com/sun/star/xml/sax/FastToken.hpp> 42 #include <com/sun/star/xml/sax/XSAXSerializable.hpp> 43 #include <com/sun/star/xml/sax/XFastSAXSerializable.hpp> 44 45 #include "../source/dom/documentbuilder.hxx" 46 47 48 using namespace ::DOM; 49 using namespace ::comphelper; 50 using namespace ::com::sun::star; 51 52 namespace 53 { 54 55 // valid xml 56 static const char validTestFile[] = 57 "<?xml version=\"1.0\" encoding=\"UTF-8\"?> \ 58 <office:document-content \ 59 xmlns:office=\"urn:oasis:names:tc:opendocument:xmlns:office:1.0\" \ 60 xmlns:xlink=\"http://www.w3.org/1999/xlink\" \ 61 office:version=\"1.0\"> \ 62 <office:scripts/> \ 63 <xlink:test/> \ 64 <office:automatic-styles teststyle=\"test\"/> \ 65 <moretest/> \ 66 some text öäü \ 67 </office:document-content> \ 68 "; 69 70 // generates a warning: unsupported xml version, unknown xml:space 71 // value 72 static const char warningTestFile[] = 73 "<?xml version=\"47-11.0\" encoding=\"UTF-8\"?> \ 74 <office:document-content \ 75 xmlns:office=\"urn:oasis:names:tc:opendocument:xmlns:office:1.0\" \ 76 xml:space=\"blafasl\" \ 77 office:version=\"1.0\"> \ 78 <office:scripts/> \ 79 <office:automatic-styles/> \ 80 </office:document-content> \ 81 "; 82 83 // <?xml not at start of file 84 static const char errorTestFile[] = 85 " <?xml version=\"1.0\" encoding=\"UTF-8\"?> \ 86 <office:document-content \ 87 xmlns:office=\"urn:oasis:names:tc:opendocument:xmlns:office:1.0\" \ 88 office:version=\"1.0\"> \ 89 <office:scripts/> \ 90 <office:automatic-styles/> \ 91 </office:document-content> \ 92 "; 93 94 // plain empty 95 static const char fatalTestFile[] = ""; 96 97 struct ErrorHandler 98 : public ::cppu::WeakImplHelper1< xml::sax::XErrorHandler > 99 { 100 sal_uInt32 mnErrCount; 101 sal_uInt32 mnFatalCount; 102 sal_uInt32 mnWarnCount; 103 104 bool noErrors() const { return !mnErrCount && !mnFatalCount && !mnWarnCount; } 105 106 ErrorHandler() : mnErrCount(0), mnFatalCount(0), mnWarnCount(0) 107 {} 108 109 virtual void SAL_CALL error( const uno::Any& ) throw (xml::sax::SAXException, uno::RuntimeException) 110 { 111 ++mnErrCount; 112 } 113 114 virtual void SAL_CALL fatalError( const uno::Any& ) throw (xml::sax::SAXException, uno::RuntimeException) 115 { 116 ++mnFatalCount; 117 } 118 119 virtual void SAL_CALL warning( const uno::Any& ) throw (xml::sax::SAXException, uno::RuntimeException) 120 { 121 ++mnWarnCount; 122 } 123 }; 124 125 struct DocumentHandler 126 : public ::cppu::WeakImplHelper1< xml::sax::XFastDocumentHandler > 127 { 128 // XFastContextHandler 129 virtual void SAL_CALL startFastElement( ::sal_Int32 Element, const uno::Reference< xml::sax::XFastAttributeList >& Attribs ) throw (xml::sax::SAXException, uno::RuntimeException) 130 { 131 OSL_TRACE("Seen element: %c with namespace 0x%x", 132 Element & 0xFFFF, Element & 0xFFFF0000); 133 } 134 135 virtual void SAL_CALL startUnknownElement( const ::rtl::OUString& Namespace, const ::rtl::OUString& Name, const uno::Reference< xml::sax::XFastAttributeList >& Attribs ) throw (xml::sax::SAXException, uno::RuntimeException) 136 { 137 } 138 139 virtual void SAL_CALL endFastElement( ::sal_Int32 Element ) throw (xml::sax::SAXException, uno::RuntimeException) 140 { 141 } 142 143 virtual void SAL_CALL endUnknownElement( const ::rtl::OUString& Namespace, const ::rtl::OUString& Name ) throw (xml::sax::SAXException, uno::RuntimeException) 144 { 145 } 146 147 virtual uno::Reference< xml::sax::XFastContextHandler > SAL_CALL createFastChildContext( ::sal_Int32 Element, const uno::Reference< xml::sax::XFastAttributeList >& Attribs ) throw (xml::sax::SAXException, uno::RuntimeException) 148 { 149 return this; 150 } 151 152 virtual uno::Reference< xml::sax::XFastContextHandler > SAL_CALL createUnknownChildContext( const ::rtl::OUString& Namespace, const ::rtl::OUString& Name, const uno::Reference< xml::sax::XFastAttributeList >& Attribs ) throw (xml::sax::SAXException, uno::RuntimeException) 153 { 154 return this; 155 } 156 157 virtual void SAL_CALL characters( const ::rtl::OUString& aChars ) throw (xml::sax::SAXException, uno::RuntimeException) 158 { 159 } 160 161 // XFastDocumentHandler 162 virtual void SAL_CALL startDocument( ) throw (xml::sax::SAXException, uno::RuntimeException) 163 { 164 } 165 166 virtual void SAL_CALL endDocument( ) throw (xml::sax::SAXException, uno::RuntimeException) 167 { 168 } 169 170 virtual void SAL_CALL setDocumentLocator( const uno::Reference< xml::sax::XLocator >& xLocator ) throw (xml::sax::SAXException, uno::RuntimeException) 171 { 172 } 173 }; 174 175 struct TokenHandler 176 : public ::cppu::WeakImplHelper1< xml::sax::XFastTokenHandler > 177 { 178 virtual ::sal_Int32 SAL_CALL getToken( const ::rtl::OUString& Identifier ) throw (uno::RuntimeException) 179 { 180 CPPUNIT_ASSERT_MESSAGE( "TokenHandler::getToken() unexpected call", 181 false ); 182 return -1; 183 } 184 185 virtual ::rtl::OUString SAL_CALL getIdentifier( ::sal_Int32 Token ) throw (uno::RuntimeException) 186 { 187 CPPUNIT_ASSERT_MESSAGE( "TokenHandler::getIdentifier() unexpected call", 188 false ); 189 return rtl::OUString(); 190 } 191 192 virtual ::sal_Int32 SAL_CALL getTokenFromUTF8( const uno::Sequence< ::sal_Int8 >& Identifier ) throw (uno::RuntimeException) 193 { 194 OSL_TRACE("getTokenFromUTF8() %s", (const char*)Identifier.getConstArray()); 195 return Identifier.getLength() ? Identifier[0] : 0; 196 } 197 198 virtual uno::Sequence< ::sal_Int8 > SAL_CALL getUTF8Identifier( ::sal_Int32 Token ) throw (uno::RuntimeException) 199 { 200 CPPUNIT_ASSERT_MESSAGE( "TokenHandler::getUTF8Identifier() unexpected call", 201 false ); 202 return uno::Sequence<sal_Int8>(); 203 } 204 }; 205 206 struct BasicTest : public CppUnit::TestFixture 207 { 208 rtl::Reference<CDocumentBuilder> mxDomBuilder; 209 rtl::Reference<ErrorHandler> mxErrHandler; 210 rtl::Reference<SequenceInputStream> mxValidInStream; 211 rtl::Reference<SequenceInputStream> mxWarningInStream; 212 rtl::Reference<SequenceInputStream> mxErrorInStream; 213 rtl::Reference<SequenceInputStream> mxFatalInStream; 214 215 void setUp() 216 { 217 // luckily, DOM builder doesn't use service fac, so we need 218 // not bootstrap uno here 219 mxErrHandler.set( new ErrorHandler() ); 220 mxDomBuilder.set( new CDocumentBuilder(Reference< XMultiServiceFactory >() )); 221 mxValidInStream.set( new SequenceInputStream(ByteSequence((sal_Int8*)validTestFile, 222 sizeof(validTestFile)/sizeof(*validTestFile))) ); 223 mxWarningInStream.set( new SequenceInputStream(ByteSequence((sal_Int8*)warningTestFile, 224 sizeof(warningTestFile)/sizeof(*warningTestFile))) ); 225 mxErrorInStream.set( new SequenceInputStream(ByteSequence((sal_Int8*)errorTestFile, 226 sizeof(errorTestFile)/sizeof(*errorTestFile))) ); 227 mxFatalInStream.set( new SequenceInputStream(ByteSequence((sal_Int8*)fatalTestFile, 228 sizeof(fatalTestFile)/sizeof(*fatalTestFile))) ); 229 mxDomBuilder->setErrorHandler(mxErrHandler.get()); 230 } 231 232 void validInputTest() 233 { 234 CPPUNIT_ASSERT_MESSAGE( "Valid input file did not result in XDocument #1", 235 mxDomBuilder->parse( 236 uno::Reference<io::XInputStream>( 237 mxValidInStream.get())).is() ); 238 CPPUNIT_ASSERT_MESSAGE( "Valid input file resulted in parse errors", 239 mxErrHandler->noErrors() ); 240 } 241 242 void warningInputTest() 243 { 244 CPPUNIT_ASSERT_MESSAGE( "Valid input file did not result in XDocument #2", 245 mxDomBuilder->parse( 246 uno::Reference<io::XInputStream>( 247 mxWarningInStream.get())).is() ); 248 CPPUNIT_ASSERT_MESSAGE( "No parse warnings in unclean input file", 249 mxErrHandler->mnWarnCount && !mxErrHandler->mnErrCount && !mxErrHandler->mnFatalCount ); 250 } 251 252 void errorInputTest() 253 { 254 CPPUNIT_ASSERT_MESSAGE( "Valid input file did not result in XDocument #3", 255 mxDomBuilder->parse( 256 uno::Reference<io::XInputStream>( 257 mxErrorInStream.get())).is() ); 258 CPPUNIT_ASSERT_MESSAGE( "No parse errors in unclean input file", 259 !mxErrHandler->mnWarnCount && mxErrHandler->mnErrCount && !mxErrHandler->mnFatalCount ); 260 } 261 262 void fatalInputTest() 263 { 264 CPPUNIT_ASSERT_MESSAGE( "Broken input file resulted in XDocument", 265 !mxDomBuilder->parse( 266 uno::Reference<io::XInputStream>( 267 mxFatalInStream.get())).is() ); 268 CPPUNIT_ASSERT_MESSAGE( "No fatal parse errors in unclean input file", 269 !mxErrHandler->mnWarnCount && !mxErrHandler->mnErrCount && mxErrHandler->mnFatalCount ); 270 }; 271 272 // Change the following lines only, if you add, remove or rename 273 // member functions of the current class, 274 // because these macros are need by auto register mechanism. 275 CPPUNIT_TEST_SUITE(BasicTest); 276 CPPUNIT_TEST(validInputTest); 277 CPPUNIT_TEST(warningInputTest); 278 CPPUNIT_TEST(errorInputTest); 279 CPPUNIT_TEST(fatalInputTest); 280 CPPUNIT_TEST_SUITE_END(); 281 }; 282 283 struct SerializerTest : public CppUnit::TestFixture 284 { 285 SerializerTest() : mbUnoInitialized(false) {} 286 287 uno::Reference<uno::XComponentContext> mxCtx; 288 rtl::Reference<CDocumentBuilder> mxDomBuilder; 289 rtl::Reference<ErrorHandler> mxErrHandler; 290 rtl::Reference<SequenceInputStream> mxInStream; 291 rtl::Reference<DocumentHandler> mxHandler; 292 rtl::Reference<TokenHandler> mxTokHandler; 293 uno::Sequence< beans::Pair< rtl::OUString, sal_Int32 > > maRegisteredNamespaces; 294 bool mbUnoInitialized; 295 296 void setUp() 297 { 298 // need working typelib, bootstrap UNO now 299 if( !mbUnoInitialized ) 300 { 301 const char* pArgs( getForwardString() ); 302 CPPUNIT_ASSERT_MESSAGE("Test file parameter", pArgs); 303 304 const rtl::OUString sBaseDir=rtl::OUString::createFromAscii(pArgs); 305 306 // bootstrap UNO 307 try 308 { 309 ::rtl::OUString aIniUrl; 310 CPPUNIT_ASSERT_MESSAGE( 311 "Converting ini file to URL", 312 osl_getFileURLFromSystemPath( 313 (sBaseDir+rtl::OUString::createFromAscii("unoxml_unittest_test.ini")).pData, 314 &aIniUrl.pData ) == osl_File_E_None ); 315 316 mxCtx = ::cppu::defaultBootstrap_InitialComponentContext(aIniUrl); 317 CPPUNIT_ASSERT_MESSAGE("Getting component context", mxCtx.is()); 318 } 319 catch( uno::Exception& ) 320 { 321 CPPUNIT_ASSERT_MESSAGE("Bootstrapping UNO", false); 322 } 323 324 mbUnoInitialized = true; 325 } 326 327 mxErrHandler.set( new ErrorHandler() ); 328 mxDomBuilder.set( new CDocumentBuilder( 329 uno::Reference< lang::XMultiServiceFactory >( 330 mxCtx->getServiceManager(), 331 uno::UNO_QUERY ))); 332 mxInStream.set( new SequenceInputStream(ByteSequence((sal_Int8*)validTestFile, 333 sizeof(validTestFile)/sizeof(*validTestFile))) ); 334 mxDomBuilder->setErrorHandler(mxErrHandler.get()); 335 336 mxHandler.set( new DocumentHandler() ); 337 mxTokHandler.set( new TokenHandler() ); 338 339 maRegisteredNamespaces.realloc(2); 340 maRegisteredNamespaces[0] = beans::make_Pair( 341 rtl::OUString( 342 RTL_CONSTASCII_USTRINGPARAM( 343 "urn:oasis:names:tc:opendocument:xmlns:office:1.0") ), 344 xml::sax::FastToken::NAMESPACE); 345 maRegisteredNamespaces[1] = beans::make_Pair( 346 rtl::OUString( 347 RTL_CONSTASCII_USTRINGPARAM( 348 "http://www.w3.org/1999/xlink") ), 349 2*xml::sax::FastToken::NAMESPACE); 350 } 351 352 void serializerTest () 353 { 354 uno::Reference< xml::dom::XDocument > xDoc= 355 mxDomBuilder->parse( 356 uno::Reference<io::XInputStream>( 357 mxInStream.get())); 358 CPPUNIT_ASSERT_MESSAGE( "Valid input file did not result in XDocument", 359 xDoc.is() ); 360 CPPUNIT_ASSERT_MESSAGE( "Valid input file resulted in parse errors", 361 mxErrHandler->noErrors() ); 362 363 uno::Reference< xml::sax::XSAXSerializable > xSaxSerializer( 364 xDoc, uno::UNO_QUERY); 365 CPPUNIT_ASSERT_MESSAGE( "XSAXSerializable not supported", 366 xSaxSerializer.is() ); 367 368 uno::Reference< xml::sax::XFastSAXSerializable > xFastSaxSerializer( 369 xDoc, uno::UNO_QUERY); 370 CPPUNIT_ASSERT_MESSAGE( "XFastSAXSerializable not supported", 371 xSaxSerializer.is() ); 372 373 xFastSaxSerializer->fastSerialize( mxHandler.get(), 374 mxTokHandler.get(), 375 uno::Sequence< beans::StringPair >(), 376 maRegisteredNamespaces ); 377 } 378 379 // Change the following lines only, if you add, remove or rename 380 // member functions of the current class, 381 // because these macros are need by auto register mechanism. 382 383 CPPUNIT_TEST_SUITE(SerializerTest); 384 CPPUNIT_TEST(serializerTest); 385 CPPUNIT_TEST_SUITE_END(); 386 }; 387 388 // ----------------------------------------------------------------------------- 389 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(BasicTest, "BasicTest"); 390 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(SerializerTest, "SerializerTest"); 391 } 392 393 394 // ----------------------------------------------------------------------------- 395 396 // this macro creates an empty function, which will called by the RegisterAllFunctions() 397 // to let the user the possibility to also register some functions by hand. 398 NOADDITIONAL; 399 400