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 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_unotools.hxx" 26 #include "unotools/configitem.hxx" 27 #include "unotools/configmgr.hxx" 28 #include "unotools/configpathes.hxx" 29 #include <comphelper/processfactory.hxx> 30 #include <com/sun/star/beans/XMultiPropertySet.hpp> 31 #include <com/sun/star/beans/XPropertySet.hpp> 32 #include <com/sun/star/util/XChangesListener.hpp> 33 #include <com/sun/star/util/XChangesNotifier.hpp> 34 #include <com/sun/star/container/XHierarchicalNameAccess.hpp> 35 #include <com/sun/star/container/XHierarchicalName.hpp> 36 #include <com/sun/star/configuration/XTemplateContainer.hpp> 37 #include <com/sun/star/container/XNameContainer.hpp> 38 #include <com/sun/star/lang/XSingleServiceFactory.hpp> 39 #include <com/sun/star/lang/XServiceInfo.hpp> 40 #include <com/sun/star/awt/XRequestCallback.hpp> 41 #include <com/sun/star/beans/PropertyValue.hpp> 42 #include <com/sun/star/beans/PropertyAttribute.hpp> 43 #include <com/sun/star/util/XStringEscape.hpp> 44 #include <com/sun/star/util/XChangesBatch.hpp> 45 #include <osl/diagnose.h> 46 #include <tools/solarmutex.hxx> 47 #include <rtl/ustrbuf.hxx> 48 49 using namespace utl; 50 using rtl::OUString; 51 using rtl::OString; 52 using namespace com::sun::star::uno; 53 using namespace com::sun::star::util; 54 using namespace com::sun::star::lang; 55 using namespace com::sun::star::beans; 56 using namespace com::sun::star::container; 57 using namespace com::sun::star::configuration; 58 59 #define C2U(cChar) OUString::createFromAscii(cChar) 60 #include <cppuhelper/implbase1.hxx> // helper for implementations 61 62 #ifdef DBG_UTIL 63 inline void lcl_CFG_DBG_EXCEPTION(const sal_Char* cText, const Exception& rEx) 64 { 65 OString sMsg(cText); 66 sMsg += OString(rEx.Message.getStr(), rEx.Message.getLength(), RTL_TEXTENCODING_ASCII_US); 67 OSL_ENSURE(sal_False, sMsg.getStr()); 68 } 69 #define CATCH_INFO(a) \ 70 catch(Exception& rEx) \ 71 { \ 72 lcl_CFG_DBG_EXCEPTION(a, rEx);\ 73 } 74 #else 75 #define lcl_CFG_DBG_EXCEPTION( a, b) 76 #define CATCH_INFO(a) catch(Exception& ){} 77 #endif 78 79 /* 80 The ConfigChangeListener_Impl receives notifications from the configuration about changes that 81 have happened. It forwards this notification to the ConfigItem it knows a pParent by calling its 82 "CallNotify" method. As ConfigItems are most probably not thread safe, the SolarMutex is acquired 83 before doing so. 84 */ 85 86 namespace utl{ 87 class ConfigChangeListener_Impl : public cppu::WeakImplHelper1 88 < 89 com::sun::star::util::XChangesListener 90 > 91 { 92 public: 93 ConfigItem* pParent; 94 const Sequence< OUString > aPropertyNames; 95 ConfigChangeListener_Impl(ConfigItem& rItem, const Sequence< OUString >& rNames); 96 ~ConfigChangeListener_Impl(); 97 98 //XChangesListener 99 virtual void SAL_CALL changesOccurred( const ChangesEvent& Event ) throw(RuntimeException); 100 101 //XEventListener 102 virtual void SAL_CALL disposing( const EventObject& Source ) throw(RuntimeException); 103 }; 104 /* -----------------------------12.02.01 11:38-------------------------------- 105 106 ---------------------------------------------------------------------------*/ 107 struct ConfigItem_Impl 108 { 109 utl::ConfigManager* pManager; 110 sal_Int16 nMode; 111 sal_Bool bIsModified; 112 sal_Bool bEnableInternalNotification; 113 114 sal_Int16 nInValueChange; 115 ConfigItem_Impl() : 116 pManager(0), 117 nMode(0), 118 bIsModified(sal_False), 119 bEnableInternalNotification(sal_False), 120 nInValueChange(0) 121 {} 122 }; 123 } 124 /* -----------------------------04.12.00 10:25-------------------------------- 125 126 ---------------------------------------------------------------------------*/ 127 class ValueCounter_Impl 128 { 129 sal_Int16& rCnt; 130 public: 131 ValueCounter_Impl(sal_Int16& rCounter): 132 rCnt(rCounter) 133 {rCnt++;} 134 ~ValueCounter_Impl() 135 { 136 OSL_ENSURE(rCnt>0, "RefCount < 0 ??"); 137 rCnt--; 138 } 139 }; 140 /* -----------------------------03.12.02 ------------------------------------- 141 142 ---------------------------------------------------------------------------*/ 143 namespace 144 { 145 // helper to achieve exception - safe handling of an Item under construction 146 template <class TYP> 147 class AutoDeleter // : Noncopyable 148 { 149 TYP* m_pItem; 150 public: 151 AutoDeleter(TYP * pItem) 152 : m_pItem(pItem) 153 { 154 } 155 156 ~AutoDeleter() 157 { 158 delete m_pItem; 159 } 160 161 void keep() { m_pItem = 0; } 162 }; 163 } 164 /* -----------------------------29.08.00 16:34-------------------------------- 165 166 ---------------------------------------------------------------------------*/ 167 ConfigChangeListener_Impl::ConfigChangeListener_Impl( 168 ConfigItem& rItem, const Sequence< OUString >& rNames) : 169 pParent(&rItem), 170 aPropertyNames(rNames) 171 { 172 } 173 /* -----------------------------29.08.00 16:34-------------------------------- 174 175 ---------------------------------------------------------------------------*/ 176 ConfigChangeListener_Impl::~ConfigChangeListener_Impl() 177 { 178 } 179 /* -----------------------------29.08.00 16:34-------------------------------- 180 181 ---------------------------------------------------------------------------*/ 182 sal_Bool lcl_Find( 183 const rtl::OUString& rTemp, 184 const OUString* pCheckPropertyNames, 185 sal_Int32 nLength) 186 { 187 //return true if the path is completely correct or if it is longer 188 //i.e ...Print/Content/Graphic and .../Print 189 for(sal_Int32 nIndex = 0; nIndex < nLength; nIndex++) 190 if( isPrefixOfConfigurationPath(rTemp, pCheckPropertyNames[nIndex]) ) 191 return sal_True; 192 return sal_False; 193 } 194 //----------------------------------------------------------------------------- 195 void ConfigChangeListener_Impl::changesOccurred( const ChangesEvent& rEvent ) throw(RuntimeException) 196 { 197 const ElementChange* pElementChanges = rEvent.Changes.getConstArray(); 198 199 Sequence<OUString> aChangedNames(rEvent.Changes.getLength()); 200 OUString* pNames = aChangedNames.getArray(); 201 202 const OUString* pCheckPropertyNames = aPropertyNames.getConstArray(); 203 204 sal_Int32 nNotify = 0; 205 for(int i = 0; i < aChangedNames.getLength(); i++) 206 { 207 OUString sTemp; 208 pElementChanges[i].Accessor >>= sTemp; 209 if(lcl_Find(sTemp, pCheckPropertyNames, aPropertyNames.getLength())) 210 pNames[nNotify++] = sTemp; 211 } 212 if( nNotify ) 213 { 214 if ( ::tools::SolarMutex::Acquire() ) 215 { 216 aChangedNames.realloc(nNotify); 217 pParent->CallNotify(aChangedNames); 218 ::tools::SolarMutex::Release(); 219 } 220 } 221 } 222 223 /* -----------------------------29.08.00 16:34-------------------------------- 224 225 ---------------------------------------------------------------------------*/ 226 void ConfigChangeListener_Impl::disposing( const EventObject& /*rSource*/ ) throw(RuntimeException) 227 { 228 pParent->RemoveChangesListener(); 229 } 230 /* -----------------------------29.08.00 12:50-------------------------------- 231 232 ---------------------------------------------------------------------------*/ 233 ConfigItem::ConfigItem(const OUString rSubTree, sal_Int16 nSetMode ) : 234 sSubTree(rSubTree), 235 pImpl(new ConfigItem_Impl) 236 { 237 AutoDeleter<ConfigItem_Impl> aNewImpl(pImpl); 238 239 pImpl->pManager = ConfigManager::GetConfigManager(); 240 pImpl->nMode = nSetMode; 241 if(0 != (nSetMode&CONFIG_MODE_RELEASE_TREE)) 242 pImpl->pManager->AddConfigItem(*this); 243 else 244 m_xHierarchyAccess = pImpl->pManager->AddConfigItem(*this); 245 246 // no more exceptions after c'tor has finished 247 aNewImpl.keep(); 248 pImpl->nMode &= ~CONFIG_MODE_PROPAGATE_ERRORS; 249 } 250 /* -----------------------------17.11.00 13:53-------------------------------- 251 252 ---------------------------------------------------------------------------*/ 253 ConfigItem::ConfigItem(utl::ConfigManager& rManager, const rtl::OUString rSubTree) : 254 sSubTree(rSubTree), 255 pImpl(new ConfigItem_Impl) 256 { 257 pImpl->pManager = &rManager; 258 pImpl->nMode = CONFIG_MODE_IMMEDIATE_UPDATE; // does not allow exceptions 259 m_xHierarchyAccess = pImpl->pManager->AddConfigItem(*this); 260 } 261 //--------------------------------------------------------------------- 262 //--- 02.08.2002 16:33:23 ----------------------------------------------- 263 sal_Bool ConfigItem::IsValidConfigMgr() const 264 { 265 return ( pImpl->pManager && pImpl->pManager->GetConfigurationProvider().is() ); 266 } 267 268 /* -----------------------------29.08.00 12:52-------------------------------- 269 270 ---------------------------------------------------------------------------*/ 271 ConfigItem::~ConfigItem() 272 { 273 if(pImpl->pManager) 274 { 275 RemoveChangesListener(); 276 pImpl->pManager->RemoveConfigItem(*this); 277 } 278 delete pImpl; 279 } 280 /* -----------------------------29.08.00 12:52-------------------------------- 281 282 ---------------------------------------------------------------------------*/ 283 void ConfigItem::ReleaseConfigMgr() 284 { 285 Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree(); 286 if(xHierarchyAccess.is()) 287 { 288 try 289 { 290 Reference<XChangesBatch> xBatch(xHierarchyAccess, UNO_QUERY); 291 xBatch->commitChanges(); 292 } 293 CATCH_INFO("Exception from commitChanges(): ") 294 } 295 RemoveChangesListener(); 296 OSL_ENSURE(pImpl->pManager, "ConfigManager already released"); 297 pImpl->pManager = 0; 298 } 299 /* -----------------------------29.08.00 12:52-------------------------------- 300 301 ---------------------------------------------------------------------------*/ 302 void ConfigItem::CallNotify( const com::sun::star::uno::Sequence<OUString>& rPropertyNames ) 303 { 304 // the call is forwarded to the virtual Notify() method 305 // it is pure virtual, so all classes deriving from ConfigItem have to decide how they 306 // want to notify listeners 307 if(!IsInValueChange() || pImpl->bEnableInternalNotification) 308 Notify(rPropertyNames); 309 } 310 311 /* -----------------------------12.12.00 17:09-------------------------------- 312 313 ---------------------------------------------------------------------------*/ 314 sal_Bool lcl_IsLocalProperty(const OUString& rSubTree, const OUString& rProperty) 315 { 316 static const sal_Char* aLocalProperties[] = 317 { 318 "Office.Common/Path/Current/Storage", 319 "Office.Common/Path/Current/Temp" 320 }; 321 static const int aLocalPropLen[] = 322 { 323 34, 324 31 325 }; 326 OUString sProperty(rSubTree); 327 sProperty += C2U("/"); 328 sProperty += rProperty; 329 330 if(sProperty.equalsAsciiL( aLocalProperties[0], aLocalPropLen[0]) || 331 sProperty.equalsAsciiL( aLocalProperties[1], aLocalPropLen[1])) 332 return sal_True; 333 334 return sal_False; 335 } 336 /* -----------------------------10.04.01 15:00-------------------------------- 337 338 ---------------------------------------------------------------------------*/ 339 void ConfigItem::impl_packLocalizedProperties( const Sequence< OUString >& lInNames , 340 const Sequence< Any >& lInValues , 341 Sequence< Any >& lOutValues ) 342 { 343 // Safe impossible cases. 344 // This method should be called for special ConfigItem-mode only! 345 OSL_ENSURE( ((pImpl->nMode & CONFIG_MODE_ALL_LOCALES ) == CONFIG_MODE_ALL_LOCALES), "ConfigItem::impl_packLocalizedProperties()\nWrong call of this method detected!\n" ); 346 347 sal_Int32 nSourceCounter ; // used to step during input lists 348 sal_Int32 nSourceSize ; // marks end of loop over input lists 349 sal_Int32 nDestinationCounter ; // actual position in output lists 350 sal_Int32 nPropertyCounter ; // counter of inner loop for Sequence< PropertyValue > 351 sal_Int32 nPropertiesSize ; // marks end of inner loop 352 Sequence< OUString > lPropertyNames ; // list of all locales for localized entry 353 Sequence< PropertyValue > lProperties ; // localized values of an configuration entry packed for return 354 Reference< XInterface > xLocalizedNode ; // if cfg entry is localized ... lInValues contains an XInterface! 355 356 // Optimise follow algorithm ... A LITTLE BIT :-) 357 // There exist two different possibilities: 358 // i ) There exist no localized entries ... => size of lOutValues will be the same like lInNames/lInValues! 359 // ii) There exist some (mostly one or two) localized entries ... => size of lOutValues will be the same like lInNames/lInValues! 360 // ... Why? If a localized value exist - the any is filled with an XInterface object (is a SetNode-service). 361 // We read all his child nodes and pack it into Sequence< PropertyValue >. 362 // The result list we pack into the return any. We never change size of lists! 363 nSourceSize = lInNames.getLength(); 364 lOutValues.realloc( nSourceSize ); 365 366 // Algorithm: 367 // Copy all names and values from in to out lists. 368 // Look for special localized entries ... You can detect it as "XInterface" packed into an Any. 369 // Use this XInterface-object to read all localized values and pack it into Sequence< PropertValue >. 370 // Add this list to out lists then. 371 372 nDestinationCounter = 0; 373 for( nSourceCounter=0; nSourceCounter<nSourceSize; ++nSourceCounter ) 374 { 375 // If item a special localized one ... convert and pack it ... 376 if( lInValues[nSourceCounter].getValueTypeName() == C2U("com.sun.star.uno.XInterface") ) 377 { 378 lInValues[nSourceCounter] >>= xLocalizedNode; 379 Reference< XNameContainer > xSetAccess( xLocalizedNode, UNO_QUERY ); 380 if( xSetAccess.is() == sal_True ) 381 { 382 lPropertyNames = xSetAccess->getElementNames() ; 383 nPropertiesSize = lPropertyNames.getLength() ; 384 lProperties.realloc( nPropertiesSize ) ; 385 386 for( nPropertyCounter=0; nPropertyCounter<nPropertiesSize; ++nPropertyCounter ) 387 { 388 #if OSL_DEBUG_LEVEL > 1 389 // Sometimes it's better to see what's going on :-) 390 OUString sPropName = lInNames[nSourceCounter]; 391 OUString sLocaleName = lPropertyNames[nPropertyCounter]; 392 #endif 393 lProperties[nPropertyCounter].Name = lPropertyNames[nPropertyCounter] ; 394 OUString sLocaleValue; 395 xSetAccess->getByName( lPropertyNames[nPropertyCounter] ) >>= sLocaleValue ; 396 lProperties[nPropertyCounter].Value <<= sLocaleValue; 397 } 398 399 lOutValues[nDestinationCounter] <<= lProperties; 400 } 401 } 402 // ... or copy normal items to return lists directly. 403 else 404 { 405 lOutValues[nDestinationCounter] = lInValues[nSourceCounter]; 406 } 407 ++nDestinationCounter; 408 } 409 } 410 /* -----------------------------10.04.01 15:00-------------------------------- 411 412 ---------------------------------------------------------------------------*/ 413 void ConfigItem::impl_unpackLocalizedProperties( const Sequence< OUString >& lInNames , 414 const Sequence< Any >& lInValues , 415 Sequence< OUString >& lOutNames , 416 Sequence< Any >& lOutValues ) 417 { 418 // Safe impossible cases. 419 // This method should be called for special ConfigItem-mode only! 420 OSL_ENSURE( ((pImpl->nMode & CONFIG_MODE_ALL_LOCALES ) == CONFIG_MODE_ALL_LOCALES), "ConfigItem::impl_unpackLocalizedProperties()\nWrong call of this method detected!\n" ); 421 422 sal_Int32 nSourceCounter ; // used to step during input lists 423 sal_Int32 nSourceSize ; // marks end of loop over input lists 424 sal_Int32 nDestinationCounter ; // actual position in output lists 425 sal_Int32 nPropertyCounter ; // counter of inner loop for Sequence< PropertyValue > 426 sal_Int32 nPropertiesSize ; // marks end of inner loop 427 OUString sNodeName ; // base name of node ( e.g. "UIName/" ) ... expand to locale ( e.g. "UIName/de" ) 428 Sequence< PropertyValue > lProperties ; // localized values of an configuration entry getted from lInValues-Any 429 430 // Optimise follow algorithm ... A LITTLE BIT :-) 431 // There exist two different possibilities: 432 // i ) There exist no localized entries ... => size of lOutNames/lOutValues will be the same like lInNames/lInValues! 433 // ii) There exist some (mostly one or two) localized entries ... => size of lOutNames/lOutValues will be some bytes greater then lInNames/lInValues. 434 // => I think we should make it fast for i). ii) is a special case and mustn't be SOOOO... fast. 435 // We should reserve same space for output list like input ones first. 436 // Follow algorithm looks for these borders and change it for ii) only! 437 // It will be faster then a "realloc()" call in every loop ... 438 nSourceSize = lInNames.getLength(); 439 440 lOutNames.realloc ( nSourceSize ); 441 lOutValues.realloc ( nSourceSize ); 442 443 // Algorithm: 444 // Copy all names and values from const to return lists. 445 // Look for special localized entries ... You can detect it as Sequence< PropertyValue > packed into an Any. 446 // Split it ... insert PropertyValue.Name to lOutNames and PropertyValue.Value to lOutValues. 447 448 nDestinationCounter = 0; 449 for( nSourceCounter=0; nSourceCounter<nSourceSize; ++nSourceCounter ) 450 { 451 // If item a special localized one ... split it and insert his parts to output lists ... 452 if( lInValues[nSourceCounter].getValueType() == ::getCppuType( (const Sequence< PropertyValue >*)NULL ) ) 453 { 454 lInValues[nSourceCounter] >>= lProperties ; 455 sNodeName = lInNames[nSourceCounter] ; 456 sNodeName += C2U("/") ; 457 nPropertiesSize = lProperties.getLength() ; 458 459 if( (nDestinationCounter+nPropertiesSize) > lOutNames.getLength() ) 460 { 461 lOutNames.realloc ( nDestinationCounter+nPropertiesSize ); 462 lOutValues.realloc ( nDestinationCounter+nPropertiesSize ); 463 } 464 465 for( nPropertyCounter=0; nPropertyCounter<nPropertiesSize; ++nPropertyCounter ) 466 { 467 lOutNames [nDestinationCounter] = sNodeName + lProperties[nPropertyCounter].Name ; 468 lOutValues[nDestinationCounter] = lProperties[nPropertyCounter].Value ; 469 ++nDestinationCounter; 470 } 471 } 472 // ... or copy normal items to return lists directly. 473 else 474 { 475 if( (nDestinationCounter+1) > lOutNames.getLength() ) 476 { 477 lOutNames.realloc ( nDestinationCounter+1 ); 478 lOutValues.realloc ( nDestinationCounter+1 ); 479 } 480 481 lOutNames [nDestinationCounter] = lInNames [nSourceCounter]; 482 lOutValues[nDestinationCounter] = lInValues[nSourceCounter]; 483 ++nDestinationCounter; 484 } 485 } 486 } 487 /* -----------------------------03.02.2003 14:44------------------------------ 488 489 ---------------------------------------------------------------------------*/ 490 Sequence< sal_Bool > ConfigItem::GetReadOnlyStates(const com::sun::star::uno::Sequence< rtl::OUString >& rNames) 491 { 492 sal_Int32 i; 493 494 // size of return list is fix! 495 // Every item must match to length of incoming name list. 496 sal_Int32 nCount = rNames.getLength(); 497 Sequence< sal_Bool > lStates(nCount); 498 499 // We must be sure to return a valid information every time! 500 // Set default to non readonly ... similar to the configuration handling of this property. 501 for ( i=0; i<nCount; ++i) 502 lStates[i] = sal_False; 503 504 // no access - no informations ... 505 Reference< XHierarchicalNameAccess > xHierarchyAccess = GetTree(); 506 if (!xHierarchyAccess.is()) 507 return lStates; 508 509 for (i=0; i<nCount; ++i) 510 { 511 try 512 { 513 if(pImpl->pManager->IsLocalConfigProvider() && lcl_IsLocalProperty(sSubTree, rNames[i])) 514 { 515 OSL_ENSURE(sal_False, "ConfigItem::IsReadonly()\nlocal mode seams to be used!?\n"); 516 continue; 517 } 518 519 OUString sName = rNames[i]; 520 OUString sPath; 521 OUString sProperty; 522 523 ::utl::splitLastFromConfigurationPath(sName,sPath,sProperty); 524 if (!sPath.getLength() && !sProperty.getLength()) 525 { 526 OSL_ENSURE(sal_False, "ConfigItem::IsReadonly()\nsplitt failed\n"); 527 continue; 528 } 529 530 Reference< XInterface > xNode; 531 Reference< XPropertySet > xSet ; 532 Reference< XPropertySetInfo > xInfo; 533 if (sPath.getLength()) 534 { 535 Any aNode = xHierarchyAccess->getByHierarchicalName(sPath); 536 if (!(aNode >>= xNode) || !xNode.is()) 537 { 538 OSL_ENSURE(sal_False, "ConfigItem::IsReadonly()\nno set available\n"); 539 continue; 540 } 541 } 542 else 543 { 544 xNode = Reference< XInterface >(xHierarchyAccess, UNO_QUERY); 545 } 546 547 xSet = Reference< XPropertySet >(xNode, UNO_QUERY); 548 if (xSet.is()) 549 { 550 xInfo = xSet->getPropertySetInfo(); 551 OSL_ENSURE(xInfo.is(), "ConfigItem::IsReadonly()\ngetPropertySetInfo failed ...\n"); 552 } 553 else 554 { 555 xInfo = Reference< XPropertySetInfo >(xNode, UNO_QUERY); 556 OSL_ENSURE(xInfo.is(), "ConfigItem::IsReadonly()\nUNO_QUERY failed ...\n"); 557 } 558 559 if (!xInfo.is()) 560 { 561 OSL_ENSURE(sal_False, "ConfigItem::IsReadonly()\nno prop info available\n"); 562 continue; 563 } 564 565 Property aProp = xInfo->getPropertyByName(sProperty); 566 lStates[i] = ((aProp.Attributes & PropertyAttribute::READONLY) == PropertyAttribute::READONLY); 567 } 568 catch(Exception&){} 569 } 570 571 return lStates; 572 } 573 574 /* -----------------------------29.08.00 15:10-------------------------------- 575 576 ---------------------------------------------------------------------------*/ 577 Sequence< Any > ConfigItem::GetProperties(const Sequence< OUString >& rNames) 578 { 579 Sequence< Any > aRet(rNames.getLength()); 580 const OUString* pNames = rNames.getConstArray(); 581 Any* pRet = aRet.getArray(); 582 Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree(); 583 if(xHierarchyAccess.is()) 584 { 585 for(int i = 0; i < rNames.getLength(); i++) 586 { 587 try 588 { 589 if(pImpl->pManager->IsLocalConfigProvider() && lcl_IsLocalProperty(sSubTree, pNames[i])) 590 { 591 OUString sProperty(sSubTree); 592 sProperty += C2U("/"); 593 sProperty += pNames[i]; 594 pRet[i] = pImpl->pManager->GetLocalProperty(sProperty); 595 } 596 else 597 pRet[i] = xHierarchyAccess->getByHierarchicalName(pNames[i]); 598 } 599 catch(Exception& rEx) 600 { 601 #if OSL_DEBUG_LEVEL > 0 602 OString sMsg("XHierarchicalNameAccess: "); 603 sMsg += OString(rEx.Message.getStr(), 604 rEx.Message.getLength(), 605 RTL_TEXTENCODING_ASCII_US); 606 sMsg += OString("\n"); 607 sMsg += OString(ConfigManager::GetConfigBaseURL().getStr(), 608 ConfigManager::GetConfigBaseURL().getLength(), 609 RTL_TEXTENCODING_ASCII_US); 610 sMsg += OString(sSubTree.getStr(), 611 sSubTree.getLength(), 612 RTL_TEXTENCODING_ASCII_US); 613 sMsg += OString("/"); 614 sMsg += OString(pNames[i].getStr(), 615 pNames[i].getLength(), 616 RTL_TEXTENCODING_ASCII_US); 617 OSL_ENSURE(sal_False, sMsg.getStr()); 618 #else 619 (void) rEx; // avoid warning 620 #endif 621 } 622 } 623 624 // In special mode "ALL_LOCALES" we must convert localized values to Sequence< PropertyValue >. 625 if((pImpl->nMode & CONFIG_MODE_ALL_LOCALES ) == CONFIG_MODE_ALL_LOCALES) 626 { 627 Sequence< Any > lValues; 628 impl_packLocalizedProperties( rNames, aRet, lValues ); 629 aRet = lValues; 630 } 631 } 632 return aRet; 633 } 634 /* -----------------------------29.08.00 17:28-------------------------------- 635 636 ---------------------------------------------------------------------------*/ 637 sal_Bool ConfigItem::PutProperties( const Sequence< OUString >& rNames, 638 const Sequence< Any>& rValues) 639 { 640 ValueCounter_Impl aCounter(pImpl->nInValueChange); 641 Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree(); 642 Reference<XNameReplace> xTopNodeReplace(xHierarchyAccess, UNO_QUERY); 643 sal_Bool bRet = xHierarchyAccess.is() && xTopNodeReplace.is(); 644 if(bRet) 645 { 646 Sequence< OUString > lNames ; 647 Sequence< Any > lValues ; 648 const OUString* pNames = NULL ; 649 const Any* pValues = NULL ; 650 sal_Int32 nNameCount ; 651 if(( pImpl->nMode & CONFIG_MODE_ALL_LOCALES ) == CONFIG_MODE_ALL_LOCALES ) 652 { 653 // If ConfigItem works in "ALL_LOCALES"-mode ... we must support a Sequence< PropertyValue > 654 // as value of an localized configuration entry! 655 // How we can do that? 656 // We must split all PropertyValues to "Sequence< OUString >" AND "Sequence< Any >"! 657 impl_unpackLocalizedProperties( rNames, rValues, lNames, lValues ); 658 pNames = lNames.getConstArray (); 659 pValues = lValues.getConstArray (); 660 nNameCount = lNames.getLength (); 661 } 662 else 663 { 664 // This is the normal mode ... 665 // Use given input lists directly. 666 pNames = rNames.getConstArray (); 667 pValues = rValues.getConstArray (); 668 nNameCount = rNames.getLength (); 669 } 670 for(int i = 0; i < nNameCount; i++) 671 { 672 if(pImpl->pManager->IsLocalConfigProvider() && lcl_IsLocalProperty(sSubTree, pNames[i])) 673 { 674 OUString sProperty(sSubTree); 675 sProperty += C2U("/"); 676 sProperty += pNames[i]; 677 pImpl->pManager->PutLocalProperty(sProperty, pValues[i]); 678 } 679 else 680 { 681 try 682 { 683 OUString sNode, sProperty; 684 if (splitLastFromConfigurationPath(pNames[i],sNode, sProperty)) 685 { 686 Any aNode = xHierarchyAccess->getByHierarchicalName(sNode); 687 688 Reference<XNameAccess> xNodeAcc; 689 aNode >>= xNodeAcc; 690 Reference<XNameReplace> xNodeReplace(xNodeAcc, UNO_QUERY); 691 Reference<XNameContainer> xNodeCont (xNodeAcc, UNO_QUERY); 692 693 sal_Bool bExist = (xNodeAcc.is() && xNodeAcc->hasByName(sProperty)); 694 if (bExist && xNodeReplace.is()) 695 xNodeReplace->replaceByName(sProperty, pValues[i]); 696 else 697 if (!bExist && xNodeCont.is()) 698 xNodeCont->insertByName(sProperty, pValues[i]); 699 else 700 bRet = sal_False; 701 } 702 else //direct value 703 { 704 xTopNodeReplace->replaceByName(sProperty, pValues[i]); 705 } 706 } 707 CATCH_INFO("Exception from PutProperties: "); 708 } 709 } 710 try 711 { 712 Reference<XChangesBatch> xBatch(xHierarchyAccess, UNO_QUERY); 713 xBatch->commitChanges(); 714 } 715 CATCH_INFO("Exception from commitChanges(): ") 716 } 717 718 return bRet; 719 } 720 /* -----------------------------08.12.05 15:27-------------------------------- 721 722 ---------------------------------------------------------------------------*/ 723 void ConfigItem::DisableNotification() 724 { 725 OSL_ENSURE( xChangeLstnr.is(), "ConfigItem::DisableNotification: notifications not enabled currently!" ); 726 RemoveChangesListener(); 727 } 728 /* -----------------------------29.08.00 16:19-------------------------------- 729 730 ---------------------------------------------------------------------------*/ 731 sal_Bool ConfigItem::EnableNotification(const Sequence< OUString >& rNames, 732 sal_Bool bEnableInternalNotification ) 733 734 { 735 OSL_ENSURE(0 == (pImpl->nMode&CONFIG_MODE_RELEASE_TREE), "notification in CONFIG_MODE_RELEASE_TREE mode not possible"); 736 pImpl->bEnableInternalNotification = bEnableInternalNotification; 737 Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree(); 738 Reference<XChangesNotifier> xChgNot(xHierarchyAccess, UNO_QUERY); 739 if(!xChgNot.is()) 740 return sal_False; 741 742 OSL_ENSURE(!xChangeLstnr.is(), "EnableNotification already called"); 743 if(xChangeLstnr.is()) 744 xChgNot->removeChangesListener( xChangeLstnr ); 745 sal_Bool bRet = sal_True; 746 747 try 748 { 749 xChangeLstnr = new ConfigChangeListener_Impl(*this, rNames); 750 xChgNot->addChangesListener( xChangeLstnr ); 751 } 752 catch(RuntimeException& ) 753 { 754 bRet = sal_False; 755 } 756 return bRet; 757 } 758 /* -----------------------------29.08.00 16:47-------------------------------- 759 760 ---------------------------------------------------------------------------*/ 761 void ConfigItem::RemoveChangesListener() 762 { 763 Reference<XChangesNotifier> xChgNot(m_xHierarchyAccess, UNO_QUERY); 764 if(xChgNot.is() && xChangeLstnr.is()) 765 { 766 try 767 { 768 xChgNot->removeChangesListener( xChangeLstnr ); 769 xChangeLstnr = 0; 770 } 771 catch(Exception & ) 772 { 773 } 774 } 775 } 776 /* -----------------------------10.07.00 -------------------------------- 777 778 ---------------------------------------------------------------------------*/ 779 void lcl_normalizeLocalNames(Sequence< OUString >& _rNames, ConfigNameFormat _eFormat, Reference<XInterface> const& _xParentNode) 780 { 781 switch (_eFormat) 782 { 783 case CONFIG_NAME_LOCAL_NAME: 784 // unaltered - this is our input format 785 break; 786 787 case CONFIG_NAME_FULL_PATH: 788 { 789 Reference<XHierarchicalName> xFormatter(_xParentNode, UNO_QUERY); 790 if (xFormatter.is()) 791 { 792 OUString * pNames = _rNames.getArray(); 793 for(int i = 0; i<_rNames.getLength(); ++i) 794 try 795 { 796 pNames[i] = xFormatter->composeHierarchicalName(pNames[i]); 797 } 798 CATCH_INFO("Exception from composeHierarchicalName(): ") 799 break; 800 } 801 } 802 OSL_ENSURE(false, "Cannot create absolute paths: missing interface"); 803 // make local paths instaed 804 805 case CONFIG_NAME_LOCAL_PATH: 806 { 807 Reference<XTemplateContainer> xTypeContainer(_xParentNode, UNO_QUERY); 808 if (xTypeContainer.is()) 809 { 810 OUString sTypeName = xTypeContainer->getElementTemplateName(); 811 sTypeName = sTypeName.copy(sTypeName.lastIndexOf('/')+1); 812 813 OUString * pNames = _rNames.getArray(); 814 for(int i = 0; i<_rNames.getLength(); ++i) 815 { 816 pNames[i] = wrapConfigurationElementName(pNames[i],sTypeName); 817 } 818 } 819 else 820 { 821 static const OUString sSetService(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.configuration.SetAccess")); 822 Reference<XServiceInfo> xSVI(_xParentNode, UNO_QUERY); 823 if (xSVI.is() && xSVI->supportsService(sSetService)) 824 { 825 OUString * pNames = _rNames.getArray(); 826 for(int i = 0; i<_rNames.getLength(); ++i) 827 { 828 pNames[i] = wrapConfigurationElementName(pNames[i]); 829 } 830 } 831 } 832 } 833 break; 834 835 case CONFIG_NAME_PLAINTEXT_NAME: 836 { 837 Reference<XStringEscape> xEscaper(_xParentNode, UNO_QUERY); 838 if (xEscaper.is()) 839 { 840 OUString * pNames = _rNames.getArray(); 841 for(int i = 0; i<_rNames.getLength(); ++i) 842 try 843 { 844 pNames[i] = xEscaper->unescapeString(pNames[i]); 845 } 846 CATCH_INFO("Exception from unescapeString(): ") 847 } 848 } 849 break; 850 851 } 852 } 853 /* -----------------------------10.07.00 -------------------------------- 854 855 ---------------------------------------------------------------------------*/ 856 Sequence< OUString > ConfigItem::GetNodeNames(const OUString& rNode) 857 { 858 ConfigNameFormat const eDefaultFormat = CONFIG_NAME_LOCAL_NAME; // CONFIG_NAME_DEFAULT; 859 860 return GetNodeNames(rNode, eDefaultFormat); 861 } 862 /* -----------------------------15.09.00 12:06-------------------------------- 863 864 ---------------------------------------------------------------------------*/ 865 Sequence< OUString > ConfigItem::GetNodeNames(const OUString& rNode, ConfigNameFormat eFormat) 866 { 867 Sequence< OUString > aRet; 868 Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree(); 869 if(xHierarchyAccess.is()) 870 { 871 try 872 { 873 Reference<XNameAccess> xCont; 874 if(rNode.getLength()) 875 { 876 Any aNode = xHierarchyAccess->getByHierarchicalName(rNode); 877 aNode >>= xCont; 878 } 879 else 880 xCont = Reference<XNameAccess> (xHierarchyAccess, UNO_QUERY); 881 if(xCont.is()) 882 { 883 aRet = xCont->getElementNames(); 884 lcl_normalizeLocalNames(aRet,eFormat,xCont); 885 } 886 887 } 888 CATCH_INFO("Exception from GetNodeNames: "); 889 } 890 return aRet; 891 } 892 /* -----------------------------15.09.00 15:52-------------------------------- 893 894 ---------------------------------------------------------------------------*/ 895 sal_Bool ConfigItem::ClearNodeSet(const OUString& rNode) 896 { 897 ValueCounter_Impl aCounter(pImpl->nInValueChange); 898 sal_Bool bRet = sal_False; 899 Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree(); 900 if(xHierarchyAccess.is()) 901 { 902 try 903 { 904 Reference<XNameContainer> xCont; 905 if(rNode.getLength()) 906 { 907 Any aNode = xHierarchyAccess->getByHierarchicalName(rNode); 908 aNode >>= xCont; 909 } 910 else 911 xCont = Reference<XNameContainer> (xHierarchyAccess, UNO_QUERY); 912 if(!xCont.is()) 913 return sal_False; 914 Sequence< OUString > aNames = xCont->getElementNames(); 915 const OUString* pNames = aNames.getConstArray(); 916 Reference<XChangesBatch> xBatch(xHierarchyAccess, UNO_QUERY); 917 for(sal_Int32 i = 0; i < aNames.getLength(); i++) 918 { 919 try 920 { 921 xCont->removeByName(pNames[i]); 922 } 923 CATCH_INFO("Exception from removeByName(): ") 924 } 925 xBatch->commitChanges(); 926 bRet = sal_True; 927 } 928 CATCH_INFO("Exception from ClearNodeSet") 929 } 930 return bRet; 931 } 932 /* -----------------------------24.11.00 10:58-------------------------------- 933 934 ---------------------------------------------------------------------------*/ 935 sal_Bool ConfigItem::ClearNodeElements(const OUString& rNode, Sequence< OUString >& rElements) 936 { 937 ValueCounter_Impl aCounter(pImpl->nInValueChange); 938 sal_Bool bRet = sal_False; 939 Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree(); 940 if(xHierarchyAccess.is()) 941 { 942 const OUString* pElements = rElements.getConstArray(); 943 try 944 { 945 Reference<XNameContainer> xCont; 946 if(rNode.getLength()) 947 { 948 Any aNode = xHierarchyAccess->getByHierarchicalName(rNode); 949 aNode >>= xCont; 950 } 951 else 952 xCont = Reference<XNameContainer> (xHierarchyAccess, UNO_QUERY); 953 if(!xCont.is()) 954 return sal_False; 955 try 956 { 957 for(sal_Int32 nElement = 0; nElement < rElements.getLength(); nElement++) 958 { 959 xCont->removeByName(pElements[nElement]); 960 } 961 Reference<XChangesBatch> xBatch(xHierarchyAccess, UNO_QUERY); 962 xBatch->commitChanges(); 963 } 964 CATCH_INFO("Exception from commitChanges(): ") 965 bRet = sal_True; 966 } 967 CATCH_INFO("Exception from GetNodeNames: ") 968 } 969 return bRet; 970 } 971 //---------------------------------------------------------------------------- 972 static inline 973 OUString lcl_extractSetPropertyName( const OUString& rInPath, const OUString& rPrefix ) 974 { 975 OUString const sSubPath = dropPrefixFromConfigurationPath( rInPath, rPrefix); 976 return extractFirstFromConfigurationPath( sSubPath ); 977 } 978 //---------------------------------------------------------------------------- 979 static 980 Sequence< OUString > lcl_extractSetPropertyNames( const Sequence< PropertyValue >& rValues, const OUString& rPrefix ) 981 { 982 const PropertyValue* pProperties = rValues.getConstArray(); 983 984 Sequence< OUString > aSubNodeNames(rValues.getLength()); 985 OUString* pSubNodeNames = aSubNodeNames.getArray(); 986 987 OUString sLastSubNode; 988 sal_Int32 nSubIndex = 0; 989 990 for(sal_Int32 i = 0; i < rValues.getLength(); i++) 991 { 992 OUString const sSubPath = dropPrefixFromConfigurationPath( pProperties[i].Name, rPrefix); 993 OUString const sSubNode = extractFirstFromConfigurationPath( sSubPath ); 994 995 if(sLastSubNode != sSubNode) 996 { 997 pSubNodeNames[nSubIndex++] = sSubNode; 998 } 999 1000 sLastSubNode = sSubNode; 1001 } 1002 aSubNodeNames.realloc(nSubIndex); 1003 1004 return aSubNodeNames; 1005 } 1006 /* -----------------------------15.09.00 15:52-------------------------------- 1007 add or change properties 1008 ---------------------------------------------------------------------------*/ 1009 sal_Bool ConfigItem::SetSetProperties( 1010 const OUString& rNode, Sequence< PropertyValue > rValues) 1011 { 1012 ValueCounter_Impl aCounter(pImpl->nInValueChange); 1013 sal_Bool bRet = sal_True; 1014 Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree(); 1015 if(xHierarchyAccess.is()) 1016 { 1017 Reference<XChangesBatch> xBatch(xHierarchyAccess, UNO_QUERY); 1018 try 1019 { 1020 Reference<XNameContainer> xCont; 1021 if(rNode.getLength()) 1022 { 1023 Any aNode = xHierarchyAccess->getByHierarchicalName(rNode); 1024 aNode >>= xCont; 1025 } 1026 else 1027 xCont = Reference<XNameContainer> (xHierarchyAccess, UNO_QUERY); 1028 if(!xCont.is()) 1029 return sal_False; 1030 1031 Reference<XSingleServiceFactory> xFac(xCont, UNO_QUERY); 1032 1033 if(xFac.is()) 1034 { 1035 const Sequence< OUString > aSubNodeNames = lcl_extractSetPropertyNames(rValues, rNode); 1036 1037 const sal_Int32 nSubNodeCount = aSubNodeNames.getLength(); 1038 1039 for(sal_Int32 j = 0; j <nSubNodeCount ; j++) 1040 { 1041 if(!xCont->hasByName(aSubNodeNames[j])) 1042 { 1043 Reference<XInterface> xInst = xFac->createInstance(); 1044 Any aVal; aVal <<= xInst; 1045 xCont->insertByName(aSubNodeNames[j], aVal); 1046 } 1047 //set values 1048 } 1049 try 1050 { 1051 xBatch->commitChanges(); 1052 } 1053 CATCH_INFO("Exception from commitChanges(): ") 1054 1055 const PropertyValue* pProperties = rValues.getConstArray(); 1056 1057 Sequence< OUString > aSetNames(rValues.getLength()); 1058 OUString* pSetNames = aSetNames.getArray(); 1059 1060 Sequence< Any> aSetValues(rValues.getLength()); 1061 Any* pSetValues = aSetValues.getArray(); 1062 1063 sal_Bool bEmptyNode = rNode.getLength() == 0; 1064 for(sal_Int32 k = 0; k < rValues.getLength(); k++) 1065 { 1066 pSetNames[k] = pProperties[k].Name.copy( bEmptyNode ? 1 : 0); 1067 pSetValues[k] = pProperties[k].Value; 1068 } 1069 bRet = PutProperties(aSetNames, aSetValues); 1070 } 1071 else 1072 { 1073 //if no factory is available then the node contains basic data elements 1074 const PropertyValue* pValues = rValues.getConstArray(); 1075 for(int nValue = 0; nValue < rValues.getLength();nValue++) 1076 { 1077 try 1078 { 1079 OUString sSubNode = lcl_extractSetPropertyName( pValues[nValue].Name, rNode ); 1080 1081 if(xCont->hasByName(sSubNode)) 1082 xCont->replaceByName(sSubNode, pValues[nValue].Value); 1083 else 1084 xCont->insertByName(sSubNode, pValues[nValue].Value); 1085 1086 OSL_ENSURE( xHierarchyAccess->hasByHierarchicalName(pValues[nValue].Name), 1087 "Invalid config path" ); 1088 } 1089 CATCH_INFO("Exception form insert/replaceByName(): ") 1090 } 1091 xBatch->commitChanges(); 1092 } 1093 } 1094 #ifdef DBG_UTIL 1095 catch(Exception& rEx) 1096 { 1097 lcl_CFG_DBG_EXCEPTION("Exception from SetSetProperties: ", rEx); 1098 #else 1099 catch(Exception&) 1100 { 1101 #endif 1102 bRet = sal_False; 1103 } 1104 } 1105 return bRet; 1106 } 1107 /* -----------------------------15.09.00 15:52-------------------------------- 1108 1109 ---------------------------------------------------------------------------*/ 1110 sal_Bool ConfigItem::ReplaceSetProperties( 1111 const OUString& rNode, Sequence< PropertyValue > rValues) 1112 { 1113 ValueCounter_Impl aCounter(pImpl->nInValueChange); 1114 sal_Bool bRet = sal_True; 1115 Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree(); 1116 if(xHierarchyAccess.is()) 1117 { 1118 Reference<XChangesBatch> xBatch(xHierarchyAccess, UNO_QUERY); 1119 try 1120 { 1121 Reference<XNameContainer> xCont; 1122 if(rNode.getLength()) 1123 { 1124 Any aNode = xHierarchyAccess->getByHierarchicalName(rNode); 1125 aNode >>= xCont; 1126 } 1127 else 1128 xCont = Reference<XNameContainer> (xHierarchyAccess, UNO_QUERY); 1129 if(!xCont.is()) 1130 return sal_False; 1131 1132 // JB: Change: now the same name handling for sets of simple values 1133 const Sequence< OUString > aSubNodeNames = lcl_extractSetPropertyNames(rValues, rNode); 1134 const OUString* pSubNodeNames = aSubNodeNames.getConstArray(); 1135 const sal_Int32 nSubNodeCount = aSubNodeNames.getLength(); 1136 1137 Reference<XSingleServiceFactory> xFac(xCont, UNO_QUERY); 1138 const bool isSimpleValueSet = !xFac.is(); 1139 1140 //remove unknown members first 1141 { 1142 const Sequence<OUString> aContainerSubNodes = xCont->getElementNames(); 1143 const OUString* pContainerSubNodes = aContainerSubNodes.getConstArray(); 1144 1145 for(sal_Int32 nContSub = 0; nContSub < aContainerSubNodes.getLength(); nContSub++) 1146 { 1147 sal_Bool bFound = sal_False; 1148 for(sal_Int32 j = 0; j < nSubNodeCount; j++) 1149 { 1150 if(pSubNodeNames[j] == pContainerSubNodes[nContSub]) 1151 { 1152 bFound = sal_True; 1153 break; 1154 } 1155 } 1156 if(!bFound) 1157 try 1158 { 1159 xCont->removeByName(pContainerSubNodes[nContSub]); 1160 } 1161 catch (Exception & ) 1162 { 1163 if (isSimpleValueSet) 1164 try 1165 { 1166 // #i37322#: fallback action: replace with <void/> 1167 xCont->replaceByName(pContainerSubNodes[nContSub], Any()); 1168 // fallback successful: continue looping 1169 continue; 1170 } 1171 catch (Exception &) 1172 {} // propagate original exception, if fallback fails 1173 1174 throw; 1175 } 1176 } 1177 try { xBatch->commitChanges(); } 1178 CATCH_INFO("Exception from commitChanges(): ") 1179 } 1180 1181 if(xFac.is()) // !isSimpleValueSet 1182 { 1183 for(sal_Int32 j = 0; j < nSubNodeCount; j++) 1184 { 1185 if(!xCont->hasByName(pSubNodeNames[j])) 1186 { 1187 //create if not available 1188 Reference<XInterface> xInst = xFac->createInstance(); 1189 Any aVal; aVal <<= xInst; 1190 xCont->insertByName(pSubNodeNames[j], aVal); 1191 } 1192 } 1193 try { xBatch->commitChanges(); } 1194 CATCH_INFO("Exception from commitChanges(): ") 1195 1196 const PropertyValue* pProperties = rValues.getConstArray(); 1197 1198 Sequence< OUString > aSetNames(rValues.getLength()); 1199 OUString* pSetNames = aSetNames.getArray(); 1200 1201 Sequence< Any> aSetValues(rValues.getLength()); 1202 Any* pSetValues = aSetValues.getArray(); 1203 1204 sal_Bool bEmptyNode = rNode.getLength() == 0; 1205 for(sal_Int32 k = 0; k < rValues.getLength(); k++) 1206 { 1207 pSetNames[k] = pProperties[k].Name.copy( bEmptyNode ? 1 : 0); 1208 pSetValues[k] = pProperties[k].Value; 1209 } 1210 bRet = PutProperties(aSetNames, aSetValues); 1211 } 1212 else 1213 { 1214 const PropertyValue* pValues = rValues.getConstArray(); 1215 1216 //if no factory is available then the node contains basic data elements 1217 for(int nValue = 0; nValue < rValues.getLength();nValue++) 1218 { 1219 try 1220 { 1221 OUString sSubNode = lcl_extractSetPropertyName( pValues[nValue].Name, rNode ); 1222 1223 if(xCont->hasByName(sSubNode)) 1224 xCont->replaceByName(sSubNode, pValues[nValue].Value); 1225 else 1226 xCont->insertByName(sSubNode, pValues[nValue].Value); 1227 } 1228 CATCH_INFO("Exception from insert/replaceByName(): "); 1229 } 1230 xBatch->commitChanges(); 1231 } 1232 } 1233 #ifdef DBG_UTIL 1234 catch(Exception& rEx) 1235 { 1236 lcl_CFG_DBG_EXCEPTION("Exception from ReplaceSetProperties: ", rEx); 1237 #else 1238 catch(Exception&) 1239 { 1240 #endif 1241 bRet = sal_False; 1242 } 1243 } 1244 return bRet; 1245 } 1246 /* -----------------------------07.05.01 12:15-------------------------------- 1247 1248 ---------------------------------------------------------------------------*/ 1249 sal_Bool ConfigItem::getUniqueSetElementName( const ::rtl::OUString& _rSetNode, ::rtl::OUString& _rName) 1250 { 1251 ::rtl::OUString sNewElementName; 1252 Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree(); 1253 sal_Bool bRet = sal_False; 1254 if(xHierarchyAccess.is()) 1255 { 1256 try 1257 { 1258 Reference< XNameAccess > xSetNode; 1259 xHierarchyAccess->getByHierarchicalName(_rSetNode) >>= xSetNode; 1260 if (xSetNode.is()) 1261 { 1262 const sal_uInt32 nPrime = 65521; // a prime number 1263 const sal_uInt32 nPrimeLess2 = nPrime - 2; 1264 sal_uInt32 nEngendering = (rand() % nPrimeLess2) + 2; // the engendering of the field 1265 1266 // the element which will loop through the field 1267 sal_uInt32 nFieldElement = nEngendering; 1268 1269 for (; 1 != nFieldElement; nFieldElement = (nFieldElement * nEngendering) % nPrime) 1270 { 1271 ::rtl::OUString sThisRoundTrial = _rName; 1272 sThisRoundTrial += ::rtl::OUString::valueOf((sal_Int32)nFieldElement); 1273 1274 if (!xSetNode->hasByName(sThisRoundTrial)) 1275 { 1276 _rName = sThisRoundTrial; 1277 bRet = sal_True; 1278 break; 1279 } 1280 } 1281 } 1282 } 1283 CATCH_INFO("Exception from getUniqueSetElementName(): ") 1284 } 1285 return bRet; 1286 } 1287 /* -----------------------------23.01.01 12:49-------------------------------- 1288 1289 ---------------------------------------------------------------------------*/ 1290 sal_Bool ConfigItem::AddNode(const rtl::OUString& rNode, const rtl::OUString& rNewNode) 1291 { 1292 ValueCounter_Impl aCounter(pImpl->nInValueChange); 1293 sal_Bool bRet = sal_True; 1294 Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree(); 1295 if(xHierarchyAccess.is()) 1296 { 1297 Reference<XChangesBatch> xBatch(xHierarchyAccess, UNO_QUERY); 1298 try 1299 { 1300 Reference<XNameContainer> xCont; 1301 if(rNode.getLength()) 1302 { 1303 Any aNode = xHierarchyAccess->getByHierarchicalName(rNode); 1304 aNode >>= xCont; 1305 } 1306 else 1307 xCont = Reference<XNameContainer> (xHierarchyAccess, UNO_QUERY); 1308 if(!xCont.is()) 1309 return sal_False; 1310 1311 Reference<XSingleServiceFactory> xFac(xCont, UNO_QUERY); 1312 1313 if(xFac.is()) 1314 { 1315 if(!xCont->hasByName(rNewNode)) 1316 { 1317 Reference<XInterface> xInst = xFac->createInstance(); 1318 Any aVal; aVal <<= xInst; 1319 xCont->insertByName(rNewNode, aVal); 1320 } 1321 try 1322 { 1323 xBatch->commitChanges(); 1324 } 1325 CATCH_INFO("Exception from commitChanges(): ") 1326 } 1327 else 1328 { 1329 //if no factory is available then the node contains basic data elements 1330 try 1331 { 1332 if(!xCont->hasByName(rNewNode)) 1333 xCont->insertByName(rNewNode, Any()); 1334 } 1335 CATCH_INFO("Exception from AddNode(): ") 1336 } 1337 xBatch->commitChanges(); 1338 } 1339 #ifdef DBG_UTIL 1340 catch(Exception& rEx) 1341 { 1342 lcl_CFG_DBG_EXCEPTION("Exception from AddNode(): ", rEx); 1343 #else 1344 catch(Exception&) 1345 { 1346 #endif 1347 bRet = sal_False; 1348 } 1349 } 1350 return bRet; 1351 } 1352 /* -----------------------------12.02.01 11:38-------------------------------- 1353 1354 ---------------------------------------------------------------------------*/ 1355 sal_Int16 ConfigItem::GetMode() const 1356 { 1357 return pImpl->nMode; 1358 } 1359 /* -----------------------------12.02.01 13:31-------------------------------- 1360 1361 ---------------------------------------------------------------------------*/ 1362 void ConfigItem::SetModified() 1363 { 1364 pImpl->bIsModified = sal_True; 1365 } 1366 /* -----------------------------05.05.01 14:07-------------------------------- 1367 1368 ---------------------------------------------------------------------------*/ 1369 void ConfigItem::ClearModified() 1370 { 1371 pImpl->bIsModified = sal_False; 1372 } 1373 /* -----------------------------12.02.01 13:31-------------------------------- 1374 1375 ---------------------------------------------------------------------------*/ 1376 sal_Bool ConfigItem::IsModified() const 1377 { 1378 return pImpl->bIsModified; 1379 } 1380 /* -----------------------------12.02.01 13:33-------------------------------- 1381 1382 ---------------------------------------------------------------------------*/ 1383 sal_Bool ConfigItem::IsInValueChange() const 1384 { 1385 return pImpl->nInValueChange > 0; 1386 } 1387 /* -----------------------------21.06.01 12:26-------------------------------- 1388 1389 ---------------------------------------------------------------------------*/ 1390 Reference< XHierarchicalNameAccess> ConfigItem::GetTree() 1391 { 1392 Reference< XHierarchicalNameAccess> xRet; 1393 if(!m_xHierarchyAccess.is()) 1394 xRet = pImpl->pManager->AcquireTree(*this); 1395 else 1396 xRet = m_xHierarchyAccess; 1397 OSL_ENSURE(xRet.is(), "AcquireTree failed"); 1398 return xRet; 1399 } 1400 /* -----------------------------22.06.01 08:42-------------------------------- 1401 1402 ---------------------------------------------------------------------------*/ 1403 void ConfigItem::LockTree() 1404 { 1405 OSL_ENSURE(0 != (pImpl->nMode&CONFIG_MODE_RELEASE_TREE), "call LockTree in CONFIG_MODE_RELEASE_TREE mode, only"); 1406 m_xHierarchyAccess = GetTree(); 1407 } 1408 /* -----------------------------22.06.01 08:42-------------------------------- 1409 1410 ---------------------------------------------------------------------------*/ 1411 void ConfigItem::UnlockTree() 1412 { 1413 OSL_ENSURE(0 != (pImpl->nMode&CONFIG_MODE_RELEASE_TREE), "call UnlockTree in CONFIG_MODE_RELEASE_TREE mode, only"); 1414 if(0 != (pImpl->nMode&CONFIG_MODE_RELEASE_TREE)) 1415 m_xHierarchyAccess = 0; 1416 } 1417 1418 1419