LCOV - code coverage report
Current view: top level - dbaccess/source/core/dataaccess - databasecontext.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 323 0.0 %
Date: 2014-04-14 Functions: 0 54 0.0 %
Legend: Lines: hit not hit

          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             : #include "apitools.hxx"
      21             : #include "core_resource.hrc"
      22             : #include "core_resource.hxx"
      23             : #include "databasecontext.hxx"
      24             : #include "databasedocument.hxx"
      25             : #include "databaseregistrations.hxx"
      26             : #include "datasource.hxx"
      27             : #include "dbastrings.hrc"
      28             : #include "module_dba.hxx"
      29             : 
      30             : #include <com/sun/star/beans/NamedValue.hpp>
      31             : #include <com/sun/star/beans/PropertyAttribute.hpp>
      32             : #include <com/sun/star/beans/XPropertySet.hpp>
      33             : #include <com/sun/star/document/MacroExecMode.hpp>
      34             : #include <com/sun/star/document/XFilter.hpp>
      35             : #include <com/sun/star/document/XImporter.hpp>
      36             : #include <com/sun/star/frame/Desktop.hpp>
      37             : #include <com/sun/star/frame/XModel.hpp>
      38             : #include <com/sun/star/frame/XModel2.hpp>
      39             : #include <com/sun/star/frame/XTerminateListener.hpp>
      40             : #include <com/sun/star/lang/DisposedException.hpp>
      41             : #include <com/sun/star/registry/InvalidRegistryException.hpp>
      42             : #include <com/sun/star/sdbc/XDataSource.hpp>
      43             : #include <com/sun/star/task/InteractionClassification.hpp>
      44             : #include <com/sun/star/ucb/InteractiveIOException.hpp>
      45             : #include <com/sun/star/ucb/IOErrorCode.hpp>
      46             : #include <com/sun/star/task/InteractionHandler.hpp>
      47             : #include <com/sun/star/util/XCloseable.hpp>
      48             : 
      49             : #include <basic/basmgr.hxx>
      50             : #include <comphelper/enumhelper.hxx>
      51             : #include <comphelper/evtlistenerhlp.hxx>
      52             : #include <comphelper/namedvaluecollection.hxx>
      53             : #include <comphelper/processfactory.hxx>
      54             : #include <comphelper/sequence.hxx>
      55             : #include <cppuhelper/implbase1.hxx>
      56             : #include <cppuhelper/supportsservice.hxx>
      57             : #include <cppuhelper/typeprovider.hxx>
      58             : #include <cppuhelper/exc_hlp.hxx>
      59             : #include <svl/filenotation.hxx>
      60             : #include <tools/debug.hxx>
      61             : #include <tools/diagnose_ex.h>
      62             : #include <tools/urlobj.hxx>
      63             : #include <ucbhelper/content.hxx>
      64             : #include <unotools/confignode.hxx>
      65             : #include <unotools/pathoptions.hxx>
      66             : #include <unotools/sharedunocomponent.hxx>
      67             : #include <list>
      68             : 
      69             : using namespace ::com::sun::star::sdbc;
      70             : using namespace ::com::sun::star::sdb;
      71             : using namespace ::com::sun::star::beans;
      72             : using namespace ::com::sun::star::uno;
      73             : using namespace ::com::sun::star::document;
      74             : using namespace ::com::sun::star::frame;
      75             : using namespace ::com::sun::star::lang;
      76             : using namespace ::com::sun::star::container;
      77             : using namespace ::com::sun::star::util;
      78             : using namespace ::com::sun::star::registry;
      79             : using namespace ::com::sun::star;
      80             : using namespace ::cppu;
      81             : using namespace ::osl;
      82             : using namespace ::utl;
      83             : 
      84             : using ::com::sun::star::task::InteractionClassification_ERROR;
      85             : using ::com::sun::star::ucb::IOErrorCode_NO_FILE;
      86             : using ::com::sun::star::ucb::InteractiveIOException;
      87             : using ::com::sun::star::ucb::IOErrorCode_NOT_EXISTING;
      88             : using ::com::sun::star::ucb::IOErrorCode_NOT_EXISTING_PATH;
      89             : 
      90             : namespace dbaccess
      91             : {
      92             : 
      93             :         typedef ::cppu::WeakImplHelper1 <   XTerminateListener
      94             :                                         >   DatabaseDocumentLoader_Base;
      95           0 :         class DatabaseDocumentLoader : public DatabaseDocumentLoader_Base
      96             :         {
      97             :         private:
      98             :             Reference< XDesktop2 >               m_xDesktop;
      99             :             ::std::list< const ODatabaseModelImpl* >  m_aDatabaseDocuments;
     100             : 
     101             :         public:
     102             :             DatabaseDocumentLoader( const Reference<XComponentContext> & rxContext);
     103             : 
     104           0 :             inline void append(const ODatabaseModelImpl& _rModelImpl )
     105             :             {
     106           0 :                 m_aDatabaseDocuments.push_back(&_rModelImpl);
     107           0 :             }
     108           0 :             inline void remove(const ODatabaseModelImpl& _rModelImpl) { m_aDatabaseDocuments.remove(&_rModelImpl); }
     109             : 
     110             :         private:
     111             :             // XTerminateListener
     112             :             virtual void SAL_CALL queryTermination( const lang::EventObject& Event ) throw (TerminationVetoException, RuntimeException, std::exception) SAL_OVERRIDE;
     113             :             virtual void SAL_CALL notifyTermination( const lang::EventObject& Event ) throw (RuntimeException, std::exception) SAL_OVERRIDE;
     114             :             // XEventListener
     115             :             virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     116             :         };
     117             : 
     118           0 :         DatabaseDocumentLoader::DatabaseDocumentLoader( const Reference<XComponentContext> & rxContext )
     119             :         {
     120           0 :             acquire();
     121             :             try
     122             :             {
     123           0 :                 m_xDesktop.set( Desktop::create(rxContext) );
     124           0 :                 m_xDesktop->addTerminateListener( this );
     125             :             }
     126           0 :             catch( const Exception& )
     127             :             {
     128             :                 DBG_UNHANDLED_EXCEPTION();
     129             :             }
     130           0 :         }
     131             : 
     132             :         struct TerminateFunctor : ::std::unary_function<ODatabaseModelImpl* , void>
     133             :         {
     134           0 :             void operator()( const ODatabaseModelImpl* _pModelImpl ) const
     135             :             {
     136             :                 try
     137             :                 {
     138           0 :                     const Reference< XModel2> xModel( _pModelImpl ->getModel_noCreate(),UNO_QUERY_THROW );
     139           0 :                     if ( !xModel->getControllers()->hasMoreElements() )
     140             :                     {
     141           0 :                         Reference<util::XCloseable> xCloseable(xModel,UNO_QUERY_THROW);
     142           0 :                         xCloseable->close(sal_False);
     143           0 :                     }
     144             :                 }
     145           0 :                 catch(const CloseVetoException&)
     146             :                 {
     147           0 :                     throw TerminationVetoException();
     148             :                 }
     149           0 :             }
     150             :         };
     151             : 
     152           0 :         void SAL_CALL DatabaseDocumentLoader::queryTermination( const lang::EventObject& /*Event*/ ) throw (TerminationVetoException, RuntimeException, std::exception)
     153             :         {
     154           0 :             ::std::list< const ODatabaseModelImpl* > aCopy(m_aDatabaseDocuments);
     155           0 :             ::std::for_each(aCopy.begin(),aCopy.end(),TerminateFunctor());
     156           0 :         }
     157             : 
     158           0 :         void SAL_CALL DatabaseDocumentLoader::notifyTermination( const lang::EventObject& /*Event*/ ) throw (RuntimeException, std::exception)
     159             :         {
     160           0 :         }
     161             : 
     162           0 :         void SAL_CALL DatabaseDocumentLoader::disposing( const lang::EventObject& /*Source*/ ) throw (RuntimeException, std::exception)
     163             :         {
     164           0 :         }
     165             : 
     166             : // ODatabaseContext
     167             : 
     168           0 : ODatabaseContext::ODatabaseContext( const Reference< XComponentContext >& _rxContext )
     169             :     :DatabaseAccessContext_Base(m_aMutex)
     170             :     ,m_aContext( _rxContext )
     171           0 :     ,m_aContainerListeners(m_aMutex)
     172             : {
     173           0 :     m_pDatabaseDocumentLoader = new DatabaseDocumentLoader( _rxContext );
     174             : 
     175             : #ifndef DISABLE_SCRIPTING
     176           0 :     ::basic::BasicManagerRepository::registerCreationListener( *this );
     177             : #endif
     178             : 
     179           0 :     osl_atomic_increment( &m_refCount );
     180             :     {
     181           0 :         m_xDBRegistrationAggregate.set( createDataSourceRegistrations( m_aContext ), UNO_SET_THROW );
     182           0 :         m_xDatabaseRegistrations.set( m_xDBRegistrationAggregate, UNO_QUERY_THROW );
     183             : 
     184           0 :         m_xDBRegistrationAggregate->setDelegator( *this );
     185             :     }
     186           0 :     osl_atomic_decrement( &m_refCount );
     187           0 : }
     188             : 
     189           0 : ODatabaseContext::~ODatabaseContext()
     190             : {
     191             : #ifndef DISABLE_SCRIPTING
     192           0 :     ::basic::BasicManagerRepository::revokeCreationListener( *this );
     193             : #endif
     194             : 
     195           0 :     if ( m_pDatabaseDocumentLoader )
     196           0 :         m_pDatabaseDocumentLoader->release();
     197             : 
     198           0 :     m_xDBRegistrationAggregate->setDelegator( NULL );
     199           0 :     m_xDBRegistrationAggregate.clear();
     200           0 :     m_xDatabaseRegistrations.clear();
     201           0 : }
     202             : 
     203             : // Helper
     204           0 : OUString ODatabaseContext::getImplementationName_static() throw( RuntimeException )
     205             : {
     206           0 :     return OUString("com.sun.star.comp.dba.ODatabaseContext");
     207             : }
     208             : 
     209           0 : Reference< XInterface > ODatabaseContext::Create(const Reference< XComponentContext >& _rxContext)
     210             : {
     211           0 :     return *( new ODatabaseContext( _rxContext ) );
     212             : }
     213             : 
     214           0 : Sequence< OUString > ODatabaseContext::getSupportedServiceNames_static(void) throw( RuntimeException )
     215             : {
     216           0 :     Sequence< OUString > aSNS( 1 );
     217           0 :     aSNS[0] = "com.sun.star.sdb.DatabaseContext";
     218           0 :     return aSNS;
     219             : }
     220             : 
     221             : // XServiceInfo
     222           0 : OUString ODatabaseContext::getImplementationName(  ) throw(RuntimeException, std::exception)
     223             : {
     224           0 :     return getImplementationName_static();
     225             : }
     226             : 
     227           0 : sal_Bool ODatabaseContext::supportsService( const OUString& _rServiceName ) throw (RuntimeException, std::exception)
     228             : {
     229           0 :     return cppu::supportsService(this, _rServiceName);
     230             : }
     231             : 
     232           0 : Sequence< OUString > ODatabaseContext::getSupportedServiceNames(  ) throw (RuntimeException, std::exception)
     233             : {
     234           0 :     return getSupportedServiceNames_static();
     235             : }
     236             : 
     237           0 : Reference< XInterface > ODatabaseContext::impl_createNewDataSource()
     238             : {
     239           0 :     ::rtl::Reference<ODatabaseModelImpl> pImpl( new ODatabaseModelImpl( m_aContext, *this ) );
     240           0 :     Reference< XDataSource > xDataSource( pImpl->getOrCreateDataSource() );
     241             : 
     242           0 :     return xDataSource.get();
     243             : }
     244             : 
     245           0 : Reference< XInterface > SAL_CALL ODatabaseContext::createInstance(  ) throw (Exception, RuntimeException, std::exception)
     246             : {
     247             :     // for convenience of the API user, we ensure the document is fully initialized (effectively: XLoadable::initNew
     248             :     // has been called at the DatabaseDocument).
     249           0 :     return impl_createNewDataSource();
     250             : }
     251             : 
     252           0 : Reference< XInterface > SAL_CALL ODatabaseContext::createInstanceWithArguments( const Sequence< Any >& _rArguments ) throw (Exception, RuntimeException, std::exception)
     253             : {
     254           0 :     ::comphelper::NamedValueCollection aArgs( _rArguments );
     255           0 :     OUString sURL = aArgs.getOrDefault( (OUString)INFO_POOLURL, OUString() );
     256             : 
     257           0 :     Reference< XInterface > xDataSource;
     258           0 :     if ( !sURL.isEmpty() )
     259           0 :         xDataSource = getObject( sURL );
     260             : 
     261           0 :     if ( !xDataSource.is() )
     262           0 :         xDataSource = impl_createNewDataSource();
     263             : 
     264           0 :     return xDataSource;
     265             : }
     266             : 
     267             : // DatabaseAccessContext_Base
     268           0 : void ODatabaseContext::disposing()
     269             : {
     270             :     // notify our listener
     271           0 :     com::sun::star::lang::EventObject aDisposeEvent(static_cast< XContainer* >(this));
     272           0 :     m_aContainerListeners.disposeAndClear(aDisposeEvent);
     273             : 
     274             :     // dispose the data sources
     275             :     // disposing seems to remove elements, so work on copy for valid iterators
     276           0 :     ObjectCache objCopy(m_aDatabaseObjects);
     277           0 :     ObjectCache::iterator const aEnd = objCopy.end();
     278           0 :     for (   ObjectCache::iterator aIter = objCopy.begin();
     279             :             aIter != aEnd;
     280             :             ++aIter
     281             :         )
     282             :     {
     283           0 :         rtl::Reference< ODatabaseModelImpl > obj(aIter->second);
     284             :             // make sure obj is acquired and does not delete itself from within
     285             :             // dispose()
     286           0 :         obj->dispose();
     287           0 :     }
     288           0 :     m_aDatabaseObjects.clear();
     289           0 : }
     290             : 
     291             : // XNamingService
     292           0 : Reference< XInterface >  ODatabaseContext::getRegisteredObject(const OUString& _rName) throw( Exception, RuntimeException, std::exception )
     293             : {
     294           0 :     MutexGuard aGuard(m_aMutex);
     295           0 :     ::connectivity::checkDisposed(DatabaseAccessContext_Base::rBHelper.bDisposed);
     296             : 
     297           0 :     OUString sURL( getDatabaseLocation( _rName ) );
     298             : 
     299           0 :     if ( sURL.isEmpty() )
     300             :         // there is a registration for this name, but no URL
     301           0 :         throw IllegalArgumentException();
     302             : 
     303             :     // check if URL is already loaded
     304           0 :     Reference< XInterface > xExistent = getObject( sURL );
     305           0 :     if ( xExistent.is() )
     306           0 :         return xExistent;
     307             : 
     308           0 :     return loadObjectFromURL( _rName, sURL );
     309             : }
     310             : 
     311           0 : Reference< XInterface > ODatabaseContext::loadObjectFromURL(const OUString& _rName,const OUString& _sURL)
     312             : {
     313           0 :     INetURLObject aURL( _sURL );
     314           0 :     if ( aURL.GetProtocol() == INET_PROT_NOT_VALID )
     315           0 :         throw NoSuchElementException( _rName, *this );
     316             : 
     317             :     try
     318             :     {
     319           0 :         ::ucbhelper::Content aContent( _sURL, NULL, comphelper::getProcessComponentContext() );
     320           0 :         if ( !aContent.isDocument() )
     321             :             throw InteractiveIOException(
     322             :                 _sURL, *this, InteractionClassification_ERROR, IOErrorCode_NO_FILE
     323           0 :             );
     324             :     }
     325           0 :     catch ( const InteractiveIOException& e )
     326             :     {
     327           0 :         if  (   ( e.Code == IOErrorCode_NO_FILE )
     328           0 :             ||  ( e.Code == IOErrorCode_NOT_EXISTING )
     329           0 :             ||  ( e.Code == IOErrorCode_NOT_EXISTING_PATH )
     330             :             )
     331             :         {
     332             :             // #i40463# #i39187#
     333           0 :             OUString sErrorMessage( DBACORE_RESSTRING( RID_STR_FILE_DOES_NOT_EXIST ) );
     334           0 :             ::svt::OFileNotation aTransformer( _sURL );
     335             : 
     336           0 :             SQLException aError;
     337           0 :             aError.Message = sErrorMessage.replaceAll( "$file$", aTransformer.get( ::svt::OFileNotation::N_SYSTEM ) );
     338             : 
     339           0 :             throw WrappedTargetException( _sURL, *this, makeAny( aError ) );
     340             :         }
     341           0 :         throw WrappedTargetException( _sURL, *this, ::cppu::getCaughtException() );
     342             :     }
     343           0 :     catch( const Exception& )
     344             :     {
     345           0 :         throw WrappedTargetException( _sURL, *this, ::cppu::getCaughtException() );
     346             :     }
     347             : 
     348             :     OSL_ENSURE( m_aDatabaseObjects.find( _sURL ) == m_aDatabaseObjects.end(),
     349             :         "ODatabaseContext::loadObjectFromURL: not intended for already-cached objects!" );
     350             : 
     351           0 :     ::rtl::Reference< ODatabaseModelImpl > pModelImpl;
     352             :     {
     353           0 :         pModelImpl.set( new ODatabaseModelImpl( _rName, m_aContext, *this ) );
     354             : 
     355           0 :         Reference< XModel > xModel( pModelImpl->createNewModel_deliverOwnership( false ), UNO_SET_THROW );
     356           0 :         Reference< XLoadable > xLoad( xModel, UNO_QUERY_THROW );
     357             : 
     358           0 :         ::comphelper::NamedValueCollection aArgs;
     359           0 :         aArgs.put( "URL", _sURL );
     360           0 :         aArgs.put( "MacroExecutionMode", MacroExecMode::USE_CONFIG );
     361           0 :         aArgs.put( "InteractionHandler", task::InteractionHandler::createWithParent(m_aContext, 0) );
     362             : 
     363           0 :         Sequence< PropertyValue > aResource( aArgs.getPropertyValues() );
     364           0 :         xLoad->load( aResource );
     365           0 :         xModel->attachResource( _sURL, aResource );
     366             : 
     367           0 :         ::utl::CloseableComponent aEnsureClose( xModel );
     368             :     }
     369             : 
     370           0 :     setTransientProperties( _sURL, *pModelImpl );
     371             : 
     372           0 :     return pModelImpl->getOrCreateDataSource().get();
     373             : }
     374             : 
     375           0 : void ODatabaseContext::appendAtTerminateListener(const ODatabaseModelImpl& _rDataSourceModel)
     376             : {
     377           0 :     m_pDatabaseDocumentLoader->append(_rDataSourceModel);
     378           0 : }
     379             : 
     380           0 : void ODatabaseContext::removeFromTerminateListener(const ODatabaseModelImpl& _rDataSourceModel)
     381             : {
     382           0 :     m_pDatabaseDocumentLoader->remove(_rDataSourceModel);
     383           0 : }
     384             : 
     385           0 : void ODatabaseContext::setTransientProperties(const OUString& _sURL, ODatabaseModelImpl& _rDataSourceModel )
     386             : {
     387           0 :     if ( m_aDatasourceProperties.end() == m_aDatasourceProperties.find(_sURL) )
     388           0 :         return;
     389             :     try
     390             :     {
     391           0 :         OUString sAuthFailedPassword;
     392           0 :         Reference< XPropertySet > xDSProps( _rDataSourceModel.getOrCreateDataSource(), UNO_QUERY_THROW );
     393           0 :         const Sequence< PropertyValue >& rSessionPersistentProps = m_aDatasourceProperties[_sURL];
     394           0 :         const PropertyValue* pProp = rSessionPersistentProps.getConstArray();
     395           0 :         const PropertyValue* pPropsEnd = rSessionPersistentProps.getConstArray() + rSessionPersistentProps.getLength();
     396           0 :         for ( ; pProp != pPropsEnd; ++pProp )
     397             :         {
     398           0 :             if ( pProp->Name == "AuthFailedPassword" )
     399             :             {
     400           0 :                 OSL_VERIFY( pProp->Value >>= sAuthFailedPassword );
     401             :             }
     402             :             else
     403             :             {
     404           0 :                 xDSProps->setPropertyValue( pProp->Name, pProp->Value );
     405             :             }
     406             :         }
     407             : 
     408           0 :         _rDataSourceModel.m_sFailedPassword = sAuthFailedPassword;
     409             :     }
     410           0 :     catch( const Exception& )
     411             :     {
     412             :         DBG_UNHANDLED_EXCEPTION();
     413             :     }
     414             : }
     415             : 
     416           0 : void ODatabaseContext::registerObject(const OUString& _rName, const Reference< XInterface > & _rxObject) throw( Exception, RuntimeException, std::exception )
     417             : {
     418           0 :     MutexGuard aGuard(m_aMutex);
     419           0 :     ::connectivity::checkDisposed(DatabaseAccessContext_Base::rBHelper.bDisposed);
     420             : 
     421           0 :     if ( _rName.isEmpty() )
     422           0 :         throw IllegalArgumentException( OUString(), *this, 1 );
     423             : 
     424           0 :     Reference< XDocumentDataSource > xDocDataSource( _rxObject, UNO_QUERY );
     425           0 :     Reference< XModel > xModel( xDocDataSource.is() ? xDocDataSource->getDatabaseDocument() : Reference< XOfficeDatabaseDocument >(), UNO_QUERY );
     426           0 :     if ( !xModel.is() )
     427           0 :         throw IllegalArgumentException( OUString(), *this, 2 );
     428             : 
     429           0 :     OUString sURL = xModel->getURL();
     430           0 :     if ( sURL.isEmpty() )
     431           0 :         throw IllegalArgumentException( DBACORE_RESSTRING( RID_STR_DATASOURCE_NOT_STORED ), *this, 2 );
     432             : 
     433           0 :     registerDatabaseLocation( _rName, sURL );
     434             : 
     435           0 :     ODatabaseSource::setName( xDocDataSource, _rName, ODatabaseSource::DBContextAccess() );
     436             : 
     437             :     // notify our container listeners
     438           0 :     ContainerEvent aEvent(static_cast<XContainer*>(this), makeAny(_rName), makeAny(_rxObject), Any());
     439           0 :     m_aContainerListeners.notifyEach( &XContainerListener::elementInserted, aEvent );
     440           0 : }
     441             : 
     442           0 : void ODatabaseContext::storeTransientProperties( ODatabaseModelImpl& _rModelImpl)
     443             : {
     444           0 :     Reference< XPropertySet > xSource( _rModelImpl.getOrCreateDataSource(), UNO_QUERY );
     445           0 :     ::comphelper::NamedValueCollection aRememberProps;
     446             : 
     447             :     try
     448             :     {
     449             :         // get the info about the properties, check which ones are transient and not readonly
     450           0 :         Reference< XPropertySetInfo > xSetInfo;
     451           0 :         if (xSource.is())
     452           0 :             xSetInfo = xSource->getPropertySetInfo();
     453           0 :         Sequence< Property > aProperties;
     454           0 :         if (xSetInfo.is())
     455           0 :             aProperties = xSetInfo->getProperties();
     456             : 
     457           0 :         if (aProperties.getLength())
     458             :         {
     459           0 :             const Property* pProperties = aProperties.getConstArray();
     460           0 :             for ( sal_Int32 i=0; i<aProperties.getLength(); ++i, ++pProperties )
     461             :             {
     462           0 :                 if  (   ( ( pProperties->Attributes & PropertyAttribute::TRANSIENT) != 0 )
     463           0 :                     &&  ( ( pProperties->Attributes & PropertyAttribute::READONLY) == 0 )
     464             :                     )
     465             :                 {
     466             :                     // found such a property
     467           0 :                     aRememberProps.put( pProperties->Name, xSource->getPropertyValue( pProperties->Name ) );
     468             :                 }
     469             :             }
     470           0 :         }
     471             :     }
     472           0 :     catch ( const Exception& )
     473             :     {
     474             :         DBG_UNHANDLED_EXCEPTION();
     475             :     }
     476             : 
     477             :     // additionally, remember the "failed password", which is not available as property
     478             :     // #i86178#
     479           0 :     aRememberProps.put( "AuthFailedPassword", _rModelImpl.m_sFailedPassword );
     480             : 
     481           0 :     OUString sDocumentURL( _rModelImpl.getURL() );
     482           0 :     if ( m_aDatabaseObjects.find( sDocumentURL ) != m_aDatabaseObjects.end() )
     483             :     {
     484           0 :         m_aDatasourceProperties[ sDocumentURL ] = aRememberProps.getPropertyValues();
     485             :     }
     486           0 :     else if ( m_aDatabaseObjects.find( _rModelImpl.m_sName ) != m_aDatabaseObjects.end() )
     487             :     {
     488             :         OSL_FAIL( "ODatabaseContext::storeTransientProperties: a database document register by name? This shouldn't happen anymore!" );
     489             :             // all the code should have been changed so that registration is by URL only
     490           0 :         m_aDatasourceProperties[ _rModelImpl.m_sName ] = aRememberProps.getPropertyValues();
     491             :     }
     492             :     else
     493             :     {
     494             :         OSL_ENSURE(  sDocumentURL.isEmpty()  &&  _rModelImpl.m_sName.isEmpty() ,
     495             :             "ODatabaseContext::storeTransientProperties: a non-empty data source which I do not know?!" );
     496           0 :     }
     497           0 : }
     498             : 
     499           0 : void SAL_CALL ODatabaseContext::addContainerListener( const Reference< XContainerListener >& _rxListener ) throw(RuntimeException, std::exception)
     500             : {
     501           0 :     m_aContainerListeners.addInterface(_rxListener);
     502           0 : }
     503             : 
     504           0 : void SAL_CALL ODatabaseContext::removeContainerListener( const Reference< XContainerListener >& _rxListener ) throw(RuntimeException, std::exception)
     505             : {
     506           0 :     m_aContainerListeners.removeInterface(_rxListener);
     507           0 : }
     508             : 
     509           0 : void ODatabaseContext::revokeObject(const OUString& _rName) throw( Exception, RuntimeException, std::exception )
     510             : {
     511           0 :     ClearableMutexGuard aGuard(m_aMutex);
     512           0 :     ::connectivity::checkDisposed(DatabaseAccessContext_Base::rBHelper.bDisposed);
     513             : 
     514           0 :     OUString sURL = getDatabaseLocation( _rName );
     515             : 
     516           0 :     revokeDatabaseLocation( _rName );
     517             :         // will throw if something goes wrong
     518             : 
     519           0 :     if ( m_aDatabaseObjects.find( _rName ) != m_aDatabaseObjects.end() )
     520             :     {
     521           0 :         m_aDatasourceProperties[ sURL ] = m_aDatasourceProperties[ _rName ];
     522             :     }
     523             : 
     524             :     // check if URL is already loaded
     525           0 :     ObjectCache::iterator aExistent = m_aDatabaseObjects.find( sURL );
     526           0 :     if ( aExistent != m_aDatabaseObjects.end() )
     527           0 :         m_aDatabaseObjects.erase( aExistent );
     528             : 
     529             :     // notify our container listeners
     530           0 :     ContainerEvent aEvent( *this, makeAny( _rName ), Any(), Any() );
     531           0 :     aGuard.clear();
     532           0 :     m_aContainerListeners.notifyEach( &XContainerListener::elementRemoved, aEvent );
     533           0 : }
     534             : 
     535           0 : sal_Bool SAL_CALL ODatabaseContext::hasRegisteredDatabase( const OUString& _Name ) throw (IllegalArgumentException, RuntimeException, std::exception)
     536             : {
     537           0 :     return m_xDatabaseRegistrations->hasRegisteredDatabase( _Name );
     538             : }
     539             : 
     540           0 : Sequence< OUString > SAL_CALL ODatabaseContext::getRegistrationNames() throw (RuntimeException, std::exception)
     541             : {
     542           0 :     return m_xDatabaseRegistrations->getRegistrationNames();
     543             : }
     544             : 
     545           0 : OUString SAL_CALL ODatabaseContext::getDatabaseLocation( const OUString& _Name ) throw (IllegalArgumentException, NoSuchElementException, RuntimeException, std::exception)
     546             : {
     547           0 :     return m_xDatabaseRegistrations->getDatabaseLocation( _Name );
     548             : }
     549             : 
     550           0 : void SAL_CALL ODatabaseContext::registerDatabaseLocation( const OUString& _Name, const OUString& _Location ) throw (IllegalArgumentException, ElementExistException, RuntimeException, std::exception)
     551             : {
     552           0 :     m_xDatabaseRegistrations->registerDatabaseLocation( _Name, _Location );
     553           0 : }
     554             : 
     555           0 : void SAL_CALL ODatabaseContext::revokeDatabaseLocation( const OUString& _Name ) throw (IllegalArgumentException, NoSuchElementException, IllegalAccessException, RuntimeException, std::exception)
     556             : {
     557           0 :     m_xDatabaseRegistrations->revokeDatabaseLocation( _Name );
     558           0 : }
     559             : 
     560           0 : void SAL_CALL ODatabaseContext::changeDatabaseLocation( const OUString& _Name, const OUString& _NewLocation ) throw (IllegalArgumentException, NoSuchElementException, IllegalAccessException, RuntimeException, std::exception)
     561             : {
     562           0 :     m_xDatabaseRegistrations->changeDatabaseLocation( _Name, _NewLocation );
     563           0 : }
     564             : 
     565           0 : sal_Bool SAL_CALL ODatabaseContext::isDatabaseRegistrationReadOnly( const OUString& _Name ) throw (IllegalArgumentException, NoSuchElementException, RuntimeException, std::exception)
     566             : {
     567           0 :     return m_xDatabaseRegistrations->isDatabaseRegistrationReadOnly( _Name );
     568             : }
     569             : 
     570           0 : void SAL_CALL ODatabaseContext::addDatabaseRegistrationsListener( const Reference< XDatabaseRegistrationsListener >& _Listener ) throw (RuntimeException, std::exception)
     571             : {
     572           0 :     m_xDatabaseRegistrations->addDatabaseRegistrationsListener( _Listener );
     573           0 : }
     574             : 
     575           0 : void SAL_CALL ODatabaseContext::removeDatabaseRegistrationsListener( const Reference< XDatabaseRegistrationsListener >& _Listener ) throw (RuntimeException, std::exception)
     576             : {
     577           0 :     m_xDatabaseRegistrations->removeDatabaseRegistrationsListener( _Listener );
     578           0 : }
     579             : 
     580             : // ::com::sun::star::container::XElementAccess
     581           0 : Type ODatabaseContext::getElementType(  ) throw(RuntimeException, std::exception)
     582             : {
     583           0 :     return::getCppuType(static_cast<Reference<XDataSource>*>(NULL));
     584             : }
     585             : 
     586           0 : sal_Bool ODatabaseContext::hasElements(void) throw( RuntimeException, std::exception )
     587             : {
     588           0 :     MutexGuard aGuard(m_aMutex);
     589           0 :     ::connectivity::checkDisposed(DatabaseAccessContext_Base::rBHelper.bDisposed);
     590             : 
     591           0 :     return 0 != getElementNames().getLength();
     592             : }
     593             : 
     594             : // ::com::sun::star::container::XEnumerationAccess
     595           0 : Reference< ::com::sun::star::container::XEnumeration >  ODatabaseContext::createEnumeration(void) throw( RuntimeException, std::exception )
     596             : {
     597           0 :     MutexGuard aGuard(m_aMutex);
     598           0 :     return new ::comphelper::OEnumerationByName(static_cast<XNameAccess*>(this));
     599             : }
     600             : 
     601             : // ::com::sun::star::container::XNameAccess
     602           0 : Any ODatabaseContext::getByName(const OUString& _rName) throw( NoSuchElementException,
     603             :                                                           WrappedTargetException, RuntimeException, std::exception )
     604             : {
     605           0 :     MutexGuard aGuard(m_aMutex);
     606           0 :     ::connectivity::checkDisposed(DatabaseAccessContext_Base::rBHelper.bDisposed);
     607           0 :     if ( _rName.isEmpty() )
     608           0 :         throw NoSuchElementException(_rName, *this);
     609             : 
     610             :     try
     611             :     {
     612           0 :         Reference< XInterface > xExistent = getObject( _rName );
     613           0 :         if ( xExistent.is() )
     614           0 :             return makeAny( xExistent );
     615             : 
     616             :         // see whether this is an registered name
     617           0 :         OUString sURL;
     618           0 :         if ( hasRegisteredDatabase( _rName ) )
     619             :         {
     620           0 :             sURL = getDatabaseLocation( _rName );
     621             :             // is the object cached under its URL?
     622           0 :             xExistent = getObject( sURL );
     623             :         }
     624             :         else
     625             :             // interpret the name as URL
     626           0 :             sURL = _rName;
     627             : 
     628           0 :         if ( !xExistent.is() )
     629             :             // try to load this as URL
     630           0 :             xExistent = loadObjectFromURL( _rName, sURL );
     631           0 :         return makeAny( xExistent );
     632             :     }
     633           0 :     catch (const NoSuchElementException&)
     634             :     {   // let these exceptions through
     635           0 :         throw;
     636             :     }
     637           0 :     catch (const WrappedTargetException&)
     638             :     {   // let these exceptions through
     639           0 :         throw;
     640             :     }
     641           0 :     catch (const RuntimeException&)
     642             :     {   // let these exceptions through
     643           0 :         throw;
     644             :     }
     645           0 :     catch (const Exception&)
     646             :     {   // exceptions other than the speciafied ones -> wrap
     647           0 :         Any aError = ::cppu::getCaughtException();
     648           0 :         throw WrappedTargetException(_rName, *this, aError );
     649           0 :     }
     650             : }
     651             : 
     652           0 : Sequence< OUString > ODatabaseContext::getElementNames(void) throw( RuntimeException, std::exception )
     653             : {
     654           0 :     MutexGuard aGuard(m_aMutex);
     655           0 :     ::connectivity::checkDisposed(DatabaseAccessContext_Base::rBHelper.bDisposed);
     656             : 
     657           0 :     return getRegistrationNames();
     658             : }
     659             : 
     660           0 : sal_Bool ODatabaseContext::hasByName(const OUString& _rName) throw( RuntimeException, std::exception )
     661             : {
     662           0 :     MutexGuard aGuard(m_aMutex);
     663           0 :     ::connectivity::checkDisposed(DatabaseAccessContext_Base::rBHelper.bDisposed);
     664             : 
     665           0 :     return hasRegisteredDatabase( _rName );
     666             : }
     667             : 
     668           0 : Reference< XInterface > ODatabaseContext::getObject( const OUString& _rURL )
     669             : {
     670           0 :     ObjectCache::iterator aFind = m_aDatabaseObjects.find( _rURL );
     671           0 :     Reference< XInterface > xExistent;
     672           0 :     if ( aFind != m_aDatabaseObjects.end() )
     673           0 :         xExistent = aFind->second->getOrCreateDataSource();
     674           0 :     return xExistent;
     675             : }
     676             : 
     677           0 : void ODatabaseContext::registerDatabaseDocument( ODatabaseModelImpl& _rModelImpl )
     678             : {
     679           0 :     OUString sURL( _rModelImpl.getURL() );
     680             : #if OSL_DEBUG_LEVEL > 1
     681             :     OSL_TRACE( "DatabaseContext: registering %s", OUStringToOString( sURL, RTL_TEXTENCODING_UTF8 ).getStr() );
     682             : #endif
     683           0 :     if ( m_aDatabaseObjects.find( sURL ) == m_aDatabaseObjects.end() )
     684             :     {
     685           0 :         m_aDatabaseObjects[ sURL ] = &_rModelImpl;
     686           0 :         setTransientProperties( sURL, _rModelImpl );
     687             :     }
     688             :     else
     689           0 :         OSL_FAIL( "ODatabaseContext::registerDatabaseDocument: already have an object registered for this URL!" );
     690           0 : }
     691             : 
     692           0 : void ODatabaseContext::revokeDatabaseDocument( const ODatabaseModelImpl& _rModelImpl )
     693             : {
     694           0 :     OUString sURL( _rModelImpl.getURL() );
     695             : #if OSL_DEBUG_LEVEL > 1
     696             :     OSL_TRACE( "DatabaseContext: deregistering %s", OUStringToOString( sURL, RTL_TEXTENCODING_UTF8 ).getStr() );
     697             : #endif
     698           0 :     m_aDatabaseObjects.erase( sURL );
     699           0 : }
     700             : 
     701           0 : void ODatabaseContext::databaseDocumentURLChange( const OUString& _rOldURL, const OUString& _rNewURL )
     702             : {
     703             : #if OSL_DEBUG_LEVEL > 1
     704             :     OSL_TRACE( "DatabaseContext: changing registration from %s to %s",
     705             :         OUStringToOString( _rOldURL, RTL_TEXTENCODING_UTF8 ).getStr(),
     706             :         OUStringToOString( _rNewURL, RTL_TEXTENCODING_UTF8 ).getStr() );
     707             : #endif
     708           0 :     ObjectCache::iterator oldPos = m_aDatabaseObjects.find( _rOldURL );
     709           0 :     ENSURE_OR_THROW( oldPos != m_aDatabaseObjects.end(), "illegal old database document URL" );
     710           0 :     ObjectCache::iterator newPos = m_aDatabaseObjects.find( _rNewURL );
     711           0 :     ENSURE_OR_THROW( newPos == m_aDatabaseObjects.end(), "illegal new database document URL" );
     712             : 
     713           0 :     m_aDatabaseObjects[ _rNewURL ] = oldPos->second;
     714           0 :     m_aDatabaseObjects.erase( oldPos );
     715           0 : }
     716             : 
     717           0 : sal_Int64 SAL_CALL ODatabaseContext::getSomething( const Sequence< sal_Int8 >& rId ) throw(RuntimeException, std::exception)
     718             : {
     719           0 :     if (rId.getLength() == 16 && 0 == memcmp(getUnoTunnelImplementationId().getConstArray(),  rId.getConstArray(), 16 ) )
     720           0 :         return reinterpret_cast<sal_Int64>(this);
     721             : 
     722           0 :     return 0;
     723             : }
     724             : 
     725           0 : Sequence< sal_Int8 > ODatabaseContext::getUnoTunnelImplementationId()
     726             : {
     727             :     static ::cppu::OImplementationId * pId = 0;
     728           0 :     if (! pId)
     729             :     {
     730           0 :         ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
     731           0 :         if (! pId)
     732             :         {
     733           0 :             static ::cppu::OImplementationId aId;
     734           0 :             pId = &aId;
     735           0 :         }
     736             :     }
     737           0 :     return pId->getImplementationId();
     738             : }
     739             : 
     740           0 : void ODatabaseContext::onBasicManagerCreated( const Reference< XModel >& _rxForDocument, BasicManager& _rBasicManager )
     741             : {
     742             : #ifdef DISABLE_SCRIPTING
     743             :     (void) _rxForDocument;
     744             :     (void) _rBasicManager;
     745             : #else
     746             :     // if it's a database document ...
     747           0 :     Reference< XOfficeDatabaseDocument > xDatabaseDocument( _rxForDocument, UNO_QUERY );
     748             :     // ... or a sub document of a database document ...
     749           0 :     if ( !xDatabaseDocument.is() )
     750             :     {
     751           0 :         Reference< XChild > xDocAsChild( _rxForDocument, UNO_QUERY );
     752           0 :         if ( xDocAsChild.is() )
     753           0 :             xDatabaseDocument.set( xDocAsChild->getParent(), UNO_QUERY );
     754             :     }
     755             : 
     756             :     // ... whose BasicManager has just been created, then add the global DatabaseDocument variable to its scope.
     757           0 :     if ( xDatabaseDocument.is() )
     758           0 :         _rBasicManager.SetGlobalUNOConstant( "ThisDatabaseDocument", makeAny( xDatabaseDocument ) );
     759             : #endif
     760           0 : }
     761             : 
     762             : }   // namespace dbaccess
     763             : 
     764             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10