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 #include "precompiled_stoc.hxx" 29 #include "sal/config.h" 30 31 #include <cstddef> 32 #include <cstdlib> 33 #include <map> 34 #include <vector> 35 36 #include "boost/noncopyable.hpp" 37 #include "com/sun/star/container/NoSuchElementException.hpp" 38 #include "com/sun/star/registry/InvalidRegistryException.hpp" 39 #include "com/sun/star/registry/XRegistryKey.hpp" 40 #include "com/sun/star/uno/Reference.hxx" 41 #include "com/sun/star/uno/XInterface.hpp" 42 #include "cppuhelper/implbase1.hxx" 43 #include "osl/diagnose.h" 44 #include "rtl/malformeduriexception.hxx" 45 #include "rtl/ref.hxx" 46 #include "rtl/string.h" 47 #include "rtl/uri.hxx" 48 #include "rtl/ustrbuf.hxx" 49 #include "rtl/ustring.h" 50 #include "rtl/ustring.hxx" 51 #include "salhelper/simplereferenceobject.hxx" 52 #include "xmlreader/span.hxx" 53 #include "xmlreader/xmlreader.hxx" 54 55 #include "textualservices.hxx" 56 57 namespace stoc { namespace simpleregistry { 58 59 namespace { 60 61 namespace css = com::sun::star; 62 63 struct Implementation { 64 rtl::OUString uri; 65 rtl::OUString loader; 66 std::vector< rtl::OUString > services; 67 std::vector< rtl::OUString > singletons; 68 }; 69 70 typedef std::map< rtl::OUString, Implementation > Implementations; 71 72 typedef std::map< rtl::OUString, std::vector< rtl::OUString > > 73 ImplementationMap; 74 75 } 76 77 class Data: public salhelper::SimpleReferenceObject, private boost::noncopyable 78 { 79 public: 80 Implementations implementations; 81 ImplementationMap services; 82 ImplementationMap singletons; 83 }; 84 85 namespace { 86 87 class Parser: private boost::noncopyable { 88 public: 89 Parser(rtl::OUString const & uri, rtl::Reference< Data > const & data); 90 91 private: 92 void handleComponent(); 93 94 void handleImplementation(); 95 96 void handleService(); 97 98 void handleSingleton(); 99 100 rtl::OUString getNameAttribute(); 101 102 xmlreader::XmlReader reader_; 103 rtl::Reference< Data > data_; 104 rtl::OUString attrUri_; 105 rtl::OUString attrLoader_; 106 rtl::OUString attrImplementation_; 107 }; 108 109 Parser::Parser(rtl::OUString const & uri, rtl::Reference< Data > const & data): 110 reader_(uri), data_(data) 111 { 112 OSL_ASSERT(data.is()); 113 int ucNsId = reader_.registerNamespaceIri( 114 xmlreader::Span( 115 RTL_CONSTASCII_STRINGPARAM( 116 "http://openoffice.org/2010/uno-components"))); 117 enum State { 118 STATE_BEGIN, STATE_END, STATE_COMPONENTS, STATE_COMPONENT_INITIAL, 119 STATE_COMPONENT, STATE_IMPLEMENTATION, STATE_SERVICE, STATE_SINGLETON }; 120 for (State state = STATE_BEGIN;;) { 121 xmlreader::Span name; 122 int nsId; 123 xmlreader::XmlReader::Result res = reader_.nextItem( 124 xmlreader::XmlReader::TEXT_NONE, &name, &nsId); 125 switch (state) { 126 case STATE_BEGIN: 127 if (res == xmlreader::XmlReader::RESULT_BEGIN && nsId == ucNsId && 128 name.equals(RTL_CONSTASCII_STRINGPARAM("components"))) 129 { 130 state = STATE_COMPONENTS; 131 break; 132 } 133 throw css::registry::InvalidRegistryException( 134 (reader_.getUrl() + 135 rtl::OUString( 136 RTL_CONSTASCII_USTRINGPARAM( 137 ": unexpected item in outer level"))), 138 css::uno::Reference< css::uno::XInterface >()); 139 case STATE_END: 140 if (res == xmlreader::XmlReader::RESULT_DONE) { 141 return; 142 } 143 throw css::registry::InvalidRegistryException( 144 (reader_.getUrl() + 145 rtl::OUString( 146 RTL_CONSTASCII_USTRINGPARAM( 147 ": unexpected item in outer level"))), 148 css::uno::Reference< css::uno::XInterface >()); 149 case STATE_COMPONENTS: 150 if (res == xmlreader::XmlReader::RESULT_END) { 151 state = STATE_END; 152 break; 153 } 154 if (res == xmlreader::XmlReader::RESULT_BEGIN && nsId == ucNsId && 155 name.equals(RTL_CONSTASCII_STRINGPARAM("component"))) 156 { 157 handleComponent(); 158 state = STATE_COMPONENT_INITIAL; 159 break; 160 } 161 throw css::registry::InvalidRegistryException( 162 (reader_.getUrl() + 163 rtl::OUString( 164 RTL_CONSTASCII_USTRINGPARAM( 165 ": unexpected item in <components>"))), 166 css::uno::Reference< css::uno::XInterface >()); 167 case STATE_COMPONENT: 168 if (res == xmlreader::XmlReader::RESULT_END) { 169 state = STATE_COMPONENTS; 170 break; 171 } 172 // fall through 173 case STATE_COMPONENT_INITIAL: 174 if (res == xmlreader::XmlReader::RESULT_BEGIN && nsId == ucNsId && 175 name.equals(RTL_CONSTASCII_STRINGPARAM("implementation"))) 176 { 177 handleImplementation(); 178 state = STATE_IMPLEMENTATION; 179 break; 180 } 181 throw css::registry::InvalidRegistryException( 182 (reader_.getUrl() + 183 rtl::OUString( 184 RTL_CONSTASCII_USTRINGPARAM( 185 ": unexpected item in <component>"))), 186 css::uno::Reference< css::uno::XInterface >()); 187 case STATE_IMPLEMENTATION: 188 if (res == xmlreader::XmlReader::RESULT_END) { 189 state = STATE_COMPONENT; 190 break; 191 } 192 if (res == xmlreader::XmlReader::RESULT_BEGIN && nsId == ucNsId && 193 name.equals(RTL_CONSTASCII_STRINGPARAM("service"))) 194 { 195 handleService(); 196 state = STATE_SERVICE; 197 break; 198 } 199 if (res == xmlreader::XmlReader::RESULT_BEGIN && nsId == ucNsId && 200 name.equals(RTL_CONSTASCII_STRINGPARAM("singleton"))) 201 { 202 handleSingleton(); 203 state = STATE_SINGLETON; 204 break; 205 } 206 throw css::registry::InvalidRegistryException( 207 (reader_.getUrl() + 208 rtl::OUString( 209 RTL_CONSTASCII_USTRINGPARAM( 210 ": unexpected item in <implementation>"))), 211 css::uno::Reference< css::uno::XInterface >()); 212 case STATE_SERVICE: 213 if (res == xmlreader::XmlReader::RESULT_END) { 214 state = STATE_IMPLEMENTATION; 215 break; 216 } 217 throw css::registry::InvalidRegistryException( 218 (reader_.getUrl() + 219 rtl::OUString( 220 RTL_CONSTASCII_USTRINGPARAM( 221 ": unexpected item in <service>"))), 222 css::uno::Reference< css::uno::XInterface >()); 223 case STATE_SINGLETON: 224 if (res == xmlreader::XmlReader::RESULT_END) { 225 state = STATE_IMPLEMENTATION; 226 break; 227 } 228 throw css::registry::InvalidRegistryException( 229 (reader_.getUrl() + 230 rtl::OUString( 231 RTL_CONSTASCII_USTRINGPARAM( 232 ": unexpected item in <service>"))), 233 css::uno::Reference< css::uno::XInterface >()); 234 } 235 } 236 } 237 238 void Parser::handleComponent() { 239 attrUri_ = rtl::OUString(); 240 attrLoader_ = rtl::OUString(); 241 xmlreader::Span name; 242 int nsId; 243 while (reader_.nextAttribute(&nsId, &name)) { 244 if (nsId == xmlreader::XmlReader::NAMESPACE_NONE && 245 name.equals(RTL_CONSTASCII_STRINGPARAM("uri"))) 246 { 247 if (attrUri_.getLength() != 0) { 248 throw css::registry::InvalidRegistryException( 249 (reader_.getUrl() + 250 rtl::OUString( 251 RTL_CONSTASCII_USTRINGPARAM( 252 ": <component> has multiple \"uri\" attributes"))), 253 css::uno::Reference< css::uno::XInterface >()); 254 } 255 attrUri_ = reader_.getAttributeValue(false).convertFromUtf8(); 256 if (attrUri_.getLength() == 0) { 257 throw css::registry::InvalidRegistryException( 258 (reader_.getUrl() + 259 rtl::OUString( 260 RTL_CONSTASCII_USTRINGPARAM( 261 ": <component> has empty \"uri\" attribute"))), 262 css::uno::Reference< css::uno::XInterface >()); 263 } 264 } else if (nsId == xmlreader::XmlReader::NAMESPACE_NONE && 265 name.equals(RTL_CONSTASCII_STRINGPARAM("loader"))) 266 { 267 if (attrLoader_.getLength() != 0) { 268 throw css::registry::InvalidRegistryException( 269 (reader_.getUrl() + 270 rtl::OUString( 271 RTL_CONSTASCII_USTRINGPARAM( 272 ": <component> has multiple \"loader\"" 273 " attributes"))), 274 css::uno::Reference< css::uno::XInterface >()); 275 } 276 attrLoader_ = reader_.getAttributeValue(false).convertFromUtf8(); 277 if (attrLoader_.getLength() == 0) { 278 throw css::registry::InvalidRegistryException( 279 (reader_.getUrl() + 280 rtl::OUString( 281 RTL_CONSTASCII_USTRINGPARAM( 282 ": <component> has empty \"loader\" attribute"))), 283 css::uno::Reference< css::uno::XInterface >()); 284 } 285 } else { 286 throw css::registry::InvalidRegistryException( 287 (reader_.getUrl() + 288 rtl::OUString( 289 RTL_CONSTASCII_USTRINGPARAM( 290 ": expected <component> attribute \"uri\" or" 291 " \"loader\""))), 292 css::uno::Reference< css::uno::XInterface >()); 293 } 294 } 295 if (attrUri_.getLength() == 0) { 296 throw css::registry::InvalidRegistryException( 297 (reader_.getUrl() + 298 rtl::OUString( 299 RTL_CONSTASCII_USTRINGPARAM( 300 ": <component> is missing \"uri\" attribute"))), 301 css::uno::Reference< css::uno::XInterface >()); 302 } 303 if (attrLoader_.getLength() == 0) { 304 throw css::registry::InvalidRegistryException( 305 (reader_.getUrl() + 306 rtl::OUString( 307 RTL_CONSTASCII_USTRINGPARAM( 308 ": <component> is missing \"loader\" attribute"))), 309 css::uno::Reference< css::uno::XInterface >()); 310 } 311 try { 312 attrUri_ = rtl::Uri::convertRelToAbs(reader_.getUrl(), attrUri_); 313 } catch (rtl::MalformedUriException & e) { 314 throw css::registry::InvalidRegistryException( 315 (reader_.getUrl() + 316 rtl::OUString( 317 RTL_CONSTASCII_USTRINGPARAM(": bad \"uri\" attribute: ")) + 318 e.getMessage()), 319 css::uno::Reference< css::uno::XInterface >()); 320 } 321 } 322 323 void Parser::handleImplementation() { 324 attrImplementation_ = getNameAttribute(); 325 if (data_->implementations.find(attrImplementation_) != 326 data_->implementations.end()) 327 { 328 throw css::registry::InvalidRegistryException( 329 (reader_.getUrl() + 330 rtl::OUString( 331 RTL_CONSTASCII_USTRINGPARAM( 332 ": duplicate <implementation name=\"")) + 333 attrImplementation_ + 334 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\">"))), 335 css::uno::Reference< css::uno::XInterface >()); 336 } 337 data_->implementations[attrImplementation_].uri = attrUri_; 338 data_->implementations[attrImplementation_].loader = attrLoader_; 339 } 340 341 void Parser::handleService() { 342 rtl::OUString name = getNameAttribute(); 343 data_->implementations[attrImplementation_].services.push_back(name); 344 data_->services[name].push_back(attrImplementation_); 345 } 346 347 void Parser::handleSingleton() { 348 rtl::OUString name = getNameAttribute(); 349 data_->implementations[attrImplementation_].singletons.push_back(name); 350 data_->singletons[name].push_back(attrImplementation_); 351 } 352 353 rtl::OUString Parser::getNameAttribute() { 354 rtl::OUString attrName; 355 xmlreader::Span name; 356 int nsId; 357 while (reader_.nextAttribute(&nsId, &name)) { 358 if (nsId == xmlreader::XmlReader::NAMESPACE_NONE && 359 name.equals(RTL_CONSTASCII_STRINGPARAM("name"))) 360 { 361 if (attrName.getLength() != 0) { 362 throw css::registry::InvalidRegistryException( 363 (reader_.getUrl() + 364 rtl::OUString( 365 RTL_CONSTASCII_USTRINGPARAM( 366 ": element has multiple \"name\" attributes"))), 367 css::uno::Reference< css::uno::XInterface >()); 368 } 369 attrName = reader_.getAttributeValue(false).convertFromUtf8(); 370 if (attrName.getLength() == 0) { 371 throw css::registry::InvalidRegistryException( 372 (reader_.getUrl() + 373 rtl::OUString( 374 RTL_CONSTASCII_USTRINGPARAM( 375 ": element has empty \"name\" attribute"))), 376 css::uno::Reference< css::uno::XInterface >()); 377 } 378 } else { 379 throw css::registry::InvalidRegistryException( 380 (reader_.getUrl() + 381 rtl::OUString( 382 RTL_CONSTASCII_USTRINGPARAM( 383 ": expected element attribute \"name\""))), 384 css::uno::Reference< css::uno::XInterface >()); 385 } 386 } 387 if (attrName.getLength() == 0) { 388 throw css::registry::InvalidRegistryException( 389 (reader_.getUrl() + 390 rtl::OUString( 391 RTL_CONSTASCII_USTRINGPARAM( 392 ": element is missing \"name\" attribute"))), 393 css::uno::Reference< css::uno::XInterface >()); 394 } 395 return attrName; 396 } 397 398 rtl::OUString pathToString(std::vector< rtl::OUString > const & path) { 399 rtl::OUStringBuffer buf; 400 for (std::vector< rtl::OUString >::const_iterator i(path.begin()); 401 i != path.end(); ++i) 402 { 403 buf.append(sal_Unicode('/')); 404 buf.append(*i); 405 } 406 if (buf.getLength() == 0) { 407 buf.append(sal_Unicode('/')); 408 } 409 return buf.makeStringAndClear(); 410 } 411 412 class Key: public cppu::WeakImplHelper1< css::registry::XRegistryKey > { 413 public: 414 Key( 415 rtl::Reference< Data > const & data, 416 std::vector< rtl::OUString > const & path): 417 data_(data), path_(path) { OSL_ASSERT(data.is()); 418 } 419 420 private: 421 /* 422 / 423 IMPLEMENTATIONS 424 <implementation> 425 UNO 426 LOCATION utf-8 427 ACTIVATOR utf-8 428 SERVICES 429 <service> 430 ... 431 SINGLETONS 432 <singleton> utf-16 433 ... 434 ... 435 SERVICES 436 <service> utf-8-list 437 ... 438 SINGLETONS 439 <singleton> utf-16 440 REGISTERED_BY utf-8-list 441 ... 442 */ 443 enum State { 444 STATE_ROOT, STATE_IMPLEMENTATIONS, STATE_IMPLEMENTATION, STATE_UNO, 445 STATE_LOCATION, STATE_ACTIVATOR, STATE_IMPLEMENTATION_SERVICES, 446 STATE_IMPLEMENTATION_SERVICE, STATE_IMPLEMENTATION_SINGLETONS, 447 STATE_IMPLEMENTATION_SINGLETON, STATE_SERVICES, STATE_SERVICE, 448 STATE_SINGLETONS, STATE_SINGLETON, STATE_REGISTEREDBY }; 449 450 virtual rtl::OUString SAL_CALL getKeyName() 451 throw (css::uno::RuntimeException); 452 453 virtual sal_Bool SAL_CALL isReadOnly() throw ( 454 css::registry::InvalidRegistryException, css::uno::RuntimeException); 455 456 virtual sal_Bool SAL_CALL isValid() throw(css::uno::RuntimeException); 457 458 virtual css::registry::RegistryKeyType SAL_CALL getKeyType( 459 rtl::OUString const & rKeyName) 460 throw ( 461 css::registry::InvalidRegistryException, 462 css::uno::RuntimeException); 463 464 virtual css::registry::RegistryValueType SAL_CALL getValueType() throw( 465 css::registry::InvalidRegistryException, css::uno::RuntimeException); 466 467 virtual sal_Int32 SAL_CALL getLongValue() throw ( 468 css::registry::InvalidRegistryException, 469 css::registry::InvalidValueException, css::uno::RuntimeException); 470 471 virtual void SAL_CALL setLongValue(sal_Int32 value) throw ( 472 css::registry::InvalidRegistryException, css::uno::RuntimeException); 473 474 virtual css::uno::Sequence< sal_Int32 > SAL_CALL getLongListValue() throw( 475 css::registry::InvalidRegistryException, 476 css::registry::InvalidValueException, css::uno::RuntimeException); 477 478 virtual void SAL_CALL setLongListValue( 479 com::sun::star::uno::Sequence< sal_Int32 > const & seqValue) 480 throw ( 481 css::registry::InvalidRegistryException, 482 css::uno::RuntimeException); 483 484 virtual rtl::OUString SAL_CALL getAsciiValue() throw ( 485 css::registry::InvalidRegistryException, 486 css::registry::InvalidValueException, css::uno::RuntimeException); 487 488 virtual void SAL_CALL setAsciiValue(rtl::OUString const & value) throw ( 489 css::registry::InvalidRegistryException, css::uno::RuntimeException); 490 491 virtual css::uno::Sequence< rtl::OUString > SAL_CALL getAsciiListValue() 492 throw ( 493 css::registry::InvalidRegistryException, 494 css::registry::InvalidValueException, css::uno::RuntimeException); 495 496 virtual void SAL_CALL setAsciiListValue( 497 css::uno::Sequence< rtl::OUString > const & seqValue) 498 throw ( 499 css::registry::InvalidRegistryException, 500 css::uno::RuntimeException); 501 502 virtual rtl::OUString SAL_CALL getStringValue() throw( 503 css::registry::InvalidRegistryException, 504 css::registry::InvalidValueException, css::uno::RuntimeException); 505 506 virtual void SAL_CALL setStringValue(rtl::OUString const & value) throw ( 507 css::registry::InvalidRegistryException, css::uno::RuntimeException); 508 509 virtual css::uno::Sequence< rtl::OUString > SAL_CALL getStringListValue() 510 throw ( 511 css::registry::InvalidRegistryException, 512 css::registry::InvalidValueException, css::uno::RuntimeException); 513 514 virtual void SAL_CALL setStringListValue( 515 css::uno::Sequence< rtl::OUString > const & seqValue) 516 throw ( 517 css::registry::InvalidRegistryException, 518 css::uno::RuntimeException); 519 520 virtual css::uno::Sequence< sal_Int8 > SAL_CALL getBinaryValue() throw ( 521 css::registry::InvalidRegistryException, 522 css::registry::InvalidValueException, css::uno::RuntimeException); 523 524 virtual void SAL_CALL setBinaryValue( 525 css::uno::Sequence< sal_Int8 > const & value) 526 throw ( 527 css::registry::InvalidRegistryException, 528 css::uno::RuntimeException); 529 530 virtual css::uno::Reference< css::registry::XRegistryKey > SAL_CALL openKey( 531 rtl::OUString const & aKeyName) 532 throw ( 533 css::registry::InvalidRegistryException, 534 css::uno::RuntimeException); 535 536 virtual css::uno::Reference< css::registry::XRegistryKey > SAL_CALL 537 createKey(rtl::OUString const & aKeyName) throw ( 538 css::registry::InvalidRegistryException, css::uno::RuntimeException); 539 540 virtual void SAL_CALL closeKey() throw ( 541 css::registry::InvalidRegistryException, css::uno::RuntimeException); 542 543 virtual void SAL_CALL deleteKey(rtl::OUString const & rKeyName) throw ( 544 css::registry::InvalidRegistryException, css::uno::RuntimeException); 545 546 virtual 547 css::uno::Sequence< css::uno::Reference< css::registry::XRegistryKey > > 548 SAL_CALL openKeys() throw ( 549 css::registry::InvalidRegistryException, css::uno::RuntimeException); 550 551 virtual css::uno::Sequence< rtl::OUString > SAL_CALL getKeyNames() throw ( 552 css::registry::InvalidRegistryException, css::uno::RuntimeException); 553 554 virtual sal_Bool SAL_CALL createLink( 555 rtl::OUString const & aLinkName, rtl::OUString const & aLinkTarget) 556 throw ( 557 css::registry::InvalidRegistryException, 558 css::uno::RuntimeException); 559 560 virtual void SAL_CALL deleteLink(rtl::OUString const & rLinkName) throw ( 561 css::registry::InvalidRegistryException, css::uno::RuntimeException); 562 563 virtual rtl::OUString SAL_CALL getLinkTarget( 564 rtl::OUString const & rLinkName) 565 throw ( 566 css::registry::InvalidRegistryException, 567 css::uno::RuntimeException); 568 569 virtual rtl::OUString SAL_CALL getResolvedName( 570 rtl::OUString const & aKeyName) 571 throw ( 572 css::registry::InvalidRegistryException, 573 css::uno::RuntimeException); 574 575 bool find( 576 rtl::OUString const & relative, std::vector< rtl::OUString > * path, 577 State * state, css::registry::RegistryValueType * type) const; 578 579 css::uno::Sequence< rtl::OUString > getChildren(); 580 581 rtl::Reference< Data > data_; 582 std::vector< rtl::OUString > path_; 583 }; 584 585 rtl::OUString Key::getKeyName() throw (css::uno::RuntimeException) { 586 return pathToString(path_); 587 } 588 589 sal_Bool Key::isReadOnly() 590 throw (css::registry::InvalidRegistryException, css::uno::RuntimeException) 591 { 592 return true; 593 } 594 595 sal_Bool Key::isValid() throw(css::uno::RuntimeException) { 596 return true; 597 } 598 599 css::registry::RegistryKeyType Key::getKeyType(rtl::OUString const & rKeyName) 600 throw (css::registry::InvalidRegistryException, css::uno::RuntimeException) 601 { 602 if (!find(rtl::OUString(), 0, 0, 0)) { 603 throw css::registry::InvalidRegistryException( 604 (rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("unknown key ")) + 605 rKeyName), 606 static_cast< cppu::OWeakObject * >(this)); 607 } 608 return css::registry::RegistryKeyType_KEY; 609 } 610 611 css::registry::RegistryValueType Key::getValueType() 612 throw (css::registry::InvalidRegistryException, css::uno::RuntimeException) 613 { 614 css::registry::RegistryValueType type = 615 css::registry::RegistryValueType_NOT_DEFINED; 616 OSL_VERIFY(find(rtl::OUString(), 0, 0, &type)); 617 return type; 618 } 619 620 sal_Int32 Key::getLongValue() throw ( 621 css::registry::InvalidRegistryException, 622 css::registry::InvalidValueException, css::uno::RuntimeException) 623 { 624 throw css::registry::InvalidValueException( 625 rtl::OUString( 626 RTL_CONSTASCII_USTRINGPARAM( 627 "com.sun.star.registry.SimpleRegistry textual services key" 628 " getLongValue not supported")), 629 static_cast< OWeakObject * >(this)); 630 } 631 632 void Key::setLongValue(sal_Int32) 633 throw (css::registry::InvalidRegistryException, css::uno::RuntimeException) 634 { 635 throw css::registry::InvalidRegistryException( 636 rtl::OUString( 637 RTL_CONSTASCII_USTRINGPARAM( 638 "com.sun.star.registry.SimpleRegistry textual services key" 639 " setLongValue not supported")), 640 static_cast< OWeakObject * >(this)); 641 } 642 643 css::uno::Sequence< sal_Int32 > Key::getLongListValue() throw ( 644 css::registry::InvalidRegistryException, 645 css::registry::InvalidValueException, css::uno::RuntimeException) 646 { 647 throw css::registry::InvalidValueException( 648 rtl::OUString( 649 RTL_CONSTASCII_USTRINGPARAM( 650 "com.sun.star.registry.SimpleRegistry textual services key" 651 " getLongListValue not supported")), 652 static_cast< OWeakObject * >(this)); 653 } 654 655 void Key::setLongListValue(css::uno::Sequence< sal_Int32 > const &) 656 throw (css::registry::InvalidRegistryException, css::uno::RuntimeException) 657 { 658 throw css::registry::InvalidRegistryException( 659 rtl::OUString( 660 RTL_CONSTASCII_USTRINGPARAM( 661 "com.sun.star.registry.SimpleRegistry textual services key" 662 " setLongListValue not supported")), 663 static_cast< OWeakObject * >(this)); 664 } 665 666 rtl::OUString Key::getAsciiValue() throw ( 667 css::registry::InvalidRegistryException, 668 css::registry::InvalidValueException, css::uno::RuntimeException) 669 { 670 State state = STATE_ROOT; 671 OSL_VERIFY(find(rtl::OUString(), 0, &state, 0)); 672 switch (state) { 673 case STATE_LOCATION: 674 return data_->implementations[path_[1]].uri; 675 case STATE_ACTIVATOR: 676 return data_->implementations[path_[1]].loader; 677 default: 678 throw css::registry::InvalidValueException( 679 rtl::OUString( 680 RTL_CONSTASCII_USTRINGPARAM( 681 "com.sun.star.registry.SimpleRegistry textual services key" 682 " getAsciiValue: wrong type")), 683 static_cast< OWeakObject * >(this)); 684 } 685 } 686 687 void Key::setAsciiValue(rtl::OUString const &) 688 throw (css::registry::InvalidRegistryException, css::uno::RuntimeException) 689 { 690 throw css::registry::InvalidRegistryException( 691 rtl::OUString( 692 RTL_CONSTASCII_USTRINGPARAM( 693 "com.sun.star.registry.SimpleRegistry textual services key" 694 " setAsciiValue not supported")), 695 static_cast< OWeakObject * >(this)); 696 } 697 698 css::uno::Sequence< rtl::OUString > Key::getAsciiListValue() throw ( 699 css::registry::InvalidRegistryException, 700 css::registry::InvalidValueException, css::uno::RuntimeException) 701 { 702 State state = STATE_ROOT; 703 OSL_VERIFY(find(rtl::OUString(), 0, &state, 0)); 704 std::vector< rtl::OUString > const * list; 705 switch (state) { 706 case STATE_SERVICE: 707 list = &data_->services[path_[1]]; 708 break; 709 case STATE_REGISTEREDBY: 710 list = &data_->singletons[path_[1]]; 711 break; 712 default: 713 throw css::registry::InvalidValueException( 714 rtl::OUString( 715 RTL_CONSTASCII_USTRINGPARAM( 716 "com.sun.star.registry.SimpleRegistry textual services key" 717 " getAsciiListValue: wrong type")), 718 static_cast< OWeakObject * >(this)); 719 } 720 if (list->size() > SAL_MAX_INT32) { 721 throw css::registry::InvalidValueException( 722 rtl::OUString( 723 RTL_CONSTASCII_USTRINGPARAM( 724 "com.sun.star.registry.SimpleRegistry textual services key" 725 " getAsciiListValue: too large")), 726 static_cast< OWeakObject * >(this)); 727 } 728 css::uno::Sequence< rtl::OUString > seq( 729 static_cast< sal_Int32 >(list->size())); 730 sal_Int32 i = 0; 731 for (std::vector< rtl::OUString >::const_iterator j(list->begin()); 732 j != list->end(); ++j) 733 { 734 seq[i++] = *j; 735 } 736 return seq; 737 } 738 739 void Key::setAsciiListValue(css::uno::Sequence< rtl::OUString > const &) 740 throw (css::registry::InvalidRegistryException, css::uno::RuntimeException) 741 { 742 throw css::registry::InvalidRegistryException( 743 rtl::OUString( 744 RTL_CONSTASCII_USTRINGPARAM( 745 "com.sun.star.registry.SimpleRegistry textual services key" 746 " setAsciiListValue not supported")), 747 static_cast< OWeakObject * >(this)); 748 } 749 750 rtl::OUString Key::getStringValue() throw ( 751 css::registry::InvalidRegistryException, 752 css::registry::InvalidValueException, css::uno::RuntimeException) 753 { 754 State state = STATE_ROOT; 755 OSL_VERIFY(find(rtl::OUString(), 0, &state, 0)); 756 switch (state) { 757 case STATE_IMPLEMENTATION_SINGLETON: 758 case STATE_SINGLETON: 759 throw css::registry::InvalidRegistryException( 760 rtl::OUString( 761 RTL_CONSTASCII_USTRINGPARAM( 762 "com.sun.star.registry.SimpleRegistry textual services key" 763 " getStringValue: does not associate singletons with" 764 " services")), 765 static_cast< OWeakObject * >(this)); 766 default: 767 break; 768 } 769 // default case extracted from switch to avoid erroneous compiler warnings 770 // on Solaris: 771 throw css::registry::InvalidValueException( 772 rtl::OUString( 773 RTL_CONSTASCII_USTRINGPARAM( 774 "com.sun.star.registry.SimpleRegistry textual services key" 775 " getStringValue: wrong type")), 776 static_cast< OWeakObject * >(this)); 777 } 778 779 void Key::setStringValue(rtl::OUString const &) 780 throw (css::registry::InvalidRegistryException, css::uno::RuntimeException) 781 { 782 throw css::registry::InvalidRegistryException( 783 rtl::OUString( 784 RTL_CONSTASCII_USTRINGPARAM( 785 "com.sun.star.registry.SimpleRegistry textual services key" 786 " setStringValue not supported")), 787 static_cast< OWeakObject * >(this)); 788 } 789 790 css::uno::Sequence< rtl::OUString > Key::getStringListValue() throw ( 791 css::registry::InvalidRegistryException, 792 css::registry::InvalidValueException, css::uno::RuntimeException) 793 { 794 throw css::registry::InvalidValueException( 795 rtl::OUString( 796 RTL_CONSTASCII_USTRINGPARAM( 797 "com.sun.star.registry.SimpleRegistry textual services key" 798 " getStringListValue not supported")), 799 static_cast< OWeakObject * >(this)); 800 } 801 802 void Key::setStringListValue(css::uno::Sequence< rtl::OUString > const &) 803 throw (css::registry::InvalidRegistryException, css::uno::RuntimeException) 804 { 805 throw css::registry::InvalidRegistryException( 806 rtl::OUString( 807 RTL_CONSTASCII_USTRINGPARAM( 808 "com.sun.star.registry.SimpleRegistry textual services key" 809 " setStringListValue not supported")), 810 static_cast< OWeakObject * >(this)); 811 } 812 813 css::uno::Sequence< sal_Int8 > Key::getBinaryValue() 814 throw ( 815 css::registry::InvalidRegistryException, 816 css::registry::InvalidValueException, css::uno::RuntimeException) 817 { 818 throw css::registry::InvalidValueException( 819 rtl::OUString( 820 RTL_CONSTASCII_USTRINGPARAM( 821 "com.sun.star.registry.SimpleRegistry textual services key" 822 " getBinarValue not supported")), 823 static_cast< OWeakObject * >(this)); 824 } 825 826 void Key::setBinaryValue(css::uno::Sequence< sal_Int8 > const &) 827 throw (css::registry::InvalidRegistryException, css::uno::RuntimeException) 828 { 829 throw css::registry::InvalidRegistryException( 830 rtl::OUString( 831 RTL_CONSTASCII_USTRINGPARAM( 832 "com.sun.star.registry.SimpleRegistry textual services key" 833 " setBinaryValue not supported")), 834 static_cast< OWeakObject * >(this)); 835 } 836 837 css::uno::Reference< css::registry::XRegistryKey > Key::openKey( 838 rtl::OUString const & aKeyName) 839 throw (css::registry::InvalidRegistryException, css::uno::RuntimeException) 840 { 841 std::vector< rtl::OUString > path; 842 if (!find(aKeyName, &path, 0, 0)) { 843 return css::uno::Reference< css::registry::XRegistryKey >(); 844 } 845 return new Key(data_, path); 846 } 847 848 css::uno::Reference< css::registry::XRegistryKey > Key::createKey( 849 rtl::OUString const &) 850 throw (css::registry::InvalidRegistryException, css::uno::RuntimeException) 851 { 852 throw css::registry::InvalidRegistryException( 853 rtl::OUString( 854 RTL_CONSTASCII_USTRINGPARAM( 855 "com.sun.star.registry.SimpleRegistry textual services key" 856 " createKey not supported")), 857 static_cast< OWeakObject * >(this)); 858 } 859 860 void Key::closeKey() 861 throw (css::registry::InvalidRegistryException, css::uno::RuntimeException) 862 {} 863 864 void Key::deleteKey(rtl::OUString const &) 865 throw (css::registry::InvalidRegistryException, css::uno::RuntimeException) 866 { 867 throw css::registry::InvalidRegistryException( 868 rtl::OUString( 869 RTL_CONSTASCII_USTRINGPARAM( 870 "com.sun.star.registry.SimpleRegistry textual services key" 871 " deleteKey not supported")), 872 static_cast< OWeakObject * >(this)); 873 } 874 875 css::uno::Sequence< css::uno::Reference< css::registry::XRegistryKey > > 876 Key::openKeys() 877 throw (css::registry::InvalidRegistryException, css::uno::RuntimeException) 878 { 879 css::uno::Sequence< rtl::OUString > names(getChildren()); 880 css::uno::Sequence< css::uno::Reference< css::registry::XRegistryKey > > 881 keys(names.getLength()); 882 for (sal_Int32 i = 0; i < keys.getLength(); ++i) { 883 keys[i] = openKey(names[i]); 884 OSL_ASSERT(keys[i].is()); 885 } 886 return keys; 887 } 888 889 css::uno::Sequence< rtl::OUString > Key::getKeyNames() 890 throw (css::registry::InvalidRegistryException, css::uno::RuntimeException) 891 { 892 css::uno::Sequence< rtl::OUString > names(getChildren()); 893 rtl::OUString prefix(pathToString(path_)); 894 prefix += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/")); 895 for (sal_Int32 i = 0; i < names.getLength(); ++i) { 896 names[i] = prefix + names[i]; 897 } 898 return names; 899 } 900 901 sal_Bool Key::createLink(rtl::OUString const &, rtl::OUString const &) 902 throw (css::registry::InvalidRegistryException, css::uno::RuntimeException) 903 { 904 throw css::registry::InvalidRegistryException( 905 rtl::OUString( 906 RTL_CONSTASCII_USTRINGPARAM( 907 "com.sun.star.registry.SimpleRegistry textual services key" 908 " createLink not supported")), 909 static_cast< OWeakObject * >(this)); 910 } 911 912 void Key::deleteLink(rtl::OUString const &) 913 throw (css::registry::InvalidRegistryException, css::uno::RuntimeException) 914 { 915 throw css::registry::InvalidRegistryException( 916 rtl::OUString( 917 RTL_CONSTASCII_USTRINGPARAM( 918 "com.sun.star.registry.SimpleRegistry textual services key" 919 " deleteLink not supported")), 920 static_cast< OWeakObject * >(this)); 921 } 922 923 rtl::OUString Key::getLinkTarget(rtl::OUString const &) 924 throw (css::registry::InvalidRegistryException, css::uno::RuntimeException) 925 { 926 throw css::registry::InvalidRegistryException( 927 rtl::OUString( 928 RTL_CONSTASCII_USTRINGPARAM( 929 "com.sun.star.registry.SimpleRegistry textual services key" 930 " getLinkTarget not supported")), 931 static_cast< OWeakObject * >(this)); 932 } 933 934 rtl::OUString Key::getResolvedName(rtl::OUString const & aKeyName) 935 throw (css::registry::InvalidRegistryException, css::uno::RuntimeException) 936 { 937 std::vector< rtl::OUString > path; 938 find(aKeyName, &path, 0, 0); 939 return pathToString(path); 940 } 941 942 bool Key::find( 943 rtl::OUString const & relative, std::vector< rtl::OUString > * path, 944 State * state, css::registry::RegistryValueType * type) const 945 { 946 std::vector< rtl::OUString > p(path_); 947 sal_Int32 i = 0; 948 do { 949 rtl::OUString seg(relative.getToken(0, '/', i)); 950 if (seg.getLength() != 0) { 951 p.push_back(seg); 952 } 953 } while (i >= 0); 954 if (path != 0) { 955 *path = p; 956 } 957 std::size_t const MAX_TRANSITIONS = 4; 958 struct StateInfo { 959 css::registry::RegistryValueType type; 960 std::size_t count; 961 struct { char const * segment; State state; } 962 transitions[MAX_TRANSITIONS]; 963 }; 964 static StateInfo const info[] = { 965 // STATE_ROOT: 966 { css::registry::RegistryValueType_NOT_DEFINED, 3, 967 { { "IMPLEMENTATIONS", STATE_IMPLEMENTATIONS }, 968 { "SERVICES", STATE_SERVICES }, 969 { "SINGLETONS", STATE_SINGLETONS } } }, 970 // STATE_IMPLEMENTATIONS: 971 { css::registry::RegistryValueType_NOT_DEFINED, 1, 972 { { 0, STATE_IMPLEMENTATION } } }, 973 // STATE_IMPLEMENTATION: 974 { css::registry::RegistryValueType_NOT_DEFINED, 1, 975 { { "UNO", STATE_UNO } } }, 976 // STATE_UNO: 977 { css::registry::RegistryValueType_NOT_DEFINED, 4, 978 { { "LOCATION", STATE_LOCATION }, 979 { "ACTIVATOR", STATE_ACTIVATOR }, 980 { "SERVICES", STATE_IMPLEMENTATION_SERVICES }, 981 { "SINGLETONS", STATE_IMPLEMENTATION_SINGLETONS } } }, 982 // STATE_LOCATION: 983 { css::registry::RegistryValueType_ASCII, 0, {} }, 984 // STATE_ACTIVATOR: 985 { css::registry::RegistryValueType_ASCII, 0, {} }, 986 // STATE_IMPLEMENTATION_SERVICES: 987 { css::registry::RegistryValueType_NOT_DEFINED, 1, 988 { { 0, STATE_IMPLEMENTATION_SERVICE } } }, 989 // STATE_IMPLEMENTATION_SERVICE: 990 { css::registry::RegistryValueType_NOT_DEFINED, 0, {} }, 991 // STATE_IMPLEMENTATION_SINGLETONS: 992 { css::registry::RegistryValueType_NOT_DEFINED, 1, 993 { { 0, STATE_IMPLEMENTATION_SINGLETON } } }, 994 // STATE_IMPLEMENTATION_SINGLETON: 995 { css::registry::RegistryValueType_STRING, 0, {} }, 996 // STATE_SERVICES: 997 { css::registry::RegistryValueType_NOT_DEFINED, 1, 998 { { 0, STATE_SERVICE } } }, 999 // STATE_SERVICE: 1000 { css::registry::RegistryValueType_ASCIILIST, 0, {} }, 1001 // STATE_SINGLETONS: 1002 { css::registry::RegistryValueType_NOT_DEFINED, 1, 1003 { { 0, STATE_SINGLETON } } }, 1004 // STATE_SINGLETON: 1005 { css::registry::RegistryValueType_STRING, 1, 1006 { { "REGISTERED_BY", STATE_REGISTEREDBY } } }, 1007 // STATE_REGISTEREDBY: 1008 { css::registry::RegistryValueType_ASCIILIST, 0, {} } }; 1009 State s = STATE_ROOT; 1010 for (std::vector< rtl::OUString >::iterator j(p.begin()); j != p.end(); ++j) 1011 { 1012 bool found = false; 1013 for (std::size_t k = 0; k < info[s].count; ++k) { 1014 if (info[s].transitions[k].segment == 0) { 1015 switch (info[s].transitions[k].state) { 1016 case STATE_IMPLEMENTATION: 1017 found = data_->implementations.find(*j) != 1018 data_->implementations.end(); 1019 break; 1020 case STATE_IMPLEMENTATION_SERVICE: 1021 case STATE_IMPLEMENTATION_SINGLETON: 1022 found = true; //TODO 1023 break; 1024 case STATE_SERVICE: 1025 found = data_->services.find(*j) != data_->services.end(); 1026 break; 1027 case STATE_SINGLETON: 1028 found = data_->singletons.find(*j) != 1029 data_->singletons.end(); 1030 break; 1031 default: 1032 std::abort(); // this cannot happen 1033 } 1034 } else { 1035 found = j->equalsAscii(info[s].transitions[k].segment); 1036 } 1037 if (found) { 1038 s = info[s].transitions[k].state; 1039 break; 1040 } 1041 } 1042 if (!found) { 1043 return false; 1044 } 1045 } 1046 if (state != 0) { 1047 *state = s; 1048 } 1049 if (type != 0) { 1050 *type = info[s].type; 1051 } 1052 return true; 1053 } 1054 1055 css::uno::Sequence< rtl::OUString > Key::getChildren() { 1056 State state = STATE_ROOT; 1057 OSL_VERIFY(find(rtl::OUString(), 0, &state, 0)); 1058 switch (state) { 1059 default: 1060 std::abort(); // this cannot happen 1061 // pseudo-fall-through to avoid warnings on MSC 1062 case STATE_ROOT: 1063 { 1064 css::uno::Sequence< rtl::OUString > seq(3); 1065 seq[0] = rtl::OUString( 1066 RTL_CONSTASCII_USTRINGPARAM("IMPLEMENTATIONS")); 1067 seq[1] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SERVICES")); 1068 seq[2] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SINGLETONS")); 1069 return seq; 1070 } 1071 case STATE_IMPLEMENTATIONS: 1072 { 1073 if (data_->implementations.size() > SAL_MAX_INT32) { 1074 throw css::registry::InvalidValueException( 1075 rtl::OUString( 1076 RTL_CONSTASCII_USTRINGPARAM( 1077 "com.sun.star.registry.SimpleRegistry textual" 1078 " services key openKeys: too large")), 1079 static_cast< OWeakObject * >(this)); 1080 } 1081 css::uno::Sequence< rtl::OUString > seq( 1082 static_cast< sal_Int32 >(data_->implementations.size())); 1083 sal_Int32 i = 0; 1084 for (Implementations::iterator j(data_->implementations.begin()); 1085 j != data_->implementations.end(); ++j) 1086 { 1087 seq[i++] = j->first; 1088 } 1089 return seq; 1090 } 1091 case STATE_UNO: 1092 { 1093 css::uno::Sequence< rtl::OUString > seq(4); 1094 seq[0] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("LOCATION")); 1095 seq[1] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ACTIVATOR")); 1096 seq[2] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SERVICES")); 1097 seq[3] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SINGLETONS")); 1098 return seq; 1099 } 1100 case STATE_LOCATION: 1101 case STATE_ACTIVATOR: 1102 case STATE_IMPLEMENTATION_SERVICE: 1103 case STATE_IMPLEMENTATION_SINGLETON: 1104 case STATE_SERVICE: 1105 case STATE_REGISTEREDBY: 1106 return css::uno::Sequence< rtl::OUString >(); 1107 case STATE_IMPLEMENTATION_SERVICES: 1108 { 1109 if (data_->implementations[path_[1]].services.size() > 1110 SAL_MAX_INT32) 1111 { 1112 throw css::registry::InvalidValueException( 1113 rtl::OUString( 1114 RTL_CONSTASCII_USTRINGPARAM( 1115 "com.sun.star.registry.SimpleRegistry textual" 1116 " services key openKeys: too large")), 1117 static_cast< OWeakObject * >(this)); 1118 } 1119 css::uno::Sequence< rtl::OUString > seq( 1120 static_cast< sal_Int32 >( 1121 data_->implementations[path_[1]].services.size())); 1122 sal_Int32 i = 0; 1123 for (std::vector< rtl::OUString >::iterator j( 1124 data_->implementations[path_[1]].services.begin()); 1125 j != data_->implementations[path_[1]].services.end(); ++j) 1126 { 1127 seq[i++] = *j; 1128 } 1129 return seq; 1130 } 1131 case STATE_IMPLEMENTATION_SINGLETONS: 1132 { 1133 if (data_->implementations[path_[1]].singletons.size() > 1134 SAL_MAX_INT32) 1135 { 1136 throw css::registry::InvalidValueException( 1137 rtl::OUString( 1138 RTL_CONSTASCII_USTRINGPARAM( 1139 "com.sun.star.registry.SimpleRegistry textual" 1140 " services key openKeys: too large")), 1141 static_cast< OWeakObject * >(this)); 1142 } 1143 css::uno::Sequence< rtl::OUString > seq( 1144 static_cast< sal_Int32 >( 1145 data_->implementations[path_[1]].singletons.size())); 1146 sal_Int32 i = 0; 1147 for (std::vector< rtl::OUString >::iterator j( 1148 data_->implementations[path_[1]].singletons.begin()); 1149 j != data_->implementations[path_[1]].singletons.end(); ++j) 1150 { 1151 seq[i++] = *j; 1152 } 1153 return seq; 1154 } 1155 case STATE_SERVICES: 1156 { 1157 if (data_->services.size() > SAL_MAX_INT32) { 1158 throw css::registry::InvalidValueException( 1159 rtl::OUString( 1160 RTL_CONSTASCII_USTRINGPARAM( 1161 "com.sun.star.registry.SimpleRegistry textual" 1162 " services key openKeys: too large")), 1163 static_cast< OWeakObject * >(this)); 1164 } 1165 css::uno::Sequence< rtl::OUString > seq( 1166 static_cast< sal_Int32 >(data_->services.size())); 1167 sal_Int32 i = 0; 1168 for (ImplementationMap::iterator j(data_->services.begin()); 1169 j != data_->services.end(); ++j) 1170 { 1171 seq[i++] = j->first; 1172 } 1173 return seq; 1174 } 1175 case STATE_SINGLETONS: 1176 { 1177 if (data_->singletons.size() > SAL_MAX_INT32) { 1178 throw css::registry::InvalidValueException( 1179 rtl::OUString( 1180 RTL_CONSTASCII_USTRINGPARAM( 1181 "com.sun.star.registry.SimpleRegistry textual" 1182 " services key openKeys: too large")), 1183 static_cast< OWeakObject * >(this)); 1184 } 1185 css::uno::Sequence< rtl::OUString > seq( 1186 static_cast< sal_Int32 >(data_->singletons.size())); 1187 sal_Int32 i = 0; 1188 for (ImplementationMap::iterator j(data_->singletons.begin()); 1189 j != data_->singletons.end(); ++j) 1190 { 1191 seq[i++] = j->first; 1192 } 1193 return seq; 1194 } 1195 case STATE_SINGLETON: 1196 { 1197 css::uno::Sequence< rtl::OUString > seq(1); 1198 seq[0] = rtl::OUString( 1199 RTL_CONSTASCII_USTRINGPARAM("REGISTERED_BY")); 1200 return seq; 1201 } 1202 } 1203 } 1204 1205 } 1206 1207 TextualServices::TextualServices(rtl::OUString const & uri): 1208 uri_(uri), data_(new Data) 1209 { 1210 try { 1211 Parser(uri, data_); 1212 } catch (css::container::NoSuchElementException &) { 1213 throw css::registry::InvalidRegistryException( 1214 (uri + 1215 rtl::OUString( 1216 RTL_CONSTASCII_USTRINGPARAM(": no such file"))), 1217 css::uno::Reference< css::uno::XInterface >()); 1218 } 1219 } 1220 1221 TextualServices::~TextualServices() {} 1222 1223 css::uno::Reference< css::registry::XRegistryKey > TextualServices::getRootKey() 1224 { 1225 return new Key(data_, std::vector< rtl::OUString >()); 1226 } 1227 1228 } } 1229