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 : : #include <classes/propertysethelper.hxx>
30 : : #include <threadhelp/transactionguard.hxx>
31 : : #include <threadhelp/readguard.hxx>
32 : : #include <threadhelp/writeguard.hxx>
33 : :
34 : :
35 : : namespace framework{
36 : :
37 : :
38 : : //-----------------------------------------------------------------------------
39 : 1747 : PropertySetHelper::PropertySetHelper(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR ,
40 : : LockHelper* pExternalLock ,
41 : : TransactionManager* pExternalTransactionManager ,
42 : : sal_Bool bReleaseLockOnCall )
43 : : : m_xSMGR (xSMGR )
44 [ + - ]: 1747 : , m_lSimpleChangeListener(pExternalLock->getShareableOslMutex())
45 [ + - ]: 1747 : , m_lVetoChangeListener (pExternalLock->getShareableOslMutex())
46 : : , m_bReleaseLockOnCall (bReleaseLockOnCall )
47 : : , m_rLock (*pExternalLock )
48 [ + - ][ + - ]: 5241 : , m_rTransactionManager (*pExternalTransactionManager )
[ + - ][ + - ]
49 : : {
50 : 1747 : }
51 : :
52 : : //-----------------------------------------------------------------------------
53 [ + - ][ + - ]: 1656 : PropertySetHelper::~PropertySetHelper()
[ + - ][ + - ]
54 : : {
55 [ - + ]: 1656 : }
56 : :
57 : : //-----------------------------------------------------------------------------
58 : 1747 : void PropertySetHelper::impl_setPropertyChangeBroadcaster(const css::uno::Reference< css::uno::XInterface >& xBroadcaster)
59 : : {
60 [ + - ]: 1747 : TransactionGuard aTransaction(m_rTransactionManager, E_SOFTEXCEPTIONS);
61 : :
62 : : // SAFE ->
63 [ + - ]: 1747 : WriteGuard aWriteLock(m_rLock);
64 [ + - ]: 1747 : m_xBroadcaster = xBroadcaster;
65 [ + - ][ + - ]: 1747 : aWriteLock.unlock();
[ + - ]
66 : : // <- SAFE
67 : 1747 : }
68 : :
69 : : //-----------------------------------------------------------------------------
70 : 8735 : void SAL_CALL PropertySetHelper::impl_addPropertyInfo(const css::beans::Property& aProperty)
71 : : throw(css::beans::PropertyExistException,
72 : : css::uno::Exception )
73 : : {
74 [ + - ]: 8735 : TransactionGuard aTransaction(m_rTransactionManager, E_SOFTEXCEPTIONS);
75 : :
76 : : // SAFE ->
77 [ + - ]: 8735 : WriteGuard aWriteLock(m_rLock);
78 : :
79 [ + - ]: 8735 : PropertySetHelper::TPropInfoHash::const_iterator pIt = m_lProps.find(aProperty.Name);
80 [ - + ][ + - ]: 8735 : if (pIt != m_lProps.end())
81 [ # # ]: 0 : throw css::beans::PropertyExistException();
82 : :
83 [ + - ][ + - ]: 8735 : m_lProps[aProperty.Name] = aProperty;
[ + - ]
84 : : // <- SAFE
85 : 8735 : }
86 : :
87 : : //-----------------------------------------------------------------------------
88 : 0 : void SAL_CALL PropertySetHelper::impl_removePropertyInfo(const ::rtl::OUString& sProperty)
89 : : throw(css::beans::UnknownPropertyException,
90 : : css::uno::Exception )
91 : : {
92 [ # # ]: 0 : TransactionGuard aTransaction(m_rTransactionManager, E_SOFTEXCEPTIONS);
93 : :
94 : : // SAFE ->
95 [ # # ]: 0 : WriteGuard aWriteLock(m_rLock);
96 : :
97 [ # # ]: 0 : PropertySetHelper::TPropInfoHash::iterator pIt = m_lProps.find(sProperty);
98 [ # # ][ # # ]: 0 : if (pIt == m_lProps.end())
99 [ # # ]: 0 : throw css::beans::UnknownPropertyException();
100 : :
101 [ # # ][ # # ]: 0 : m_lProps.erase(pIt);
[ # # ]
102 : : // <- SAFE
103 : 0 : }
104 : :
105 : : //-----------------------------------------------------------------------------
106 : 1747 : void SAL_CALL PropertySetHelper::impl_enablePropertySet()
107 : : {
108 : 1747 : }
109 : :
110 : : //-----------------------------------------------------------------------------
111 : 1656 : void SAL_CALL PropertySetHelper::impl_disablePropertySet()
112 : : {
113 [ + - ]: 1656 : TransactionGuard aTransaction(m_rTransactionManager, E_SOFTEXCEPTIONS);
114 : :
115 : : // SAFE ->
116 [ + - ]: 1656 : WriteGuard aWriteLock(m_rLock);
117 : :
118 [ + - ]: 1656 : css::uno::Reference< css::uno::XInterface > xThis(static_cast< css::beans::XPropertySet* >(this), css::uno::UNO_QUERY);
119 [ + - ]: 1656 : css::lang::EventObject aEvent(xThis);
120 : :
121 [ + - ]: 1656 : m_lSimpleChangeListener.disposeAndClear(aEvent);
122 [ + - ]: 1656 : m_lVetoChangeListener.disposeAndClear(aEvent);
123 [ + - ]: 1656 : m_lProps.free();
124 : :
125 [ + - ][ + - ]: 1656 : aWriteLock.unlock();
[ + - ][ + - ]
126 : : // <- SAFE
127 : 1656 : }
128 : :
129 : : //-----------------------------------------------------------------------------
130 : 2 : sal_Bool PropertySetHelper::impl_existsVeto(const css::beans::PropertyChangeEvent& aEvent)
131 : : {
132 : : /* Dont use the lock here!
133 : : The used helper is threadsafe and it lives for the whole lifetime of
134 : : our own object.
135 : : */
136 [ + - ]: 2 : ::cppu::OInterfaceContainerHelper* pVetoListener = m_lVetoChangeListener.getContainer(aEvent.PropertyName);
137 [ + - ]: 2 : if (! pVetoListener)
138 : 2 : return sal_False;
139 : :
140 [ # # ]: 0 : ::cppu::OInterfaceIteratorHelper pListener(*pVetoListener);
141 [ # # ]: 0 : while (pListener.hasMoreElements())
142 : : {
143 : : try
144 : : {
145 : : css::uno::Reference< css::beans::XVetoableChangeListener > xListener(
146 [ # # ]: 0 : ((css::beans::XVetoableChangeListener*)pListener.next()),
147 [ # # ]: 0 : css::uno::UNO_QUERY_THROW);
148 [ # # ][ # # ]: 0 : xListener->vetoableChange(aEvent);
149 : : }
150 [ # # # # : 0 : catch(const css::uno::RuntimeException&)
# ]
151 [ # # ]: 0 : { pListener.remove(); }
152 [ # # ]: 0 : catch(const css::beans::PropertyVetoException&)
153 : 0 : { return sal_True; }
154 : : }
155 : :
156 [ # # ]: 2 : return sal_False;
157 : : }
158 : :
159 : : //-----------------------------------------------------------------------------
160 : 2 : void PropertySetHelper::impl_notifyChangeListener(const css::beans::PropertyChangeEvent& aEvent)
161 : : {
162 : : /* Dont use the lock here!
163 : : The used helper is threadsafe and it lives for the whole lifetime of
164 : : our own object.
165 : : */
166 [ + - ]: 2 : ::cppu::OInterfaceContainerHelper* pSimpleListener = m_lSimpleChangeListener.getContainer(aEvent.PropertyName);
167 [ - + ]: 2 : if (! pSimpleListener)
168 : 2 : return;
169 : :
170 [ # # ]: 0 : ::cppu::OInterfaceIteratorHelper pListener(*pSimpleListener);
171 [ # # ]: 0 : while (pListener.hasMoreElements())
172 : : {
173 : : try
174 : : {
175 : : css::uno::Reference< css::beans::XPropertyChangeListener > xListener(
176 [ # # ]: 0 : ((css::beans::XVetoableChangeListener*)pListener.next()),
177 [ # # ]: 0 : css::uno::UNO_QUERY_THROW);
178 [ # # ][ # # ]: 0 : xListener->propertyChange(aEvent);
179 : : }
180 [ # # # # ]: 0 : catch(const css::uno::RuntimeException&)
181 [ # # ]: 0 : { pListener.remove(); }
182 [ # # ]: 2 : }
183 : : }
184 : :
185 : : //-----------------------------------------------------------------------------
186 : 2 : css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL PropertySetHelper::getPropertySetInfo()
187 : : throw(css::uno::RuntimeException)
188 : : {
189 [ + - ]: 2 : TransactionGuard aTransaction(m_rTransactionManager, E_HARDEXCEPTIONS);
190 : :
191 [ + - ]: 2 : css::uno::Reference< css::beans::XPropertySetInfo > xInfo(static_cast< css::beans::XPropertySetInfo* >(this), css::uno::UNO_QUERY_THROW);
192 [ + - ]: 2 : return xInfo;
193 : : }
194 : :
195 : : //-----------------------------------------------------------------------------
196 : 2 : void SAL_CALL PropertySetHelper::setPropertyValue(const ::rtl::OUString& sProperty,
197 : : const css::uno::Any& aValue )
198 : : throw(css::beans::UnknownPropertyException,
199 : : css::beans::PropertyVetoException ,
200 : : css::lang::IllegalArgumentException ,
201 : : css::lang::WrappedTargetException ,
202 : : css::uno::RuntimeException )
203 : : {
204 : : // TODO look for e.g. readonly props and reject setProp() call!
205 : :
206 [ + - ]: 2 : TransactionGuard aTransaction(m_rTransactionManager, E_HARDEXCEPTIONS);
207 : :
208 : : // SAFE ->
209 [ + - ]: 2 : WriteGuard aWriteLock(m_rLock);
210 : :
211 [ + - ]: 2 : PropertySetHelper::TPropInfoHash::const_iterator pIt = m_lProps.find(sProperty);
212 [ - + ][ + - ]: 2 : if (pIt == m_lProps.end())
213 [ # # ]: 0 : throw css::beans::UnknownPropertyException();
214 : :
215 [ + - ]: 2 : css::beans::Property aPropInfo = pIt->second;
216 : :
217 : 2 : sal_Bool bLocked = sal_True;
218 [ - + ]: 2 : if (m_bReleaseLockOnCall)
219 : : {
220 [ # # ]: 0 : aWriteLock.unlock();
221 : 0 : bLocked = sal_False;
222 : : // <- SAFE
223 : : }
224 : :
225 [ + - ]: 2 : css::uno::Any aCurrentValue = impl_getPropertyValue(aPropInfo.Name, aPropInfo.Handle);
226 : :
227 [ - + ]: 2 : if (! bLocked)
228 : : {
229 : : // SAFE ->
230 [ # # ]: 0 : aWriteLock.lock();
231 : 0 : bLocked = sal_True;
232 : : }
233 : :
234 : 2 : sal_Bool bWillBeChanged = (aCurrentValue != aValue);
235 [ - + ]: 2 : if (! bWillBeChanged)
236 : 2 : return;
237 : :
238 [ + - ]: 2 : css::beans::PropertyChangeEvent aEvent;
239 : 2 : aEvent.PropertyName = aPropInfo.Name;
240 : 2 : aEvent.Further = sal_False;
241 : 2 : aEvent.PropertyHandle = aPropInfo.Handle;
242 : 2 : aEvent.OldValue = aCurrentValue;
243 : 2 : aEvent.NewValue = aValue;
244 [ + - ][ + - ]: 2 : aEvent.Source = css::uno::Reference< css::uno::XInterface >(m_xBroadcaster.get(), css::uno::UNO_QUERY);
[ + - ]
245 : :
246 [ - + ]: 2 : if (m_bReleaseLockOnCall)
247 : : {
248 [ # # ]: 0 : aWriteLock.unlock();
249 : 0 : bLocked = sal_False;
250 : : // <- SAFE
251 : : }
252 : :
253 [ + - ][ - + ]: 2 : if (impl_existsVeto(aEvent))
254 [ # # ]: 0 : throw css::beans::PropertyVetoException();
255 : :
256 [ + - ]: 2 : impl_setPropertyValue(aPropInfo.Name, aPropInfo.Handle, aValue);
257 : :
258 [ + - ][ + - ]: 2 : impl_notifyChangeListener(aEvent);
[ - + ][ - + ]
[ + - ][ - + ]
[ + - ][ + - ]
259 : : }
260 : :
261 : : //-----------------------------------------------------------------------------
262 : 52821 : css::uno::Any SAL_CALL PropertySetHelper::getPropertyValue(const ::rtl::OUString& sProperty)
263 : : throw(css::beans::UnknownPropertyException,
264 : : css::lang::WrappedTargetException ,
265 : : css::uno::RuntimeException )
266 : : {
267 [ + - ]: 52821 : TransactionGuard aTransaction(m_rTransactionManager, E_HARDEXCEPTIONS);
268 : :
269 : : // SAFE ->
270 [ + - ]: 52821 : ReadGuard aReadLock(m_rLock);
271 : :
272 [ + - ]: 52821 : PropertySetHelper::TPropInfoHash::const_iterator pIt = m_lProps.find(sProperty);
273 [ - + ][ + - ]: 52821 : if (pIt == m_lProps.end())
274 [ # # ]: 0 : throw css::beans::UnknownPropertyException();
275 : :
276 [ + - ]: 52821 : css::beans::Property aPropInfo = pIt->second;
277 : :
278 [ - + ]: 52821 : if (m_bReleaseLockOnCall)
279 [ # # ]: 0 : aReadLock.unlock();
280 : :
281 [ + - ][ + - ]: 52821 : return impl_getPropertyValue(aPropInfo.Name, aPropInfo.Handle);
[ + - ]
282 : : }
283 : :
284 : : //-----------------------------------------------------------------------------
285 : 0 : void SAL_CALL PropertySetHelper::addPropertyChangeListener(const ::rtl::OUString& sProperty,
286 : : const css::uno::Reference< css::beans::XPropertyChangeListener >& xListener)
287 : : throw(css::beans::UnknownPropertyException,
288 : : css::lang::WrappedTargetException ,
289 : : css::uno::RuntimeException )
290 : : {
291 [ # # ]: 0 : TransactionGuard aTransaction(m_rTransactionManager, E_HARDEXCEPTIONS);
292 : :
293 : : // SAFE ->
294 [ # # ]: 0 : ReadGuard aReadLock(m_rLock);
295 : :
296 [ # # ]: 0 : PropertySetHelper::TPropInfoHash::const_iterator pIt = m_lProps.find(sProperty);
297 [ # # ][ # # ]: 0 : if (pIt == m_lProps.end())
298 [ # # ]: 0 : throw css::beans::UnknownPropertyException();
299 : :
300 [ # # ]: 0 : aReadLock.unlock();
301 : : // <- SAFE
302 : :
303 [ # # ][ # # ]: 0 : m_lSimpleChangeListener.addInterface(sProperty, xListener);
[ # # ]
304 : 0 : }
305 : :
306 : : //-----------------------------------------------------------------------------
307 : 0 : void SAL_CALL PropertySetHelper::removePropertyChangeListener(const ::rtl::OUString& sProperty,
308 : : const css::uno::Reference< css::beans::XPropertyChangeListener >& xListener)
309 : : throw(css::beans::UnknownPropertyException,
310 : : css::lang::WrappedTargetException ,
311 : : css::uno::RuntimeException )
312 : : {
313 [ # # ]: 0 : TransactionGuard aTransaction(m_rTransactionManager, E_SOFTEXCEPTIONS);
314 : :
315 : : // SAFE ->
316 [ # # ]: 0 : ReadGuard aReadLock(m_rLock);
317 : :
318 [ # # ]: 0 : PropertySetHelper::TPropInfoHash::const_iterator pIt = m_lProps.find(sProperty);
319 [ # # ][ # # ]: 0 : if (pIt == m_lProps.end())
320 [ # # ]: 0 : throw css::beans::UnknownPropertyException();
321 : :
322 [ # # ]: 0 : aReadLock.unlock();
323 : : // <- SAFE
324 : :
325 [ # # ][ # # ]: 0 : m_lSimpleChangeListener.removeInterface(sProperty, xListener);
[ # # ]
326 : 0 : }
327 : :
328 : : //-----------------------------------------------------------------------------
329 : 0 : void SAL_CALL PropertySetHelper::addVetoableChangeListener(const ::rtl::OUString& sProperty,
330 : : const css::uno::Reference< css::beans::XVetoableChangeListener >& xListener)
331 : : throw(css::beans::UnknownPropertyException,
332 : : css::lang::WrappedTargetException ,
333 : : css::uno::RuntimeException )
334 : : {
335 [ # # ]: 0 : TransactionGuard aTransaction(m_rTransactionManager, E_HARDEXCEPTIONS);
336 : :
337 : : // SAFE ->
338 [ # # ]: 0 : ReadGuard aReadLock(m_rLock);
339 : :
340 [ # # ]: 0 : PropertySetHelper::TPropInfoHash::const_iterator pIt = m_lProps.find(sProperty);
341 [ # # ][ # # ]: 0 : if (pIt == m_lProps.end())
342 [ # # ]: 0 : throw css::beans::UnknownPropertyException();
343 : :
344 [ # # ]: 0 : aReadLock.unlock();
345 : : // <- SAFE
346 : :
347 [ # # ][ # # ]: 0 : m_lVetoChangeListener.addInterface(sProperty, xListener);
[ # # ]
348 : 0 : }
349 : :
350 : : //-----------------------------------------------------------------------------
351 : 0 : void SAL_CALL PropertySetHelper::removeVetoableChangeListener(const ::rtl::OUString& sProperty,
352 : : const css::uno::Reference< css::beans::XVetoableChangeListener >& xListener)
353 : : throw(css::beans::UnknownPropertyException,
354 : : css::lang::WrappedTargetException ,
355 : : css::uno::RuntimeException )
356 : : {
357 [ # # ]: 0 : TransactionGuard aTransaction(m_rTransactionManager, E_SOFTEXCEPTIONS);
358 : :
359 : : // SAFE ->
360 [ # # ]: 0 : ReadGuard aReadLock(m_rLock);
361 : :
362 [ # # ]: 0 : PropertySetHelper::TPropInfoHash::const_iterator pIt = m_lProps.find(sProperty);
363 [ # # ][ # # ]: 0 : if (pIt == m_lProps.end())
364 [ # # ]: 0 : throw css::beans::UnknownPropertyException();
365 : :
366 [ # # ]: 0 : aReadLock.unlock();
367 : : // <- SAFE
368 : :
369 [ # # ][ # # ]: 0 : m_lVetoChangeListener.removeInterface(sProperty, xListener);
[ # # ]
370 : 0 : }
371 : :
372 : : //-----------------------------------------------------------------------------
373 : 2 : css::uno::Sequence< css::beans::Property > SAL_CALL PropertySetHelper::getProperties()
374 : : throw(css::uno::RuntimeException)
375 : : {
376 [ + - ]: 2 : TransactionGuard aTransaction(m_rTransactionManager, E_HARDEXCEPTIONS);
377 : :
378 : : // SAFE ->
379 [ + - ]: 2 : ReadGuard aReadLock(m_rLock);
380 : :
381 : 2 : sal_Int32 c = (sal_Int32)m_lProps.size();
382 [ + - ]: 2 : css::uno::Sequence< css::beans::Property > lProps(c);
383 : 2 : PropertySetHelper::TPropInfoHash::const_iterator pIt ;
384 : :
385 [ + + ][ + - ]: 24 : for ( pIt = m_lProps.begin();
386 [ + - ]: 12 : pIt != m_lProps.end() ;
387 : : ++pIt )
388 : : {
389 [ + - ][ + - ]: 10 : lProps[--c] = pIt->second;
390 : : }
391 : :
392 [ + - ][ + - ]: 2 : return lProps;
393 : : // <- SAFE
394 : : }
395 : :
396 : : //-----------------------------------------------------------------------------
397 : 0 : css::beans::Property SAL_CALL PropertySetHelper::getPropertyByName(const ::rtl::OUString& sName)
398 : : throw(css::beans::UnknownPropertyException,
399 : : css::uno::RuntimeException )
400 : : {
401 [ # # ]: 0 : TransactionGuard aTransaction(m_rTransactionManager, E_HARDEXCEPTIONS);
402 : :
403 : : // SAFE ->
404 [ # # ]: 0 : ReadGuard aReadLock(m_rLock);
405 : :
406 [ # # ]: 0 : PropertySetHelper::TPropInfoHash::const_iterator pIt = m_lProps.find(sName);
407 [ # # ][ # # ]: 0 : if (pIt == m_lProps.end())
408 [ # # ]: 0 : throw css::beans::UnknownPropertyException();
409 : :
410 [ # # ][ # # ]: 0 : return pIt->second;
[ # # ]
411 : : // <- SAFE
412 : : }
413 : :
414 : : //-----------------------------------------------------------------------------
415 : 0 : sal_Bool SAL_CALL PropertySetHelper::hasPropertyByName(const ::rtl::OUString& sName)
416 : : throw(css::uno::RuntimeException)
417 : : {
418 [ # # ]: 0 : TransactionGuard aTransaction(m_rTransactionManager, E_HARDEXCEPTIONS);
419 : :
420 : : // SAFE ->
421 [ # # ]: 0 : ReadGuard aReadLock(m_rLock);
422 : :
423 [ # # ]: 0 : PropertySetHelper::TPropInfoHash::iterator pIt = m_lProps.find(sName);
424 [ # # ]: 0 : sal_Bool bExist = (pIt != m_lProps.end());
425 : :
426 [ # # ][ # # ]: 0 : return bExist;
427 : : // <- SAFE
428 : : }
429 : :
430 : : } // namespace framework
431 : :
432 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|