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