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 : /** Attention: stl headers must(!) be included at first. Otherwhise it can make trouble
21 : with solaris headers ...
22 : */
23 : #include <vector>
24 : #include <services/pathsettings.hxx>
25 : #include <threadhelp/readguard.hxx>
26 : #include <threadhelp/writeguard.hxx>
27 : #include <services.h>
28 :
29 : #include "helper/mischelper.hxx"
30 :
31 : #include <com/sun/star/beans/Property.hpp>
32 : #include <com/sun/star/beans/XProperty.hpp>
33 : #include <com/sun/star/beans/PropertyAttribute.hpp>
34 : #include <com/sun/star/container/XContainer.hpp>
35 : #include <com/sun/star/beans/XPropertySet.hpp>
36 : #include <com/sun/star/util/XChangesNotifier.hpp>
37 : #include <com/sun/star/util/PathSubstitution.hpp>
38 :
39 : #include <tools/urlobj.hxx>
40 : #include <rtl/ustrbuf.hxx>
41 : #include <rtl/logfile.hxx>
42 :
43 : #include <comphelper/configurationhelper.hxx>
44 : #include <comphelper/processfactory.hxx>
45 : #include <unotools/configpaths.hxx>
46 :
47 : #include <fwkdllapi.h>
48 :
49 :
50 : #define CFGPROP_USERPATHS rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("UserPaths"))
51 : #define CFGPROP_WRITEPATH rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("WritePath"))
52 :
53 : /*
54 : 0 : old style "Template" string using ";" as seperator
55 : 1 : internal paths "Template_internal" string list
56 : 2 : user paths "Template_user" string list
57 : 3 : write path "Template_write" string
58 : */
59 :
60 : #define POSTFIX_INTERNAL_PATHS rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("_internal"))
61 : #define POSTFIX_USER_PATHS rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("_user"))
62 : #define POSTFIX_WRITE_PATH rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("_writable"))
63 :
64 : const sal_Int32 IDGROUP_OLDSTYLE = 0;
65 : const sal_Int32 IDGROUP_INTERNAL_PATHS = 1;
66 : const sal_Int32 IDGROUP_USER_PATHS = 2;
67 : const sal_Int32 IDGROUP_WRITE_PATH = 3;
68 :
69 : const sal_Int32 IDGROUP_COUNT = 4;
70 :
71 1507 : sal_Int32 impl_getPropGroup(sal_Int32 nID)
72 : {
73 1507 : return (nID % IDGROUP_COUNT);
74 : }
75 :
76 :
77 : namespace framework
78 : {
79 :
80 : //-----------------------------------------------------------------------------
81 : // XInterface, XTypeProvider, XServiceInfo
82 :
83 608 : DEFINE_XINTERFACE_7 ( PathSettings ,
84 : OWeakObject ,
85 : DIRECT_INTERFACE ( css::lang::XTypeProvider ),
86 : DIRECT_INTERFACE ( css::lang::XServiceInfo ),
87 : DERIVED_INTERFACE( css::lang::XEventListener, css::util::XChangesListener),
88 : DIRECT_INTERFACE ( css::util::XChangesListener ),
89 : DIRECT_INTERFACE ( css::beans::XPropertySet ),
90 : DIRECT_INTERFACE ( css::beans::XFastPropertySet ),
91 : DIRECT_INTERFACE ( css::beans::XMultiPropertySet )
92 : )
93 :
94 0 : DEFINE_XTYPEPROVIDER_7 ( PathSettings ,
95 : css::lang::XTypeProvider ,
96 : css::lang::XServiceInfo ,
97 : css::lang::XEventListener ,
98 : css::util::XChangesListener ,
99 : css::beans::XPropertySet ,
100 : css::beans::XFastPropertySet ,
101 : css::beans::XMultiPropertySet
102 : )
103 :
104 95 : DEFINE_XSERVICEINFO_ONEINSTANCESERVICE ( PathSettings ,
105 : ::cppu::OWeakObject ,
106 : SERVICENAME_PATHSETTINGS ,
107 : IMPLEMENTATIONNAME_PATHSETTINGS
108 : )
109 :
110 19 : DEFINE_INIT_SERVICE ( PathSettings,
111 : {
112 : /*Attention
113 : I think we don't need any mutex or lock here ... because we are called by our own static method impl_createInstance()
114 : to create a new instance of this class by our own supported service factory.
115 : see macro DEFINE_XSERVICEINFO_MULTISERVICE and "impl_initService()" for further informations!
116 : */
117 :
118 : // fill cache
119 : impl_readAll();
120 : }
121 : )
122 :
123 : //-----------------------------------------------------------------------------
124 19 : PathSettings::PathSettings( const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR )
125 : // Init baseclasses first
126 : // Attention: Don't change order of initialization!
127 : // ThreadHelpBase is a struct with a lock as member. We can't use a lock as direct member!
128 : // We must garant right initialization and a valid value of this to initialize other baseclasses!
129 : : ThreadHelpBase()
130 19 : , ::cppu::OBroadcastHelperVar< ::cppu::OMultiTypeInterfaceContainerHelper, ::cppu::OMultiTypeInterfaceContainerHelper::keyType >(m_aLock.getShareableOslMutex())
131 : , ::cppu::OPropertySetHelper(*(static_cast< ::cppu::OBroadcastHelper* >(this)))
132 : , ::cppu::OWeakObject()
133 : // Init member
134 : , m_xSMGR (xSMGR)
135 : , m_pPropHelp(0 )
136 38 : , m_bIgnoreEvents(sal_False)
137 : {
138 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "PathSettings::PathSettings" );
139 19 : }
140 :
141 : //-----------------------------------------------------------------------------
142 57 : PathSettings::~PathSettings()
143 : {
144 19 : css::uno::Reference< css::util::XChangesNotifier > xBroadcaster(m_xCfgNew, css::uno::UNO_QUERY);
145 19 : if (xBroadcaster.is())
146 19 : xBroadcaster->removeChangesListener(m_xCfgNewListener);
147 19 : if (m_pPropHelp)
148 19 : delete m_pPropHelp;
149 38 : }
150 :
151 : //-----------------------------------------------------------------------------
152 0 : void SAL_CALL PathSettings::changesOccurred(const css::util::ChangesEvent& aEvent)
153 : throw (css::uno::RuntimeException)
154 : {
155 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "PathSettings::changesOccurred" );
156 :
157 0 : sal_Int32 c = aEvent.Changes.getLength();
158 0 : sal_Int32 i = 0;
159 0 : sal_Bool bUpdateDescriptor = sal_False;
160 :
161 0 : for (i=0; i<c; ++i)
162 : {
163 0 : const css::util::ElementChange& aChange = aEvent.Changes[i];
164 :
165 0 : ::rtl::OUString sChanged;
166 0 : aChange.Accessor >>= sChanged;
167 :
168 0 : ::rtl::OUString sPath = ::utl::extractFirstFromConfigurationPath(sChanged);
169 0 : if (!sPath.isEmpty())
170 : {
171 0 : PathSettings::EChangeOp eOp = impl_updatePath(sPath, sal_True);
172 0 : if (
173 : (eOp == PathSettings::E_ADDED ) ||
174 : (eOp == PathSettings::E_REMOVED)
175 : )
176 0 : bUpdateDescriptor = sal_True;
177 : }
178 0 : }
179 :
180 0 : if (bUpdateDescriptor)
181 0 : impl_rebuildPropertyDescriptor();
182 0 : }
183 :
184 : //-----------------------------------------------------------------------------
185 0 : void SAL_CALL PathSettings::disposing(const css::lang::EventObject& aSource)
186 : throw(css::uno::RuntimeException)
187 : {
188 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "PathSettings::disposing" );
189 0 : WriteGuard aWriteLock(m_aLock);
190 :
191 0 : if (aSource.Source == m_xCfgNew)
192 0 : m_xCfgNew.clear();
193 :
194 0 : aWriteLock.unlock();
195 0 : }
196 :
197 : //-----------------------------------------------------------------------------
198 19 : void PathSettings::impl_readAll()
199 : {
200 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "PathSettings::impl_readAll" );
201 : RTL_LOGFILE_CONTEXT(aLog, "framework (as96863) ::PathSettings::load config (all)");
202 :
203 : try
204 : {
205 : // TODO think about me
206 19 : css::uno::Reference< css::container::XNameAccess > xCfg = fa_getCfgNew();
207 19 : css::uno::Sequence< ::rtl::OUString > lPaths = xCfg->getElementNames();
208 :
209 19 : sal_Int32 c = lPaths.getLength();
210 475 : for (sal_Int32 i = 0; i < c; ++i)
211 : {
212 456 : const ::rtl::OUString& sPath = lPaths[i];
213 456 : impl_updatePath(sPath, sal_False);
214 19 : }
215 : }
216 0 : catch(const css::uno::RuntimeException& )
217 : {
218 : }
219 :
220 19 : impl_rebuildPropertyDescriptor();
221 19 : }
222 :
223 : //-----------------------------------------------------------------------------
224 : // NO substitution here ! It's done outside ...
225 456 : OUStringList PathSettings::impl_readOldFormat(const ::rtl::OUString& sPath)
226 : {
227 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "PathSettings::impl_readOldFormat" );
228 456 : css::uno::Reference< css::container::XNameAccess > xCfg( fa_getCfgOld() );
229 456 : OUStringList aPathVal;
230 :
231 456 : if( xCfg->hasByName(sPath) )
232 : {
233 437 : css::uno::Any aVal( xCfg->getByName(sPath) );
234 :
235 437 : ::rtl::OUString sStringVal;
236 437 : css::uno::Sequence< ::rtl::OUString > lStringListVal;
237 :
238 437 : if (aVal >>= sStringVal)
239 : {
240 304 : aPathVal.push_back(sStringVal);
241 : }
242 133 : else if (aVal >>= lStringListVal)
243 : {
244 133 : aPathVal << lStringListVal;
245 437 : }
246 : }
247 :
248 456 : return aPathVal;
249 : }
250 :
251 : //-----------------------------------------------------------------------------
252 : // NO substitution here ! It's done outside ...
253 456 : PathSettings::PathInfo PathSettings::impl_readNewFormat(const ::rtl::OUString& sPath)
254 : {
255 456 : const ::rtl::OUString CFGPROP_INTERNALPATHS(RTL_CONSTASCII_USTRINGPARAM("InternalPaths"));
256 456 : const ::rtl::OUString CFGPROP_ISSINGLEPATH(RTL_CONSTASCII_USTRINGPARAM("IsSinglePath"));
257 :
258 456 : css::uno::Reference< css::container::XNameAccess > xCfg = fa_getCfgNew();
259 :
260 : // get access to the "queried" path
261 456 : css::uno::Reference< css::container::XNameAccess > xPath;
262 456 : xCfg->getByName(sPath) >>= xPath;
263 :
264 456 : PathSettings::PathInfo aPathVal;
265 :
266 : // read internal path list
267 456 : css::uno::Reference< css::container::XNameAccess > xIPath;
268 456 : xPath->getByName(CFGPROP_INTERNALPATHS) >>= xIPath;
269 456 : aPathVal.lInternalPaths << xIPath->getElementNames();
270 :
271 : // read user defined path list
272 456 : aPathVal.lUserPaths << xPath->getByName(CFGPROP_USERPATHS);
273 :
274 : // read the writeable path
275 456 : xPath->getByName(CFGPROP_WRITEPATH) >>= aPathVal.sWritePath;
276 :
277 : // read state props
278 456 : xPath->getByName(CFGPROP_ISSINGLEPATH) >>= aPathVal.bIsSinglePath;
279 :
280 : // analyze finalized/mandatory states
281 456 : aPathVal.bIsReadonly = sal_False;
282 456 : css::uno::Reference< css::beans::XProperty > xInfo(xPath, css::uno::UNO_QUERY);
283 456 : if (xInfo.is())
284 : {
285 456 : css::beans::Property aInfo = xInfo->getAsProperty();
286 456 : sal_Bool bFinalized = ((aInfo.Attributes & css::beans::PropertyAttribute::READONLY ) == css::beans::PropertyAttribute::READONLY );
287 :
288 : // Note: Till we support finalized / mandatory on our API more in detail we handle
289 : // all states simple as READONLY ! But because all realy needed paths are "mandatory" by default
290 : // we have to handle "finalized" as the real "readonly" indicator .
291 456 : aPathVal.bIsReadonly = bFinalized;
292 : }
293 :
294 456 : return aPathVal;
295 : }
296 :
297 : //-----------------------------------------------------------------------------
298 0 : void PathSettings::impl_storePath(const PathSettings::PathInfo& aPath)
299 : {
300 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "PathSettings::impl_storePath" );
301 0 : m_bIgnoreEvents = sal_True;
302 :
303 0 : css::uno::Reference< css::container::XNameAccess > xCfgNew = fa_getCfgNew();
304 0 : css::uno::Reference< css::container::XNameAccess > xCfgOld = fa_getCfgOld();
305 :
306 : // try to replace path-parts with well known and uspported variables.
307 : // So an office can be moved easialy to another location without loosing
308 : // it's related paths.
309 0 : PathInfo aResubstPath(aPath);
310 0 : impl_subst(aResubstPath, sal_True);
311 :
312 : // update new configuration
313 0 : if (! aResubstPath.bIsSinglePath)
314 : {
315 : ::comphelper::ConfigurationHelper::writeRelativeKey(xCfgNew,
316 : aResubstPath.sPathName,
317 : CFGPROP_USERPATHS,
318 0 : css::uno::makeAny(aResubstPath.lUserPaths.getAsConstList()));
319 : }
320 :
321 : ::comphelper::ConfigurationHelper::writeRelativeKey(xCfgNew,
322 : aResubstPath.sPathName,
323 : CFGPROP_WRITEPATH,
324 0 : css::uno::makeAny(aResubstPath.sWritePath));
325 :
326 0 : ::comphelper::ConfigurationHelper::flush(xCfgNew);
327 :
328 : // remove the whole path from the old configuration !
329 : // Otherwise we cant make sure that the diff between new and old configuration
330 : // on loading time realy represent an user setting !!!
331 :
332 : // Check if the given path exists inside the old configuration.
333 : // Because our new configuration knows more then the list of old paths ... !
334 0 : if (xCfgOld->hasByName(aResubstPath.sPathName))
335 : {
336 0 : css::uno::Reference< css::beans::XPropertySet > xProps(xCfgOld, css::uno::UNO_QUERY_THROW);
337 0 : xProps->setPropertyValue(aResubstPath.sPathName, css::uno::Any());
338 0 : ::comphelper::ConfigurationHelper::flush(xCfgOld);
339 : }
340 :
341 0 : m_bIgnoreEvents = sal_False;
342 0 : }
343 :
344 : //-----------------------------------------------------------------------------
345 456 : void PathSettings::impl_mergeOldUserPaths( PathSettings::PathInfo& rPath,
346 : const OUStringList& lOld )
347 : {
348 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "PathSettings::impl_mergeOldUserPaths" );
349 456 : OUStringList::const_iterator pIt;
350 3021 : for ( pIt = lOld.begin();
351 2014 : pIt != lOld.end() ;
352 : ++pIt )
353 : {
354 551 : const ::rtl::OUString& sOld = *pIt;
355 :
356 551 : if (rPath.bIsSinglePath)
357 : {
358 : LOG_ASSERT2(lOld.size()>1, "PathSettings::impl_mergeOldUserPaths()", "Single path has more then one path value inside old configuration (Common.xcu)!")
359 95 : if (! rPath.sWritePath.equals(sOld))
360 14 : rPath.sWritePath = sOld;
361 : }
362 : else
363 : {
364 3004 : if (
365 1824 : ( rPath.lInternalPaths.findConst(sOld) == rPath.lInternalPaths.end()) &&
366 999 : ( rPath.lUserPaths.findConst(sOld) == rPath.lUserPaths.end() ) &&
367 181 : (! rPath.sWritePath.equals(sOld) )
368 : )
369 29 : rPath.lUserPaths.push_back(sOld);
370 : }
371 : }
372 456 : }
373 :
374 : //-----------------------------------------------------------------------------
375 456 : PathSettings::EChangeOp PathSettings::impl_updatePath(const ::rtl::OUString& sPath ,
376 : sal_Bool bNotifyListener)
377 : {
378 : // SAFE ->
379 456 : WriteGuard aWriteLock(m_aLock);
380 :
381 456 : PathSettings::PathInfo* pPathOld = 0;
382 456 : PathSettings::PathInfo* pPathNew = 0;
383 456 : PathSettings::EChangeOp eOp = PathSettings::E_UNDEFINED;
384 456 : PathSettings::PathInfo aPath;
385 :
386 : try
387 : {
388 456 : aPath = impl_readNewFormat(sPath);
389 456 : aPath.sPathName = sPath;
390 : // replace all might existing variables with real values
391 : // Do it before these old paths will be compared against the
392 : // new path configuration. Otherwise some striungs uses different variables ... but substitution
393 : // will produce strings with same content (because some variables are redundant!)
394 456 : impl_subst(aPath, sal_False);
395 : }
396 0 : catch(const css::uno::RuntimeException&)
397 0 : { throw; }
398 0 : catch(const css::container::NoSuchElementException&)
399 0 : { eOp = PathSettings::E_REMOVED; }
400 0 : catch(const css::uno::Exception&)
401 0 : { throw; }
402 :
403 : try
404 : {
405 : // migration of old user defined values on demand
406 : // can be disabled for a new major
407 456 : OUStringList lOldVals = impl_readOldFormat(sPath);
408 : // replace all might existing variables with real values
409 : // Do it before these old paths will be compared against the
410 : // new path configuration. Otherwise some striungs uses different variables ... but substitution
411 : // will produce strings with same content (because some variables are redundant!)
412 456 : impl_subst(lOldVals, fa_getSubstitution(), sal_False);
413 456 : impl_mergeOldUserPaths(aPath, lOldVals);
414 : }
415 0 : catch(const css::uno::RuntimeException&)
416 0 : { throw; }
417 : // Normal(!) exceptions can be ignored!
418 : // E.g. in case an addon installs a new path, which was not well known for an OOo 1.x installation
419 : // we cant find a value for it inside the "old" configuration. So a NoSuchElementException
420 : // will be normal .-)
421 0 : catch(const css::uno::Exception&)
422 : {}
423 :
424 456 : PathSettings::PathHash::iterator pPath = m_lPaths.find(sPath);
425 456 : if (eOp == PathSettings::E_UNDEFINED)
426 : {
427 456 : if (pPath != m_lPaths.end())
428 0 : eOp = PathSettings::E_CHANGED;
429 : else
430 456 : eOp = PathSettings::E_ADDED;
431 : }
432 :
433 456 : switch(eOp)
434 : {
435 : case PathSettings::E_ADDED :
436 : {
437 456 : if (bNotifyListener)
438 : {
439 0 : pPathOld = 0;
440 0 : pPathNew = &aPath;
441 0 : impl_notifyPropListener(eOp, sPath, pPathOld, pPathNew);
442 : }
443 456 : m_lPaths[sPath] = aPath;
444 : }
445 456 : break;
446 :
447 : case PathSettings::E_CHANGED :
448 : {
449 0 : if (bNotifyListener)
450 : {
451 0 : pPathOld = &(pPath->second);
452 0 : pPathNew = &aPath;
453 0 : impl_notifyPropListener(eOp, sPath, pPathOld, pPathNew);
454 : }
455 0 : m_lPaths[sPath] = aPath;
456 : }
457 0 : break;
458 :
459 : case PathSettings::E_REMOVED :
460 : {
461 0 : if (pPath != m_lPaths.end())
462 : {
463 0 : if (bNotifyListener)
464 : {
465 0 : pPathOld = &(pPath->second);
466 0 : pPathNew = 0;
467 0 : impl_notifyPropListener(eOp, sPath, pPathOld, pPathNew);
468 : }
469 0 : m_lPaths.erase(pPath);
470 : }
471 : }
472 0 : break;
473 :
474 : default: // to let compiler be happy
475 0 : break;
476 : }
477 :
478 456 : return eOp;
479 : }
480 :
481 : //-----------------------------------------------------------------------------
482 0 : css::uno::Sequence< sal_Int32 > PathSettings::impl_mapPathName2IDList(const ::rtl::OUString& sPath)
483 : {
484 0 : ::rtl::OUString sOldStyleProp = sPath;
485 0 : ::rtl::OUString sInternalProp = sPath+POSTFIX_INTERNAL_PATHS;
486 0 : ::rtl::OUString sUserProp = sPath+POSTFIX_USER_PATHS;
487 0 : ::rtl::OUString sWriteProp = sPath+POSTFIX_WRITE_PATH;
488 :
489 : // Attention: The default set of IDs is fix and must follow these schema.
490 : // Otherwhise the outside code ant work for new added properties.
491 : // Why ?
492 : // The outside code must fire N events for every changed property.
493 : // And the knowing about packaging of variables of the structure PathInfo
494 : // follow these group IDs ! But if such ID isnt in the range of [0..IDGROUP_COUNT]
495 : // the outside cant determine the right group ... and cant fire the right events .-)
496 :
497 0 : css::uno::Sequence< sal_Int32 > lIDs(IDGROUP_COUNT);
498 0 : lIDs[0] = IDGROUP_OLDSTYLE ;
499 0 : lIDs[1] = IDGROUP_INTERNAL_PATHS;
500 0 : lIDs[2] = IDGROUP_USER_PATHS ;
501 0 : lIDs[3] = IDGROUP_WRITE_PATH ;
502 :
503 0 : sal_Int32 c = m_lPropDesc.getLength();
504 0 : sal_Int32 i = 0;
505 0 : for (i=0; i<c; ++i)
506 : {
507 0 : const css::beans::Property& rProp = m_lPropDesc[i];
508 :
509 0 : if (rProp.Name.equals(sOldStyleProp))
510 0 : lIDs[IDGROUP_OLDSTYLE] = rProp.Handle;
511 : else
512 0 : if (rProp.Name.equals(sInternalProp))
513 0 : lIDs[IDGROUP_INTERNAL_PATHS] = rProp.Handle;
514 : else
515 0 : if (rProp.Name.equals(sUserProp))
516 0 : lIDs[IDGROUP_USER_PATHS] = rProp.Handle;
517 : else
518 0 : if (rProp.Name.equals(sWriteProp))
519 0 : lIDs[IDGROUP_WRITE_PATH] = rProp.Handle;
520 : }
521 :
522 0 : return lIDs;
523 : }
524 :
525 : //-----------------------------------------------------------------------------
526 0 : void PathSettings::impl_notifyPropListener( PathSettings::EChangeOp /*eOp*/ ,
527 : const ::rtl::OUString& sPath ,
528 : const PathSettings::PathInfo* pPathOld,
529 : const PathSettings::PathInfo* pPathNew)
530 : {
531 0 : css::uno::Sequence< sal_Int32 > lHandles(1);
532 0 : css::uno::Sequence< css::uno::Any > lOldVals(1);
533 0 : css::uno::Sequence< css::uno::Any > lNewVals(1);
534 :
535 0 : css::uno::Sequence< sal_Int32 > lIDs = impl_mapPathName2IDList(sPath);
536 0 : sal_Int32 c = lIDs.getLength();
537 0 : sal_Int32 i = 0;
538 0 : sal_Int32 nMaxID = m_lPropDesc.getLength()-1;
539 0 : for (i=0; i<c; ++i)
540 : {
541 0 : sal_Int32 nID = lIDs[i];
542 :
543 0 : if (
544 : (nID < 0 ) ||
545 : (nID > nMaxID)
546 : )
547 0 : continue;
548 :
549 0 : lHandles[0] = nID;
550 0 : switch(impl_getPropGroup(nID))
551 : {
552 : case IDGROUP_OLDSTYLE :
553 : {
554 0 : if (pPathOld)
555 : {
556 0 : ::rtl::OUString sVal = impl_convertPath2OldStyle(*pPathOld);
557 0 : lOldVals[0] <<= sVal;
558 : }
559 0 : if (pPathNew)
560 : {
561 0 : ::rtl::OUString sVal = impl_convertPath2OldStyle(*pPathNew);
562 0 : lNewVals[0] <<= sVal;
563 : }
564 : }
565 0 : break;
566 :
567 : case IDGROUP_INTERNAL_PATHS :
568 : {
569 0 : if (pPathOld)
570 0 : lOldVals[0] <<= pPathOld->lInternalPaths.getAsConstList();
571 0 : if (pPathNew)
572 0 : lNewVals[0] <<= pPathNew->lInternalPaths.getAsConstList();
573 : }
574 0 : break;
575 :
576 : case IDGROUP_USER_PATHS :
577 : {
578 0 : if (pPathOld)
579 0 : lOldVals[0] <<= pPathOld->lUserPaths.getAsConstList();
580 0 : if (pPathNew)
581 0 : lNewVals[0] <<= pPathNew->lUserPaths.getAsConstList();
582 : }
583 0 : break;
584 :
585 : case IDGROUP_WRITE_PATH :
586 : {
587 0 : if (pPathOld)
588 0 : lOldVals[0] <<= pPathOld->sWritePath;
589 0 : if (pPathNew)
590 0 : lNewVals[0] <<= pPathNew->sWritePath;
591 : }
592 0 : break;
593 : }
594 :
595 : fire(lHandles.getArray(),
596 0 : lNewVals.getArray(),
597 0 : lOldVals.getArray(),
598 : 1,
599 0 : sal_False);
600 0 : }
601 0 : }
602 :
603 : //-----------------------------------------------------------------------------
604 1368 : void PathSettings::impl_subst( OUStringList& lVals ,
605 : const css::uno::Reference< css::util::XStringSubstitution >& xSubst ,
606 : sal_Bool bReSubst)
607 : {
608 1368 : OUStringList::iterator pIt;
609 :
610 6810 : for ( pIt = lVals.begin();
611 4540 : pIt != lVals.end() ;
612 : ++pIt )
613 : {
614 902 : const ::rtl::OUString& sOld = *pIt;
615 902 : ::rtl::OUString sNew ;
616 902 : if (bReSubst)
617 0 : sNew = xSubst->reSubstituteVariables(sOld);
618 : else
619 902 : sNew = xSubst->substituteVariables(sOld, sal_False);
620 :
621 902 : *pIt = sNew;
622 902 : }
623 1368 : }
624 :
625 : //-----------------------------------------------------------------------------
626 456 : void PathSettings::impl_subst(PathSettings::PathInfo& aPath ,
627 : sal_Bool bReSubst)
628 : {
629 456 : css::uno::Reference< css::util::XStringSubstitution > xSubst = fa_getSubstitution();
630 :
631 456 : impl_subst(aPath.lInternalPaths, xSubst, bReSubst);
632 456 : impl_subst(aPath.lUserPaths , xSubst, bReSubst);
633 456 : if (bReSubst)
634 0 : aPath.sWritePath = xSubst->reSubstituteVariables(aPath.sWritePath);
635 : else
636 456 : aPath.sWritePath = xSubst->substituteVariables(aPath.sWritePath, sal_False);
637 456 : }
638 :
639 : //-----------------------------------------------------------------------------
640 1498 : ::rtl::OUString PathSettings::impl_convertPath2OldStyle(const PathSettings::PathInfo& rPath) const
641 : {
642 1498 : OUStringList::const_iterator pIt;
643 1498 : OUStringList lTemp;
644 1498 : lTemp.reserve(rPath.lInternalPaths.size() + rPath.lUserPaths.size() + 1);
645 :
646 7500 : for ( pIt = rPath.lInternalPaths.begin();
647 5000 : pIt != rPath.lInternalPaths.end() ;
648 : ++pIt )
649 : {
650 1002 : lTemp.push_back(*pIt);
651 : }
652 4518 : for ( pIt = rPath.lUserPaths.begin();
653 3012 : pIt != rPath.lUserPaths.end() ;
654 : ++pIt )
655 : {
656 8 : lTemp.push_back(*pIt);
657 : }
658 :
659 1498 : if (!rPath.sWritePath.isEmpty())
660 1435 : lTemp.push_back(rPath.sWritePath);
661 :
662 1498 : ::rtl::OUStringBuffer sPathVal(256);
663 9384 : for ( pIt = lTemp.begin();
664 7886 : pIt != lTemp.end() ;
665 : )
666 : {
667 2445 : sPathVal.append(*pIt);
668 2445 : ++pIt;
669 2445 : if (pIt != lTemp.end())
670 947 : sPathVal.appendAscii(";");
671 : }
672 :
673 1498 : return sPathVal.makeStringAndClear();
674 : }
675 :
676 : //-----------------------------------------------------------------------------
677 0 : OUStringList PathSettings::impl_convertOldStyle2Path(const ::rtl::OUString& sOldStylePath) const
678 : {
679 0 : OUStringList lList;
680 0 : sal_Int32 nToken = 0;
681 0 : do
682 : {
683 0 : ::rtl::OUString sToken = sOldStylePath.getToken(0, ';', nToken);
684 0 : if (!sToken.isEmpty())
685 0 : lList.push_back(sToken);
686 : }
687 : while(nToken >= 0);
688 :
689 0 : return lList;
690 : }
691 :
692 : //-----------------------------------------------------------------------------
693 0 : void PathSettings::impl_purgeKnownPaths(const PathSettings::PathInfo& rPath,
694 : OUStringList& lList)
695 : {
696 0 : OUStringList::const_iterator pIt;
697 0 : for ( pIt = rPath.lInternalPaths.begin();
698 0 : pIt != rPath.lInternalPaths.end() ;
699 : ++pIt )
700 : {
701 0 : const ::rtl::OUString& rItem = *pIt;
702 0 : OUStringList::iterator pItem = lList.find(rItem);
703 0 : if (pItem != lList.end())
704 0 : lList.erase(pItem);
705 : }
706 0 : for ( pIt = rPath.lUserPaths.begin();
707 0 : pIt != rPath.lUserPaths.end() ;
708 : ++pIt )
709 : {
710 0 : const ::rtl::OUString& rItem = *pIt;
711 0 : OUStringList::iterator pItem = lList.find(rItem);
712 0 : if (pItem != lList.end())
713 0 : lList.erase(pItem);
714 : }
715 :
716 0 : OUStringList::iterator pItem = lList.find(rPath.sWritePath);
717 0 : if (pItem != lList.end())
718 0 : lList.erase(pItem);
719 0 : }
720 :
721 : //-----------------------------------------------------------------------------
722 19 : void PathSettings::impl_rebuildPropertyDescriptor()
723 : {
724 : // SAFE ->
725 19 : WriteGuard aWriteLock(m_aLock);
726 :
727 19 : sal_Int32 c = (sal_Int32)m_lPaths.size();
728 19 : sal_Int32 i = 0;
729 19 : m_lPropDesc.realloc(c*IDGROUP_COUNT);
730 :
731 19 : PathHash::const_iterator pIt;
732 1425 : for ( pIt = m_lPaths.begin();
733 950 : pIt != m_lPaths.end() ;
734 : ++pIt )
735 : {
736 456 : const PathSettings::PathInfo& rPath = pIt->second;
737 456 : css::beans::Property* pProp = 0;
738 :
739 456 : pProp = &(m_lPropDesc[i]);
740 456 : pProp->Name = rPath.sPathName;
741 456 : pProp->Handle = i;
742 456 : pProp->Type = ::getCppuType((::rtl::OUString*)0);
743 456 : pProp->Attributes = css::beans::PropertyAttribute::BOUND;
744 456 : if (rPath.bIsReadonly)
745 0 : pProp->Attributes |= css::beans::PropertyAttribute::READONLY;
746 456 : ++i;
747 :
748 456 : pProp = &(m_lPropDesc[i]);
749 456 : pProp->Name = rPath.sPathName+POSTFIX_INTERNAL_PATHS;
750 456 : pProp->Handle = i;
751 456 : pProp->Type = ::getCppuType((css::uno::Sequence< ::rtl::OUString >*)0);
752 : pProp->Attributes = css::beans::PropertyAttribute::BOUND |
753 456 : css::beans::PropertyAttribute::READONLY;
754 456 : ++i;
755 :
756 456 : pProp = &(m_lPropDesc[i]);
757 456 : pProp->Name = rPath.sPathName+POSTFIX_USER_PATHS;
758 456 : pProp->Handle = i;
759 456 : pProp->Type = ::getCppuType((css::uno::Sequence< ::rtl::OUString >*)0);
760 456 : pProp->Attributes = css::beans::PropertyAttribute::BOUND;
761 456 : if (rPath.bIsReadonly)
762 0 : pProp->Attributes |= css::beans::PropertyAttribute::READONLY;
763 456 : ++i;
764 :
765 456 : pProp = &(m_lPropDesc[i]);
766 456 : pProp->Name = rPath.sPathName+POSTFIX_WRITE_PATH;
767 456 : pProp->Handle = i;
768 456 : pProp->Type = ::getCppuType((::rtl::OUString*)0);
769 456 : pProp->Attributes = css::beans::PropertyAttribute::BOUND;
770 456 : if (rPath.bIsReadonly)
771 0 : pProp->Attributes |= css::beans::PropertyAttribute::READONLY;
772 456 : ++i;
773 : }
774 :
775 19 : if (m_pPropHelp)
776 0 : delete m_pPropHelp;
777 19 : m_pPropHelp = new ::cppu::OPropertyArrayHelper(m_lPropDesc, sal_False); // false => not sorted ... must be done inside helper
778 :
779 19 : aWriteLock.unlock();
780 : // <- SAFE
781 19 : }
782 :
783 : //-----------------------------------------------------------------------------
784 1507 : css::uno::Any PathSettings::impl_getPathValue(sal_Int32 nID) const
785 : {
786 1507 : const PathSettings::PathInfo* pPath = impl_getPathAccessConst(nID);
787 1507 : if (! pPath)
788 0 : throw css::container::NoSuchElementException();
789 :
790 1507 : css::uno::Any aVal;
791 1507 : switch(impl_getPropGroup(nID))
792 : {
793 : case IDGROUP_OLDSTYLE :
794 : {
795 1498 : ::rtl::OUString sVal = impl_convertPath2OldStyle(*pPath);
796 1498 : aVal <<= sVal;
797 : }
798 1498 : break;
799 :
800 : case IDGROUP_INTERNAL_PATHS :
801 : {
802 3 : aVal <<= pPath->lInternalPaths.getAsConstList();
803 : }
804 3 : break;
805 :
806 : case IDGROUP_USER_PATHS :
807 : {
808 3 : aVal <<= pPath->lUserPaths.getAsConstList();
809 : }
810 3 : break;
811 :
812 : case IDGROUP_WRITE_PATH :
813 : {
814 3 : aVal <<= pPath->sWritePath;
815 : }
816 3 : break;
817 : }
818 :
819 1507 : return aVal;
820 : }
821 :
822 : //-----------------------------------------------------------------------------
823 0 : void PathSettings::impl_setPathValue( sal_Int32 nID ,
824 : const css::uno::Any& aVal)
825 : {
826 0 : PathSettings::PathInfo* pOrgPath = impl_getPathAccess(nID);
827 0 : if (! pOrgPath)
828 0 : throw css::container::NoSuchElementException();
829 :
830 : // We work on a copied path ... so we can be sure that errors during this operation
831 : // does not make our internal cache invalid .-)
832 0 : PathSettings::PathInfo aChangePath(*pOrgPath);
833 :
834 0 : switch(impl_getPropGroup(nID))
835 : {
836 : case IDGROUP_OLDSTYLE :
837 : {
838 0 : ::rtl::OUString sVal;
839 0 : aVal >>= sVal;
840 0 : OUStringList lList = impl_convertOldStyle2Path(sVal);
841 0 : impl_subst(lList, fa_getSubstitution(), sal_False);
842 0 : impl_purgeKnownPaths(aChangePath, lList);
843 0 : if (! impl_isValidPath(lList))
844 0 : throw css::lang::IllegalArgumentException();
845 :
846 0 : if (aChangePath.bIsSinglePath)
847 : {
848 : LOG_ASSERT2(lList.size()>1, "PathSettings::impl_setPathValue()", "You try to set more then path value for a defined SINGLE_PATH!")
849 0 : if ( !lList.empty() )
850 0 : aChangePath.sWritePath = *(lList.begin());
851 : else
852 0 : aChangePath.sWritePath = ::rtl::OUString();
853 : }
854 : else
855 : {
856 0 : OUStringList::const_iterator pIt;
857 0 : for ( pIt = lList.begin();
858 0 : pIt != lList.end() ;
859 : ++pIt )
860 : {
861 0 : aChangePath.lUserPaths.push_back(*pIt);
862 : }
863 0 : }
864 : }
865 0 : break;
866 :
867 : case IDGROUP_INTERNAL_PATHS :
868 : {
869 0 : if (aChangePath.bIsSinglePath)
870 : {
871 0 : ::rtl::OUStringBuffer sMsg(256);
872 0 : sMsg.appendAscii("The path '" );
873 0 : sMsg.append (aChangePath.sPathName);
874 0 : sMsg.appendAscii("' is defined as SINGLE_PATH. It's sub set of internal paths cant be set.");
875 : throw css::uno::Exception(sMsg.makeStringAndClear(),
876 0 : static_cast< ::cppu::OWeakObject* >(this));
877 : }
878 :
879 0 : OUStringList lList;
880 0 : lList << aVal;
881 0 : if (! impl_isValidPath(lList))
882 0 : throw css::lang::IllegalArgumentException();
883 0 : aChangePath.lInternalPaths = lList;
884 : }
885 0 : break;
886 :
887 : case IDGROUP_USER_PATHS :
888 : {
889 0 : if (aChangePath.bIsSinglePath)
890 : {
891 0 : ::rtl::OUStringBuffer sMsg(256);
892 0 : sMsg.appendAscii("The path '" );
893 0 : sMsg.append (aChangePath.sPathName);
894 0 : sMsg.appendAscii("' is defined as SINGLE_PATH. It's sub set of internal paths cant be set.");
895 : throw css::uno::Exception(sMsg.makeStringAndClear(),
896 0 : static_cast< ::cppu::OWeakObject* >(this));
897 : }
898 :
899 0 : OUStringList lList;
900 0 : lList << aVal;
901 0 : if (! impl_isValidPath(lList))
902 0 : throw css::lang::IllegalArgumentException();
903 0 : aChangePath.lUserPaths = lList;
904 : }
905 0 : break;
906 :
907 : case IDGROUP_WRITE_PATH :
908 : {
909 0 : ::rtl::OUString sVal;
910 0 : aVal >>= sVal;
911 0 : if (! impl_isValidPath(sVal))
912 0 : throw css::lang::IllegalArgumentException();
913 0 : aChangePath.sWritePath = sVal;
914 : }
915 0 : break;
916 : }
917 :
918 : // TODO check if path has at least one path value set
919 : // At least it depends from the feature using this path, if an empty path list is allowed.
920 :
921 : // first we should try to store the changed (copied!) path ...
922 : // In case an error occure on saving time an exception is thrown ...
923 : // If no exception occures we can update our internal cache (means
924 : // we can overwrite pOrgPath !
925 0 : impl_storePath(aChangePath);
926 0 : pOrgPath->takeOver(aChangePath);
927 0 : }
928 :
929 : //-----------------------------------------------------------------------------
930 0 : sal_Bool PathSettings::impl_isValidPath(const OUStringList& lPath) const
931 : {
932 0 : OUStringList::const_iterator pIt;
933 0 : for ( pIt = lPath.begin();
934 0 : pIt != lPath.end() ;
935 : ++pIt )
936 : {
937 0 : const ::rtl::OUString& rVal = *pIt;
938 0 : if (! impl_isValidPath(rVal))
939 0 : return sal_False;
940 : }
941 :
942 0 : return sal_True;
943 : }
944 :
945 : //-----------------------------------------------------------------------------
946 0 : sal_Bool PathSettings::impl_isValidPath(const ::rtl::OUString& sPath) const
947 : {
948 : // allow empty path to reset a path.
949 : // idea by LLA to support empty paths
950 : // if (sPath.getLength() == 0)
951 : // {
952 : // return sal_True;
953 : // }
954 :
955 0 : return (! INetURLObject(sPath).HasError());
956 : }
957 :
958 : //-----------------------------------------------------------------------------
959 1507 : ::rtl::OUString impl_extractBaseFromPropName(const ::rtl::OUString& sPropName)
960 : {
961 1507 : sal_Int32 i = -1;
962 :
963 1507 : i = sPropName.indexOf(POSTFIX_INTERNAL_PATHS);
964 1507 : if (i > -1)
965 3 : return sPropName.copy(0, i);
966 1504 : i = sPropName.indexOf(POSTFIX_USER_PATHS);
967 1504 : if (i > -1)
968 3 : return sPropName.copy(0, i);
969 1501 : i = sPropName.indexOf(POSTFIX_WRITE_PATH);
970 1501 : if (i > -1)
971 3 : return sPropName.copy(0, i);
972 :
973 1498 : return sPropName;
974 : }
975 :
976 : //-----------------------------------------------------------------------------
977 0 : PathSettings::PathInfo* PathSettings::impl_getPathAccess(sal_Int32 nHandle)
978 : {
979 : // SAFE ->
980 0 : ReadGuard aReadLock(m_aLock);
981 :
982 0 : if (nHandle > (m_lPropDesc.getLength()-1))
983 0 : return 0;
984 :
985 0 : const css::beans::Property& rProp = m_lPropDesc[nHandle];
986 0 : ::rtl::OUString sProp = impl_extractBaseFromPropName(rProp.Name);
987 0 : PathSettings::PathHash::iterator rPath = m_lPaths.find(sProp);
988 :
989 0 : if (rPath != m_lPaths.end())
990 0 : return &(rPath->second);
991 :
992 0 : return 0;
993 : // <- SAFE
994 : }
995 :
996 : //-----------------------------------------------------------------------------
997 1507 : const PathSettings::PathInfo* PathSettings::impl_getPathAccessConst(sal_Int32 nHandle) const
998 : {
999 : // SAFE ->
1000 1507 : ReadGuard aReadLock(m_aLock);
1001 :
1002 1507 : if (nHandle > (m_lPropDesc.getLength()-1))
1003 0 : return 0;
1004 :
1005 1507 : const css::beans::Property& rProp = m_lPropDesc[nHandle];
1006 1507 : ::rtl::OUString sProp = impl_extractBaseFromPropName(rProp.Name);
1007 1507 : PathSettings::PathHash::const_iterator rPath = m_lPaths.find(sProp);
1008 :
1009 1507 : if (rPath != m_lPaths.end())
1010 1507 : return &(rPath->second);
1011 :
1012 0 : return 0;
1013 : // <- SAFE
1014 : }
1015 :
1016 : //-----------------------------------------------------------------------------
1017 0 : sal_Bool SAL_CALL PathSettings::convertFastPropertyValue( css::uno::Any& aConvertedValue,
1018 : css::uno::Any& aOldValue ,
1019 : sal_Int32 nHandle ,
1020 : const css::uno::Any& aValue )
1021 : throw(css::lang::IllegalArgumentException)
1022 : {
1023 : // throws NoSuchElementException !
1024 0 : css::uno::Any aCurrentVal = impl_getPathValue(nHandle);
1025 :
1026 : return PropHelper::willPropertyBeChanged(
1027 : aCurrentVal,
1028 : aValue,
1029 : aOldValue,
1030 0 : aConvertedValue);
1031 : }
1032 :
1033 : //-----------------------------------------------------------------------------
1034 0 : void SAL_CALL PathSettings::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle,
1035 : const css::uno::Any& aValue )
1036 : throw(css::uno::Exception)
1037 : {
1038 : // throws NoSuchElement- and IllegalArgumentException !
1039 0 : impl_setPathValue(nHandle, aValue);
1040 0 : }
1041 :
1042 : //-----------------------------------------------------------------------------
1043 1507 : void SAL_CALL PathSettings::getFastPropertyValue(css::uno::Any& aValue ,
1044 : sal_Int32 nHandle) const
1045 : {
1046 1507 : aValue = impl_getPathValue(nHandle);
1047 1507 : }
1048 :
1049 : //-----------------------------------------------------------------------------
1050 1551 : ::cppu::IPropertyArrayHelper& SAL_CALL PathSettings::getInfoHelper()
1051 : {
1052 1551 : return *m_pPropHelp;
1053 : }
1054 :
1055 : //-----------------------------------------------------------------------------
1056 19 : css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL PathSettings::getPropertySetInfo()
1057 : throw(css::uno::RuntimeException)
1058 : {
1059 19 : return css::uno::Reference< css::beans::XPropertySetInfo >(createPropertySetInfo(getInfoHelper()));
1060 : }
1061 :
1062 : //-----------------------------------------------------------------------------
1063 912 : css::uno::Reference< css::util::XStringSubstitution > PathSettings::fa_getSubstitution()
1064 : {
1065 : // SAFE ->
1066 912 : ReadGuard aReadLock(m_aLock);
1067 912 : css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
1068 912 : css::uno::Reference< css::util::XStringSubstitution > xSubst = m_xSubstitution;
1069 912 : aReadLock.unlock();
1070 : // <- SAFE
1071 :
1072 912 : if (! xSubst.is())
1073 : {
1074 : // create the needed substitution service.
1075 : // We must replace all used variables inside readed path values.
1076 : // In case we can't do so ... the whole office can't work really.
1077 : // That's why it seams to be OK to throw a RuntimeException then.
1078 19 : css::uno::Reference< css::uno::XComponentContext > xContext( comphelper::getComponentContext(xSMGR) );
1079 19 : xSubst = css::util::PathSubstitution::create(xContext);
1080 :
1081 : // SAFE ->
1082 19 : WriteGuard aWriteLock(m_aLock);
1083 19 : m_xSubstitution = xSubst;
1084 19 : aWriteLock.unlock();
1085 : }
1086 :
1087 912 : return xSubst;
1088 : }
1089 :
1090 : //-----------------------------------------------------------------------------
1091 456 : css::uno::Reference< css::container::XNameAccess > PathSettings::fa_getCfgOld()
1092 : {
1093 456 : const ::rtl::OUString CFG_NODE_OLD(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Office.Common/Path/Current"));
1094 :
1095 : // SAFE ->
1096 456 : ReadGuard aReadLock(m_aLock);
1097 456 : css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
1098 456 : css::uno::Reference< css::container::XNameAccess > xCfg = m_xCfgOld;
1099 456 : aReadLock.unlock();
1100 : // <- SAFE
1101 :
1102 456 : if (! xCfg.is())
1103 : {
1104 : xCfg = css::uno::Reference< css::container::XNameAccess >(
1105 : ::comphelper::ConfigurationHelper::openConfig(
1106 : comphelper::getComponentContext(xSMGR),
1107 : CFG_NODE_OLD,
1108 : ::comphelper::ConfigurationHelper::E_STANDARD), // not readonly! Somtimes we need write access there !!!
1109 19 : css::uno::UNO_QUERY_THROW);
1110 :
1111 : // SAFE ->
1112 19 : WriteGuard aWriteLock(m_aLock);
1113 19 : m_xCfgOld = xCfg;
1114 19 : aWriteLock.unlock();
1115 : }
1116 :
1117 456 : return xCfg;
1118 : }
1119 :
1120 : //-----------------------------------------------------------------------------
1121 475 : css::uno::Reference< css::container::XNameAccess > PathSettings::fa_getCfgNew()
1122 : {
1123 475 : const ::rtl::OUString CFG_NODE_NEW(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Office.Paths/Paths"));
1124 :
1125 : // SAFE ->
1126 475 : ReadGuard aReadLock(m_aLock);
1127 475 : css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
1128 475 : css::uno::Reference< css::container::XNameAccess > xCfg = m_xCfgNew;
1129 475 : aReadLock.unlock();
1130 : // <- SAFE
1131 :
1132 475 : if (! xCfg.is())
1133 : {
1134 : xCfg = css::uno::Reference< css::container::XNameAccess >(
1135 : ::comphelper::ConfigurationHelper::openConfig(
1136 : comphelper::getComponentContext(xSMGR),
1137 : CFG_NODE_NEW,
1138 : ::comphelper::ConfigurationHelper::E_STANDARD),
1139 19 : css::uno::UNO_QUERY_THROW);
1140 :
1141 : // SAFE ->
1142 19 : WriteGuard aWriteLock(m_aLock);
1143 19 : m_xCfgNew = xCfg;
1144 19 : m_xCfgNewListener = new WeakChangesListener(this);
1145 19 : aWriteLock.unlock();
1146 :
1147 19 : css::uno::Reference< css::util::XChangesNotifier > xBroadcaster(xCfg, css::uno::UNO_QUERY_THROW);
1148 19 : xBroadcaster->addChangesListener(m_xCfgNewListener);
1149 : }
1150 :
1151 475 : return xCfg;
1152 : }
1153 :
1154 : } // namespace framework
1155 :
1156 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|