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