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