LCOV - code coverage report
Current view: top level - solver/unxlngi6.pro/inc/comphelper - accessiblecontexthelper.hxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 33 33 100.0 %
Date: 2012-08-25 Functions: 14 14 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 9 18 50.0 %

           Branch data     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                 :            : #ifndef COMPHELPER_ACCESSIBLE_CONTEXT_HELPER_HXX
      21                 :            : #define COMPHELPER_ACCESSIBLE_CONTEXT_HELPER_HXX
      22                 :            : 
      23                 :            : #include <cppuhelper/compbase2.hxx>
      24                 :            : #include <com/sun/star/accessibility/XAccessibleContext.hpp>
      25                 :            : #include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp>
      26                 :            : #include <com/sun/star/lang/DisposedException.hpp>
      27                 :            : #include <comphelper/broadcasthelper.hxx>
      28                 :            : #include "comphelper/comphelperdllapi.h"
      29                 :            : 
      30                 :            : //.........................................................................
      31                 :            : namespace comphelper
      32                 :            : {
      33                 :            : //.........................................................................
      34                 :            : 
      35                 :            :     //=====================================================================
      36                 :            :     //= IMutex
      37                 :            :     //=====================================================================
      38                 :            : 
      39                 :            :     // This whole thingie here (own mutex classes and such) is a HACK. I hate the SolarMutex.
      40                 :            :     // See below for more explanations ....
      41                 :            : 
      42                 :            :     /** abstract interface for implementing a mutex
      43                 :            :     */
      44                 :       5304 :     class COMPHELPER_DLLPUBLIC IMutex
      45                 :            :     {
      46                 :            :     public:
      47                 :            :         virtual ~IMutex();
      48                 :            :         virtual void acquire() = 0;
      49                 :            :         virtual void release() = 0;
      50                 :            :     };
      51                 :            : 
      52                 :            :     //=====================================================================
      53                 :            :     //= OMutexGuard
      54                 :            :     //=====================================================================
      55                 :            : 
      56                 :            :     class OMutexGuard
      57                 :            :     {
      58                 :            :         IMutex* m_pMutex;
      59                 :            :     public:
      60                 :      85224 :         inline OMutexGuard( IMutex* _pMutex )
      61                 :      85224 :             :m_pMutex( _pMutex )
      62                 :            :         {
      63         [ +  - ]:      85224 :             if ( m_pMutex )
      64                 :      85224 :                 m_pMutex->acquire();
      65                 :      85224 :         }
      66                 :            : 
      67                 :      85224 :         inline ~OMutexGuard( )
      68                 :            :         {
      69         [ +  - ]:      85224 :             if ( m_pMutex )
      70                 :      85224 :                 m_pMutex->release();
      71                 :      85224 :         }
      72                 :            :     };
      73                 :            : 
      74                 :            :     //=====================================================================
      75                 :            :     //= OAccessibleContextHelper
      76                 :            :     //=====================================================================
      77                 :            : 
      78                 :            :     class OContextHelper_Impl;
      79                 :            :     typedef ::cppu::WeakAggComponentImplHelper2 <   ::com::sun::star::accessibility::XAccessibleContext,
      80                 :            :                                                     ::com::sun::star::accessibility::XAccessibleEventBroadcaster
      81                 :            :                                                 >   OAccessibleContextHelper_Base;
      82                 :            : 
      83                 :            :     /** helper class for implementing an AccessibleContext
      84                 :            :     */
      85                 :            :     class COMPHELPER_DLLPUBLIC OAccessibleContextHelper
      86                 :            :                 :public ::comphelper::OBaseMutex
      87                 :            :                 ,public OAccessibleContextHelper_Base
      88                 :            :     {
      89                 :            :     private:
      90                 :            :         OContextHelper_Impl*    m_pImpl;
      91                 :            : 
      92                 :            :     protected:
      93                 :            :         OAccessibleContextHelper( );
      94                 :            :         ~OAccessibleContextHelper( );
      95                 :            : 
      96                 :            :         /** ctor
      97                 :            : 
      98                 :            :             <p>If you need additional object safety for your class, and want to ensure that your own
      99                 :            :             mutex is locked before the mutex this class provides is, than use this ctor.</p>
     100                 :            : 
     101                 :            :             <p>Beware that this is a hack. Unfortunately, OpenOffice.org has two different mutex hierarchies,
     102                 :            :             which are not compatible. In addition, wide parts of the code (especially VCL) is not thread-safe,
     103                 :            :             but instead relies on a <em>single global mutex</em>. As a consequence, components using
     104                 :            :             directly or indirectly such code need to care for this global mutex. Yes, this is as ugly as
     105                 :            :             anything.</p>
     106                 :            : 
     107                 :            :             <p>Note that the external lock is used as additional lock, not as the only one. The own mutex of the
     108                 :            :             instance is used for internal actions, and every action which potentially involves external code
     109                 :            :             (for instance every call to a virtual method overridden by derivees) is <em>additionally</em> and
     110                 :            :             <em>first</em> guarded by with the external lock.</p>
     111                 :            : 
     112                 :            :             <p>Beware of the lifetime of the lock - you must ensure that the lock exists at least as long as
     113                 :            :             the context does. A good approach to implement the lock may be to derive you own context
     114                 :            :             not only from OAccessibleContextHelper, but also from IMutex.</p>
     115                 :            : 
     116                 :            :             <p>One more note. This lock is definately not used once the dtor is reached. Means whatever
     117                 :            :             the dtor implementation does, it does <em>not</em> guard the external lock. See this as a contract.
     118                 :            :             <br/>You should ensure the same thing for own derivees which do not supply the lock themself,
     119                 :            :             but get them from yet another derivee.</p>
     120                 :            :             @see forgetExternalLock
     121                 :            :         */
     122                 :            :         OAccessibleContextHelper( IMutex* _pExternalLock );
     123                 :            : 
     124                 :            :         /** late construction
     125                 :            :         @param _rxAccessible
     126                 :            :             the Accessible object which created this context.
     127                 :            :             <p>If your derived implementation implements the XAccessible (and does not follow the proposed
     128                 :            :             separation of XAccessible from XAccessibleContext), you may pass <code>this</code> here.</p>
     129                 :            : 
     130                 :            :             <p>The object is hold weak, so it's life time is not affected.</p>
     131                 :            : 
     132                 :            :             <p>The object is needed for performance reasons: for <method>getAccessibleIndexInParent</method>,
     133                 :            :             all children (which are XAccessible's theirself) of our parent have to be asked. If we know our
     134                 :            :             XAccessible, we can compare it with all the children, instead of asking all children for their
     135                 :            :             context and comparing this context with ourself.</p>
     136                 :            :         */
     137                 :            :         void    lateInit( const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& _rxAccessible );
     138                 :            : 
     139                 :            :         /** retrieves the creator previously set with <method>lateInit</method>
     140                 :            :         */
     141                 :            :         ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
     142                 :            :                 getAccessibleCreator( ) const;
     143                 :            : 
     144                 :            :         /** forgets the reference to the external lock, if present.
     145                 :            : 
     146                 :            :             <p>This means any further locking will not be guard the external lock anymore, never.</p>
     147                 :            : 
     148                 :            :             <p>To be used in derived classes which do not supply the external lock themself, but instead get
     149                 :            :             them passed from own derivees (or clients).</p>
     150                 :            :         */
     151                 :            :         void    forgetExternalLock();
     152                 :            : 
     153                 :            :     public:
     154                 :            :         // XAccessibleEventBroadcaster
     155                 :            :         using WeakAggComponentImplHelperBase::addEventListener;
     156                 :            :         virtual void SAL_CALL addEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException);
     157                 :            :         using WeakAggComponentImplHelperBase::removeEventListener;
     158                 :            :         virtual void SAL_CALL removeEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException);
     159                 :            : 
     160                 :            :         // XAccessibleContext - still waiting to be overwritten
     161                 :            :         virtual sal_Int32 SAL_CALL getAccessibleChildCount(  ) throw (::com::sun::star::uno::RuntimeException) = 0;
     162                 :            :         virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL getAccessibleChild( sal_Int32 i ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException) = 0;
     163                 :            :         virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL getAccessibleParent(  ) throw (::com::sun::star::uno::RuntimeException) = 0;
     164                 :            :         virtual sal_Int16 SAL_CALL getAccessibleRole(  ) throw (::com::sun::star::uno::RuntimeException) = 0;
     165                 :            :         virtual ::rtl::OUString SAL_CALL getAccessibleDescription(  ) throw (::com::sun::star::uno::RuntimeException) = 0;
     166                 :            :         virtual ::rtl::OUString SAL_CALL getAccessibleName(  ) throw (::com::sun::star::uno::RuntimeException) = 0;
     167                 :            :         virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleRelationSet > SAL_CALL getAccessibleRelationSet(  ) throw (::com::sun::star::uno::RuntimeException) = 0;
     168                 :            :         virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleStateSet > SAL_CALL getAccessibleStateSet(  ) throw (::com::sun::star::uno::RuntimeException) = 0;
     169                 :            : 
     170                 :            :         // XAccessibleContext - default implementations
     171                 :            :         /** default implementation for retrieving the index of this object within the parent
     172                 :            :             <p>This basic implementation here returns the index <code>i</code> of the child for which
     173                 :            :                 <code>&lt;parent&gt;.getAccessibleChild( i )</code> equals our creator.</p>
     174                 :            :         */
     175                 :            :         virtual sal_Int32 SAL_CALL getAccessibleIndexInParent(  ) throw (::com::sun::star::uno::RuntimeException);
     176                 :            :         /** default implementation for retrieving the locale
     177                 :            :             <p>This basic implementation returns the locale of the parent context,
     178                 :            :             as retrieved via getAccessibleParent()->getAccessibleContext.</p>
     179                 :            :         */
     180                 :            :         virtual ::com::sun::star::lang::Locale SAL_CALL getLocale(  ) throw (::com::sun::star::accessibility::IllegalAccessibleComponentStateException, ::com::sun::star::uno::RuntimeException);
     181                 :            : 
     182                 :            :     public:
     183                 :            :         // helper struct for granting selective access rights
     184                 :            :         struct OAccessControl
     185                 :            :         {
     186                 :            :             friend class OContextEntryGuard;
     187                 :            :             friend class OContextHelper_Impl;
     188                 :            :             friend class OExternalLockGuard;
     189                 :            :         private:
     190                 :     258113 :             OAccessControl() { }
     191                 :            :         };
     192                 :            : 
     193                 :            :         // ensures that the object is alive
     194                 :            :         inline  void            ensureAlive( const OAccessControl& ) const SAL_THROW( ( ::com::sun::star::lang::DisposedException ) );
     195                 :            :         inline  IMutex*         getExternalLock( const OAccessControl& );
     196                 :            :         inline  ::osl::Mutex&   GetMutex( const OAccessControl& );
     197                 :            : 
     198                 :            :     protected:
     199                 :            :         // OComponentHelper
     200                 :            :         virtual void SAL_CALL disposing();
     201                 :            : 
     202                 :            :     protected:
     203                 :            :         // helper
     204                 :            :         /** notifies all AccessibleEventListeners of a certain event
     205                 :            : 
     206                 :            :         @precond    not too be called with our mutex locked
     207                 :            :         @param  _nEventId
     208                 :            :             the id of the even. See AccessibleEventType
     209                 :            :         @param  _rOldValue
     210                 :            :             the old value to be notified
     211                 :            :         @param  _rNewValue
     212                 :            :             the new value to be notified
     213                 :            :         */
     214                 :            :         virtual void SAL_CALL   NotifyAccessibleEvent(
     215                 :            :                     const sal_Int16 _nEventId,
     216                 :            :                     const ::com::sun::star::uno::Any& _rOldValue,
     217                 :            :                     const ::com::sun::star::uno::Any& _rNewValue
     218                 :            :                 );
     219                 :            : 
     220                 :            :         // life time control
     221                 :            :         /// checks whether the object is alive (returns <TRUE/> then) or disposed
     222                 :            :         sal_Bool    isAlive() const;
     223                 :            :         /// checks for beeing alive. If the object is already disposed (i.e. not alive), an exception is thrown.
     224                 :            :         void        ensureAlive() const SAL_THROW( ( ::com::sun::star::lang::DisposedException ) );
     225                 :            : 
     226                 :            :         /** ensures that the object is disposed.
     227                 :            :         @precond
     228                 :            :             to be called from within the destructor of your derived class only!
     229                 :            :         */
     230                 :            :         void        ensureDisposed( );
     231                 :            : 
     232                 :            :         /** shortcut for retrieving the context of the parent (returned by getAccessibleParent)
     233                 :            :         */
     234                 :            :         ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext >
     235                 :            :                     implGetParentContext() SAL_THROW( ( ::com::sun::star::uno::RuntimeException ) );
     236                 :            : 
     237                 :            :         // access to the base class' broadcast helper/mutex
     238                 :       5805 :         ::cppu::OBroadcastHelper&       GetBroadcastHelper()        { return rBHelper; }
     239                 :     173826 :         const ::cppu::OBroadcastHelper& GetBroadcastHelper() const  { return rBHelper; }
     240                 :      98111 :         ::osl::Mutex&                   GetMutex()                  { return m_aMutex; }
     241                 :            :         IMutex*                         getExternalLock( );
     242                 :            :     };
     243                 :            : 
     244                 :            :     //---------------------------------------------------------------------
     245                 :      86503 :     inline  void OAccessibleContextHelper::ensureAlive( const OAccessControl& ) const SAL_THROW( ( ::com::sun::star::lang::DisposedException ) )
     246                 :            :     {
     247                 :      86503 :         ensureAlive();
     248                 :      86503 :     }
     249                 :            : 
     250                 :            :     //---------------------------------------------------------------------
     251                 :      85107 :     inline  IMutex* OAccessibleContextHelper::getExternalLock( const OAccessControl& )
     252                 :            :     {
     253                 :      85107 :         return getExternalLock();
     254                 :            :     }
     255                 :            : 
     256                 :            :     //---------------------------------------------------------------------
     257                 :      86503 :     inline  ::osl::Mutex& OAccessibleContextHelper::GetMutex( const OAccessControl& )
     258                 :            :     {
     259                 :      86503 :         return GetMutex();
     260                 :            :     }
     261                 :            : 
     262                 :            :     //=====================================================================
     263                 :            :     //= OContextEntryGuard
     264                 :            :     //=====================================================================
     265                 :            :     typedef ::osl::ClearableMutexGuard  OContextEntryGuard_Base;
     266                 :            :     /** helper class for guarding the entry into OAccessibleContextHelper methods.
     267                 :            : 
     268                 :            :         <p>The class has two responsibilities:
     269                 :            :         <ul><li>it locks the mutex of an OAccessibleContextHelper instance, as long as the guard lives</li>
     270                 :            :             <li>it checks if an given OAccessibleContextHelper instance is alive, else an exception is thrown
     271                 :            :                 our of the constructor of the guard</li>
     272                 :            :         </ul>
     273                 :            :         <br/>
     274                 :            :         This makes it your first choice (hopefully :) for guarding any interface method implementations of
     275                 :            :         you derived class.
     276                 :            :         </p>
     277                 :            :     */
     278                 :            :     class OContextEntryGuard : public OContextEntryGuard_Base
     279                 :            :     {
     280                 :            :     public:
     281                 :            :         /** constructs the guard
     282                 :            : 
     283                 :            :             <p>The given context (it's mutex, respectively) is locked, and an exception is thrown if the context
     284                 :            :             is not alive anymore. In the latter case, of course, the mutex is freed, again.</p>
     285                 :            : 
     286                 :            :         @param _pContext
     287                 :            :             the context which shall be guarded
     288                 :            :         @precond <arg>_pContext</arg> != NULL
     289                 :            :         */
     290                 :            :         inline OContextEntryGuard( OAccessibleContextHelper* _pContext );
     291                 :            : 
     292                 :            :         /** destructs the guard.
     293                 :            :             <p>The context (it's mutex, respectively) is unlocked.</p>
     294                 :            :         */
     295                 :            :         inline ~OContextEntryGuard();
     296                 :            :     };
     297                 :            : 
     298                 :            :     //.....................................................................
     299                 :      86503 :     inline OContextEntryGuard::OContextEntryGuard( OAccessibleContextHelper* _pContext  )
     300         [ +  - ]:      86503 :         :OContextEntryGuard_Base( _pContext->GetMutex( OAccessibleContextHelper::OAccessControl() ) )
     301                 :            :     {
     302         [ +  - ]:      86503 :         _pContext->ensureAlive( OAccessibleContextHelper::OAccessControl() );
     303                 :      86503 :     }
     304                 :            : 
     305                 :            :     //.....................................................................
     306                 :      86503 :     inline OContextEntryGuard::~OContextEntryGuard()
     307                 :            :     {
     308                 :      86503 :     }
     309                 :            : 
     310                 :            :     //=====================================================================
     311                 :            :     //= OExternalLockGuard
     312                 :            :     //=====================================================================
     313                 :            :     class OExternalLockGuard
     314                 :            :             :public OMutexGuard
     315                 :            :             ,public OContextEntryGuard
     316                 :            :     {
     317                 :            :     public:
     318                 :            :         inline OExternalLockGuard( OAccessibleContextHelper* _pContext );
     319                 :            :         inline ~OExternalLockGuard( );
     320                 :            :     };
     321                 :            : 
     322                 :            :     //.....................................................................
     323                 :      85107 :     inline OExternalLockGuard::OExternalLockGuard( OAccessibleContextHelper* _pContext )
     324                 :            :         :OMutexGuard( _pContext->getExternalLock( OAccessibleContextHelper::OAccessControl() ) )
     325 [ +  - ][ +  - ]:      85107 :         ,OContextEntryGuard( _pContext )
                 [ +  - ]
     326                 :            :     {
     327                 :            :         // #102438#
     328                 :            :         // Only lock the external mutex,
     329                 :            :         // release the ::osl::Mutex of the OAccessibleContextHelper instance.
     330                 :            :         // If you call into another UNO object with locked ::osl::Mutex,
     331                 :            :         // this may lead to dead locks.
     332         [ +  - ]:      85107 :         clear();
     333                 :      85107 :     }
     334                 :            : 
     335                 :            :     //.....................................................................
     336         [ +  - ]:      85107 :     inline OExternalLockGuard::~OExternalLockGuard( )
     337                 :            :     {
     338                 :      85107 :     }
     339                 :            : 
     340                 :            : //.........................................................................
     341                 :            : }   // namespace comphelper
     342                 :            : //.........................................................................
     343                 :            : 
     344                 :            : #endif // COMPHELPER_ACCESSIBLE_CONTEXT_HELPER_HXX
     345                 :            : 
     346                 :            : 
     347                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10