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 3288 : sal_Int32 impl_getPropGroup(sal_Int32 nID)
72 : {
73 3288 : return (nID % IDGROUP_COUNT);
74 : }
75 :
76 :
77 : namespace framework
78 : {
79 :
80 : //-----------------------------------------------------------------------------
81 : // XInterface, XTypeProvider, XServiceInfo
82 :
83 2429 : 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 360 : DEFINE_XSERVICEINFO_ONEINSTANCESERVICE ( PathSettings ,
105 : ::cppu::OWeakObject ,
106 : SERVICENAME_PATHSETTINGS ,
107 : IMPLEMENTATIONNAME_PATHSETTINGS
108 : )
109 :
110 72 : 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 72 : 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 72 : , ::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 144 : , m_bIgnoreEvents(sal_False)
137 : {
138 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "PathSettings::PathSettings" );
139 72 : }
140 :
141 : //-----------------------------------------------------------------------------
142 216 : PathSettings::~PathSettings()
143 : {
144 72 : css::uno::Reference< css::util::XChangesNotifier > xBroadcaster(m_xCfgNew, css::uno::UNO_QUERY);
145 72 : if (xBroadcaster.is())
146 72 : xBroadcaster->removeChangesListener(m_xCfgNewListener);
147 72 : if (m_pPropHelp)
148 72 : delete m_pPropHelp;
149 144 : }
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 72 : 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 72 : css::uno::Reference< css::container::XNameAccess > xCfg = fa_getCfgNew();
207 72 : css::uno::Sequence< ::rtl::OUString > lPaths = xCfg->getElementNames();
208 :
209 72 : sal_Int32 c = lPaths.getLength();
210 1800 : for (sal_Int32 i = 0; i < c; ++i)
211 : {
212 1728 : const ::rtl::OUString& sPath = lPaths[i];
213 1728 : impl_updatePath(sPath, sal_False);
214 72 : }
215 : }
216 0 : catch(const css::uno::RuntimeException& )
217 : {
218 : }
219 :
220 72 : impl_rebuildPropertyDescriptor();
221 72 : }
222 :
223 : //-----------------------------------------------------------------------------
224 : // NO substitution here ! It's done outside ...
225 1728 : OUStringList PathSettings::impl_readOldFormat(const ::rtl::OUString& sPath)
226 : {
227 : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "PathSettings::impl_readOldFormat" );
228 1728 : css::uno::Reference< css::container::XNameAccess > xCfg( fa_getCfgOld() );
229 1728 : OUStringList aPathVal;
230 :
231 1728 : if( xCfg->hasByName(sPath) )
232 : {
233 1656 : css::uno::Any aVal( xCfg->getByName(sPath) );
234 :
235 1656 : ::rtl::OUString sStringVal;
236 1656 : css::uno::Sequence< ::rtl::OUString > lStringListVal;
237 :
238 1656 : if (aVal >>= sStringVal)
239 : {
240 1152 : aPathVal.push_back(sStringVal);
241 : }
242 504 : else if (aVal >>= lStringListVal)
243 : {
244 504 : aPathVal << lStringListVal;
245 1656 : }
246 : }
247 :
248 1728 : return aPathVal;
249 : }
250 :
251 : //-----------------------------------------------------------------------------
252 : // NO substitution here ! It's done outside ...
253 1728 : PathSettings::PathInfo PathSettings::impl_readNewFormat(const ::rtl::OUString& sPath)
254 : {
255 1728 : const ::rtl::OUString CFGPROP_INTERNALPATHS(RTL_CONSTASCII_USTRINGPARAM("InternalPaths"));
256 1728 : const ::rtl::OUString CFGPROP_ISSINGLEPATH(RTL_CONSTASCII_USTRINGPARAM("IsSinglePath"));
257 :
258 1728 : css::uno::Reference< css::container::XNameAccess > xCfg = fa_getCfgNew();
259 :
260 : // get access to the "queried" path
261 1728 : css::uno::Reference< css::container::XNameAccess > xPath;
262 1728 : xCfg->getByName(sPath) >>= xPath;
263 :
264 1728 : PathSettings::PathInfo aPathVal;
265 :
266 : // read internal path list
267 1728 : css::uno::Reference< css::container::XNameAccess > xIPath;
268 1728 : xPath->getByName(CFGPROP_INTERNALPATHS) >>= xIPath;
269 1728 : aPathVal.lInternalPaths << xIPath->getElementNames();
270 :
271 : // read user defined path list
272 1728 : aPathVal.lUserPaths << xPath->getByName(CFGPROP_USERPATHS);
273 :
274 : // read the writeable path
275 1728 : xPath->getByName(CFGPROP_WRITEPATH) >>= aPathVal.sWritePath;
276 :
277 : // read state props
278 1728 : xPath->getByName(CFGPROP_ISSINGLEPATH) >>= aPathVal.bIsSinglePath;
279 :
280 : // analyze finalized/mandatory states
281 1728 : aPathVal.bIsReadonly = sal_False;
282 1728 : css::uno::Reference< css::beans::XProperty > xInfo(xPath, css::uno::UNO_QUERY);
283 1728 : if (xInfo.is())
284 : {
285 1728 : css::beans::Property aInfo = xInfo->getAsProperty();
286 1728 : 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 1728 : aPathVal.bIsReadonly = bFinalized;
292 : }
293 :
294 1728 : 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 1728 : 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 1728 : OUStringList::const_iterator pIt;
350 11448 : for ( pIt = lOld.begin();
351 7632 : pIt != lOld.end() ;
352 : ++pIt )
353 : {
354 2088 : const ::rtl::OUString& sOld = *pIt;
355 :
356 2088 : 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 360 : if (! rPath.sWritePath.equals(sOld))
360 54 : rPath.sWritePath = sOld;
361 : }
362 : else
363 : {
364 11416 : if (
365 6912 : ( rPath.lInternalPaths.findConst(sOld) == rPath.lInternalPaths.end()) &&
366 3810 : ( rPath.lUserPaths.findConst(sOld) == rPath.lUserPaths.end() ) &&
367 694 : (! rPath.sWritePath.equals(sOld) )
368 : )
369 118 : rPath.lUserPaths.push_back(sOld);
370 : }
371 : }
372 1728 : }
373 :
374 : //-----------------------------------------------------------------------------
375 1728 : PathSettings::EChangeOp PathSettings::impl_updatePath(const ::rtl::OUString& sPath ,
376 : sal_Bool bNotifyListener)
377 : {
378 : // SAFE ->
379 1728 : WriteGuard aWriteLock(m_aLock);
380 :
381 1728 : PathSettings::PathInfo* pPathOld = 0;
382 1728 : PathSettings::PathInfo* pPathNew = 0;
383 1728 : PathSettings::EChangeOp eOp = PathSettings::E_UNDEFINED;
384 1728 : PathSettings::PathInfo aPath;
385 :
386 : try
387 : {
388 1728 : aPath = impl_readNewFormat(sPath);
389 1728 : 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 1728 : 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 1728 : 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 1728 : impl_subst(lOldVals, fa_getSubstitution(), sal_False);
413 1728 : 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 1728 : PathSettings::PathHash::iterator pPath = m_lPaths.find(sPath);
425 1728 : if (eOp == PathSettings::E_UNDEFINED)
426 : {
427 1728 : if (pPath != m_lPaths.end())
428 0 : eOp = PathSettings::E_CHANGED;
429 : else
430 1728 : eOp = PathSettings::E_ADDED;
431 : }
432 :
433 1728 : switch(eOp)
434 : {
435 : case PathSettings::E_ADDED :
436 : {
437 1728 : if (bNotifyListener)
438 : {
439 0 : pPathOld = 0;
440 0 : pPathNew = &aPath;
441 0 : impl_notifyPropListener(eOp, sPath, pPathOld, pPathNew);
442 : }
443 1728 : m_lPaths[sPath] = aPath;
444 : }
445 1728 : 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 1728 : 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 5184 : void PathSettings::impl_subst( OUStringList& lVals ,
605 : const css::uno::Reference< css::util::XStringSubstitution >& xSubst ,
606 : sal_Bool bReSubst)
607 : {
608 5184 : OUStringList::iterator pIt;
609 :
610 25860 : for ( pIt = lVals.begin();
611 17240 : pIt != lVals.end() ;
612 : ++pIt )
613 : {
614 3436 : const ::rtl::OUString& sOld = *pIt;
615 3436 : ::rtl::OUString sNew ;
616 3436 : if (bReSubst)
617 0 : sNew = xSubst->reSubstituteVariables(sOld);
618 : else
619 3436 : sNew = xSubst->substituteVariables(sOld, sal_False);
620 :
621 3436 : *pIt = sNew;
622 3436 : }
623 5184 : }
624 :
625 : //-----------------------------------------------------------------------------
626 1728 : void PathSettings::impl_subst(PathSettings::PathInfo& aPath ,
627 : sal_Bool bReSubst)
628 : {
629 1728 : css::uno::Reference< css::util::XStringSubstitution > xSubst = fa_getSubstitution();
630 :
631 1728 : impl_subst(aPath.lInternalPaths, xSubst, bReSubst);
632 1728 : impl_subst(aPath.lUserPaths , xSubst, bReSubst);
633 1728 : if (bReSubst)
634 0 : aPath.sWritePath = xSubst->reSubstituteVariables(aPath.sWritePath);
635 : else
636 1728 : aPath.sWritePath = xSubst->substituteVariables(aPath.sWritePath, sal_False);
637 1728 : }
638 :
639 : //-----------------------------------------------------------------------------
640 3261 : ::rtl::OUString PathSettings::impl_convertPath2OldStyle(const PathSettings::PathInfo& rPath) const
641 : {
642 3261 : OUStringList::const_iterator pIt;
643 3261 : OUStringList lTemp;
644 3261 : lTemp.reserve(rPath.lInternalPaths.size() + rPath.lUserPaths.size() + 1);
645 :
646 16170 : for ( pIt = rPath.lInternalPaths.begin();
647 10780 : pIt != rPath.lInternalPaths.end() ;
648 : ++pIt )
649 : {
650 2129 : lTemp.push_back(*pIt);
651 : }
652 9909 : for ( pIt = rPath.lUserPaths.begin();
653 6606 : pIt != rPath.lUserPaths.end() ;
654 : ++pIt )
655 : {
656 42 : lTemp.push_back(*pIt);
657 : }
658 :
659 3261 : if (!rPath.sWritePath.isEmpty())
660 3037 : lTemp.push_back(rPath.sWritePath);
661 :
662 3261 : ::rtl::OUStringBuffer sPathVal(256);
663 20199 : for ( pIt = lTemp.begin();
664 16938 : pIt != lTemp.end() ;
665 : )
666 : {
667 5208 : sPathVal.append(*pIt);
668 5208 : ++pIt;
669 5208 : if (pIt != lTemp.end())
670 1947 : sPathVal.appendAscii(";");
671 : }
672 :
673 3261 : 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 72 : void PathSettings::impl_rebuildPropertyDescriptor()
723 : {
724 : // SAFE ->
725 72 : WriteGuard aWriteLock(m_aLock);
726 :
727 72 : sal_Int32 c = (sal_Int32)m_lPaths.size();
728 72 : sal_Int32 i = 0;
729 72 : m_lPropDesc.realloc(c*IDGROUP_COUNT);
730 :
731 72 : PathHash::const_iterator pIt;
732 5400 : for ( pIt = m_lPaths.begin();
733 3600 : pIt != m_lPaths.end() ;
734 : ++pIt )
735 : {
736 1728 : const PathSettings::PathInfo& rPath = pIt->second;
737 1728 : css::beans::Property* pProp = 0;
738 :
739 1728 : pProp = &(m_lPropDesc[i]);
740 1728 : pProp->Name = rPath.sPathName;
741 1728 : pProp->Handle = i;
742 1728 : pProp->Type = ::getCppuType((::rtl::OUString*)0);
743 1728 : pProp->Attributes = css::beans::PropertyAttribute::BOUND;
744 1728 : if (rPath.bIsReadonly)
745 0 : pProp->Attributes |= css::beans::PropertyAttribute::READONLY;
746 1728 : ++i;
747 :
748 1728 : pProp = &(m_lPropDesc[i]);
749 1728 : pProp->Name = rPath.sPathName+POSTFIX_INTERNAL_PATHS;
750 1728 : pProp->Handle = i;
751 1728 : pProp->Type = ::getCppuType((css::uno::Sequence< ::rtl::OUString >*)0);
752 : pProp->Attributes = css::beans::PropertyAttribute::BOUND |
753 1728 : css::beans::PropertyAttribute::READONLY;
754 1728 : ++i;
755 :
756 1728 : pProp = &(m_lPropDesc[i]);
757 1728 : pProp->Name = rPath.sPathName+POSTFIX_USER_PATHS;
758 1728 : pProp->Handle = i;
759 1728 : pProp->Type = ::getCppuType((css::uno::Sequence< ::rtl::OUString >*)0);
760 1728 : pProp->Attributes = css::beans::PropertyAttribute::BOUND;
761 1728 : if (rPath.bIsReadonly)
762 0 : pProp->Attributes |= css::beans::PropertyAttribute::READONLY;
763 1728 : ++i;
764 :
765 1728 : pProp = &(m_lPropDesc[i]);
766 1728 : pProp->Name = rPath.sPathName+POSTFIX_WRITE_PATH;
767 1728 : pProp->Handle = i;
768 1728 : pProp->Type = ::getCppuType((::rtl::OUString*)0);
769 1728 : pProp->Attributes = css::beans::PropertyAttribute::BOUND;
770 1728 : if (rPath.bIsReadonly)
771 0 : pProp->Attributes |= css::beans::PropertyAttribute::READONLY;
772 1728 : ++i;
773 : }
774 :
775 72 : if (m_pPropHelp)
776 0 : delete m_pPropHelp;
777 72 : m_pPropHelp = new ::cppu::OPropertyArrayHelper(m_lPropDesc, sal_False); // false => not sorted ... must be done inside helper
778 :
779 72 : aWriteLock.unlock();
780 : // <- SAFE
781 72 : }
782 :
783 : //-----------------------------------------------------------------------------
784 3288 : css::uno::Any PathSettings::impl_getPathValue(sal_Int32 nID) const
785 : {
786 3288 : const PathSettings::PathInfo* pPath = impl_getPathAccessConst(nID);
787 3288 : if (! pPath)
788 0 : throw css::container::NoSuchElementException();
789 :
790 3288 : css::uno::Any aVal;
791 3288 : switch(impl_getPropGroup(nID))
792 : {
793 : case IDGROUP_OLDSTYLE :
794 : {
795 3261 : ::rtl::OUString sVal = impl_convertPath2OldStyle(*pPath);
796 3261 : aVal <<= sVal;
797 : }
798 3261 : break;
799 :
800 : case IDGROUP_INTERNAL_PATHS :
801 : {
802 9 : aVal <<= pPath->lInternalPaths.getAsConstList();
803 : }
804 9 : break;
805 :
806 : case IDGROUP_USER_PATHS :
807 : {
808 9 : aVal <<= pPath->lUserPaths.getAsConstList();
809 : }
810 9 : break;
811 :
812 : case IDGROUP_WRITE_PATH :
813 : {
814 9 : aVal <<= pPath->sWritePath;
815 : }
816 9 : break;
817 : }
818 :
819 3288 : 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 3288 : ::rtl::OUString impl_extractBaseFromPropName(const ::rtl::OUString& sPropName)
960 : {
961 3288 : sal_Int32 i = -1;
962 :
963 3288 : i = sPropName.indexOf(POSTFIX_INTERNAL_PATHS);
964 3288 : if (i > -1)
965 9 : return sPropName.copy(0, i);
966 3279 : i = sPropName.indexOf(POSTFIX_USER_PATHS);
967 3279 : if (i > -1)
968 9 : return sPropName.copy(0, i);
969 3270 : i = sPropName.indexOf(POSTFIX_WRITE_PATH);
970 3270 : if (i > -1)
971 9 : return sPropName.copy(0, i);
972 :
973 3261 : 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 3288 : const PathSettings::PathInfo* PathSettings::impl_getPathAccessConst(sal_Int32 nHandle) const
998 : {
999 : // SAFE ->
1000 3288 : ReadGuard aReadLock(m_aLock);
1001 :
1002 3288 : if (nHandle > (m_lPropDesc.getLength()-1))
1003 0 : return 0;
1004 :
1005 3288 : const css::beans::Property& rProp = m_lPropDesc[nHandle];
1006 3288 : ::rtl::OUString sProp = impl_extractBaseFromPropName(rProp.Name);
1007 3288 : PathSettings::PathHash::const_iterator rPath = m_lPaths.find(sProp);
1008 :
1009 3288 : if (rPath != m_lPaths.end())
1010 3288 : 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 3288 : void SAL_CALL PathSettings::getFastPropertyValue(css::uno::Any& aValue ,
1044 : sal_Int32 nHandle) const
1045 : {
1046 3288 : aValue = impl_getPathValue(nHandle);
1047 3288 : }
1048 :
1049 : //-----------------------------------------------------------------------------
1050 3475 : ::cppu::IPropertyArrayHelper& SAL_CALL PathSettings::getInfoHelper()
1051 : {
1052 3475 : return *m_pPropHelp;
1053 : }
1054 :
1055 : //-----------------------------------------------------------------------------
1056 72 : css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL PathSettings::getPropertySetInfo()
1057 : throw(css::uno::RuntimeException)
1058 : {
1059 72 : return css::uno::Reference< css::beans::XPropertySetInfo >(createPropertySetInfo(getInfoHelper()));
1060 : }
1061 :
1062 : //-----------------------------------------------------------------------------
1063 3456 : css::uno::Reference< css::util::XStringSubstitution > PathSettings::fa_getSubstitution()
1064 : {
1065 : // SAFE ->
1066 3456 : ReadGuard aReadLock(m_aLock);
1067 3456 : css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
1068 3456 : css::uno::Reference< css::util::XStringSubstitution > xSubst = m_xSubstitution;
1069 3456 : aReadLock.unlock();
1070 : // <- SAFE
1071 :
1072 3456 : 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 72 : css::uno::Reference< css::uno::XComponentContext > xContext( comphelper::getComponentContext(xSMGR) );
1079 72 : xSubst = css::util::PathSubstitution::create(xContext);
1080 :
1081 : // SAFE ->
1082 72 : WriteGuard aWriteLock(m_aLock);
1083 72 : m_xSubstitution = xSubst;
1084 72 : aWriteLock.unlock();
1085 : }
1086 :
1087 3456 : return xSubst;
1088 : }
1089 :
1090 : //-----------------------------------------------------------------------------
1091 1728 : css::uno::Reference< css::container::XNameAccess > PathSettings::fa_getCfgOld()
1092 : {
1093 1728 : const ::rtl::OUString CFG_NODE_OLD(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Office.Common/Path/Current"));
1094 :
1095 : // SAFE ->
1096 1728 : ReadGuard aReadLock(m_aLock);
1097 1728 : css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
1098 1728 : css::uno::Reference< css::container::XNameAccess > xCfg = m_xCfgOld;
1099 1728 : aReadLock.unlock();
1100 : // <- SAFE
1101 :
1102 1728 : 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 72 : css::uno::UNO_QUERY_THROW);
1110 :
1111 : // SAFE ->
1112 72 : WriteGuard aWriteLock(m_aLock);
1113 72 : m_xCfgOld = xCfg;
1114 72 : aWriteLock.unlock();
1115 : }
1116 :
1117 1728 : return xCfg;
1118 : }
1119 :
1120 : //-----------------------------------------------------------------------------
1121 1800 : css::uno::Reference< css::container::XNameAccess > PathSettings::fa_getCfgNew()
1122 : {
1123 1800 : const ::rtl::OUString CFG_NODE_NEW(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Office.Paths/Paths"));
1124 :
1125 : // SAFE ->
1126 1800 : ReadGuard aReadLock(m_aLock);
1127 1800 : css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
1128 1800 : css::uno::Reference< css::container::XNameAccess > xCfg = m_xCfgNew;
1129 1800 : aReadLock.unlock();
1130 : // <- SAFE
1131 :
1132 1800 : 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 72 : css::uno::UNO_QUERY_THROW);
1140 :
1141 : // SAFE ->
1142 72 : WriteGuard aWriteLock(m_aLock);
1143 72 : m_xCfgNew = xCfg;
1144 72 : m_xCfgNewListener = new WeakChangesListener(this);
1145 72 : aWriteLock.unlock();
1146 :
1147 72 : css::uno::Reference< css::util::XChangesNotifier > xBroadcaster(xCfg, css::uno::UNO_QUERY_THROW);
1148 72 : xBroadcaster->addChangesListener(m_xCfgNewListener);
1149 : }
1150 :
1151 1800 : return xCfg;
1152 : }
1153 :
1154 : } // namespace framework
1155 :
1156 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|